OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】Flutterで簡単かつクオリティの高いアニメーションを実装する方法

# はじめに
Flutterでは、MaterialDesignに則って、デザインの知識がなくとも、そこそこの見栄えのUIが作れます。
が、作り込むことでより洗練され、使いやすい、あるいは使いたくなるようなアプリにすることができると思ってます。

作り込みには、フォントや画像、アイコン、配色など色々ありますが、**今回はアニメーションについての記事**となります。

# 想定読者
・Flutterのアニメーションでどんなことができるか知りたい。
・Flutterでアニメーションを実装したい

# 前提
**前提として、独自のアニメーションを実装する方法は紹介しません**。
今回紹介するのは、[animations](https://pub.dev/packages/animations)というパッケージです。

なぜ、独自のアニメーションを実装する方法ではなく、パッケージを紹介するのかというと理由は二点あります。
・アニメーションの知識がないとそもそも効果的なアニメーションを作れないから
・クオリティが高いアニメーションを実装するのは初心者には難しいから

スキルアップのために、独自で実装する方法も勉強するべきだとは思いますが、独自の実装はハードルが高いと思ってます。
（というか、実際私は挫折しました）

例えば、下記の動画を見てほしいです。

https://youtu.be/yI-8QHpGIP4

すごく簡単にアニメーションを実装できるなぁという印象を抱きますが、**実際これをどうアプリに組み込めばいいのか**？って部分は、わからなかったです。
正確にいうと、アプリに組み込めはしますが、**実装方法を知るだけでは、効果的な使い方がわからない**です。有名なアプリのアニメーションを参考にしたり、アニメーション自体の勉強を別途しないと効果的な使い方ができないと思います。

なので、初心者が効果的に使えるアニメーションの勉強をするにはまず[animations](https://pub.dev/packages/animations)を学び、ある程度自由に使えるようになった後、詳しい実装方法を知りたいとか、独自のアニメーションを実装したいというタイミングで、アニメーションについて学んでいくのがいいのかなと考えました。

もし独自でアニメーションを実装する方法を勉強したいという方は、以下の記事が大変参考になりますので、ご参照ください。

https://medium.com/flutter-jp/implicit-animation-b9d4b7358c28

https://medium.com/flutter-jp/transition-9c57528c84b8

またアニメーションの取り入れ方について学びたい場合は、下記のページが参考になります。

https://m2.material.io/design/motion/understanding-motion.html#principles


# 実装可能な４パターン
それでは本題の[animations](https://pub.dev/packages/animations)について説明していきます。
このパッケージには実装可能なパターンが以下の四つあります。
- Container transform
- Shared axis
- Fade through
- Fade

どういう動きになるかはそれぞれ記事を見ていただけるとわかりやすいと思いますが、簡単に説明していきたいと思います。

### Container transform

[サンプル](https://pub.dev/packages/animations#container-transform)のように、コンテナが変形することにより、二つのUIを表示するアニメーションです。
よく見られるのは、**アルバムなどの画像をグリッドで表示する一覧ページ上で、各項目をタップした時、その画像が画面全体に広がりながら、詳細ページに遷移するアニメーション**でしょうか。

### Shared axis
[サンプル](https://pub.dev/packages/animations#shared-axis)のように、画面を左右、上下、前面に移動させながらUIを表示するアニメーションです。
**フリックでページを切り替えるときにフリックの方向にアニメーションさせたり、オーバレイを強調表示したいときに使える**かと思います。

### Fade through
[サンプル](https://pub.dev/packages/animations#fade-through)のように、表示を切り替える際にフェードするアニメーションです。
説明では、**強い関係性がない要素の遷移時に使用する**ようです。サンプルにあるように、ボトムナビゲーションバーでコンテンツを切り替えたりするときに使うと良さそうですね。

### Fade
[サンプルのように](https://pub.dev/packages/animations#fade)、**ダイアログやスナックバーのような何かのタイミングで表示(または非表示)するUIの表示・非表示のタイミングでフェードするアニメーション**です。

# 実装方法
サンプルコードを書こうと思ったのですが、紹介されているチュートリアル的なものがとてもわかりやすかったのでそっちを紹介しておきます。
簡単に実装できて、動きを体感できるのでぜひ試してみてください。

https://codelabs.developers.google.com/codelabs/material-motion-flutter#0

# おわりに

個人的に、iPhoneのギャラリーのアニメーションを実装してみたくて、試行錯誤しながら実装進めてたのですが、このパッケージ使えば簡単に実装できることに気づきました。
完成したらまた別記事で紹介してみたいと思います。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">iOSのギャラリーの画面遷移を模したものを実装中。</p>&mdash; 今井　智 (@MLLB60944015) <a href="https://twitter.com/MLLB60944015/status/1629113092230758402?ref_src=twsrc%5Etfw">February 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
CloudFront のログが S3 バケットに保存されない時は ACL を確認

CloudFront の標準ログ記録機能を使うと、S3 バケットにログを保存して Athena でクエリを使って検索できるのでとても便利です。

CloudFront ディストリビューションの設定に標準ログ記録の設定がありますが、ここを有効にしただけではログが正常に保存されません。
![スクリーンショット 2023-03-15 17.10.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1488939/12955ced-4fef-f360-30df-8ec1f16a9a5a.png)

# S3 の設定
CloudFront のログを S3 バケットで受け取るためには、S3 バケットの ACL の設定を有効にする必要があります。
バケット作成時は以下から設定します。
![スクリーンショット 2023-03-15 17.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1488939/28a70422-5d60-0113-0271-348d670803bd.png)
これで、あとは CloudFront の標準ログ記録を有効になっていれば記録が始まります。

バケット作成済みでも問題ありません。
バケットの ACL 設定から CloudFront のログをバケットに書き込むアカウントの正規 ID を手動で追加できます。
以下の正規 ID を設定します。

```
正規ID : c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0
オブジェクト : リスト許可・書き込み許可
バケット ACL : 読み込み許可・書き込み許可
```

これは awslogsdelivery のアカウント正規 ID でどの環境でもこのアカウントを設定します。

バケットのアクセス許可のタブの下の方にある「アクセスコントロールリスト (ACL)」の編集ボタンから以下のように設定します。

![スクリーンショット 2023-03-15 17.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1488939/a309a360-4d7f-0f8e-3e94-3fb89fb7ada1.png)

少し待って S3 バケットにログが記録され始めれば成功です。

# 参考
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html

https://dev.classmethod.jp/articles/cloudfront-access-log-dont-choose-no-acl-s3-bucket/

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html
C言語でSTLコンテナ(std::vector)を再現してみる


# プロローグ
私がこの記事を書こうと思ったきっかけは、あるどこかのプログラミングサイトで「C言語でもSTLコンテナ(std::vector)」のような動かすにはどうしたらいいのだろうと思ったからです。

# 免責事項

本来なら、アロケーターの部分を考慮しなければならないのですが、まずは
（実力がない）
アロケーターを考慮しないことにします...。



## push_back関数を再現してみる

安直に考えたこととしては、<b><font color="#0000ff">stdlib.h</font></b> に入っている<b><font size=5 color="ff0000">malloc関数</font></b>を使ってみることにしました。


``` main.c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int* array = NULL;
size_t size = 0;

///<summary>
///値を追加する関数
///<summary>
///<param name="index"> 追加いしたい値</param>
///<return>成功・失敗</return>
bool push_back(int value)
{
    size++;
    
    // 値を取得する
    int* tmp = (int*)realloc(array,size * sizeof(int));
    
    // ヒープ生成に失敗
    if(tmp == NULL)
    {
        return false;
    }

    // 今までの値を入れる
    for(int i = 0;i < size - 1;i++)
    {
        *(tmp + i) = *(array + i);
    }
    
    *(tmp + size - 1) = value;
    array = tmp;
    
    return true;
}
```

## erase関数を再現してみる
erase関数は以下のようになると思います。

``` main.c

///<summary>
///要素を削除
///<summary>
///<param name="index"> 削除したい要素</param>
///<return>成功・失敗</return>
bool erase(int index)
{
    if(0 <= index && index < size)
    {
        int* tmp = (int*)malloc((size - 1) * sizeof(int));
        
        if(tmp == NULL)
        {
            return false;
        }
        
        for(int i = 0;i < size;i++)
        {
            if(i > index)
            {
                *(tmp + i - 1) = *(array + i); 
            }
            else
            {
                *(tmp + i) = *(array + i);
            }
        }
        
        array = tmp;
        size--;
        return true;
    }
    else
    {
        return false;
    }
}

```

## clear関数を再現してみる
clear関数は以下のようになると思います。
``` main.c
///<summary>
///すべて削除
///<summary>
///<param name="index"> 削除したい要素</param>
///<return>成功・失敗</return>
bool clear()
{
    if(array == NULL)
    {
        return false;
    }
    
    array = NULL;
    size = 0;
    
    return true;
}

```

## empty関数を再現してみる
empty関数は以下のようになります
``` main.c

bool empty()
{
    return array == NULL ? true : false;
}

```

# 試しに使ってみました

以下のように実際に実行してみました
``` main.c

int main(void)
{
    array = malloc(1 * sizeof(int));
    
    if(array == NULL)
    {
        abort();
    }
    
    *(array + 0) = 0;
    
    for(int i = 0;i < 5;i++)
    {
        push_back(i + 1);
    }
    
    erase(2);    // 実際に消されているか確認する
    erase(-350); // 無効な値を入れてみる
    
    for(int i = 0;i < size;i++)
    {
        printf("%d\n",*(array + i));
    }
    
    clear();
    printf("empty %s\n",empty() == true ? "空です。" : "空ではありません");
    return 0;
}
```

# 実行結果
```
0
1
3
4
5
empty 空です。

status : 0
```

# 最後に
これが最善の方法ではないし、アロケーターを考慮したときに多分やり方とかが変わってくると思うので今後も改良したいと思います。

ありがとうございました。

<!-- EOF -->
Raspberry Pi Picoの初期設定

初期設定で詰まったので備忘録として。
Raspberry Pi Pico、以下ラズパイピコと略

#### ①MicroPythonをインストール
ここ (https://www.raspberrypi.com/documentation/microcontrollers/micropython.html) から"<font color="DeepPink">MicroPython</font>"のファームウェアをインストールします。

#### ②Thonnyをインストールする
1,　ここ (https://thonny.org/) からThonnyをインストールする。
2,　Thonnyを起動して最後の言語設定は、"Language"は"<font color="DeepPink">日本語</font>"、"Initial Setting"は"<font color="DeepPink">Standard</font>"を選択する。
3,　起動したら、[ツール]-[オプション]-[インタプリタ]で、
"Thonny はコードの実行にどのインタプリタまたはデバイスを使用すればよいですか？"は"<font color="DeepPink">MicroPython （Raspberry Pi Pico）</font>"を選択し、
"ポート"は"<font color="DeepPink">USBシリアルデバイス(COM)</font>"を選択する

#### ③ラズパイピコとパソコンを接続する
1,　ラズパイピコのBOOTSELボタンを押しながらパソコンに接続する。
2,　パソコンにラズパイピコが認識されるのでそこに①でインストールしたUF2ファイルをドラッグ&ドロップする。
3,　コピーが完了したら再起動されるので、ラズパイピコをパソコンから抜いてもう一度再接続する。

#### ④プログラムを書いてみる
```python:main.py
import machine
import utime
led = machine.Pin(25, machine.Pin.OUT)
while True:
    led.value(1) #点灯
    utime.sleep(5) #5秒待機
    led.value(0) #消灯
    utime.sleep(1) #1秒待機
```
保存先に[This computer]と[Raspberry Pi Pico]が選べるので<font color="DeepPink">[Raspberry Pi Pico]</font>を選んでファイル名を<font color="OrangeRed">main.py</font>にして保存すると外部電源に接続したときに起動する。
(リンクだけです)入試問題の「 86400 (number)」を 調べてみた。

オリジナル

https://qiita.com/mrrclb48z/items/5d55ee27184d0d89c13e

# 参考
＞1日が86,400秒

https://www.google.com/search?q=86400&rlz=1CAUHAM_enJP1038JP1038&oq=86400&aqs=chrome..69i57j35i39l2j0i512l2j69i60l2j69i61.869j0j7&sourceid=chrome&ie=UTF-8


https://qiita.com/mrrclb48z/items/810dba8d7e032d98da44


# おすすすめの過去問があれば教えて下さい。
Elixirでファイル圧縮/解凍

`:zip`を使う

https://www.erlang.org/doc/man/zip.html

## 圧縮 zip

```elixir
zip_name = ~c'file.zip'
target_list = [~c'./xx/a.txt', ~c'./xx/b.txt'] # ディレクトリも指定可

:zip.create(zip_name, target_list)
```

```elixir
# 圧縮対象のプレフィックスを指定したい場合
zip_name = ~c'file.zip'
target_list = [~c'a.txt', ~c'b.txt']
target_prefix = ~c'./xx' # target_listのプレフィックス

:zip.create(zip_name, target_list, cwd: target_prefix)
```

※distを相対パスで指定した場合、cwdに関係なくカレントディレクトリ基準になる

## 解凍 unzip

```elixir
zip_name = ~c'file.zip'
to_dir = ~c'./' # 解凍先

:zip.extract(zip_name, cwd: to_dir)
```

## 補足

- `:zip`は`:`から始まっていることからも分かる通り、Erlangのモジュール
- そのため、引数は String でなく **CharList** である点に注意
    - `'char_list'`表記は非推奨になる動きがあるので`~c'char_list'`を推奨
    - String から CharList へは`String.to_charlist/1`で変換できる
    - 実は一部の引数以外は String でも動いたが、ややこしいので統一した

## 感想

cwd = CurrentWorkingDirectory と考えると、相対パスの指定が分かりづらい
- `:zip.create` では `圧縮対象リストのプレフィックス`
- `:zip.extract` では `解凍先ディレクトリ`
として捉えるほうが分かりやすいかもしれない
rails + docker + fargateでのアプリデプロイへの道

# 各ファイルの設定
## ファイルのディレクトリ－
```
src(appを格納)
Dockerfile
docker-compose.yml
entrypoint.sh
start.sh
```

## Dockerfile
```
FROM ruby:3.0.1

ENV RAILS_ENV=production

RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn

RUN apt-get install -y nodejs npm && npm install n -g && n 14.19.1


WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

RUN yarn install --check-files
RUN bundle exec rails webpacker:compile

COPY start.sh /start.sh
RUN chmod 777 /start.sh
CMD ["sh", "/start.sh"]
```

## docker-compose.yml
```
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./src/db:/var/lib/postgres
    environment:
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
    depends_on:
      - db

```

## entrypoint.sh
```
#!/bin/bash
set -e

rm -f /task3_juhatyu/tmp/pids/server.pid

exec "$@"
```

## start.sh
```
#!/bin/sh

if [ "${RAILS_ENV}" = "production" ]
then
    bundle exec rails assets:precompile
fi

bundle exec pumactl start
```

## datebase.yml
```
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: postgres
  password: password
  host: db

development:
  <<: *default
  database: app_name_development

test:
  <<: *default
  database: app_name_test

production:
  <<: *default
  database: app_name_production
  username: app_name
  password: <%= ENV['TIMER_APP2_DATABASE_PASSWORD'] %>
```

# terminalでの操作
```
docker image build .
docker compose run web rails db:create
docker compose run web rails db:migrate
docker compose run web rails db:seed
```

# AWSで作成するもの

1.VPCとサブネットの作成
2.internet gatewayとルートテーブルの設定
3.ECRにインスタンスを作成
4.ECSのクラスターとタスクの作成

## 1.VPCとサブネットの作成
VPC:インターネット上のどこを使うか
サブネット：VPC内を分ける
```VPC:VPCの設定
Name tag - optional: app_name
IPv4 CIDR: 192.168.1.0/24
```
```サブネット:サブネットの設定
VPC ID: VPCで作成したものを設定
subnet name: app_name-subnet-01
Availability Zone: 1aなどを選ぶ
IPv4 CIDR block: 192.168.1.0/24
```

## 2.internet gatewayとルートテーブルの設定
```Internet gateway settings:Internet gateway
name: app_name-ing

1.設定したingを選択
2.actionのattach to VPCで作成したVPCを選択
3.route table の作成
4.vpcとサブネットの関連付け
```

## 3.ECRにインスタンスを作成
```ECR:ECR
Repository name: app_name

1.view push commandsを実行
（2は上記でbuildしているので省略）
```
ISBN 読み取りにチェックディジットを実装する

## 概要

以下は ISBN のバーコード読み取り誤差を防ぐためのメソッドである。
現状、3 回連続で同じ値だった場合に成功としている。これでは読み取りに時間がかかるし、正確でないこともある。
精度の向上と高速化を図り、チェックディジットによる誤差防止策に変更したい。

```js
Quagga.onDetected(function (result) {
  if (DetectedCode == result.codeResult.code) {
    DetectedCount++;
  } else {
    DetectedCount = 0;
    DetectedCode = result.codeResult.code;
  }
  if (DetectedCount >= 3) {
    console.log(result.codeResult.code);
    isbn.value = result.codeResult.code;
    DetectedCode = "";
    DetectedCount = 0;
  }
});
```

## 値について

- 値は全 13 桁を期待する。
- チェックディジットは読み取られた値の最後の桁であり、「左端から奇数番目のケタを 1 倍、偶数番目のケタを 3 倍したものの総和」である。これが 10 で割り切れれば正しいコード、割り切れなければ誤ったコードと判定される。

## 解決策

1. 値は slice()メソッドでチェックディジットとバーコードディジットを別々に抽出している。
2. 奇数桁と偶数桁の和に 3 を掛けたものを for ループで計算する。
3. 和とチェックディジットの和が 10 で割り切れるかどうかで、バーコードが正しいかどうかを判断する。

- バーコードが正しい場合、検出されたコードを記録し、isbn の値を検出されたコードに設定する。
- そうでない場合は、エラーメッセージを記録する。

```js
Quagga.onDetected(function (result) {
  const detectedCode = result.codeResult.code;

  if (detectedCode.length != 13) {
    //桁があっているか確認する
    console.log("Barcode error: length " + detectedCode);
    return;
  }

  const checkDigit = parseInt(detectedCode.slice(-1)); // バーコードからチェックディジットを抽出する
  const barcodeDigits = detectedCode.slice(0, -1).split(""); // チェックディジットを除いたバーコードの桁を抽出する

  let sum = 0;
  for (let i = 0; i < barcodeDigits.length; i++) {
    if (i % 2 === 0) {
      sum += parseInt(barcodeDigits[i]); // 奇数桁を足す
    } else {
      sum += 3 * parseInt(barcodeDigits[i]); // 偶数桁を3倍する
    }
  }

  if ((sum + checkDigit) % 10 === 0) {
    // バーコードが正しいか確認する
    console.log(detectedCode);
    isbn.value = detectedCode;
  } else {
    console.log("Barcode error: " + detectedCode);
  }
});
```
minio docker-composeした時にバケットを自動的に作成する

ググっていろいろな記事を参考にしたけど、結局はコピペで動作しなかったので動くように頑張った。

# 目的
`minio`を`docker-compose`で起動しバケットを自動で作成したい。

# ググって試すも動作しなかった

## mkcertで証明書を作成
```shell
brew install mkcert nss
mkcert -install
mkdir mkcert
mkcert -cert-file mkcert/public.crt -key-file mkcert/private.key localhost 127.0.0.1
```

## トライ
```yml:docker-compose.yml
minio:
    image: minio/minio:latest
    ports:
        - 9000:9000
        - 9090:9090
    environment:
        - MINIO_ROOT_USER=minioadmin
        - MINIO_ROOT_PASSWORD=minioadmin
        - MINIO_SERVER_URL=https://localhost:9000
    entrypoint: sh
    command: -c "
        cd ./docker/minio;
        minio server /data --address :9000 --console-address :9090;"
    volumes:
        - ./mkcert:/root/.minio/certs

minio_createbuckets:
    image: minio/mc:latest
    depends_on:
        - minio
    entrypoint: >
        /bin/sh -c "
        mc alias set minioio https://minio:9000 minioadmin minioadmin;
        mc mb --ignore-existing minioio/test;
        mc anonymous set public minioio/test;
        exit 0;"
```

## 結果
参考記事の記述の通り試すも失敗
```shell
mc: <ERROR> Unable to initialize new alias from the provided credentials. Get "https://minio:9000": dial tcp 127.0.0.1:9000: connect: connection refused.
```

# 原因は`minio/mc`のコンテナの方に証明書の設置が必要だった

## mkcertで証明書を作成
```shell
brew install mkcert nss
mkcert -install
mkdir mkcert
mkcert -cert-file mkcert/public.crt -key-file mkcert/private.key localhost minio 127.0.0.1
```

## トライ
動作しなかった`docker-compose.yml`との差分は`変更点`を確認ください。
```yml:docker-compose.yml
minio:
    image: minio/minio:latest
    ports:
        - 9000:9000
        - 9090:9090
    environment:
        - MINIO_ROOT_USER=minioadmin
        - MINIO_ROOT_PASSWORD=minioadmin
        - MINIO_SERVER_URL=http://localhost:9000
    entrypoint: sh
    command: -c "
        cd ./docker/minio;
        minio server /data --address :9000 --console-address :9090;"
    volumes:
        - ./mkcert:/root/.minio/certs

minio_createbuckets:
    image: minio/mc:latest
    depends_on:
        - minio
    entrypoint: >
        /bin/sh -c "
        mc alias set minioio https://minio:9000 minioadmin minioadmin;
        mc mb --ignore-existing minioio/test;
        mc anonymous set public minioio/test;
        exit 0;"
    # 変更点
    volumes:
        - ./mkcert:/root/.mc/certs/CAs
```

## 結果
`mc alias set minioio https://minio:9000 minioadmin minioadmin;`の実行結果
```shell
Added `minioio` successfully.
```

# 参考
記事作成時の各コンテナのバージョン
`minio/minio:RELEASE.2023-03-13T19-46-17Z`
`minio/mc:RELEASE.2023-02-28T00-12-59Z`
背景モデリングのメモ

## 背景モデリング
<br>
<br>

https://www.youtube.com/watch?v=oCYkCG6RxfA

<br>
<br>

https://cgworld.jp/feature/202110-mco5-report.html

<br>
<br>

https://area.autodesk.jp/column/tutorial/background-modeling/05-original-bg-01/

<br>
<br>

https://cgworld.jp/course/online/blender/?cat=41

<br>
<br>

https://www.oca.ac.jp/work_books/5748/

<br>
<br>
<br>
<br>


随時更新予定（たぶん）
https://twitter.com/MapleSyrup77
Instagram APIから取得できる投稿ごとの指標

# Instagram グラフAPIのメディア指標考

Instagram のグラフAPIを触ってます。

## メディアの種類ごとに変わる指標

メディア関係で取得できる指標値はメディアの種類によって変わるんですよね・・・
細かい定義の違いがあるためか、微妙に名前が異なっていて扱いにくいです。

例えば、
- 動画の再生数は投稿では、video_viewsがリールではplays
- engagementと似た概念でtotal_interactionsが存在する
など

## メディアの種類と取得可能な指標
ということで整理してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49042/6504f724-9446-c839-aeb1-aebd19efeb3c.png)

ちなみに、ig-userのinsightsと違って期間指定しての表示には対応してないです。

### 参考
https://developers.facebook.com/docs/instagram-api/reference/ig-media
https://developers.facebook.com/docs/instagram-api/reference/ig-media/insights

## リードマーケティングとInstagramの設計

どうでもいい話ですが、APIの設計などを見ていると
リール、ストーリーなどもリードマーケティングの概念を含めて考えるとよく作られてるなーと感じます。

- リール：　リードの獲得ツール
- ストーリー：　ナーチャリングツール
- プロフィール： マーケティングゴール
7zipを用いたワンタッチ展開 (解凍)＆参照を行いたい

## はじめに
前回の投稿で7zipを用いてファイルをダブルクリックのみで展開 (解凍) する方法について紹介した。ただ、以前紹介した方法ではファイルの展開はできても、展開後にできたファイルは手動で開かないといけなかった。
そこで、今回は展開されたファイルも自動で開けるような設定を模索していく。


https://qiita.com/YMT2520/items/1504ede5ef3cdae36754

↑前回の記事

## 手順
今回使用するのは
* 7zip
* レジストリエディタ
* テキストエディタ (batファイルが作成できればなんでも良い)
の三つです。
前回に比べてテキストエディタが増えていますが、今回はこれを使って自動化する簡単なコードを書いていきます。

7zipの設定やレジストリエディタの使い方は前回の投稿を参考にしてください。

zipファイルのダブルクリックがなされた際に、7zipを用いて展開->エクスプローラーを使ってファイルを展開という手順が踏めればよいので、テキストエディタに以下のように書いて保存し、拡張子を.bat形式へと変更します。

```bat:autoExtraction.bat
@echo off

if not "%~0"=="%~dp0.\%~nx0" (
    start /min cmd /c,"%~dp0.\%~nx0" %*
    exit
)

"C:\Program Files\7-Zip\7zG.exe" x "%~1" -aos -o*
explorer "%~dpn1"

```

最初の`if not`の節は展開中にコマンドプロンプトを最小化して起動するために記述しています。条件として、batファイルを開いたのがほかのプログラムであるかどうかを判断し、ほかのプログラムがbatファイルを開いたのであれば、2行目の処理に移り、引数を保持したままコマンドプロンプトを最小化して起動しなおします。
一方、batファイル自身が開いたのであれば、処理を終了することで無限ループに陥るのを防いでいます。(参考元: [Hatena Blog; 火蛾の深潭](https://firedfly.hatenablog.com/entry/20091124/p1))

次いで、7zipでダブルクリックしたファイルを展開する行があり、ここでは`-aos`オプションをつけることで、展開済みのファイルであれば上書き処理をしないようにしています。
これを外せば上書き処理の確認プロンプトが表示されるようになります。詳しくは7zipのヘルプを参照してください。
最後に展開したフォルダをエクスプローラーで表示する命令を置くことで、展開後にエクスプローラーでファイルを表示してくれます。

この作った.batファイルを適当なところに置いておきます。
私の場合は`C:\Users\ユーザー名\`下に置いています。
これで下準備は完了したので、レジストリエディタを開き、`コンピューター\HKEY_CLASSES_ROOT\7-Zip.zip\shell\open\command`に移動して規定をダブルクリックして、値のデータに`"C:\Users\ユーザー名\autoExtraction.bat" "%1"`と入力し、タスクマネージャーからエクスプローラーを再起動すれば、ダブルクリックのみで7zipで展開、エクスプローラーで展開後のフォルダを自動で参照することができるようになっているはずです。対応したレジストリキーを同様に書き換えれば、他の拡張子も自動で展開、参照することができます。

## まとめと改良点
今回、7zipを用いて、zipファイルを展開後エクスプローラーで表示する設定を行った。7zipでも標準搭載してくれるとありがたいが、、、
最初はレジストリをいじるだけでなんとか行えないかと試行錯誤していたが、どうにも私の技術力では無理そうだったのであきらめてbatファイルを実行することで実現した。
ただ、batファイルをいじるのは初めてだったので、引数や、拡張子の取り出しなど初歩的なことを学ぶ機会となった。
(x**3-x)**2 (y**3-y)=86400の整数解「王道の整数問題！86400って確か... 【東工大】【数学　大学入試】」をwolframalphaとsympyでやってみたい。

分配していません。絞り込み?と言う表現も他サイトで見ました。
①wolframalphaで、できました。
②?pythonistaの方へ。ループ？一行でする方法を教えて下さい。
③?sympy? python標準の不等式を教えて下さい。


オリジナル

https://youtu.be/MfBwxwVnqaI


上と同じです。大学入試数学問題集成＞【２】テキスト

https://mathexamtest.web.fc2.com/2023/202310267/2023102670100mj.html#top-0102

# wolframで
結果は全部同じです。
自然言語

https://ja.wolframalpha.com/input?i=%28x**3-x%29**2+%28y**3-y%29%3D86400

https://ja.wolframalpha.com/input?i=%28x%5E3+-+x%29%5E2+%28y%5E3+-+y%29+%3D86400

https://ja.wolframalpha.com/input?i=%28x3-x%29**2*%28y3-y%29%3D86400%E3%81%AE%E6%95%B4%E6%95%B0%E8%A7%A3

https://www.wolframalpha.com/input?i=%28x%5E3-x%29%5E2%28y%5E3-y%29%3D86400%E3%81%AE%E6%95%B4%E6%95%B0%E8%A7%A3&lang=ja

https://ja.wolframalpha.com/input?i=%28x3-x%29**2*%28y3-y%29%3D86400+integer

数学入力

https://ja.wolframalpha.com/input?i2d=true&i=Power%5B%5C%2840%29Power%5Bx%2C3%5D-x%5C%2841%29%2C2%5D%5C%2840%29Power%5By%2C3%5D-y%5C%2841%29%3D86400%E3%81%AE%E6%95%B4%E6%95%B0%E8%A7%A3

結果
x = ± 5 , y = 2
x = ± 4 , y = 3

# sympyで(solveで、できませんでした。)
```python
from sympy import *
x=symbols('x', integer = True)
y=symbols('y', integer = True)
print("#",solve(Eq((x**3-x)**2*(y**3-y),86400)))
```

# ~~sympyで~~python標準で(ループで)
**こっそりwolframで**

https://ja.wolframalpha.com/input?i=0%3C%28y3-y%29%3C%3D86400%E3%81%AE%E6%95%B4%E6%95%B0%E8%A7%A3

結果
2<=y<=44

https://ja.wolframalpha.com/input?i=0%3C%28x**3-x%29**2%3C%3D86400%E3%81%AE%E6%95%B4%E6%95%B0%E8%A7%A3

結果
...
x = ± 6

**こっそりsympy不等式で**
```python
(勉強中)
```

**多めに検索？**
```python
n=44+1
n86400=86400
for x in range(-n, n):
    for y in range(-n, n):
        if((x**3-x)**2*(y**3-y)==n86400): 
            print("#",x,y)
# -5 2
# -4 3
# 4 3
# 5 2
```

# 参考
forループの参考。覚えていないので。

https://ja.stackoverflow.com/questions/73763/python-%e3%81%aeitertools-permutations%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e6%95%99%e3%81%88%e3%81%a6%e4%b8%8b%e3%81%95%e3%81%84-%e5%85%a8%e9%83%a8%e3%81%ae%e7%b5%84%e3%81%bf%e5%90%88%e3%82%8f%e3%81%9b%e3%81%ae%e4%bd%9c%e3%82%8a%e6%96%b9%e3%82%92%e6%95%99%e3%81%88%e3%81%a6%e4%b8%8b%e3%81%95%e3%81%84

https://math-fun.net/20211226/21160/

https://docs.sympy.org/latest/modules/solvers/inequalities.html

https://commis.hatenablog.com/?page=1671082264

https://qiita.com/mrrclb48z/items/81a1b678233a84b6b32a
Parallels Desktop の MacOS VM で時間が合わなくなるのでやったこと

(メモ)
Parallels Desktop の MacOS VM を実行してる時に実行元の PC 本体をスリープすると時刻がズレてくので、ズレないようにする。

cron で root 権限を用いて以下のコマンドを実行すれば良い。(時刻合わせのコマンド)
`sntp -sS time.asia.apple.com`

コマンドに落とし込むとこう。

```bash
sudo crontab -e

###### 以下を出てきた Vim に追記する ######
* * * * * sntp -sS time.asia.apple.com
```
人工知能による対話エージェントシステム

自然言語処理による対話エージェントシステムを開発し、パワハラやセクハラなど不適切な発言を検知し、注意喚起メッセージを表示する機能、文章作成機能、要約機能を提供することが可能になった。これにより、相手を傷つけるような言葉遣いを避けることができ、スピーディかつ適切な表現で文章を作成することができ、また、長い文章を要約することで、簡潔な情報を得ることができる。現在、より優秀な対話エージェントシステムの開発が進められており、コミュニケーションを円滑に進めることが期待される。


### 技術分野
ここで紹介されている技術は自然言語処理である。自然言語処理は、人間が普段使っている自然な言葉をコンピュータに理解させるための技術で、対話システムや文章作成、要約などの分野で活用されている。
SNSやチャットアプリは、現代のコミュニケーションの一つの形として、個人間や企業や団体の情報発信などに利用されています。

### 背景
近年、SNSやチャットアプリ等の普及によって、人々のコミュニケーションの多くが対話アプリケーションを介して行うように変化しました。そして、様々な発言が飛び交う中で、パワーハラスメントやセクハラなどの不適切な言動が問題視されるようになりました。
同時に、ビジネスの現場でもコミュニケーションの円滑化が求められます。


### 課題
最近、職場や社会におけるパワハラやセクハラなどの不適切な発言が問題視されています。このような発言には多くの人々がストレスを感じ、その影響で精神疾患になる人も少なくありません。さらに、コミュニケーションは、文章作成能力や伝える能力、聴く能力に依存していると言われます。それらの能力の欠如により、相手を傷つけたり不快にさせたりすることが課題となっています。


### 解決手段
対話を行う両者が直接言葉のやりをせずに、SNSやチャットアプリといった対話アプリケーションに導入された対話エージェントシステムが仲介して、間接的にコミュニケーションを行います。その対話エージェントシステムには3つの機能が含まれます。1つ目は、相手を不快にさせる可能性がある発言を検知し、警告する機能。2つ目は、発話者が伝えたいことを自然言語処理により分析して受話者が理解しやすいよう文章化し、受話者に届ける機能。3つ目は受話者に届いた文章を自然言語処理により要約し、受話者に届ける機能。これらの機能により、本システムを仲介することで、間接的な対話が可能になります。

### 効果
会話の内容をリアルタイムで解析し、敬語が不十分だったり、不適切な表現を使うといった場合、対話エージェントシステムはそれらの発言を検知し、注意喚起します。これにより、相手の気持ちを意識して話をすることができるようになります。
自分が伝えたいことを対話エージェントシステムに伝えると、対話エージェントシステムがそれを分析し、文章を作成します。これにより、時間を節約しながら、適切な表現で相手に伝えることができます。
長い文章が届いたときは、対話エージェントシステムに要約してもらうことができます。これにより、簡潔な情報だけで済むため、受話者の負担も減り、コミュニケーションがスムーズに進みます。
これらの機能により、文章作成能力や伝える能力、聴く能力に依存しない円滑かつ適切なコミュニケーションが可能となります。

### 実施形態
本システムは、自然言語処理を利用した対話エージェントシステムです。主な機能として、パワハラやセクハラなどの不適切な発言を検知し注意喚起を行う機能、文章作成機能、文章要約機能を備えています。本システムは、SNSやチャットアプリ上で使用されることを想定しており、発話者と受話者の間に介在して、より円滑なコミュニケーションを実現することを目的としています。自然言語処理技術を用いた人工知能が導入されており、サーバーが必要に応じて処理を行います。

### 請求項
SNSやチャットアプリ等の対話アプリケーションに導入することで、発話者と受話者のやりとりを仲介して、パワハラやセクハラなどの不適切な発言を検知して注意喚起を行う機能、文章作成機能、文章要約機能を提供する、自然言語処理による対話エージェントシステム。


### 課題
最近、職場や社会におけるパワハラやセクハラなどの相手を傷つける不適切な発言が社会問題になっています。
### 要約
本システムは、自然言語処理を使用した対話エージェントシステムについてのものです。このシステムは、注意メッセージを表示することで、パワーハラスメントやセクハラなどの不適切な発言を検知することができ、文章作成機能や要約機能を提供します。このシステムはSNSやチャットアプリ上で使用されることを想定しています。自然言語処理を行う人工知能を使用するためにサーバーが必要になります。これにより、相互の発言や、文字によるコミュニケーションを円滑に行うことができ、相手を傷つけることがなくなると期待されています。
キーボードのキーが引っかかって打ちづらかったので滑りをよくした話

キーボードの老朽化でキーが引っかかるようになり、タイプミスが目立つようになってきたので滑りをよくしました。
同じ悩みを抱えてる方のご参考になればと考え記事にしておきます。

# はじめに

対象のキーボードはメンブレン式です。
どうやらここのプラスチック同士の滑りが悪く、タイプ時に引っかかっているようです。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287643/0d0c74fe-951f-91c7-2225-fefaeedb9604.jpeg">

:::note alert
※パンタグラフ式など他のタイプで同じことができるかは確認していないので注意してください。
:::

# 準備するもの

今回使ったのはこれ！
「KURE シリコンスプレー」
<img width="25%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287643/d378043f-d32d-ee0f-17e3-3d057cf5ff42.jpeg">

:::note alert
注意：KURE556のような油をさすのはさすがに避けた方が良いと思います。
:::

# いざ、スプレー！

キーの隙間からスプレーしていきます。
2，3キー間隔で「シュッ」という感じで吹きかけました。
シューーと一度にやってしまわず、細かい間隔でやった方がうまくいくと思います。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287643/6da1fcb0-5066-20ed-a8b8-80b588ef0811.jpeg">

# 結果

めっちゃ快適！
正直なところダメ元でやったんですが、全然違います！全く引っかかりません！
音がもう違います！！！

ということで、同じ悩みを抱えている方、やっちゃっても大丈夫なのかなーと迷われている方の参考になれば良いなと思います。
電子申告で「jpkimobileが繰り返し停止しています」とか「value cannot be null parameter name: data」みたいなエラーが出るときはカードを動かさないでやるといいよ

電子申告で「jpkimobileが繰り返し停止しています」とか「value cannot be null parameter name: data」みたいなエラーが出るとき

## 結論: 暗証番号とパスワード入力時にカード離しちゃだめ
結論としてはこれだけです。端末にマイナンバーカードをつけたまま、暗証番号と認証用パスワードを入力しましょう。

不親切すぎるよこの設計!!
css で背景色を虹色でアニメーション

CSS で背景色を虹色で変えるアニメーションをやってみる
出来上がったやつのイメージはこんな感じ

https://sueasen.github.io/javascript-exercise/work/backgrandrainbow/

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjavdLg" data-user="sueasen" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sueasen/pen/JjavdLg">
  Untitled</a> by sueasen (<a href="https://codepen.io/sueasen">@sueasen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- html は枠だけ
```html:index.html
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="./style.css">
</head>

</html>
```

- css でアニメーション設定
```CSS:style.css
@charset "utf-8";

html {
    animation-name: rainbow;
    animation-duration: 7s;
    animation-iteration-count: infinite;
    /** 
    animation: rainbow 7s infinite;
    */
}

@keyframes rainbow {
    0% {
        background-color: red;
    }
    13% {
        background-color: orange;
    }
    26% {
        background-color: yellow;
    }
    39% {
        background-color: green;
    }
    52% {
        background-color: aqua;
    }
    65% {
        background-color: aqua;
    }
    78% {
        background-color: blue;
    }
    91% {
        background-color:purple;
    }
    100% {
        background-color: red;
    }
}
```

- 小ネタ．．．背景画像スライド
```CSS
body {
    background-image: url(./imagePath/example/image.jpg);
    background-size: 100vw 100vh; /* 画面サイズ 横100vw, 縦100vh*/
    background-attachment: fixed;
    animation: slide 5s linear infinite;
}
@keyframes slide {
    0% {
        background-position: 0 0;
    }

    100% {
        background-position: -100vw -100vh; /* 画面サイズに合わせる + は右下, - は左上にスライド*/
    }
}

```
Delhi to Chandigarh Taxi

Oneness Taxi is a leading taxi service provider that connects Delhi to Chandigarh and other nearby places. With a wide range of comfortable and reliable taxis, Oneness Taxi makes your journey seamless and hassle-free.
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287713/9f6c3177-bf9e-3ad1-97ce-1570b2e0b6d5.png)


Whether you need to travel for business or pleasure, our experienced and courteous drivers will ensure that you reach your destination safely and on time. We offer a range of taxi options, including sedans, SUVs, and luxury cars, to cater to your specific travel needs.

Our Delhi to Chandigarh taxi service is particularly popular, with many customers choosing us over other taxi providers due to our competitive pricing and exceptional service. With Oneness Taxi, you can sit back and relax while we take care of all your travel needs.

We also offer additional services, such as airport transfers and outstation trips, making us your one-stop-shop for all your travel needs. So why wait? Book your Oneness Taxi today and experience a journey like never before!
For more information visit our website Oneness Taxi.
【備忘録】データベース設計の流れ


## データベース設計の流れ

1. 作りたいものからデータを抽出する
    1. 何をデータとして保存する？
        1. システムで使用するもの
        2. ユーザーが登録するもの（ユーザー名など）
2. 表の形式を考える
    1. まずは全部のデータをひとつのテーブルに突っ込む
    2. 一つのレコードを検索するときに、一意に特定できるかチェックする。
        1. できない場合は主キーをつけて一意に特定できるように
    3. しかし、一つのカラムがList形式の場合主キーを付けても一意に特定できない[例えばこれ](https://youtu.be/Yg546Zua39A?t=1535)
        1. 一意に特定できるようにするために、要素ごとにカラムを作りIDを割り当てると、要素が増えるためにカラムを増やさないといけない
        2. 主キーを２つのIDの組み合わせとみれば、主キーが各カラムの値を一意に特定できる（**第一正規化**）
    4. しかし、更新や削除を行うとき複数のレコードを更新しなければならないことがある。そのときにデータに矛盾が生じるかも？[例えばこれ](https://youtu.be/Yg546Zua39A?t=2378)
        1. 重複をなくすためにテーブルを分割する（**第二正規化**）
    5. 一つのテーブルAに、IDとその具体的な値をもつテーブル設計の場合、登録されていないデータの登録をテーブルAでは行えない。[例えばこれ](https://youtu.be/Yg546Zua39A?t=2998)
        1. テーブルを分割（**第三正規化**）

### 重要なポイント

- 正規形
    - 一貫性と効率性を持った形でデータを保持するためのデータ形式
- 正規化
    - 一貫性と効率性を持つようにデータベースを設計すること（正規形にすること）
- 第一正規化
    - 一つのセルの中には一つの値しか含まない。これにより効率よく検索ができる
- 関数従属性
    - $y = f(x)$: 入力$x$に対して出力$y$が決まる
    - $yはxに従属する$: x → y
    - 1つのセル（入力）に一つの値（出力）の方針も関数従属性
- 第二正規化
    - 第一正規形から部分関数従属を排除
        - 部分関数従属　＝　主キーの一部に対して従属する列がある
【Slack】アカウント解除後のアカウントのプロフィール写真を削除する

結論からいうと、プライマリオーナー（最高権限）でもできません

アカウントを一時的にシングルチャンネルゲストとして招待して、アカウントにログインいただき、プロフィール写真を変更するしかないです

アカウントを解除しても、課金が停止されるのみでアカウントを完全に削除できることではないので、退職する際にはSlackのプロフィール写真を削除したほうがいいかもしれません
【Google Workspace】csvでユーザー追加

Google Workspace
3月4月は人の出入りが多く、前足での作業だけではつらいので、csvでユーザー追加したいと思います。

全然難しいことしませんけど、まあこういう記事があってもいいかと思って書いてます。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269472/12f5f2c0-4923-a0de-7749-555a070c9b27.png)

1. [管理コンソール] - [ディレクトリ] - [ユーザー]をクリック

![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269472/25553ccb-2ef5-4a48-39c0-98101086ab88.png)

2. [ユーザーの一括更新]をクリック

![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269472/12ddc7d3-d81b-c44d-6a39-48ce2f1f4934.png)
3. [空のcsvテンプレートをダウンロード]をクリック

4. users.csvというファイルがDLできるので、記入

姓名、メールアドレス、パスワード、組織部門（Org Unit Path）が必須項目
そのほかに、[New Licenses]という列に数字をいれてやるとライセンスを割り当てることもできます

[ライセンスと数字の対応表](https://developers.google.com/admin-sdk/licensing/v1/how-tos/products?hl=ja)

5. 項番3の画像にある[csvファイルを添付]をクリックし、ファイルをアップロード

完了！
10分で理解できるディープラーニングによる画像分類のポイント

# 概要
画像分類は、ディープラーニングの中でも非常に人気が高く、多くの実用的な応用例が存在します。この記事では、初心者から中級者向けに、ディープラーニングを用いた画像分類を行う際のポイントを10分で理解できるように解説します。具体的には、以下の内容について説明します。

1. 画像分類の基本概念
2. データセットの準備
3. モデルの構築と学習
4. 精度評価と可視化
5. チューニングのポイント

# 1.画像分類の基本概念
画像分類は、コンピュータビジョンの基本的なタスクの一つで、与えられた画像がどのカテゴリに属するかを自動的に判断する技術です。画像分類のアプリケーションは多岐にわたり、自動運転車の物体認識、医療画像の病変検出、監視カメラによる人物識別などがあります。
まずは、以下に解説サイトや本によく登場してくる画像分類の基本概念についていくつか詳しく解説します。
## 特徴抽出
画像分類では、まず画像から有用な情報（特徴量）を抽出することが重要です。特徴量は、画像の色、テクスチャ、形状、エッジなど、画像内のパターンを表現するための数値です。特徴抽出の方法には手動で設計された特徴量（手動特徴量）と、機械学習によって自動的に抽出される特徴量（自動特徴量）があります。

## 畳み込みニューラルネットワーク（CNN）
近年、画像分類の分野で最も成功しているアプローチは、畳み込みニューラルネットワーク（CNN）を用いたものです。CNNは、階層的な特徴表現を学習することができるため、画像分類に非常に適しています。CNNの各層では、畳み込み演算により局所的な特徴量を抽出し、プーリング層で空間的な情報を圧縮しています。これにより、高次の特徴表現が構築され、最終的に全結合層でクラス分類が行われます。

## 学習データ
画像分類の性能は、学習データの質に大きく依存します。充分な量とバリエーションのデータが必要であり、画像とそれに対応するカテゴリラベルのペアからなるデータセットが用いられます。また、データセットは学習用、検証用、評価用に分割され、過学習を防ぐために交差検証やデータ拡張が行われることが一般的です。

## 評価指標
画像分類モデルの性能を評価するために、いくつかの指標が用いられます。
今回はその中でも主要な評価指標をいくつか紹介します。

**正解率（Accuracy）**: 
全ての予測のうち、正しく分類された割合です。
全体的な性能を評価するのに適していますが、クラスのバランスが悪い場合は不適切な指標となることがあります。
**適合率（Precision）**:
あるクラスと予測された画像のうち、実際にそのクラスに属する画像の割合です。
偽陽性（誤検出）を低く抑えることが重要な場合に適した指標です。
**再現率（Recall）**:
あるクラスに属する画像のうち、正しくそのクラスと予測された画像の割合です。
偽陰性（見逃し）を低く抑えることが重要な場合に適した指標です。
**F1スコア**: 
適合率と再現率の調和平均で、両者のバランスを評価するための指標です。
クラスのバランスが悪い場合や、適合率と再現率のトレードオフを考慮する場合に適した指標です。
**混同行列（Confusion Matrix）**:
クラスごとの正解数と誤分類数をまとめた表で、モデルの性能を詳細に把握することができます。
クラスごとの弱点や誤分類の傾向を明らかにするために用いられます。

これらの評価指標を用いて、画像分類モデルの性能を総合的に評価し、改善点を見つけ出すことが重要です。
また、問題設定やアプリケーションに応じて、最適な評価指標を選択することが求められます。

以降は、上記基本概念を元に実際に画像分類を行おうとする際に大切なポイントです。

# 2.データセットの準備
ディープラーニングにおいては、大量のデータセットが必要です。データセットは、画像とその画像に対応するラベル（クラス）から構成されます。データセットを準備する際には、以下のことに注意しましょう。

1. **データのバリエーション**: 異なる角度や環境で撮影された画像を集める
2. **データの正規化**: 画像のサイズや色情報を揃える
3. **データの分割**: 学習用、検証用、評価用のデータセットに分割する

# 3.モデルの構築と学習
画像分類には、畳み込みニューラルネットワーク（CNN）がよく用いられます。以下の手順でモデルを構築しましょう。

1. **畳み込み層**: 画像の特徴を抽出する
2. **活性化関数**: 非線形性を持たせる
3. **プーリング層**: データを圧縮し、過学習を防ぐ
4. **全結合層**: 最終的なクラス分類を行う
学習には、損失関数と最適化アルゴリズムを選択し、モデルのパラメータを更新していきます。代表的な損失関数にはクロスエントロピー損失、最適化アルゴリズムには勾配降下法やAdamがあります。

# 4.精度評価と可視化
モデルの学習が完了したら、検証用データセットを用いて精度を評価します。最初に「評価指標」の項目に記載した
正解率（accuracy）や適合率（precision）、再現率（recall）、F1スコアなどの指標を用いてモデルの性能を評価しましょう。
また、学習曲線や混同行列を可視化することで、モデルの学習状況やクラスごとの性能を把握することができます。

# 5.チューニングのポイント
画像分類の性能を向上させるためには、以下のチューニングポイントに注意しましょう。

+ モデルのアーキテクチャ: より深い層や異なる活性化関数を試す
+ ハイパーパラメータの調整: 学習率やバッチサイズなどを変更する
+ データ拡張: データセットの水増しを行い、汎化性能を向上させる
+ 転移学習: 事前学習済みのモデルを用いて、学習時間を短縮し性能を向上させる
+ アンサンブル学習: 複数のモデルの予測結果を組み合わせることで、精度を向上させる

# まとめ
この記事では、ディープラーニングを用いた画像分類を行う際のポイントを10分で理解できるように解説しました。
これを機に、ぜひ実際にディープラーニングを用いた画像分類のプロジェクトに挑戦してみてください！
toSql() のクエリの ? に対するバインドが失敗しているとかいうバグ

### はじめに
未経験でエンジニアになって間もないので、知識不足などあると思います。
何卒ご理解ください。

### 前提条件
たくさんの会合があって、それぞれに参加者がいる状況を想定して開発しています。
会合情報が書いてあるテーブル（ここでは`Meetingsテーブル`とします）
と
参加者情報が書いてあるテーブル（ここでは`Participantsテーブル`とします）
があって
それぞれ `Meetingsテーブルのid` と `Participantsテーブルのmeeting_id` で結合している。

Participantsの情報の中に、status= 0：参加、1：不参加 という情報があり、
参加数だけ取ってきて表示したいとします。
```
$sub = Participant::select('participants.meeting_id',DB::raw('count(*) as cnt'))
                    ->where('participants.status', '=', 0)
                    ->groupby('patricipants.meeting_id');

$query = Meeting::select(
            'meetings.id as id',
            'meetings.name as name',
           その他Meetingの情報
            'entry_num.cnt'
        )
            ->leftjoin(DB::raw('('.$sub->toSql().') as entry_num'),'meetings.id','entry_num.meeting_id');
```
としたところ、下記のエラーが・・・
```
SQLSTATE[HY000]: General error: 2031 No data supplied for parameters in prepared statement

select
  count(*) as aggregate
from
  `meetings`
  left join (
    select
      `participants`.`meeting_id`,
      count(*) as cnt
    from
      `participants`
    where
      `participants`.`status` = ?
    group by
      `participants`.`meeting_id`
  ) as entry_num on `meetings`.`id` = `entry_num`.`meeting_id`
```
ナンノコッチャわからない・・・
    where
      `participants`.`status` = ?
ってstatus=0って指定しているはずだけどな？？

とりあえず片っ端からググる

toSql()ってなんだろうなと思ってググっていると
こちらの記事に出会いました。
https://codelikes.com/confirm-laravel-sql/#toc2

> toSqlメソッドを呼ぶと、実際に実行するSQLがパラメータ箇所を「?」で伏せた状態で返ってきます。

なるほど、だから status = 0 が取れていなかったのか・・・

```
$sub = Participant::select('participants.meeting_id',DB::raw('count(*) as cnt'))
                    ->where('participants.status', '=', 0)
                    ->groupby('patricipants.meeting_id');

$subGetBindings = $subGetBindings = preg_replace_array('/\?/', $sub->getBindings(), $sub->toSql());

$query = Meeting::select(
            'meetings.id as id',
            'meetings.name as name',
           その他Meetingの情報
            'entry_num.cnt'
        )
            ->leftjoin(DB::raw('('.$subGetBindings.') as entry_num'),'meetings.id','entry_num.meeting_id');
```

`$subGetBindings = $subGetBindings = preg_replace_array('/\?/', $sub->getBindings(), $sub->toSql());`
ここでLaravelで用意されているpreg_replace_arrayヘルパーを使用して置換することができます。

すると、キャンセル分を含めずに参加人数を取ってくることができました:point_up:

忘れないようにメモとして残しておきます。
XAMPPの「Are you sure you are using the right ib_logfiles to start up the database?」のエラーに対してib_logfileをbackupから引っ張ってきたら解決できた話

MySQLを起動するごとにmysql.dbテーブルがcorruptする現象に見舞われていたのですが、エラーログを確認し、ある記事を参考にしてxamppに落とし込んだら今のところ問題なく起動できるようになっているので、備忘録として共有したいなと思い記事を執筆してみます。

まだまだ初心者なので具体的な解決理由についてはわかりかねます。詳しい方がいらっしゃれば諸々ご教示いただけると嬉しいです。

# ib_logfileのバックアップ、そして削除

実際のエラーログ _xampp\mysql\data\mysql_error.log_ は以下の通り。

>[Warning] InnoDB: Are you sure you are using the right ib_logfiles to start up the database? Log sequence number in the ib_logfiles is xxxxxx, less than the log sequence number in the first system tablespace file header, xxxxxx.
[ERROR] InnoDB: Page [page id: space=x, page number=x] log sequence number xxxxxx is in the future! Current system log sequence number xxxxxx.

大まかな流れは以下の記事を参考にいたしました。

https://mimirswell.ggnet.co.jp/blog-193

エラーを確認するおib_logfileに原因があるようなので、mysqlを一度終了させ、 _\xampp\mysql\data_ にあるib_logfile（自分の環境ではib_logfile0とib_logfile1の2ファイルがありました）を別で保存し、削除。

再度起動すると自動でib_logfileが生成され、エラーログがなくなりました。

# 原因はmysqlを正常に終了させていたなかったから？

もともとmysqlが起動できなかった問題に直面していて、以下の記事を参考にbackupフォルダからdataフォルダにペーストして正常に起動できるようになった前提があります。

https://y-a-d.hatenablog.jp/entry/2020/01/28/183000

ただ起動できてもGRANTしたはずのUSERが消えたり、GRANTしようとしたら
 
>Index for table 'db' is corrupt; try to repair it

のエラーが出たりと不具合が頻発していたのがきっかけで、毎回起動する度に

>REPAIR TABLE mysql.user

をしてGRANTするのが面倒だったので根本的解決を目指した次第です。

上記の記事でコントロールパネルからスタート、ストップを行うことが記述されており、また他の記事でも似たような情報があったため、mysqlを正常に終了させることと、コマンドだけでなく、SQLに対しての理解度の重要さを痛感いたしました。
【まとめ】レビューで指摘されがちシリーズ

この記事は私が【レビューで指摘されがちシリーズ】と題して書いた記事をまとめた記事です。今後も【レビューで指摘されがちシリーズ】の記事が増えれば、この記事も更新予定です。

私は2022年の6月より Ruby on Rails を使った案件から .NET Framework, Windows Forms を使った案件に変わりました。C# を扱った経験がなかったため割と基礎的なことをレビューで指摘されることが多いです。せっかくなので指摘されたことは記事にしています。

ちなみに `C# を扱った経験がなかったため` と言い訳していますが、実際は言語に関係ない一般的なことも指摘されています…（でも、ほら私はまだエンジニア歴3年目だから…）

## コードの書き方全般
https://qiita.com/lx-sasabo/items/1b7f82d8c21e37c3d1e4

https://qiita.com/lx-sasabo/items/fddebfe1ecc79c917c33

https://qiita.com/lx-sasabo/items/115ece9a2525cd16e23b

https://qiita.com/lx-sasabo/items/a794e8e9514badfde213

https://qiita.com/lx-sasabo/items/866d3b7366b7ff5d4dd7

## C# 固有

https://qiita.com/lx-sasabo/items/36c021cc52720d1479f2

https://qiita.com/lx-sasabo/items/6799da56d224f41832ed

https://qiita.com/lx-sasabo/items/8540fa147fcf4ef0ff2e

https://qiita.com/lx-sasabo/items/eec4dfbae0418775d08f
大規模言語モデル「LLaMA」を自分のPCで実行する

自分のPCでLLaMAを実行するツールが公開されたのでご紹介します。

# LLaMAとは
FacebookでおなじみのMeta社が開発した研究者向けの大規模言語モデルです。

https://ai.facebook.com/blog/large-language-model-llama-meta-ai/

https://github.com/facebookresearch/llama

パラメータ数により、4つのモデルがあります。
- 7B（70億）
- 13B（130億）
- 30B（300億）
- 65B（650億）

# Dalai
そのツールはこちら。

https://cocktailpeanut.github.io/dalai/

名前は「[ダライ・ラマ](https://ja.wikipedia.org/wiki/%E3%83%80%E3%83%A9%E3%82%A4%E3%83%BB%E3%83%A9%E3%83%9E)」から来ていると思われます。
![ダライ・ラマ14世](https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Dalailama1_20121014_4639.jpg/406px-Dalailama1_20121014_4639.jpg)
（中国からアクセスできなさそう ^^;）

早速、環境構築から始めてみます。

なお、この記事を書いているときのDalaiのバージョンは「0.1.0」になります。
<font color="#FF0000">（注：毎日のように更新されており、以降の説明はもはや過去のものとなっています）</font>

## 環境構築
私の環境はWindowsですので、以降、Windowsでの説明になります。

### WSL環境の構築
残念ながらWindowsネイティブな環境では動かないので、WSL環境を用意します。
<font color="#FF0000">（注：現在は、公式サイトにVisual Studio Communityを使った環境構築方法が載っています）</font>
ここではubuntuを用意します。
（詳細は省略）

環境は最新に更新しておいてください。
```
sudo apt update
sudo apt upgrade -y
sudo apt dist-upgrade -y
sudo apt autoremove -y
```

### Node.jsのインストール
次にNode.jsをインストールします。
そのため、まずはnvmをインストールします。
```
sudo apt install curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source ~/.bashrc
```
その後、Node.jsをインストールします。
```
nvm install node
```

### pythonのインストール
次にpythonをインストールします。
```
sudo apt install python3 -y
```

### venvのインストール
さらに、仮想環境であるvenvをインストールします。
```
sudo apt install python3.8-venv
```
venvのバージョンは、pythonに合わせてください。


### Dalaiのインストール
「Dalai」をNode.jsにインストールします。
以下のコマンドを実行します。
```
npx dalai llama
```
（npmパッケージの中身は[こちら](https://www.npmjs.com/package/dalai)で確認できます）

なお、このコマンドでインストールされるモデルは「7B」というモデルで、それ以外のモデルもインストールしたい場合は、以下のように指定します。
```
npx dalai llama 7B 13B 30B 65B
```

なお、途中のダウンロードや変換処理で失敗したときは、もう一度コマンドを実行してみてください。

これで環境構築は終了です。

### おまけ
モデルをダウンロードしてくると、大量にストレージを使ってしまいますが、各モデルのフォルダ内の「consolidated.00.pth」等は削除することができます。
（「ggml-model-f16.bin」「ggml-model-q4_0.bin」等に量子化変換されているため）

## 実行
では動かしてみます。

まずWebサーバを起動します。
```
npx dalai serve
```
（後ろにポート番号を付けることもできます）

次にWebブラウザから「http\://localhost:3000」にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/9155d8d6-b3e9-5d78-5749-f8a985d1010a.png)
右上の「models」で、使用するモデルの変更が出来ます。

なお現在は、残念ながら7Bだと英語でしか会話ができないみたいですし、回答がまともではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/9103abf5-2c02-b795-85af-da7f2410db09.png)

### おまけ
バックグラウンドでは、以下のようなコマンドが動いているようです。
```
./main --seed -1 --threads 4 --n_predict 1000 --model models/7B/ggml-model-q4_0.bin \
   --top_k 40 --top_p 0.9 --temp 0.8 --repeat_last_n 64 --repeat_penalty 1.3 \
   -p "お金持ちになる方法を教えてください。"
```

# まとめ
それほど簡単ではないですが、一応、自分のPCに大規模言語モデルAIを入れて動かすことが出来ました。
API経由での利用もできるようなので、こちらを利用することに意味があるのかもしれません。

# 追加情報
どんどんバージョンが上がっているdalaiですが、updateは以下のように行えばいいようです。
（以下は、0.3.0に上げる場合）
```
npx dalai@0.3.0 setup
```
【Dioxus】Propsの型を明示して渡す

rustのフロントエンドフレームワーク(クロスプラットフォームGUIフレームワーク)であるdioxusでは通常`rsx!`マクロ内で以下のようにプロパティを渡します．
```rust
cx.render(rsx! {
	TextButton{text:"テキスト", on_click: move |_|{is_clicked.set(true)}}
})
```
この引数は`TextButton`コンポーネントの作成時に`dioxus::prelude::Scope`の型パラメーターとして与えたものです．
```rust
use dioxus::prelude::*;

#[derive(Props)]
struct TextButtonProps<'a> {
    #[props(into)]
    text: String,

    #[props(default = 1)]
    number: usize,
    
    on_click: EventHandler<'a>,
}

fn TextButton<'a>(cx: Scope<'a, TextButtonProps<'a>>) -> Element {
    cx.render(rsx! {
        div {
            (0..cx.props.number).map(|_|
                rsx!{
                    button { onclick: move |_|{cx.props.on_click.call(())},"{cx.props.text}"}
                }
            )
        }
    })
}
```

引数の数が多くてコンパイルエラーの箇所が分かりずらいときなど，場合によっては`TextButtonProps`を普通の構造体として作成しコンポーネントに渡したい場合があると思います．
dioxusではそれも可能であり，普通に作成するかビルダーパターンで作成したプロパティを`ScopeState::component`の引数とするか，baseエクスプレッション(スプレッド構文)を利用することで渡すことができます．yewにおける`props!`マクロが無い代わりに，ビルダーパターンを用いることで`into`や`default`の恩恵を受けられます．

```rust
fn App(cx: Scope) -> Element {
    let is_clicked = use_state(cx, || false);

    let text_button_props_v1 = TextButtonProps {
        text: "テキストボタン".to_string(),
        number: 2,
        on_click: cx.event_handler(move |_| is_clicked.set(true)),
    };

    let text_button_props_v2 = TextButtonProps::builder()
        .text("text button")
        .on_click(cx.event_handler(move |_| is_clicked.set(true)))
        .build();

    cx.render(rsx! {
        cx.component(TextButton, text_button_props_v1, "text_button")
        TextButton{number: 3, ..text_button_props_v2}
        is_clicked.get().then(||
            rsx!{div{"クリックされました"}}
        )
    })
}
```
コールバックとして渡すクロージャーは明示的に`EventHandler`に変換する必要があります．

もちろんチャイルドコンポーネントも渡すことができます．
```rust
#[derive(Props)]
struct ChildButtonProps<'a> {
    children: Element<'a>,
}

fn ChildButton<'a>(cx: Scope<'a, ChildButtonProps<'a>>) -> Element {
    cx.render(rsx! {
        button {&cx.props.children}
    })
}

fn App(cx: Scope) -> Element {
    let child_button_props = ChildButtonProps {
        children: cx.render(rsx! {
            div{"チャイルドボタン"}
            div{"チャイルドボタン"}
        }),
    };

    cx.render(rsx! {
        ChildButton{..child_button_props}
        ChildButton{"チャイルドボタン２"}
    })
}
```
このプロパティの渡し方は`Rc<dyn Fn>`を引数として渡したいときなどにも便利です(通常の方法では`EventHandler`に変換されてしまいます)．
SQLパフォーマンスあれこれ

DBパフォーマンスに関して、調べた内容を忘れないように残しておきます。

# 環境

```sql
SELECT * FROM v$version;

Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
CORE	12.1.0.2.0	Production
TNS for 64-bit Windows: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
```

# 注意点

* IN句
  * INとExistは速度は変わらない<br>(昔はExistのほうが速かったらしいが、今はオプティマイザが賢くなったため違いはない)

  * INは要素個数が多いものを左に寄せると高速化できる<br>

     例えば、<br>
  
    ```sql
     SELECT * FROM Address WHERE prefecture IN ('鳥取', '徳島', '東京', '大阪');
    ```
 
    より<br>
 
    ```sql
      SELECT * FROM Address WHERE prefecture IN ('東京', '大阪', '鳥取', '徳島'); 
    ```
    のほうが速い
  

* インデックス
  
  * 以下のようなパターンはdayにINDEXを追加しても効果がない<br>

     ```sql
      Where to_char(day,'YYYY/MM/DD') = '2023/03/15'
     ```
    ### 対処法

    1. 等号の右辺に関数を持ってくるとdayに貼り付けたINDEXを有効化できる

       ```sql
        Where day = to_date('2023/03/15' ,'YYYY/MM/DD')
       ```

    2. 「to_char(birthday,’YYYY/MM/DD’)」をファッションインデックスにする<br>左辺まるまるINDEXにすれば高速化できる
       ```sql
       CREATE INDEX IDX_SAMPLE ON SAMPLE_TABLE(to_char(day,'YYYY/MM/DD'))
       ```


  * コストの低い実行計画にする<br>


    実行計画は意外と奥が深い。。
    コストが少ない順に並べると以下のようになる。
    可能な限り、上位の結果となるようにINDEXを貼りつける。


　　　　***1. 索引一意スキャン(INDEX UNIQUE SCAN)***
　　　　　　※主キー(PMKey)で検索、ユニークに検索するときが一番速い

　　　　***2. 索引レンジスキャン(INDEX RANGE SCAN)***
　　　　　　※主キー以外のINDEXで検索

　　　　***3. 索引スキップスキャン(INDEX SKIP SCAN)***
　　　　　　※複合INDEXで1列目条件を無効にしているパターン
　　　　　　　複合INDEXはすべての項目をWHERE句に入れなければ遅くなる。

　　　　***4. 索引フルスキャン(INDEX FULL SCAN)***
　　　　　　※INDEXが処理に必要なカラム全てを保持していると発生

　　　　***5. 索引高速フルスキャン(INDEX FAST FULL SCAN)***
　　　　　　※問い合わせに必要なすべての列がインデックスに含まれていて、
　　　　　　　インデックスキーの1つ以上の列にnot null制約が指定されている場合

　　　　***6. 全表スキャン(TABLE ACCESS FULL)***
メモ：Ubuntuでfail2ban設定

sshの接続を抑止する。

## インストール
```shell
$ sudo apt update
$ sudo apt install fail2ban
```

## 設定

設定する。ローカル（社内）アクセスからのIPは無視

### 設定ファイルをコピー
```shell
$ cd /etc/fail2ban/

$ sudo cp -p jail.conf jail.local

```

### 設定内容（diff）

> banルールはデフォルト

```shell
< #ignoreip = 127.0.0.1/8 ::1
---
> ignoreip = 192.168.128.0/24
```

## 自動起動設定

```shell
$ sudo systemctl enable fail2ban
Synchronizing state of fail2ban.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable fail2ban
Created symlink /etc/systemd/system/multi-user.target.wants/fail2ban.service → /lib/systemd/system/fail2ban.service.
```

## 起動

```shell
$ sudo systemctl start fail2ban
```

## ステータス

```shell
$ sudo systemctl status fail2ban
● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-03-15 05:26:56 UTC; 1min 7s ago
       Docs: man:fail2ban(1)
   Main PID: 309615 (fail2ban-server)
      Tasks: 5 (limit: 2237)
     Memory: 13.7M
        CPU: 324ms
     CGroup: /system.slice/fail2ban.service
             └─309615 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

Mar 15 05:26:56 aries systemd[1]: Started Fail2Ban Service.
Mar 15 05:26:57 aries fail2ban-server[309615]: Server ready
```