OmniAICreator/Qiita-1.07M huggingface dataset:
CUDA C/C++ でデバイスのプロパティを表示させる

タイトル通りすっ(・ω・`)

```cpp
#include <cuda_runtime.h>
#include <stdio.h>
#include <cstdlib>

int main() {
    int deviceCount;
    cudaError_t error_id = cudaGetDeviceCount(&deviceCount);

    if (error_id != cudaSuccess) {
        printf("cudaGetDeviceCount returned %d\n-> %s\n", (int)error_id, cudaGetErrorString(error_id));
        printf("Result = FAIL\n");
        exit(EXIT_FAILURE);
    }

    if (deviceCount == 0) {
        printf("There are no available device(s) that support CUDA\n");
    } else {
        printf("Detected %d CUDA Capable device(s)\n", deviceCount);
    }

    for (int i = 0; i < deviceCount; ++i) {
        cudaDeviceProp prop;
        cudaGetDeviceProperties(&prop, i);

        printf("Device %d:\n", i);
        printf("  Name: %s\n", prop.name);
        printf("  Compute Capability: %d.%d\n", prop.major, prop.minor);
        printf("  Total Global Memory: %llu bytes\n", (unsigned long long)prop.totalGlobalMem);
        printf("  Shared Memory per Block: %lu bytes\n", (unsigned long)prop.sharedMemPerBlock);
        printf("  Registers per Block: %d\n", prop.regsPerBlock);
        printf("  Warp Size: %d\n", prop.warpSize);
        printf("  Memory Clock Rate (MHz): %d\n", prop.memoryClockRate / 1000);
        printf("  Memory Bus Width (bits): %d\n", prop.memoryBusWidth);
        printf("  L2 Cache Size: %d bytes\n", prop.l2CacheSize);
        printf("  Max Threads per MultiProcessor: %d\n", prop.maxThreadsPerMultiProcessor);
        printf("  Max Threads per Block: %d\n", prop.maxThreadsPerBlock);
        printf("  Max Grid Size: [%d, %d, %d]\n", prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]);
        printf("  Max Threads Dimensions: [%d, %d, %d]\n", prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]);
    }

    return 0;
}
```

ようるべで使ったコードすっ(・ω・`)
cscの作法 その549

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
IPv6を叩け。

# 環境
windows11

# 参考にしたページ

https://tututen.hatenablog.jp/entry/20110517/1305597351


# サンプルコード

```
using System;
using System.Net;
using System.Net.Sockets;

class Program {
	private static bool ListenFlag = true;
	static void Client(string ipAddr_v6, string ipAddr_v4, int port) {
		Console.WriteLine("IPv6 で送ります。");
		Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
		socket.Connect(new IPEndPoint(IPAddress.Parse(ipAddr_v6), port));
		socket.Disconnect(false);
		socket.Dispose();
		Console.WriteLine("3秒ほどWaitします");
		System.Threading.Thread.Sleep(3000);
		Console.WriteLine("IPv4 で送ります。");
		socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
		socket.Connect(new IPEndPoint(IPAddress.Parse(ipAddr_v4), port));
		socket.Disconnect(false);
		socket.Dispose();
	}
	static void Server(int port) {
		Console.WriteLine("Start IPv6 Listen");
		Listen(IPAddress.IPv6Any, port);
		Console.WriteLine("Start IPv4 Listen");
		Listen(IPAddress.Any, port);
		while (ListenFlag)
		{
			System.Threading.Thread.Sleep(10000);
			Console.WriteLine("Listen now ...");
		}
		Console.WriteLine("End Listen");
	}
	private static void Listen(IPAddress ipaddr, int port) {
		TcpListener listen = new TcpListener(ipaddr, port);
		listen.Start();
		listen.BeginAcceptSocket(DoAcceptSocketCallback, listen);
	}
	private static void DoAcceptSocketCallback(IAsyncResult ar) {
		TcpListener listen = ar.AsyncState as TcpListener;
		Socket socket = listen.EndAcceptSocket(ar);
		Console.WriteLine("Connect Success.");
		if (socket.AddressFamily == AddressFamily.InterNetworkV6)
		{
			Console.WriteLine("IPv6");
			Console.WriteLine("送信元IP");
			Console.WriteLine(socket.LocalEndPoint.ToString());
		}
		else if (socket.AddressFamily == AddressFamily.InterNetwork)
		{
			Console.WriteLine("IPv4");
			Console.WriteLine("送信元IP");
			Console.WriteLine(socket.LocalEndPoint.ToString());
		}
		listen.BeginAcceptSocket(DoAcceptSocketCallback, listen);
	}
	static void Main(string[] args) {
		string ipaddr_v6 = "fe80::*:*:*:cfa6%16";
		string ipaddr_v4 = "192.168.0.104";
		Console.WriteLine("0	:Client");
		Console.WriteLine("other:Server");
		int num = 0;
		try
		{
			num = int.Parse(Console.ReadLine());
		}
		catch (Exception)
		{
			num = int.MaxValue;
		}
		switch (num)
		{
		case 0:
			Console.WriteLine("Start Client");
			Client(ipaddr_v6, ipaddr_v4, 9999);
			Console.WriteLine("End Client");
		break;
		default:
			Console.WriteLine("Start Server");
			Server(9999);
			Console.WriteLine("End Server");
		break;
		}
	}
}

```

# 実行結果
server
```

>v6
0       :Client
other:Server
1
Start Server
Start IPv6 Listen
Start IPv4 Listen
Listen now ...
Connect Success.
IPv6
送信元IP
[fe80::*:*:*:cfa6%16]:9999
Connect Success.
IPv4
送信元IP
192.168.0.104:9999
Listen now ...
Listen now ...

```
client
```
>v6
0       :Client
other:Server
0
Start Client
IPv6 で送ります。
3秒ほどWaitします
IPv4 で送ります。
End Client

```

以上。
認証と認可の違いってなんで重要？

# 認証、認可の違いを聞かれることがあったので三行でまとめる

認証は、 指紋認証、顔認証に代表される通り、あなたは「誰か」を確認すること。
認可は、「あなたが何をしてもいいかを決めること」
多くの場合、認証と認可は同時に行われるため普段意識していないと区別できない。

# 認証、認可が全く別のところで行われることってあるの？
ある。例えば、GoogleアカウントでログインしてChatGPTを使うとき、Googleがあなたのアカウントの認証を行い、その結果を受けてChatGPTがそのユーザーに許可された機能を認可する。つまり、認証はGoogleで行われ、認可はChatGPT内で行われる。

# auth0, cognito, firebaseなどの認証機能を理解する上で認証と認可の違いは重要
認証サービスが何をしているのか、どういう処理が走るのかを理解するためには、認証と認可の違いを知っておくことが非常に重要。認証サービスは「ユーザーが誰であるか」を確認し、その後、認可部分を自分のシステム内でどう処理するかを考える際に、両者の違いを理解しておくと、設計がスムーズになる。
GitHubのソースコード管理【ベストプラクティス】

## はじめに
GitHubを使用したソースコード管理の基本を紹介します。

## 1. mainブランチ
本番環境用の安定版コードを保持

mainブランチは常に安定した状態で保つ必要があります。
本番環境で稼働しているコードは、常にこのブランチに含まれており、リリース済みのコードが管理されています。
通常、mainブランチへの変更は、リリースが完了した後に行います。
本番環境で問題が発生した場合、緊急の修正はhotfixブランチで行い、修正後はmainブランチにマージします。
マージ先:
releaseブランチやhotfixブランチで行われた変更は、最終的にmainブランチにマージされます。
## 2. developブランチ
開発中のコードを集約するためのブランチ

開発中のコードや新しい機能、バグ修正はすべてdevelopブランチに集約されます。
このブランチでは、まだ本番環境にリリースするには不安定な変更が含まれている可能性があります。
developブランチは、最終的に安定した状態でreleaseブランチへ移行し、リリース準備を整えます。
featureブランチやbugfixブランチで行った変更は、まずdevelopにマージされます。
マージ先:
feature、bugfix、releaseブランチからの変更はdevelopブランチにマージされます。
## 3. featureブランチ
新機能を開発するためのブランチ

新しい機能を開発する際は、developブランチから新しいfeatureブランチを切ります。
各機能は、独立したfeatureブランチで開発され、完成後にdevelopブランチに統合されます。
featureブランチは、特定の機能が完成した段階でマージされるため、個別に管理することで他の作業と干渉することなく進行できます。
マージ先:
開発が完了したfeatureブランチは、developブランチにマージされます。
## 4. bugfixブランチ
バグ修正を行うためのブランチ

バグ修正用のブランチは、developブランチから派生します。
通常、既存の機能に問題が発生した場合に使われます。
bugfixブランチでは、バグを修正することに集中し、修正が完了したらdevelopブランチにマージします。
bugfixブランチは、緊急の修正が必要でない場合に使用され、通常の開発サイクル内で処理されます。
マージ先:
修正が完了したbugfixブランチは、developブランチにマージされます。
## 5. releaseブランチ
リリース準備を行うためのブランチ

developブランチで安定した状態になった時点で、リリース準備を行うためにreleaseブランチを作成します。
このブランチでは、リリースに向けた最終調整やバグ修正を行います。
releaseブランチは本番リリース前に行う最後の調整やテストが行われる場所です。
調整が完了したら、最終的にmainブランチにマージし、リリースします。
マージ先:
releaseブランチは、リリース準備が整った後、mainブランチにマージされます。
また、developブランチにも変更が反映されます。
## 6. hotfixブランチ
本番環境での緊急修正を行うためのブランチ

本番環境で深刻な問題が発生した場合、mainブランチから直接hotfixブランチを作成し、緊急の修正を行います。
修正後は、mainブランチにマージし、問題が解決したことを確認した後、必要に応じてdevelopブランチにも変更を反映させます。
マージ先:
hotfixブランチは、修正が完了した後、mainとdevelopブランチにマージされます。
## 7. stagingブランチ（オプション）
リリース前の最終確認を行うためのブランチ

stagingブランチは、releaseブランチから分岐し、実際に本番環境にリリースする前に最終確認を行うためのブランチです。
本番環境への影響を最小限に抑えるため、stagingブランチで最終テストを行い、問題がないことを確認した後、mainブランチにマージします。
マージ先:
最終テスト後、stagingブランチはmainブランチにマージされ、リリースが行われます。
## まとめ
GitHubを使用したソースコード管理では、適切なブランチ戦略を採用することで、チーム開発の効率が大幅に向上します。

main: 本番用の安定コードを保持
develop: 開発中のコードを集約
feature: 新機能開発
bugfix: バグ修正
release: リリース準備
hotfix: 緊急修正
staging: 最終確認（オプション）

これらのブランチを適切に使い分けることで、開発の透明性を高め、リリースサイクルの安定性を確保できます。
Webアプリケーション開発と運用【AWS】

# はじめに
AWSを使用してWebアプリケーションを構築するための基本的な流れを紹介します。
実際に使用する主要なサービスを簡単に解説します。

# 使用する技術スタック
ソースコード管理: GitHub
CI/CD: GitHub Actions（ECSへデプロイ）
コンテナ管理: AWS ECS（Fargate）
ロードバランサー: AWS ALB
データベース: AWS RDS（PostgreSQL/MySQL）
シークレット管理: AWS Secrets Manager
ログ監視: AWS CloudWatch
# 1. ソースコード管理 - GitHub
まず、GitHubを使ってコードの管理を行います。
GitHubは、チームでの開発を円滑にするための強力なツールです。
コードのバージョン管理やプルリクエスト機能を使って、コードの変更履歴を追跡したり、レビューを通じて品質を保つことができます。

メリット: コードの管理が簡単で、チームでの協力作業がしやすい。
# 2. CI/CD - GitHub Actions
次に、GitHub Actionsを使ってCI/CDを自動化します。
GitHub Actionsはリポジトリ内でコードが変更されるたびにトリガーされ、アプリケーションのビルド・テスト・デプロイを自動で行います。

具体的な流れ:

リポジトリにコードをプッシュ。
GitHub Actionsがビルドを実行。
Dockerイメージを作成し、Amazon ECRにプッシュ。
**AWS ECS (Fargate)**で新しいコンテナをデプロイ。
メリット: 手動でのデプロイ作業が不要になり、エラーを減らして効率化できる。

# 3. コンテナ管理 - AWS ECS（Fargate）
アプリケーションはAWS ECS (Elastic Container Service)を使って管理します。
特にFargateを利用することで、インフラの管理を気にせずにコンテナをデプロイできます。

Fargateの特徴:

サーバーレスで、インフラ管理不要。
自動的にリソースをスケール（必要に応じてサーバーが増減）。
容易にスケーリングが可能。
メリット: サーバー管理を気にせず、アプリケーションに集中できる。

# 4. ロードバランサー - AWS ALB
**AWS ALB (Application Load Balancer)**を使って、インターネットからのトラフィックを複数のコンテナインスタンスに分散します。ALBは、HTTPやHTTPSのリクエストに特化しており、トラフィックを最適に分配できます。

特徴:

複数のコンテナにトラフィックを分散。
ヘルスチェックを自動で行い、問題のあるインスタンスを除外。
URLやヘッダーに基づいてルーティング可能。
メリット: 高可用性とスケーラビリティを簡単に実現。

# 5. データベース - AWS RDS（PostgreSQL/MySQL）
データはAWS RDS (Relational Database Service)を使って管理します。
RDSは、リレーショナルデータベースの運用を簡素化するサービスで、PostgreSQLやMySQLなどが利用可能です。

特徴:

自動バックアップとパッチ管理。
自動スケーリングでトラフィックの増加に対応。
高可用性（マルチAZ）をサポート。
メリット: 手間なく高可用性なデータベースを構築でき、データのバックアップや保護が自動で行われる。

# 6. シークレット管理 - AWS Secrets Manager
AWS Secrets Managerを使用して、APIキーやデータベースのパスワードなどの機密情報を安全に管理します。Secrets Managerは、シークレット情報を暗号化して保管し、アクセス管理を簡単に行うことができます。

特徴:

APIキーやパスワードを安全に管理。
自動的にシークレット情報をローテーション。
アクセス制御をきめ細かく設定可能。
メリット: セキュリティを強化し、シークレット情報の漏洩リスクを低減。

# 7. ログ監視 - AWS CloudWatch
AWS CloudWatchを使って、アプリケーションやインフラのログを集約・監視します。
CloudWatchは、リアルタイムでログデータを分析し、異常を検出した際にアラートを設定することができます。

特徴:

ログデータを集約して一元管理。
カスタムメトリクスやアラームを設定して、問題が発生した際に通知。
リアルタイムでの監視と分析。
メリット: 異常の早期発見と迅速な対応が可能。

# まとめ
これらのサービスを組み合わせることで、スケーラブルで高可用性なWebアプリケーションの構築と運用が可能になります。
AWSを利用することで、サーバーの管理や運用に関する負担を軽減し、開発者はアプリケーションに集中できる環境を整えることができます。
(注意)M5StampS3 (LX7) のバイトオーダーを調べる(格納される時のバイトの並び)


M5StampS3のバイトオーダーを調べる(格納される時のバイトの並び)



C++ Arduino アルゴリズム M5stack M5StampS3



参考


https://qiita.com/ryuichi1208/items/31442f9e8a7a7c94aeec



x 過去ログを見ょ!!!
x アルゴリズムは、あまり関係ないけど?
x 研究調査目的で非営利で引用しました。
x 「シリアルモニタ」は、なんどか開き直す
x 3.1.1
x unionは、共有体　(共用体)
x ビットとバイトの並びは、物理装置とコンパイラに依存する。
x 1番下のコメントにあるように厳密では、ない。


目的
メモリー内でのバイトの並びを調べる
共有体　(共用体)を使用した時のバイトの並び


結果
----


![o_coq787.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3a936583-d167-d9af-29ab-6325382a2ed4.jpeg)



プログラム
----


```c++



//ser_byte_order_M5StampS3

void setup() {
  // put your setup code here, to run once:

  //シリアルの初期化
  Serial.begin(9600);
  Serial.println();
  //シリアルの待ちが0.5*9
  for (int i = 0; i < 9; i++) {
    delay(500);  //接続待ち
    Serial.print('.');
  }  //for
  Serial.println();

  union {
    uint32_t b4;
    uint16_t b2[2];
    uint8_t  b1[4];
  } bytes;

  bytes.b4 = 0x12345678;
  Serial.printf ("bytes.b4: %08X\n", bytes.b4);
  Serial.printf ("bytes.b2: %04X, %04X\n", bytes.b2[0], bytes.b2[1]);
  Serial.printf ("bytes.b1: %02X, %02X, %02X, %02X\n", bytes.b1[0], bytes.b1[1], bytes.b1[2], bytes.b1[3]);

}

void loop() {
  // put your main code here, to run repeatedly:

}


```
【ポケポケ】モンボを安易に使うべきではない


## 問

次の状況を考える。

* 次ターンまでに手札にタネポケが2枚以上欲しい
* 手札にはタネポケが1枚もないが、モンボは1枚ある
* 山札は残り12枚で、そのうち5枚がタネポケ
* 博士の研究は存在しない

この場合、現ターンでモンボを使うべきか？

## 考える

### 現ターンにモンボを使う場合

現ターンにモンボを使うと、次ターンの山札は残り11枚中4枚がタネポケとなるので…

```math
\begin{align}
次ターンまでにタネポケが2体揃う確率 &= 次ターンのトップがタネポケである確率 \\
&= \frac{4}{11}
\end{align}
```

### 次ターンにモンボを使う場合

現ターンにモンボを使わないと、次ターンの山札は残り12枚中5枚がタネポケとなるので…

```math
\begin{align}
次ターンまでにタネポケが2体揃う確率 &= 次ターンのトップがタネポケである確率 \\
&= \frac{5}{12}
\end{align}
```

### どちらが大きい？

```math
\begin{align}
現ターンにモンボを使ったときの確率 = \frac{4}{11} = \frac{48}{132} \\
次ターンにモンボを使ったときの確率 = \frac{5}{12} = \frac{55}{132} \\
\end{align}
```

よって次ターンにモンボを使ったほうがタネポケを2体揃えやすい。
（微差だが）

またサポートなどが欲しい場合は現ターンにモンボを使うべきだとも言える。

## おまけ

```math
\begin{align}
&1 < a < b \text{ として} \\
&\frac{a-1}{b-1} = \frac{(a-1)b}{(b-1)b} = \frac{ab - b}{b(b-1)} \\
&\frac{a}{b} = \frac{a(b-1)}{b(b-1)} = \frac{ab - a}{b(b-1)} \\
&\therefore \frac{a-1}{b-1} < \frac{a}{b}
\end{align}
```

## 最後に

カスミナーフしろ！
MVCモデル

MVCモデルを簡単に言うと、
　M：処理のロジック
 　V：画面のこと
  　C：全体制御
   ていうイメージらしいです。

これをjavaで扱うと、
　M　: Bean
    　V　：JSP
     　C　 : servlet
      という感じです。」
[JavaScript] でゲームコントローラを扱う

基本的な使い方は[例のとこ](https://developer.mozilla.org/ja/docs/Web/API/Gamepad_API/Using_the_Gamepad_API)にもあるのですが、
webに上がってる情報だけではいろいろと不足ということで。

## index は当てにするべからず

コントローラ1つだけという仕様であれば気にする必要ないですが、
複数のコントローラを扱うときは要注意。

[Gamepad.index](https://developer.mozilla.org/ja/docs/Web/API/Gamepad/index)は、認識された順に0から付与されていきます。  
すなわち

- 実行中にコントローラを追加
- ページをリロード

といった手順でindexの入れ替わり、すなわち操作対象の入れ替わりが発生し得ると。  
仕様的にあかんやつですね。  
というわけで…

## プレイヤー本位の仕様にしよう

大抵のゲームでは、プレイヤーは最大何人で、それぞれのプレイヤーはどんな位置付けか
仕様として明確に決まっています。つまり、Gamepad.indexではなく、この仕様に準じた
プレイヤー番号で配列を扱うべきであり、それぞれのプレイヤーに対応するGamepad.index
のコントローラを参照(または未割り当て)といった構造にすることが最善手となります。

## コントローラを合理的に割り当てよう

では、認識順に入ってくるgamepadconnectedイベントでは、
それぞれどのプレイヤーに割り当てるとよいでしょうか。

1. 切断前に使っていたコントローラに合わせる
ゲーム中に一旦コントローラを外してまた戻したとき、そのコントローラは
どのプレイヤーに割り当てるべきでしょうか。いうまでもなく、
外す前に使っていたプレイヤーです。
というわけで、gamepaddisconnectedイベントが発生した後でも
使っていたコントローラの[Gamepad.id](https://developer.mozilla.org/ja/docs/Web/API/Gamepad/id)値は保持しておきましょう。  
再度同じGamepad.idでgamepadconnectedイベントが来たとき、  
外したプレイヤーに再優先で割り当てます。  

1. ユーザ設定優先
多くのPCゲームでは、何番目のプレイヤーがどのコントローラを扱うかという
ユーザ設定があります。
その設定をプレイヤー順に調べ、Gamepad.idと一致するところを優先します。  
ただし、そのプレイヤーが既に別のコントローラを扱うことになっている場合は、  
勝手に差し替えるのもよくないのでスルーとします。  

1. その他のプレイヤー
特別な措置が必要なくなったところで、他の未設定プレイヤーに割り当てていきます。

### さらなる問題点

Gamepad.idって、idを名乗ってるくせに同一製品が複数繋がっていると重複してます。  
実際に参照されるのはindexの方なので、共存して使い分けることはできます。  
ただ、どのプレイヤーがどちらという観点では、明確に区別する方法が(たぶん)ない。
同一製品2つ外して差し直したら入れ替わる可能性ありますが、諦めましょう。  

## 動作確認はChrome/EdgeとFirefox双方で

Firefoxでは、gamepadconnectedイベントで入ってきたGamepadインスタンスを
保持しておけばそこから操作を読み取ることは可能ですが、この実装では
ChromeやEdgeで反応しなくなります。  
公式手順通り[navigator.getGamepads()](https://developer.mozilla.org/ja/docs/Web/API/Navigator/getGamepads)で取得すればよいのですが、  
テストする側としてはChromeやEdgeで行う必要あるところです。  

逆に、Firefoxではコントローラの操作が発生するまでgamepadconnectedイベントが
来ない特性があったりして、実装によっては検出漏れもあり得るので、
Firefoxでのテストも必要になってきます。

他のブラウザは…未調査(ぉ

## DInputコントローラにも対応しよう

近年ではXbox仕様の13ボタンコントローラが主流となっていますが、
ボタンが13個にデグレで決め打ちされててセガサターン等の6ボタン配列にもなってなくて
ゲームによってはとても不便なので、筆者は16ボタンのDInputコントローラを
主に使ってたりします。  
(現行製品がもうサンワサプライぐらいしか残ってないの困ったもんだ)  

### ボタン数

筆者が確認した限りでは、最大[24ボタン](https://www.elecom.co.jp/products/JC-DUX50BK.html)  

### 方向キー

XInputでは方向キーも通常のボタン扱いですが、DInputではハットスイッチ扱いに
なっているので、特殊な扱いが必要となります。  
筆者が確認した限りでは Gamepad.axis[9] が該当のようですが、全てそこかは不明。  
ニュートラルのとき±1から大きく離れた値になっているので、それを検出するのが確実。  

方向キーを上方向に入れると-1、そこから時計回りに左上で+1、その間は7等分  
…というなんか変な仕様。  
これって本物の無段階ハットスイッチが正しく反応しないような。  
製品持ってないから確認できないけど。  
(20年ぐらい前に店頭で見かけたやつ、確保してなかったのが悔やまれる)  
(あとSteamDeckのトラックパッドがハットスイッチらしいのだが確認できず)  

### アナログスティック

製品により、右スティックの該当箇所が全く違ってたり。  
左スティックは Gamepad.axis[0,1] で固定?(信用はしてない)  
まぁ、通常ボタンでさえ製品により違うのがDInputなので。  

## コントローラテスト

とりあえず[適当に作ってみた](https://yges.work/misc/gamepad.html)  
Unlicenseにしてあるので、ソース持ってって流用してもよいです。  


### ぼやき

ほんとはSteamDeckでの反応をみたかったのだが、認識されなかった。  
OMG.
符号理論におけるシンドロームは２倍化できない


# シンドローム２倍加計画は達成不可能である
バーレカンプ・マッシー法に対する検査行列の構造を以下のように書くことが出来る。


```math
\begin{pmatrix}
\frac{1}{f(x_i)},\frac{x_i}{f(x_i)},...,\frac{x^k_i}{f(x_i)}\end{pmatrix}^T

=

\begin{pmatrix}
\frac{1}{f(a_1)},\frac{1}{f(a_2)},...,\frac{1}{f(a_n)}\\
\frac{a_1}{f(a_1)},\frac{a_2}{f(a_2)},...,\frac{a_n}{f(a_n)}\\
\frac{a^2_1}{f(a_1)},\frac{a^2_2}{f(a_2)},...,\frac{a^2_n}{f(a_n)}\\
... \\
\frac{a^k_1}{f(a_1)},\frac{a^k_2}{f(a_2)},...,\frac{a^k_n}{f(a_n)}
\end{pmatrix}
```

```math
=
\begin{pmatrix}
a^0_1,a^0_2,...,a^0_n\\
a_1,a_2,...,a_n\\
a^2_1,a^2_2,...,a^2_n\\
...\\
a^k_1,a^k_2,...,a^k_n\\
\end{pmatrix}
\cdot
\begin{pmatrix}
\frac{1}{f(a_1)},0,0,...,0\\
0,\frac{1}{f(a_2)},0,...,0\\
0,0,\frac{1}{f(a_3)},...,0\\
...\\
0,0,...,0,\frac{1}{f(a_n)}
\end{pmatrix}\\
=\\
V\cdot F
```
```math
=

(a^i,a^{2i},a^{3i},...,a^{ki})
\cdot
\begin{pmatrix}
\frac{1}{f(a_1)},0,0,...,0\\
0,\frac{1}{f(a_2)},0,...,0\\
0,0,\frac{1}{f(a_3)},...,0\\
...\\
0,0,...,0,\frac{1}{f(a_n)}
\end{pmatrix}\\
\cdot
(e_0,e_1,e_2,...,e_n)^T
```
```math
=(\frac{a_1^i}{f(a_1)},\frac{a_2^{2i}}{f(a_2)},...,\frac{a_n^{ki}}{f(a_n)})
\cdot
(e_1,e_2,...,e_n)^T
```

ここで行列$V$はVandermonde行列である。

# シンドロームが２倍化できないことの例
GF(16)の生成多項式を、$x^4+x^3+1$とする。
今、リードソロモン符号の検査行列を次のように書く。
$$(2^i,2^{2i},2^{3i},2^{4i},2^{5i},2^{6i})^T$$
すると、最初の３列を抜き出してみると、

```math
\begin{pmatrix}
1 & 2 & 4 \\
1 & 4 & 9 \\
1 & 8 & 15 \\
1 & 9 & 14 \\
1 & 11 & 10 \\
1 & 15 & 3
\end{pmatrix}
```
となる。このとき符号の０番目、１番目、２番目に値１のエラーが発生した場合のシンドロームを計算すると、
$$(7,12,6,6,0,13)$$
である。
もし２倍化によってシンドロームが伸長できたとすると、このシンドロームの最初の３要素から後半が計算できるはずであるが、この要素の掛け算からは計算できないような０の値が出てきてしまうので、そのような２倍化は不可能であることが分かる。
よって、シンドローム２倍化計画は達成不可能である。

どうやら私は２乗してから足すことと、足してから２乗することの違いを理解していないようだ。
コードを生成しないcollection

コードを生成しないCollectionできました。ただ、インターフェースへの代入処理が入るため
コードの生成量はあまり変わらないかもしれません。あんまり意味がないかもしれません。
listとかmapって思ったより、多用しないため。セルフホストに適用したら、メモリ枯渇しました。
RustにはenumへのCollectionもありますが、それを実装するかもしれません。
気が向けば。

```
#include <comelang.h>

int main(int argc, char** argv)
{
    list<object: string>*% li = new list<object: string>();

    li.add(s"AAA");
    li.add(s"BBB");
    li.add(s"CCC");

    foreach(it, li) {
        puts(it);
    }

    return 0;
}
```

こんな感じです。addなどのlistのコード生成はobjectインターフェースのみとなります。
ただ、li.add(s"AAA");objectインターフェースへの代入処理が入るため、実際はコード生成量は
あまり変わりません。意味ないですね。がくり。
ちょっと,anyへの代入にしてコード生成してみます。ちょっとその仕事今からやります。
Raspberry Pi Zero 2 WでOpenCVを使った動体検知テスト

# 1.はじめに
[前回記事](https://qiita.com/dokuhakoneko/items/bcd8cbbcc6e2f077c127)の続きを行う。
今回は[参考サイト](https://qiita.com/hase-k0x01/items/acd0d9159a9001ebfbd3)をRaspberry Pi Zero 2 Wで実装し、マシンスペック的に動作可能か確認する。

# 2.手順
1. OpenCVインストール
2. 参考サイトの動体検知ソースコードを実行

# 3.OpenCVのインストール
まずOpenCVをインストールすべく参考サイト内で引用されている[パソコン工房の記事](https://www.pc-koubou.jp/magazine/19205)を参考にするが、一部変更。
```:記事内のコマンド
sudo apt-get install python-opencv
```
```:本環境のコマンド
sudo apt install python3-opencv
```
### ``apt-get``と``apt``の違いについて
[このサイト](https://qiita.com/karaage0703/items/f01db1cf49b151022b7c)の内容から要約すると`` apt ``のほうが
・``apt-get``や``apt-cache``を内包した新しいコマンド
・ユーザレベルなら使いやすい
という事で基本は`` apt ``で良い。

### ``python-opencv``と``python3-opencv``の違いについて
名前から分かる通り、``python3-opencv``はPython3.xx.xxのバージョンに向けたOpenCVのバインディングである。本記事投稿時では、これが主流となっている。
``python-opencv``はPython2.xx.xxのバージョンに向けたOpenCVのバインディングで簡単に言うと古い。Python2自体は更新が止まっているため、今後の使い勝手を考えるとPython3のほうが無難。もちろん使用環境によってはその限りではないが。

現在のPythonバージョンの確認のコマンドは以下。
```
python -V
```
本環境ではPython 3.11.2がインストールされていた。

# 4.動体検知ソースコード
参考サイトのソースコードをそのまま使用したいが、一部エラーが発生し面倒なのでnanoで``#``にてコメントアウトし対応する。
コメントアウトする行は87、88行目でウィンドウ表示に輪郭を入れるものらしい。
コメントアウトしない場合、以下のエラーが出ていた。
```
[ WARN:@05.330] global ./modules/videoio/src/cap_gstreamer.cpp (1405) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1

Traceback (most recent call last):
  File "/home/duruga/test/security_cam_motion.py", line 87, in <module>
    image, contours, hierarchy = cv.findContours(thresh.copy(), cv.RETR_EXTERNAL , cv.CHAIN_APPROX_SIMPLE)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected 3, got 2)
```
このエラーはcv.findContours()の戻り値の足りないため発生している。
・OpenCV 2.x.x / 3.x.x : "image", contours, hierarchy = cv.findContours(...)
・OpenCV 4.x.x : contours, hierarchy = cv.findContours(...)
OpenCV 4系はimageが返ってこないためエラーになっている。

使用環境のOpenCVのバージョン確認方法は以下。
```
python -c "import cv2; print(cv2.__version__)"
```
本環境では4.6.0であった。エラーになって当たり前。

# 5.動作確認
前節のソースコードを適当なディレクトリに保存して実行する。
今回は画面キャプチャボードを使用し、スマホの画面をカメラ入力としている。
ホーム画面で操作をしていないとき。
![20250131_153845037_iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992520/ffa4cea9-2a4a-8aa2-4e7c-234fe6873142.jpeg)

操作をしたとき。
![20250131_154010118_iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992520/743009ae-9084-a944-5f1a-a6d9fd297985.jpeg)
正常に画面を入力でき、画面操作によって入力映像に変化があった際には左下数値が0→0.08...に変化している。
この程度の負荷であればRaspberry Pi Zero 2 Wでも動作可能と確認できた。

# 6.おわりに
Raspberry Pi Zero 2 Wにて元々Raspberry Pi 3 Model B Plusで動作してたソースコードをほぼそのまま動作させた。
元のソースコードでカメラの解像度を下げていることもあってか、動作自体は問題ないように感じた。
もちろんJetson nanoなどの高性能な環境と比べるとマウスの動きにラグはあるが、想像していた動作に比べると遥に余裕があると感じた。

次回は目的の動きがない時にアクションを起こす「静体検知」を行いたい。
バックエンドで設計書のコロケーションをやってみた

こんにちは。
みなさま、設計書、書いていますか？
私は昔、Office製品で設計書を書いていましたが、最近はもっぱらMarkdownで書いています。
Markdownで書くなら、できればGitで管理して、プルリクエストも活用したいですね。
それをうまく運用するために、私は設計書をソースコード同様にGitリポジトリ内に配置することにしました。
今回はそのお話です。

## コロケーションとは

コロケーションとは、関連するリソースを近くに置くことを指します。
コロケーションは、Next.jsの公式ページで触れられています。

https://nextjs.org/docs/app/getting-started/project-structure#colocation

コロケーション自体は設計書に焦点をあてたものではないのですが、私のチームではこれをバックエンドプログラムの設計書に適用してみたというのが今回のお話です。
もしかしたら今回やったことはどこかに書いてあるのかも知れませんが、とりあえず私のチームではコロケーションを参考に独自でやってみたと思ってください。

## やってみたコロケーションのイメージ

今回はAWS Lambdaを用いたサーバーレスによるバックエンドでやってみました。
言語はPythonです。
以下は構成のイメージです。

```shell
/
├── app
│   ├── function_a
│   │   ├── handler.py
│   │   └── README.md
│   ├── function_b
│   │   ├── handler.py
│   │   └── README.md
│   └── function_c
│       ├── handler.py
│       └── README.md
├── docs
│   ├── database.md
│   └── system_diagram.drawio
└── README.md
```

機能＝AWS Lambda関数ごとにディレクトリを作り、その中にhandlerと設計書となるREADME.mdを置きました。
README.mdにマークダウン形式で設計を書いていきます。

機能をまたぐ設計や、構成図・データベース設計などはdocsディレクトリに配置しました。

## このような構成にした理由

今回の構成の始まりは、設計書をマークダウンで書きたい、プルリクエストを活用したいというところから始まっています。
構成を検討する過程で、以下のパターンも議論しました。

```shell
/
├── app
│   └─── functions
│       ├── function_a.py
│       ├── function_b.py
│       └── function_c.py
├── docs
│   ├── database.md
│   ├── function_a.md
│   ├── function_b.md
│   ├── function_c.md
│   └── system_diagram.drawio
└── README.md
```

```shell
/
├── app
│   └─── functions
│       ├── function_a.md
│       ├── function_b.md
│       ├── function_c.md
│       ├── function_a.py
│       ├── function_b.py
│       └── function_c.py
├── docs
│   ├── system_diagram.drawio
│   └── database.md
└── README.md
```

上のパターンは、ソースコードと設計書が離れており、あまりメリットを感じられなかったため、採用しませんでした。
下のパターンは、単純に見づらいので採用しませんでした。
実際のソースコードでは、さらに多くの機能名が含まれるため、この構成だと設計書を探すのが大変になるのが容易に想像できました。

構成図やデータベース設計など、機能をまたぐものはdocsディレクトリにまとめました。
本当は、共通的なディレクトリを作るとコンフリクトが起きやすくなるので避けたかったのですが、現実問題データベース設計などは機能ごとに独立させるのは無理があるので、許容しました。

## この構成における設計書で書くもの

この構成における設計書で書くものは以下の通りです。

- 機能の概要
    - 何をする機能か
    - 大まかな処理の流れ
- 入出力内容
    - パラメータ
    - 出力するファイル・データのフォーマットなど
- 使用方法／テスト方法

これらをMarkdownで表現できる形で書いていきます。
この構成を適用しているのはバックエンドのため、いわゆる画面イメージは含めていません。また、フローチャートやシーケンス図も入れていません。
それらが不要になるほど、個々の機能を小さくすることを重視しており、図示が必要ならdraw.ioなどで作成してdocsディレクトリに置くという形にしています。

## メリットとデメリット

メリットの一つはコロケーションの思想通り、ソースコードと設計書が近いのでとても探しやすいことです。
特に説明しなくても、開発者が簡単にソースコードと設計書を行き来できるため、効率的です。
他のメリットとしては、ディレクトリ構成に進捗が如実に現れること、プルリクエストを追うだけで進捗が把握できることです。
この構成で開発が始まると、以下のように進行します。

- まず機能名のディレクトリができる
- 次に機能名のディレクトリ配下に設計書ができる
- 設計書のプルリクエストができて、マージされる
- 次にソースコードができる
- ソースコードのプルリクエストができて、マージされる

機能のディレクトリに設計書だけあれば、それは設計完了ではあるが実装はまだと言えます。
また、設計書もソースコードもレビュー依頼がプルリクエストに集中するので追うものが減り効率があがります。
現実的には、管理者が追うべきものはプルリクエスト以外にもIssueなどがありますが、実装に関することが追いやすいのは良いことだと思います。

反対に、デメリットとしてはディレクトリ構成を工夫しないとこの構成は採用しづらいことが挙げられます。
もう一つのデメリットとしては、レビュー専任の人にとっては必ずしも探しやすい構成とはいえないことです。
そもそもGitリポジトリを見ない人がいる場合はこの構成は見送るべきかもしれません。

## まとめ

以上、バックエンドで設計書のコロケーションをやってみたというお話でした。
感想としては、開発者しか見ないドキュメントはGitリポジトリに入れ、機能ごとにソースコードと設計書をまとめると、確かに探しやすくて良いと感じました。
同時に開発者で完結しないドキュメントは、別の媒体で管理した方がよいでしょう。
本記事で書いたことが誰かの参考になれば幸いです。
【初心者向け】Pythonで学ぶ回帰分析入門

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/758f0e60-d376-62b5-aa38-967cb759cc5b.png)

機械学習やデータ分析を始めると、「売上を予測したい」「今後の気温や株価を予測したい」といった、「**連続値を予測**」する場面に出会うことがよくあります。そんなときに使える基本手法が「**回帰分析**」です。
本記事では、回帰分析の概念から、Python（scikit-learn）を用いた簡単なサンプルコードの説明までを行います。これから回帰分析を始めたい方の一助になれば幸いです。

---

## 回帰分析とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/071ecea3-ba1b-47e7-74cd-ca4fb4b58b1d.png)

- **目的**  
  ある「数値（連続値）」を予測する手法。売上や株価、温度、家賃などを予測したい場合に用いられる。

- **考え方**  
  - 「**説明変数**」と呼ばれる予測の根拠となるデータ（特徴量）と、「**目的変数**」と呼ばれる予測したい値がある。
  - データを学習して、両者の関係をできるだけ正確に捉える関数（モデル）を作る。

- **なぜ重要か**  
  - 将来の値を定量的に予測できるため、意思決定や計画立案に役立つ。
  - 特徴量の影響度を把握することで、どの要素が結果に大きく影響しているか分析できる。

---

## 回帰分析の種類

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/fc1c9300-21e6-39b2-d627-9ed40a0618e4.png)

代表的な手法として、以下が挙げられます。

1. **単回帰分析**  
   - 説明変数が1つの場合。最も基本的な線形回帰モデル。
   - 例：「勉強時間（説明変数）」から「テストの点数（目的変数）」を予測する。

2. **重回帰分析**  
   - 説明変数が複数ある場合。実際のビジネスや研究ではこちらを使う方が多い。
   - 例：「広告費・出店エリア・客足」など複数の要素から「売上」を予測する。

3. **多項式回帰**  
   - 説明変数を2次式や3次式などの形でモデル化する場合。非線形な関係を捉えたいときに使われる。

4. **その他の回帰**  
   - リッジ回帰、Lasso回帰、Elastic Net回帰などの「正則化回帰」
   - ランダムフォレスト回帰、XGBoost、LightGBMなどのアンサンブル手法
   - ニューラルネットワークを使った深層学習ベースの回帰
   - データや目的に応じて使い分けるのがポイント。

---

## 【実践】Python（scikit-learn）で回帰分析をやってみよう
ここでは、scikit-learnに含まれている「**California Housing Dataset**」を使って住宅価格を予測する例を紹介します。

![mermaid-diagram-2025-01-30-221903.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/d1750489-7779-cf57-7968-d5b381b89935.png)


### 1. 必要なライブラリの準備
```bash
pip install numpy pandas scikit-learn
```

### 2. データ読み込みと前処理
```python
import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split

housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
```

### 3. モデルの学習と予測
```python
from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
```

### 4. モデルの評価
```python
from sklearn.metrics import mean_squared_error, r2_score

mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print("RMSE:", rmse)
print("R^2 :", r2)
```

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/3421710d-4d29-00f4-45ba-fb9cfa1f0923.png)


## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/9631e03d-99fc-adc6-db64-e7759a82fb15.png)

- 回帰分析は「**数値を予測**」したいときに用いられる、機械学習の基本手法。
- Python（scikit-learn）を使えば、数行のコードで実装・評価が可能。
- データや用途に合わせて、単回帰・重回帰・正則化回帰・アンサンブルなど、多様な手法を試すことで精度向上が期待できる。

本記事では、線形回帰の基礎的なサンプルを紹介しました。機械学習で回帰を扱う第一歩として、ぜひ自分のデータセットを使って試してみてください。
アプリケーションに割り当てられている論理コアを確認したいときのコマンド

アプリケーション(プロセス)に割り当てられている論理コアを確認したいときのコマンド


## コマンド

psコマンドでpsrのオプションを指定する

```shell
ubuntu@ubuntu:~$ man ps |grep "psr "
       psr         PSR       processor that process last executed on.
ubuntu@ubuntu:~$
```

実行例
```shell
ubuntu@ubuntu:~$ ps -eo psr,pid,comm --sort=psr
PSR     PID COMMAND
  0       1 systemd
  0       2 kthreadd
  0       3 pool_workqueue_release
...<snip>...
  0     818 login
  0     901 dockerd
  0    1329 ps
  1      21 cpuhp/1
  1      22 idle_inject/1
  1      23 migration/1
...<snip>...
  1     717 dbus-daemon
  1    1236 kworker/R-tls-s
  1    1301 sshd
  2      17 rcu_preempt
  2      27 cpuhp/2
  2      28 idle_inject/2
 ...<snip>...
  2    1244 sshd
  2    1245 sshd
  2    1312 kworker/u11:3-events_power_efficient
  3      33 cpuhp/3
  3      34 idle_inject/3
  3      35 migration/3
 ...<snip>...
  3    1190 bash
  3    1302 bash
  3    1319 kworker/u12:4-flush-252:0
ubuntu@ubuntu:~$
```
Node.jsとTypeORM：プレースホルダーの利用方法

皆さん、こんばんは。

今日は「Node.jsとTypeORM：プレースホルダーの利用方法」についてご紹介します。

プレースホルダーは、SQLクエリ内で動的な値を安全に挿入するために使用され、特にSQLインジェクションの防止に有効です。
TypeORMでは、クエリビルダーやリポジトリメソッドを使用してプレースホルダーを簡単に扱うことができます。

# プレースホルダーの基本

プレースホルダーは、クエリ内で変数部分を:や?などの記号で置き換えることで実現します。
TypeORMでは主に以下の2種類のプレースホルダーが使用されます。

- 名前付きプレースホルダー (:name)
- 位置指定プレースホルダー (?)

## 名前付きプレースホルダーの例

```
import { getRepository } from "typeorm";
import { User } from "./entity/User";

const userRepository = getRepository(User);

const user = await userRepository.findOne({
  where: {
    firstName: "John",
    lastName: "Doe",
  },
});
```

上記の例では、TypeORMが内部的にプレースホルダーを使用して安全にクエリを実行しています。

### QueryBuilderを使用した名前付きプレースホルダー

```typescript
const users = await getRepository(User)
  .createQueryBuilder("user")
  .where("user.firstName = :firstName", { firstName: "John" })
  .andWhere("user.lastName = :lastName", { lastName: "Doe" })
  .getMany();
```

この例では、`:firstName`と`:lastName`が名前付きプレースホルダーとして使用されています。`{ firstName: "John", lastName: "Doe" }`のオブジェクトで値をバインドしています。

## 位置指定プレースホルダーの例

位置指定プレースホルダーは、?を使用して値を順番にバインドします。

```
const users = await getRepository(User)
  .createQueryBuilder("user")
  .where("user.firstName = ?", ["John"])
  .andWhere("user.lastName = ?", ["Doe"])
  .getMany();
```

ただし、名前付きプレースホルダーの方が可読性が高いため、一般的には名前付きを推奨します。

# 生SQLクエリでのプレースホルダーの使用

TypeORMでは、生のSQLクエリを実行する際にもプレースホルダーを使用できます。これにより、より柔軟なクエリを安全に実行できます。

```typescript
const rawData = await getConnection().query(
  `SELECT * FROM user WHERE firstName = $1 AND lastName = $2`,
  ["John", "Doe"]
);
```

上記の例では、$1と$2が位置指定プレースホルダーとして使用されています。値は配列で順番にバインドされます。

## プレースホルダーを使用するメリット

- セキュリティの向上: プレースホルダーを使用することで、SQLインジェクション攻撃を防ぐことができます。ユーザー入力を直接クエリに埋め込むのではなく、安全にバインドするためです。
- パフォーマンスの向上: データベースは同じクエリ構造を再利用できるため、クエリの実行計画をキャッシュしやすくなります。
- 可読性と保守性の向上: クエリが明確になり、動的な値の挿入が容易になります。

## ベストプラクティス
- 常にプレースホルダーを使用する: 動的な値をクエリに挿入する際は、必ずプレースホルダーを使用してセキュリティを確保しましょう。
- 名前付きプレースホルダーを優先する: 複数の値を扱う場合、名前付きの方が可読性が高く、管理しやすいため推奨されます。
- 生のSQLクエリは慎重に使用する: TypeORMの機能で実現できる場合は、生のSQLクエリを避け、ORMの機能を活用しましょう。どうしても必要な場合は、プレースホルダーを適切に使用してください。

## 具体的なコード例

以下に、TypeORMで名前付きプレースホルダーを使用してユーザーを検索する具体的な例を示します。

```typescript
import { getRepository } from "typeorm";
import { User } from "./entity/User";

async function findUser(firstName: string, lastName: string): Promise<User | undefined> {
  const userRepository = getRepository(User);
  
  const user = await userRepository.findOne({
    where: {
      firstName: firstName,
      lastName: lastName,
    },
  });

  return user;
}
```

また、クエリビルダーを使用した例は以下の通りです。

```typescript
import { getRepository } from "typeorm";
import { User } from "./entity/User";

async function findUsers(firstName: string, lastName: string): Promise<User[]> {
  const users = await getRepository(User)
    .createQueryBuilder("user")
    .where("user.firstName = :firstName", { firstName })
    .andWhere("user.lastName = :lastName", { lastName })
    .getMany();

  return users;
}
```

# まとめ

TypeORMにおけるプレースホルダーの使用は、セキュリティやクエリの可読性、パフォーマンス向上に寄与します。特に動的な値を扱う際は、必ずプレースホルダーを活用することで、安全かつ効率的なデータベース操作が可能となります。
TypeORMのドキュメントも参考にしながら、適切な方法でプレースホルダーを活用してください。


ぜひ参考にしてみてください。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
備忘録　.rubocop.yml の設定項目

## 自己紹介
はじめまして、はる（[@lemonade_37](https://twitter.com/lemonade_37)）と申します。
エンジニアとして働き始めて約11ヶ月が経過しました🐣


## 概要
既存の Rails アプリ内に RuboCop を導入したかったのですが、厳しすぎるルールだと修正量が膨大になってしまい、ちょうど良い設定内容を考えるのが難しかったです。
参考記事を参考に、揃えるべきところはチェックしつつも、少しゆるめなルールで導入しました。その際の備忘録です。

### 環境
- Mac OS（Apple Silicon）
- Docker
- Ruby 3.2.3
- Rails 7.1.3
- Importmap
- Tailwindcss、daisyUI
- PostgreSQL

:::note warn
ケースバイケースであり、あくまで私を取り巻く環境において考えたものです🙇
より良い考え方がありましたら、ぜひコメントにて教えていただけますと幸いです。
:::


## 設定内容
```yml:.rubocop.yml
inherit_from: .rubocop_todo.yml

require:
  - rubocop-rails
  - rubocop-capybara
  - rubocop-performance
  - rubocop-rubycw

AllCops:
  DisabledByDefault: true # デフォルトで全てのRuboCopをオフ、必要なものだけオン。今後必要に応じて項目を追加。
  DisplayCopNames: true
  NewCops: enable
  Exclude:
    - "vendor/**/*"
    - "db/**/*"
    - "bin/**/*"
    - "lib/**/*"
    - "spec/**/*"
    - "config/**/*"
    - "node_modules/**/*"

Bundler:
  Enabled: true

Lint:
  Enabled: true

Lint/EmptyClass:
  Enabled: false

Performance:
  Enabled: true

Rubycw:
  Enabled: true

Security:
  Enabled: true

# Rails
Rails/I18nLocaleTexts:
  Enabled: true

Rails/LexicallyScopedActionFilter:
  Enabled: true

Rails/TimeZone:
  Enabled: true

# Style
Style/StringLiterals:
  Enabled: true

Style/SymbolArray:
  Enabled: true

Style/EmptyMethod:
  Enabled: true

Style/CommentedKeyword:
  Enabled: true

Style/GuardClause:
  Enabled: true

# Layout
Layout/EmptyLines:
  Enabled: true

Layout/EmptyLinesAroundBlockBody:
  Enabled: true

Layout/EmptyLinesAroundMethodBody:
  Enabled: true

Layout/EmptyLineBetweenDefs:
  Enabled: true

Layout/SpaceBeforeFirstArg:
  Enabled: true

Layout/SpaceBeforeSemicolon:
  Enabled: true

Layout/SpaceAfterColon:
  Enabled: true

Layout/SpaceAfterComma:
  Enabled: true

Layout/SpaceInsideHashLiteralBraces:
  EnforcedStyle: space

Layout/SpaceInsideParens:
  EnforcedStyle: no_space

Layout/TrailingWhitespace:
  Enabled: true

Layout/TrailingEmptyLines:
  Enabled: true

Layout/IndentationConsistency:
  Enabled: true

Layout/IndentationWidth:
  Enabled: true
  Width: 2

Layout/DefEndAlignment:
  Enabled: true

```

## まとめ
自分なりに、既存プロジェクトに合った設定を考えてみました。
様々なプロジェクトを経験する中で、社内でちょうど良い設定を模索していきたいと思います。


　
## 参考・引用記事
- [.rubocop.ymlシンプルに、ゆるめにやりたいんじゃ](https://hoshinotsuyoshi.com/post/rubocop_yaml/)
- [【Rails】RuboCopの導入 ~ おすすめルールの設定方法](https://blog.to-ko-s.com/rubocop-setting/#i-6)
- [【Rails】RuboCop 設定編（2020年10月版）](https://qiita.com/piggydev/items/8a9f5cd4486861819a69)
- [RuboCop :: RuboCop Docs](https://docs.rubocop.org/rubocop/)


## 関連記事

https://qiita.com/lemonade_37/items/f2f25ab1b80609955392
【Homebrew】意図的にインストールしたFormulaeのリストを取得する方法

## Formulaeのリスト

以下のコマンドを実行することで表題のリストを取得できます。

```terminal
$ brew list --installed-on-request
bat
cask
cmake
...
```

https://github.com/Homebrew/brew/pull/17125

また、次のコマンドを実行すると説明も合わせて出力できます。

```terminal
$ brew desc $(brew list --installed-on-request) | column -t -s ":"
bat                     Clone of cat(1) with syntax highlighting and Git integration
cask                    Emacs dependency management
cmake                   Cross-platform make
...
```

## Caskのリスト

Caskのリストを取得するには以下のようにします。

```terminal
$ brew list --cask -1
alfred
arc
autoraiseapp
...
```
選択肢がたくさんあるショートカットキー（Excel）

ググるたびに複数のやり方が出てきて迷うことがあったので、一覧にしてまとめてみました。
`+`は同時押し、`→`は順番に押していく表記です。

# 貼り付け
## ・値貼り付け
|ショートカットキー||
|:-:|:-|
|`Ctrl + Shift + V`|○ 2023年8月から追加された新機能<br>△ Microsoft365のみ使用可<br>△ 対応する書式貼り付けのショートカットがない|

## ・値貼り付け／書式貼り付け（セットで覚えたい場合）
|ショートカットキー||
|:-:|:-|
|`アプリケーションキー` → `V`<br>`アプリケーションキー` → `R`|○ ２キーで済む（同時押しも可）<br>△ あまり使わないキーなので覚えにくい<br>△ キーボードによってはキーが無いこともある|
|`Alt` → `E` → `S` → `V` → `Enter`<br>`Alt` → `E` → `S` → `T` → `Enter`|○ `Alt` → `E` → `S` だけ覚えればダイアログを<br>　見て操作すればいいので覚える負担が少ない<br>○ 片手しか使えないときは便利かも<br>△ ５段階あるので面倒くさい|
|`Ctrl + Alt + V` → `V` → `Enter`<br>`Ctrl + Alt + V` → `T` → `Enter`|○ `Ctrl + Alt + V`だけ覚えればダイアログを<br>　見て操作すればいいので覚える負担が少ない<br>○ コピー（`Ctrl+C`）からの指の動きが少なくて済む<br>△ ３キー同時押しがしんどい|
|`Ctrl + V` → `Ctrl` → `V`<br>`Ctrl + V` → `Ctrl` → `R`|△ 同時押し→順番押しでミスりがち（私だけ？）|
|`Shift + F10` → `V`<br>`Shift + F10` → `R`|○ アプリケーションキーがないとき用<br>△ F10が遠いのであまり使いたくない|



# シートの移動
|ショートカットキー||
|:-:|:-|
|`Ctrl + Fn + ⇧／⇩`|△  キーボードによって位置が違うので覚えにくい|
|`Ctrl + PageUp／PageDown`|△ キーボードによって位置が違うので覚えにくい<br>△ `Fn`も押さないと`PageUp／PageDown`が有効にならないキーボードもある|
|`F6` → `⇦／⇨` → `Enter`|△ F6が遠いのであまり使いたくない<br>○ キー配列によってはPageUpとかより使いやすいかも|

# 行列の操作
## ・行選択
|ショートカットキー|||
|:-:|:-|:-|
|`Shift + space`|一行選択|
|`Shift + space` → `Shift + ↑／↓`|一行選択→複数行へ拡張|
|`Shift + ↑／↓` → `Shift + space`|セル範囲選択→行全体へ拡張|

## ・列選択
|ショートカットキー||
|:-:|:-|
|`Ctrl + space`|列選択|
|`Ctrl + space` → `Shift + ←／→`|列選択→複数列へ拡張|
|`Shift + ←／→` → `Ctrl + space`|行選択→列全体へ拡張|

## ・行(列)選択したあとの操作
|ショートカットキー||
|:-:|:-|
|挿入| `Ctrl + Shift + ;`|
|削除| `Ctrl + [-]`|

## ・セル／セル範囲を選択した状態での操作
|ショートカットキー|||
|:-:|:-|:-|
|挿入|(列) `Alt` → `I` → `C`<br>(行) `Alt` → `I` → `R`|○ 積極的に使いたい|
|挿入|(列) `Ctrl + Shift + ;` → `C` → `Enter`<br>(行) `Ctrl + Shift + ;` → `R` → `Enter`|△ 手数が多い|
|削除|(列) `Alt` → `H` → `D` → `C`<br>(行) `Alt` → `H` → `D` → `R`|○ 積極的に使いたい|
|削除|(列) `Ctrl + [-]` → `C` → `Enter`<br>(行) `Ctrl + [-]` → `R` → `Enter`|△ 手数が多い|

# まとめ
キーボードの配列によるところも大きいので、PC環境が変わったとき等どれを使うか再考してみることをおすすめします:relaxed:
Godotで初めてゲームを作りました！

Godotというゲームエンジンを使って、初めてゲームを作りました。まだチュートリアルの３ページ目なんですけどwww

https://godotengine.org/

### なぜGodotを選んだのか
Godotというメジャーではないゲームエンジンを使ったのか？それは子供からGodotを勧められたからです。おそらく一般的には、UnityやUnrealを使うのが一般的ですし、私もそう思ってました。しかし、子供が私にGodotを薦めてきたのはいくつか理由がありました。
1. Unityは有料化などでゴタゴタガあり、Unityから抜けようとするクリエーターが増加しつつあるらしいです。
2. Unrealは映像ガチ系で映像に敏感な人が使うので、私はそれほどビジュアルに関心がないので。
3. 2Dと3Dの両方できるので、私のようにパズルゲームを作りたい人に向いている。
4. 内部のGDScriptはPythonに似てるらしい。これはPythonistaの私には追い風だ。
5. 最近大ヒットしたバックショットルーレットのようなインディーゲームを作る人が好んでいるようだ。私のように個人でゲームを作ってみたい人にGodotの方が向いてますね。

https://store.steampowered.com/app/2835570/Buckshot_Roulette/?l=japanese

### デメリットもあります
Godotは日本ではメジャーではないので、日本語の資料が少ないこと。私は英語でプログラミングを学んできたので、それほどのデメリットではないかと。20年前のPythonと同じで日本でほとんど知られていないけど、普及しそうな気配があるので、早い時期からかかわっているのは競争優位性がありそう（はやらないこともあるけどね）。

### 超初心者はフリーのオンライン講座へ
チュートリアルの中には、プログラミング初心者のためにハーバード大学の[コンピュータサイエンス講座](https://cs50.harvard.edu/x/2025/)のリンクが張ってあります。ここら辺は初心者に優しいですね。

Godotはエディタがついてるので、それでプログラミングしていきます。

![godot_tutorial_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734194/c67df237-6150-b55a-342d-c0c844baa68a.png)

一歩一歩慎重にオブジェクトを追加して、スクリプトを書きました。。ついにキャラを動かすことができました。私のキーボードは矢印キーがないので、ASDWキーでも動くように設定を追加しました。

[First Game Programming in Godot](https://www.youtube.com/shorts/n-rJm5oNGwQ)

子供たちに見せたら、「パパが先にゲーム作るなんて許せなーい！」だって。子供たちを悔しがらせることが何よりもうれしかったですwww(^^)
【随時更新予定】tmuxの使い方メモ

# Completionのインストール
TAB補完を行うためにCompletionをインストールします。

https://github.com/imomaliev/tmux-bash-completion/issues/10

```bash
==> tmux
Example configuration has been installed to:
  /opt/homebrew/opt/tmux/share/tmux

Bash completion has been installed to:
  /opt/homebrew/etc/bash_completion.d
```

https://stackoverflow.com/questions/25909105/no-manual-for-man-command-under-tmux-in-os-x

# tmuxの起動

```bash
tmux
```

# セッションの終了

```bash
exit
```

# セッションのアタッチ

```bash
tmux attach
```

```bash:alias(短縮版)
tmux a
```

# セッションのデタッチ
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash
C-b d
```

# セッション一覧の表示

```bash
tmux list-session
```

```bash:alias(短縮版)
tmux ls
```

# ウィンドウの作成
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash
C-b c
```

# ウィンドウの切り換え
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash:1つ後のウィンドウに進む
C-b n
```

```bash:1つ前のウィンドウに戻る
C-b p
```

# ウィンドウの強制終了
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash
C-b &
```

実行後、kill-window XXX? (y/n)に対して、`y`を入力

# 対話的なウィンドウの選択
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash
C-b w
```

ウィンドウの切替はj(進む), k(戻る)のキーか、カーソルキーで表示させたいウィンドウを選択して、Enterキーを打鍵します。

# ウィンドウの番号で移動
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash
C-b 数字
```

# ウィンドウ名を変更
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash
C-b ,
```

# クライアント数を表示

```bash
tmux list-client
```

```bash:alias(短縮版)
tmux lsc
```

# 明示的にセッションを指定してアタッチ

```bash
tmux a -t <TARGET_SESSION>
```

他のクライアントをデタッチしてアタッチする場合

```bash
tmux a -t <TARGET_SESSION> -d
```

# セッションの切り替え
※ デフォルトプレフィックスキーはC-b(control + b)の場合

```bash:1つ前のセッションに切り替え
C-b (
```

```bash:1つあとのセッションに切り替え
C-b )
```

# セッション名を指定してセッションを作成

```bash
tmux new -s <NEW_SESSION_NAME>
```

# 既存のセッション名を変更

```bash
tmux rename-session -t <OLD_SESSION_NAME> <NEW_SESSION_NAME>
```

# Reference
https://amzn.asia/d/61ejObg
マルチエージェント深層強化学習

ここではざっくりマルチエージェントAIについて紹介したいと思います。




# 導入 
## マルチエージェントシステム

まずマルチエージェントシステムについて紹介します。

マルチエージェントシステムとは複数のロボット（あるいは人）がそれぞれ自律的に意思決定し、相互に影響を及ぼし合うようなシステムのことです。ロボット（エージェント）が複数（multiple）いるからマルチエージェントという名前がついています。
例えば、サッカーは11エージェントvs11エージェントのスポーツと言えます。人間はトレーニングを積んでいくと、チームメートの動きを見て自分がどう動けばいいかを自律的に判断できるようになります。例えば、どこら辺のポジションを取ればいいのか、誰にパスを出せばよいのか、などです。

また、株式市場もマルチエージェントシステムといえます。各投資家がエージェントにあたり、それぞれ自分の利益だけを最大化しようとします。

## マルチエージェントシステムへの期待
このように、チームで協力したり、まわりと競い合って自己の利益を追求する現象は日常生活にあふれています。
これをロボットにもやらせてみよう、というのがマルチエージェントシステム研究の出発点です。つまり、ロボットが協力し合ってタスクを解いたり、群衆のなかで上手く他者を出し抜いて生き残ったりすることをさせてたい、ということです。



# 機械学習とマルチエージェントシステム

マルチエージェントシステムを考える上で機械学習なしで語るのは難しいでしょう。

以下では、「機械学習×マルチエージェントシステム」について議論します。その中でも特にエージェントどうしが協力し合って共通の課題を解くCooperative Settingについて見ていきます。

## 難しさとその面白さ

ロボットにチームワークを教えこむとなると、以下のよう難しさ（面白さ）があります。

- 自分のプレー選択がどれくらいチームのパフォーマンスに影響しているかを定量的に評価するには？
- 計算時間を抑えるために各エージェントの意思決定方法（強化学習でいう方策）を同時に更新した場合、チームワークのバランスが崩れたりしないか？サッカーでいうと、ボールホルダーはパスを選択したが、周りの味方はドリブルを開始すると思って反応できなかった、などがその例。




## 研究分野

機械学習×マルチエージェントの分野として代表的なものを二つ紹介します。

### マルチエージェント深層強化学習

深層学習を使ってAIが自律的に賢くなることを研究する深層強化学習 (Deep Reinforcement Learning)はよく知られています。これを拡張し, 複数のエージェントが同時にそれぞれ自律的に賢くなる方法論を研究するマルチエージェント深層強化学習というものがあります。2017年あたりから海外を中心に発展を遂げてきている分野です。

代表的なアルゴリズムに以下のようなものがあります。

- QMIX [ICML2018]
- Multi-Agent Proximal Policy Optimization (MAPPO) [NeurIPS2022]
- Multi-Agent Transformer [NeurIPS2022]
- Heterogeneous-Agent Soft Actor-Critic (HASAC) [ICLR2024]

このブログでは以上のようなアルゴリズムを今後紹介していきます。

### LLM×マルチエージェント（「心の理論」）

人間はチームワークをするとき、他所の行動やその意図を推測します。発達心理学で「サリーとアン課題」というものがありますが、他者の視点でものを考えることに関する研究は様々な分野に及びます。

人が他者の心の状態、目的、意図、知識、信念、志向、疑念、推測などを推測する直観による心の機能のことを「心の理論」と呼びます（wikipedia引用）。コンピュータソフトが「心の理論」を手に入れるかは非常に興味深い問いです。近年、LLM（Large Language Model）が「心の理論」に近いものを手に入れられるかどうか、という研究などが出ています。例えば、Li et al. (EMNLP2023)がそれにあたります。

他にも、以下の例のようにLLM×マルチエージェントの論文がちらほら出ています。これらについても、今後このブログで扱っていきたいと思います。

- Huao et al. Language Grounded Multi-agent Reinforcement Learning with Human-interpretable Communication. NeurIPS, 2024.
- Zhang e al. Towards Efficient LLM Grounding for Embodied Multi-Agent Collaboration. arXiv:2405.14314.







# 日本における研究動向


マルチエージェント深層強化学習の研究だと、海外の研究チームではJakob N. Forester先生の研究チームやShimon Whitesonなどが有名です。

海外に比べると, 日本ではマルチエージェントAI、特にマルチエージェント深層強化学習の研究はあまり盛んに行われていないように思われます。「マルチエージェントシステム」と打つと上に出てくるのは豊田中央研究所のホームページなどがあります。 「マルチエージェント深層強化学習」と打つと元松尾研究室の今井さんのスライドが出てきます。 いずれにせよ、マルチエージェント深層強化学習やLLM×マルチエージェントAIを日本で専門にやっている研究者や研究チームは極めて少ないというのが現状だと思います。





# 最後に


ロボットどうしが協調・協力することは今後ますます重要になってくると思います。 すでにスマート倉庫などでは複数のAGV（無人搬送車）が協調して物を運んでいます。街中にロボットが分散して物流を担う時代がやってくる未来もそう遠くないと思います。 ドローンやトラック, 配送ロボットが組み合わさってマルチモーダルな物流網の実現がカギになります。マルチエージェントシステムは将来の物流網の要となる技術になることが予想されます。
それ以外にも, 

- チームスポーツの新しい戦術の発明
- 戦地でのロボット（ドローン、トラック、ロボット）の協調行動
- 複数台ロボットの巡回パトロール
- 会社内での複数部門のAIの協調（例えば、生産計画AIと配送計画AIの協調によるサプライチェーン最適化など）

など、応用が多岐にわたります。




今後このブログではマルチエージェントAIについて発信し続けたいと思います。

次回もお楽しみに。



このブログは株式会社EfficiNet Xのテックブログです。

http://efficinetx.co.jp
【AZ-305_備忘】 SQL Database


# はじめに

AZ-305の問題集を解いていたのですが、Azure SQL　Databaseの選択肢が多くいつ何を選択すればよいのか全く理解できていないことに気づいたので、調査・整理することを目的に記載します。

# 大まかな選択肢

まずは大きく三つの選択肢

1. Azure SQL Database
1. Azure SQL Managed Instance
1. Azure VM上に構築したSQL Server

#### 選択ポイント

まず何が違うのか。ですが、
1番、2番はPaaS、3番はIaaSです。
MSが管理している範囲が違います。

3>2>1　の順にユーザが自由にできる範囲が広いです。
※ユーザが管理すべき範囲大きいということになります。

例えば既に利用しているSQLデータベースで細かい制御を行っている場合、PaaSでは制御できないことがあります。そうすると必然的に3番を選択することになります。
単純に物理的なサーバをAzureに移動させたいだけ。という要望があった際も３番となるかと思います。（オンプレミスとほぼ変わりなくVMへアクセスしてメンテナンス）

可能な限り管理をMSへ任せたい場合は2,3を検討します。
オンプレミス移行でなるべく管理工数を減らしたいが、ある程度互換性のあるサービスを選びたい場合は２、移行等でなく新規であれば３などの使い分けになるのではと思います。

コストはAzure SQL Managed Instance　＞　Azure SQL Database

#### 公式ドキュメント
https://learn.microsoft.com/ja-jp/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql

# Azure SQL Database

5つの選択肢があります。

- 仮想コアベース
    1. General Purpose
    1. Business Critical 
    3. Hyperscale 
    サーバレス(従量課金)か、プロビジョニング済み(固定料金)

 https://learn.microsoft.com/ja-jp/azure/azure-sql/database/service-tiers-dtu?view=azuresql
 
- DTU
    1. Standard
    1. Premium

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/service-tiers-sql-database-vcore?view=azuresql

 #### 選択ポイント

 ###### 仮想コアかDTUか
 仮想コアベースではコア数、メモリ、ストレージ サイズなどを選択可能
 DTUモデルは仮想コアほどきっちり性能を定義せず、DTUという指標を使って性能を決めます。（DTUモデルは抽象的）
 問題の選択肢をここで絞るのは難しい印象ですが、ざっくり記憶。

 ######  公式ドキュメント一部抜粋ヒント

MSとしては仮想コア推し。仮想コアだけのメリットは下記
・Azure SQL Database 仮想コアベース Hyperscaleのストレージサイズは「10 GB – 128 TB」とずば抜けている。
・サーバレスを利用できる
・予約インスタンス・ハイブリッド得点が利用できる
・コンピューティング、メモリ、I/O、ストレージの上限が高い
・オンプレミスのデプロイからの移行の計画が容易

###### 細かい部分

問題集にも少しでてきたので抜粋
I/Oレイテンシ：ビジネスクリティカルは超高速SSD、Premiumも251IOPSと高い


#### 公式ドキュメント

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/purchasing-models?view=azuresql


# スケーリング

#### Azure SQL Database
仮想コア、DTUどちらを選んでも下記２つのスケーリングから選択可能

1. 単一データベース
1. エラスティックプール

エラスティックプールは複数のデータベースをプール全体のリソース（複数の単一データベース）で自動スケーリングしてくれる。

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/single-database-scale?view=azuresql&tabs=azure-portal

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/elastic-pool-scale?view=azuresql&tabs=azure-portal


# 最後に

見づらい部分もあるので、気づいた時に修正します。
間違えている点があれば優しく教えていただけると嬉しいです。
【Rspec】#<ActiveRecord::Associations::CollectionProxy []>

# はじめに

以下モデルのdeleteメソッドのspecを書いていて、なぜか空を判定してしまっていました。


## モデル

```ruby
class PearentModel < ApplicationRecord

  has_many :child_model, dependent: :destroy

  default_scope { where(is_deleted: false) }

# テスト対象
  def delete
    略(子モデルのis_deletedをtrueに更新する処理)
  end
end

```

```ruby
class ChildModel < ApplicationRecord
  belongs_to :parent_model

  default_scope { where(is_deleted: false) }
end
```

## 修正前のRspec

```ruby
expect(parent_model.child_model.all? { |child| child.is_deleted }).to be_truethy
```

```parent_model.child_model```が空でした。


# 原因と解決方法
テスト対象のメソッドはis_deletedをtrueに更新する処理であるため、 ```default_scope { where(is_deleted: false) }```によってレコードを取得できていませんでした。
```unscope```を使うことでdefault_scopeを無視してレコードを取得し、is_deletedがtrueに更新されていることをテストするようにしました。


## 修正後のRspec

```ruby
expect(parent_model.child_model.unscope.all? { |child| child.is_deleted }).to be truethy
```

# おわりに
テストデータの関連付けがうまくいっていないものだと思い込み、数時間溶かしてしまったので供養しておきます。
空に対して```.all?```を実行するとtrueが返ってくるので、テスト対象が空になっていないことを確認しておかないといけないですね。
個人的なWSL上でのUbuntu設定

# 概要

最近WSLを使っています。環境をリセットする機会も多いので、構築手順をまとめました。

## Windows側の`PATH`を読み込まないようにする

Windows側の環境変数を読み込む設定の場合、Shellの応答性が極端に低くなる（1行1行表示するたびに時間がかかる）ようになります。`/etc/wsl.conf`を設置し、Windows側の`PATH`読み込みを無効にします。この設定の副作用として、`explorer.exe`などを使う場合、絶対パスで指定する必要が出てきてしまうので、これはaliasを作ることで対処します。

```conf:/etc/wsl.conf
[boot]
systemd=true
[interop]
appendWindowsPath=false
```

以下のエイリアスを設定。

```bash
alias e.='/mnt/c/WINDOWS/explorer.exe .'
alias code="/mnt/c/Users/***/AppData/Local/Programs/Microsoft\ VS\ Code/bin/code"
alias powershell.exe="/mnt/c/WINDOWS/System32/WindowsPowerShell/*/powershell.exe"
alias cmd.exe="/mnt/c/WINDOWS/system32/cmd.exe"
alias clip.exe="/c/WINDOWS/system32/clip.exe"
```

以上です。
[Railsガイド]複数データベース接続対応について(更新中)


https://railsguides.jp/active_record_multiple_databases.html

:::note
データベースレベルでのスケールに対応するため、Railsには複数データベース対応がされている。

<主な機能>
- 複数の「writer」データベースと、それぞれに対応する「replica」データベース
- 作業中のモデルでのコネクション自動切り替え
- HTTP verbや直近の書き込みに応じたwriterとreplicaの自動スワップ
- 複数のデータベースの作成、削除、マイグレーション、各種操作を行うRailsタスク

※replicaのロードバランシングはまだ未対応
:::

# データベースへの接続設定について
まずActiveRecord経由でデータベースに接続するため、`/config/database.yml`に対して、接続設定を定義する。

```yaml
# 定義例

# 環境共通の設定
default: &default
  adapter: # 接続するDBの種類(sqlite3,mysql2,postgresqlなど)
  encoding: # 文字コード
  collation: # 照合順序
  pool: # 確保する接続プールの個数
  timeout: # 接続のタイムアウト時間
  socket: # ソケット
  host: # ホスト名/IPアドレス
  username: # ユーザー名
  password: # パスワード

# 開発環境の設定
development:
  primary:
    <<: *default # defaultの設定の共有
    database: # データベース名

# テスト環境の設定
test:
  primary:
    <<: *default
    database: 

# 本番環境の設定
production:
  primary:
    <<: *default
    database: 
```

# アプリケーションのセットアップ
### 新しいテーブルを追加するケース

#### 接続情報の定義
`animal`という名前の第2のデータベースを追加して、両方のデータベースにそれぞれ`replica`を追加した場合の例
```yaml
production:
  primary:
    database: my_primary_database
    username: root
    password: <%= ENV['ROOT_PASSWORD'] %>
    adapter: mysql2
  primary_replica:
    database: my_primary_database
    username: root_readonly
    password: <%= ENV['ROOT_READONLY_PASSWORD'] %>
    adapter: mysql2
    replica: true
  animals:
    database: my_animals_database
    username: animals_root
    password: <%= ENV['ANIMALS_ROOT_PASSWORD'] %>
    adapter: mysql2
    migrations_paths: db/animals_migrate
  animals_replica:
    database: my_animals_database
    username: animals_readonly
    password: <%= ENV['ANIMALS_READONLY_PASSWORD'] %>
    adapter: mysql2
    replica: true
```
複数のデータベースを用いる場合の重要な設定
- `primary`と`primary_replica`のデータベース名は同じにする
  - 2つは同じデータを持つため
- `writer`と`replica`では異なるデータベースユーザー名を使い、かつ`replica`のパーミッションは（writeではなく）readのみにする
  - `replica: true`というエントリがないと、どちらが`replica`でどちらが`writer`かをRailsが区別できなくなる 
- 新しい`writer`データベース用のマイグレーションを置くディレクトリを`migrations_paths`キーに設定する


#### コネクションモデルのセットアップ
- データベースへの接続は抽象クラスで定義する
- `connects_to`メソッドを使用して、接続を定義する
```ruby
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { writing: :primary, reading: :primary_replica }
end
```

- ApplicationRecordを別のクラス名に変えている場合は、`primary_abstract_class`を設定する
  - これにより、RailsはコネクションをどのクラスのActiveRecord::Baseと共有すべきかを認識できる 
```ruby
class PrimaryApplicationRecord < ActiveRecord::Base
  primary_abstract_class

  connects_to database: { writing: :primary, reading: :primary_replica }
end
```

- 追加したデータベースへの接続は別の抽象クラスを定義する

```ruby
class AnimalsRecord < ApplicationRecord
  self.abstract_class = true

  connects_to database: { writing: :animals, reading: :animals_replica }
end
```

- 上記のコネクションモデルを継承したモデルクラスにて、それぞれのDBへクエリが発行される

```ruby
class Car < ApplicationRecord
  # primaryデータベースに自動的に話しかける
end
```

- ポイント
  - データベースへの接続を「単一のモデル内」で行うこと
  - そのモデルを継承してテーブルを利用すること 
  - データベースクライアントがオープンできるコネクション数には上限がある。Railsはコネクションを指定する名前に`モデル名`を用いるので、同じデータベースに複数のモデルから接続するとコネクション数が増加する