OmniAICreator/Qiita-1.07M huggingface dataset:
【Unity】UniTaskのキャンセル処理（その２）

# はじめに
:::note info
**この記事は下記記事の続きです**
[【Unity】UniTaskのキャンセル処理（その１）](https://qiita.com/isshi777/items/ef8f3335ae1be595da1b)
:::

## Try-Catch-Finallyを使用する
前回の記事から少し変えたソース（下記）で同様の操作をします
主な変更は`Try-Catch-Finally`で囲み`ログを追加`、`Catch内のReturn値`です

**１、Aキーを押すだけ**
**２、Aキーを押した直後にZキーを押して５秒くらい待機**
それぞれどのようなログが出るでしょうか？
```test.cs
public class UniTaskTest1 : MonoBehaviour
{
	private CancellationTokenSource cancelTonkenSource = new CancellationTokenSource();

	private void Update()
	{
		if(Input.GetKeyDown(KeyCode.A))
		{
			this.cancelTonkenSource = new CancellationTokenSource();
			this.MainProcess(this.cancelTonkenSource.Token).Forget();
		}
		else if (Input.GetKeyDown(KeyCode.Z))
		{
			this.cancelTonkenSource?.Cancel();
		}
	}

	private async UniTask MainProcess(CancellationToken cancelToken)
	{
		try
		{
			var val = await this.Process1(cancelToken);
			Debug.Log("結果：" + val);
		}
		catch(OperationCanceledException e)
		{
			Debug.Log("MainProcess catch");
		}
		finally
		{
			Debug.Log("MainProcess finally");
		}
	}

	private async UniTask<int> Process1(CancellationToken cancelToken)
	{
		try
		{
			Debug.Log("開始");
			int result = -1;
			await UniTask.Delay(TimeSpan.FromSeconds(3f), cancellationToken: cancelToken);
			Debug.Log("待機終了");

			result = 1;
			if (cancelToken.IsCancellationRequested)
			{
				Debug.Log("キャンセル2");
				return result;
			}

			result = 2;
			return result;
		}
		catch (OperationCanceledException e)
		{
			Debug.Log("Process1 catch");
			return 99;
		}
		finally
		{
			Debug.Log("Process1 finally");
		}
	}
}
```
### 正解
**１、Aキーを押すだけ**
![スクリーンショット 2025-04-10 002043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820411/ead79895-77f3-4982-a12a-16a33e342bbf.png)


**２、Aキーを押した直後にZキーを押して５秒くらい待機**
![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820411/9973a75b-2487-4394-9649-7bcec5ff1145.png)


## まとめ
重要なのは２の操作時なので２を見てみます。
どうやらキャンセルは`例外`を出しているようです。
`if (cancelToken.IsCancellationRequested)`ではなく`Try-Catch`でキャンセルの監視をしたほうがよさそうです。
Try-Catchで囲み、キャンセル時にしたい処理はCatch内に書く、キャンセルしてもしなくても最後に行いたい処理はfinally内に書くのがよさそうですね。
　
**でも気になる・・。**
なんでMainProcess側のCatch内のログは出てないの？
呼び出したProcess1で例外出たんだよ？
続きは次の記事で。

**次の記事（続き）**
[【Unity】UniTaskのキャンセル処理（その３）](https://qiita.com/isshi777/items/4ddb70abb629bd5d1b5a)
【Unity】UniTaskのキャンセル処理（その１）

# はじめに
UniTaskのキャンセルって意識してますか。
とりあえず
`１、CancellationTokenSourceを作成`
`２、CancellationTokenを引数で渡す`
`３，キャンセルしたくなったらCancellationTokenSourceのCancel関数を呼ぶ`
程度のことしか知らない危険なプログラマの１人である私の備忘録。


## IsCancellationRequestedを使用
以下のソースで次の操作をします

**１、Aキーを押すだけ**
**２、Aキーを押した直後にZキーを押して５秒くらい待機**
それぞれどのようなログが出るでしょうか？
```test.cs
public class UniTaskTest1 : MonoBehaviour
{
	private CancellationTokenSource cancelTonkenSource = new CancellationTokenSource();

	private void Update()
	{
		if(Input.GetKeyDown(KeyCode.A))
		{
			this.cancelTonkenSource = new CancellationTokenSource();
			this.MainProcess(this.cancelTonkenSource.Token).Forget();
		}
		else if (Input.GetKeyDown(KeyCode.Z))
		{
			this.cancelTonkenSource?.Cancel();
		}
	}

	private async UniTask MainProcess(CancellationToken cancelToken)
	{
		var val = await this.Process1(cancelToken);
		Debug.Log("結果：" + val);
	}

	private async UniTask<int> Process1(CancellationToken cancelToken)
	{
		Debug.Log("開始");
		int result = -1;
		await UniTask.Delay(TimeSpan.FromSeconds(3f), cancellationToken: cancelToken);
		Debug.Log("待機終了");

		result = 1;
		if(cancelToken.IsCancellationRequested)
		{
			Debug.Log("キャンセル2");
			return result;
		}

		result = 2;
		return result;
	}
}
```
### 正解
**１、Aキーを押すだけ**
![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820411/36677e0d-1a44-4e6f-a61c-d06653cd96a7.png)

**２、Aキーを押した直後にZキーを押して５秒くらい待機**
![スクリーンショット 2025-04-09 235759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820411/7771f97b-2ce4-4f67-b0f6-ade08f019454.png)


## まとめ
・すぐにZキーを押してキャンセルさせると開始のログしか吐かれません。
・その下の`if(cancelToken.IsCancellationRequested)`の処理はキャンセルされた時用の処理に見えますが呼ばれもしません。
・MainProcess関数内の結果ログも吐かれません。

**なんで？**
続きは次の記事

**次の記事（続き）**
[【Unity】UniTaskのキャンセル処理（その２）](https://qiita.com/isshi777/items/ef231f2c6d51d69d13ce)
trivyを理解する


# 目的
- trivyを理解する

# 手段
killercodaで手を動かす

### 環境
killercodaで手を動かす

### trivyとは
trivy はセキュリティスキャナです。trivy はコンテナイメージ・ファイルシステム・リポジトリに対して脆弱性やSBOMのスキャンを実行できます。例えば、現在利用中のコンテナイメージに対して特定 CVE が該当しているかどうかを確認できます。

### 手を動かす

コマンドフォーマットは以下の通りです。

```bash
controlplane:~$ trivy --help
NAME:
   trivy - A simple and comprehensive vulnerability scanner for containers

USAGE:
   trivy [global options] command [command options] target

VERSION:
   0.22.0

COMMANDS:
   image, i          scan an image
   filesystem, fs    scan local filesystem for language-specific dependencies and config files
   rootfs            scan rootfs
   repository, repo  scan remote repository
   client, c         client mode
   server, s         server mode
   config, conf      scan config files
   plugin, p         manage plugins
   help, h           Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --quiet, -q        suppress progress bar and log output (default: false) [$TRIVY_QUIET]
   --debug, -d        debug mode (default: false) [$TRIVY_DEBUG]
   --cache-dir value  cache directory (default: "/root/.cache/trivy") [$TRIVY_CACHE_DIR]
   --help, -h         show help (default: false)
   --version, -v      print the version (default: false)
# trivy {実行対象} |grep -E "CVE-XXXX-XXXX" のような形式で利用します
```

既存 deployment の image を確認します。

```bash
controlplane:~$ k -n applications get po -oyaml |grep image:
    - image: nginx:1.19.1-alpine-perl
      image: docker.io/library/nginx:1.19.1-alpine-perl
    - image: nginx:1.19.1-alpine-perl
      image: docker.io/library/nginx:1.19.1-alpine-perl
    - image: nginx:1.20.2-alpine
      image: docker.io/library/nginx:1.20.2-alpine
# -oyaml でyamlフォーマットで出力すれば一覧で確認できます
```

特定イメージに対して trivy でスキャンします。

```bash
controlplane:~$ trivy image nginx:1.19.1-alpine-perl | grep "CVE-2021-28831"      
| busybox      | CVE-2021-28831   |          | 1.31.1-r9         | 1.31.1-r10    | busybox: invalid free or segmentation |
| ssl_client   | CVE-2021-28831   | HIGH     | 1.31.1-r9         | 1.31.1-r10    | busybox: invalid free or segmentation |
# スキャン対象のコンテナイメージは当該 CVE に該当しています。
```

# あとがき
もう1つくらい書きたい。。。

# ソース
- [trivy](https://trivy.dev/latest/)
【Java・VSCode】ショートカットなど便利技

すべてのコマンドを試していないので、間違いがあったら申し訳ありません。。。

インストールは↓
https://note.com/codek2/n/n5c7831639bd7

## 基本のショートカット
Ctrl + Space → コード補完

Ctrl + Shift + O → 未使用のimportを削除 & 必要なimportを追加

Ctrl + Shift + P → コマンドパレットを開く

Ctrl + Z / Ctrl + Y → 元に戻す / やり直す

Ctrl + C / Ctrl + X / Ctrl + V → コピー / カット / ペースト

Ctrl + S → ファイルを保存

Ctrl + Shift + S → すべてのファイルを保存

## コーディング補助
getter・setter自動生成
右クリック→ソース アクション→Generate Getters and Setters

toString() 自動生成
右クリック→ソース アクション→Generate toString()

コンストラクタ自動生成
右クリック→ソース アクション→Generate Constructors

Ctrl + . → クイック修正（エラー修正や未定義メソッドの作成）

## クラス・メソッドの移動
Ctrl + P → ファイルをすばやく開く

F12 → 定義に移動（変数やメソッドの定義へジャンプ）

Alt + ← / → → 前後の移動（移動した履歴を戻る/進む）

Ctrl + Shift + F → プロジェクト全体で検索

Ctrl + D → 選択した単語を次に検索

## コードの整形
Shift + Alt + F → コードをフォーマット（きれいに整形）

Alt+ Shift + O → 自動インポート

Ctrl + / → コメントアウト（行コメント //）

Shift + Alt + A → ブロックコメント /* */ を追加

## 実行・デバッグ
F5 → デバッグ実行

Ctrl + F5 → デバッグなしで実行

F9 → ブレークポイントを追加/削除

F10 → ステップオーバー（次の行へ進む）

F11 → ステップイン（メソッドの中に入る）

Shift + F11 → ステップアウト（メソッドから出る）

## 便利なVSCode機能
Ctrl + B → サイドバーの表示/非表示

Ctrl + N → 新しいファイルを作成

Ctrl + Tab → 開いているファイル間を切り替え

Ctrl + Shift + T → 閉じたタブを再度開く

Alt + ↑ / ↓ → 選択した行を上下に移動

Shift + Alt + ↑ / ↓ → 選択した行をコピーして上下に複製

## ターミナルに出力された文字が文字化けしている場合
プロジェクト内の.vscode\launch.jsonなどに
以下の「"vmArgs": "-Dfile.encoding=UTF-8"」を追記
```
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "java",
      "name": "Launch Java Program",
      "request": "launch",
      "mainClass": "BufferedInputSample", // あなたのクラス名
      "vmArgs": "-Dfile.encoding=UTF-8"
    }
  ]
}
```

## メソッド名をクリックして該当のメソッドにジャンプする
Windows：Ctrl を押しながらメソッド名を クリック
(動作しない場合：Javaの拡張機能（Language Support for Java by Red Hat）がインストールされていないかも)

## コマンドライン引数を使用する
[表示]→[外観]→[セカンダリサイドバー]にチェックを入れる

ドロップダウンリストから[アクティブファイル(引数あり)]を選択

▷をクリック

上部に表示される入力欄に引数(100 200など)を入力しEnter

## Mavenのクリーン
コードを実行しても思ったとおりに表示されない場合は前に作成したwarファイルの中の構成が古いままになっているかも
cleanを行うとなおることがある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680113/75e131b9-25ae-4728-af17-8a9c731957fa.png)

## Javaのプロジェクトをワークスペースに追加
[ファイル]→[フォルダーをワークスペースに追加]

## デバッグ実行するには
1．止めたい行の行番号の左側をクリックすると赤い丸がつく

2．以下のどちらかで実行
方法1：ショートカット
F5 を押す（Windows / Mac 共通）

方法2：画面から実行
画面右上の▼からDebug Javaを選択

画面の左上あたりにデバッグ関係のツールバーが表示される

ステップオーバー(F10)：次の行へ
ステップイン(F11)：メソッドの中の処理へ移動
停止(Shift+f5)：デバッグをやめたいとき

---


https://zenn.dev/codek2/articles/e9e44f3e0023fb

https://note.com/codek2

https://www.youtube.com/@codek2_studio
ImagePolicyWebhook を理解する


# 目的
- ImagePolicyWebhook を理解する

# 手段
killercodaで手を動かす

### 環境
killercoda

### ImagePolicyWebhook とは
kube-apiserver に実装可能な admission control の1つです。admission control は kube-apiserver に対する通信に適用できるルールのようなものです。ImagePolicyWebhook の場合、kube-apiserver が外部のコンテナレジストリからコンテナイメージをダウンロードする動作を制御するものです。必要な設定ファイルは以下の通りです。

- admission_config.json: kube-apiserver とバックエンドの通信に適用される設定ファイル

```bash
controlplane:/etc/kubernetes/policywebhook$ cat admission_config.json 
{
   "apiVersion": "apiserver.config.k8s.io/v1",
   "kind": "AdmissionConfiguration",
   "plugins": [
      {
         "name": "ImagePolicyWebhook",
         "configuration": {
            "imagePolicy": {
               "kubeConfigFile": "/etc/kubernetes/policywebhook/kubeconf",　# ImagePolicyWebhookで利用する設定ファイルを指定します
               "allowTTL": 100, # TTLを設定します
               "denyTTL": 50,
               "retryBackoff": 500,
               "defaultAllow": false # バックエンドとの通信が失敗した場合、ダウンロード可否を設定します。falseはダウンロードを禁止します
            }
         }
      }
   ]
}```

- admission_config.json: kube-apiserver とバックエンドの通信に適用される設定ファイル

```bash
controlplane:/etc/kubernetes/policywebhook$ cat kubeconf 
apiVersion: v1
kind: Config

# clusters refers to the remote service.
clusters: # ImagePolicyWebhook を適用するバックエンドのサービスを定義します
- cluster:
    certificate-authority: /etc/kubernetes/policywebhook/external-cert.pem  # CA for verifying the remote service.
    server: https://localhost:1234                   # URL of remote service to query. Must use 'https'.
  name: image-checker

contexts:
- context:
    cluster: image-checker
    user: api-server
  name: image-checker
current-context: image-checker
preferences: {}

# users refers to the API server's webhook configuration.
users: # バックエンドとの通信に利用する TLS 証明書を設定します
- name: api-server
  user:
    client-certificate: /etc/kubernetes/policywebhook/apiserver-client-cert.pem     # cert for the webhook admission controller to use
    client-key:  /etc/kubernetes/policywebhook/apiserver-client-key.pem             # key matching the cert
```

kube-apiserver に対しては下記二つの設定が必要になります。

```bash
controlplane:/etc/kubernetes/manifests$ cat kube-apiserver.yaml |grep -E "Policy|admission"
    - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook # ImagePolicyWebhook を追加します
    - --admission-control-config-file=/etc/kubernetes/policywebhook/admission_config.json # ImagePolicyWebhook で利用する設定ファイルを指定します
```

コンテナを起動します。

```bash
ontrolplane:/etc/kubernetes/manifests$ k run nginx --image=nginx
Error from server (Forbidden): pods "nginx" is forbidden: Post "https://localhost:1234/?timeout=30s": dial tcp 127.0.0.1:1234: connect: connection refused
controlplane:/etc/kubernetes/manifests$ 
# バックエンドとの TLS 通信に失敗したため、コンテナイメージのダウンロードに失敗します。
```

# あとがき
もう一つくらい書きたい。

# ソース
- [ImagePolicyWebhook ](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook)
勉強予定

<h3>最優先</h3>

```ruby:
  panda : 合計自動計算 / 
   
          自動グラフ化 (Matplotlib) / Vlookup


  NumPy  : sum・average 

  openpyxl : 複数Excelを1つに 

  pdf : 複数PDFから複数条件検索 

        表データ抽出し、CSVやDBに保存

  最後 : Streamlit. :notionメモ検索  (DBつき) 

  クラウド アップロード方法(フレームワークわかってから)    : Streamlit Cloud

  サイトデータ　Excel保存
・タイトル
・支援額、
・支援者数、
・URL
https://www.makuake.com/discover/categories/product/?sort=popular

メルカリショップス　4000個　CSV保存
・商品画像URL
・商品名、
・商品説明
・ブランド
・値段
・カテゴリ
・商品の状態 
・配送方法 
・発送元地域 
・発送日数 
・商品ステータス

```

<br>
<h3>優先度低め</h3>

```ruby:
   SQLAlchemy : DB使う機会増えたら
   
   Schedule : 毎日決まった時間作業実行
   
   PyAutoGUI : マウスやキーボード自動化

```
🚀 FastAPIとノーコードでアプリ開発＆セキュリティマスター！ 🔐📱

こんにちは、韓国在住のsanaです！

🚀 FastAPI + JWT + Redisでインジェクションシステムを実践！ 🔐

💻 FastAPIを使って、JWTとRedisを駆使したインジェクションシステムを実践！
初心者から上級者まで、セキュリティ技術をしっかりと身につけることができます✨
https://u.inf.run/4j4KPlC

📱 コーディングなしでアプリ作成！エクセルクローリングが簡単に！ 🛠️

🔧 プログラミングなしで、アプリ開発ができちゃう！
初心者でも簡単に始められるので、スピーディにアプリ制作が可能💡
これからアプリ開発を始めたい方にぴったり！🎯

https://u.inf.run/3R7HE06
【Swift】OSLogについて

OSLogはAppleのUnified Logging Systemの一部であり、
アプリケーションからのログを一元管理する

アプリのパフォーマンス影響が最小限となるよう
設計されており、Xcode 15から利用可能

## メリット [print]との違い
・Appleによる統一的な設計によりパフォーマンスがよい
・サブシステム/カテゴリで分類でき、フィルタリングが容易
・ログレベル（OSLogType）を分類可能

簡易アプリではprintで事足りるが、本格的なアプリや大規模アプリの場合は
OSLogを使用するとよい印象


## 使用方法
#### Loggerの作成
```
// インスタンス作成
let logger = Logger(subsystem: "com.app.hogehoge", category: "Logger")
```
subsystemにはアプリケーションのバンドル識別子を、
categoryにはログメッセージのカテゴリを指定します
これにより、Xcodeのコンソールでログをフィルタリングしやすくなります
#### ログ出力
```
// ログレベル：debugのログを出力
logger.debug("debug test.")
```
ログレベルに沿って各APIを叩きます

:::note info
ログレベル一覧
・default (notice): 特に重要ではない一般的なログ
・info: トラブルシューティングに役立つ情報
・debug: 開発中のデバッグ用メッセージ
・warning: 非致命的な失敗を報告するための警告
・error: 重大なエラーや失敗を報告するためのメッセージ
・fault: システムレベルのエラーを記録するためのメッセージ
:::

## パフォーマンス向上する上での注意点
#### ・APIを独自関数でラップ
これが一番パフォーマンスに影響すると思われる
ログメッセージをコンパイル時に解析する等の最適化は、
Logger APIを独自関数でラップすると損なわれてしまう

[Xcode 12 and OSLog (os.log): wrapping OSLogMessage causes compile error: Argument must be a string interpolation](https://stackoverflow.com/questions/62675874/xcode-12-and-oslog-os-log-wrapping-oslogmessage-causes-compile-error-argumen)

#### ・永続化するログレベルの多用
ログレベルの中には永続化（ディスクに書き込まれる）ものがあり、
多用するとパフォーマンスが落ちる
・永続化するもの
error, fault, default

開発中に多用する箇所はコスト低いdebug,traceを使い、
リリース時には間引く
infoはデフォルトでは永続化されないが、永続化に設定できる

#### ・静的なログメッセージを渡す
OSLogに渡すメッセージは静的文字列であることが推奨される
動的なメソッドをdescriptionで渡すのをなるべく避ける

ファイル名やメソッド名を出力させたい場合は#function, #file
のような`特殊リテラル式`を使うとよい
※特殊リテラル式はコンパイル時に静的文字列へ変換されるため

#### ・動的なログメッセージのコスト最小化
上記で致し方なく動的なメッセージを渡す場合は高コストな処理
でないかを確認すべきである

処理に時間がかかる関数や大きなデータ構造を直接渡すことをさけ、
必要なデータのみを抽出して渡すようにする

#### ・カテゴリを分けすぎない（100個以上）
基本的でOSLogはスレッドセーフのため、複数のLoggerからログを
同時に出力しても問題ないように作られているが、さすがに100個以上は
推奨されていないらしい

#### ・ログの量と頻度
ループ内や、1秒間に何度も呼ばれるような関数内でのログ出力は避ける
どうしても入れる場合はサンプリング/スロットリング（間引き）をおこなう
[Astro]SSG設定なのにNoAdapterInstalledが出た

`SSG`で`Astro`をビルドするつもりが`NoAdapterInstalled`でこけました。

## 結論
`Astro`は`astro.config.*`で設定されているモードよりも実装を優先するようです。動的に処理するコードが含まれている場合は、`static`から`hybrid`に変更されるようです。

## 原因
私の場合は、
```
prerender = false
```
がページに紛れ込んでいました。`true`に変更後無事ビルドが通りました。

## 参考

https://docs.astro.build/ja/guides/on-demand-rendering/
ClaudeにMCPをインストールしたときにつまずいた話

## どこでつまずいたか
jsonファイル編集後に再起動してもハンマーマークが出ない

## 対処方法
PC本体の再起動をしたら反映された

## 追記
タスクマネージャーでClaudeを完全に落として起動させれば反映されるということでした。
試してみたらそちらの方が早いので今後はこの方法にします。
WSLのクラッシュダンプにご用心 - WSLクラッシュダンプを作らせない方法

## 環境
Bun: v1.2.9
#### wsl --version
WSL version: 2.4.13.0
Kernel version: 5.15.167.4-1
WSLg version: 1.0.65
MSRDC version: 1.2.5716
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.19045.5737

## あらすじ

自分はWSL内でbunをよく使っていて、ホットリロード開発をよくするのですが、
現在のbunのホットリロードは不安定で、よくクラッシュします。
Issueも上げました。コーディングコミュニティー初心者だったのでクラッシュのたびに上げて怒られました。

https://github.com/oven-sh/bun/issues/18311

そしてクラッシュしたあとに色々あってWindowsのエクスプローラーを見るのですが、
なんかストレージが圧迫されてる！
ウイルスかと思いWizTree(ストレージのファイルの大小関係を可視化するアプリ)を立ち上げるとなんということでしょう
一時ファイルの`wsl-crash-XXXXXXXXXX-XXXXX-_home_tntsuperman_.bun_bin_bun-4.dmp`が6GB以上も圧迫してるではないですか
## どういうことか
bunがクラッシュしたのでクラッシュダンプが生成されたようです。
## どうにかしたい
親愛なる友Microsoft Copilotに聞いてみよう！
「wslクラッシュ時にダンプファイルを作らせないようにするには？」と聞いてみました。
> WSL（Windows Subsystem for Linux）のクラッシュ時にダンプファイルを作成させないようにするには、以下の方法があります：
> - wsl.confファイルの編集:- WSLの設定ファイルであるwsl.confを作成または編集します。
> - ファイルの内容に以下を追加します:
> ```
> [network]
> generateDump=false
> ```
> - 保存後、WSLを再起動してください。
> .....

続いて「wsl.confはどこにありますか」と質問。
> `wsl.conf`はWSLインスタンスごとに設定されるファイルで、通常はWSLのファイルシステム内に配置されています。具体的な場所は以下です：
> 
> `/etc/wsl.conf`
> 
> このファイルはデフォルトでは存在しないことがあるため、必要に応じて自分で作成する必要があります。作成する手順は以下の通りです：
> .....

ではやってみよう。
```bash
$ sudo vim /etc/ws.conf
```
```/etc/wsl.conf
.....
[network]
generateDump=false
```
## 結論
WSL内でアプリとかがクラッシュするとダンプファイルができる。(超大きい)
なのでWSLの`/etc/wsl.conf`に
```/etc/wsl.conf
[network]
generateDump=false
```
を付け足す方がいい。
~~そしてbunのホットリロードはクラッシュしやすい。~~
クラッシュしやすいホットリロードの問題が修正されたそうです！！

https://github.com/oven-sh/bun/pull/19237

良いWSLライフを!
for / ファイル読み込みフォルダ 書き方 / デバッグ / 関数作るか作らんかの違い/ smtplib と imaplib 

```
CSVやexcelファイル使うとき、よく使う
for row in reader:
```

```ruby : range 仕組み
for i in range(1, 5):  
    print(f"{i}回目の処理")

    結果
    1回目の処理
2回目の処理
3回目の処理
4回目の処理
```

```ruby:seleniumのみで、タブ切り替えるときよく使う
for i in range(1, len(driver.window_handles)):  
タブが３つあり、 ['タブ1', 'タブ2', 'タブ3'] な場合、len(driver.window_handles) の中身は、 3
```

<br>
<h3>使いたい : フォルダ数個とフォルダ一個</h3>

```ruby:フォルダ数個
folder_path = ["/Users/chomechomesuke/Desktop/other/excel", "/Users/chomechomesuke/Desktop/other/kyujin", "/Users/chomechomesuke/Desktop/other/pdf"]
```

```ruby:フォルダ1個だけ
folder_path = "/Users/chomechomesuke/Desktop/other/"
```

<h3>指定CSSないよ</h3>
<h4>原因 : html構造 変わった</h4>

![スクリーンショット 2025-03-03 17.36.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/b8ea380c-82a8-4dd5-a55e-e455db041da8.png)


```ruby: 対処法
# 検索結果のリンクを取得（DuckDuckGoの検索結果の構造に基づく）
results = driver.find_elements(By.CSS_SELECTOR, "a.result__link")  
```

<br>
<h4>contentブロックとif / elseブロックセット</h4>
contentとif elseのインデントは、分ける

![スクリーンショット 2025-03-10 19.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/f13c4e52-c157-4f96-a346-c85fec5ed9f9.png)

![スクリーンショット 2025-03-10 19.14.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/f291153b-f0d8-4115-8773-cca64bfd866d.png)



<br>
<h4>if /eise は、いつもインデント４個分</h4>

![スクリーンショット 2025-03-10 17.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/259be36e-13a4-420a-8fa5-cfd9cff44ede.png)


<br>
<h4>ファイル、書き込み保存ちゃんとできてる？</h4>

```ruby:
import os

if os.access(json_file_path, os.W_OK):
    print("書き込み可能")
else:
    print("書き込み不可")
```
<br>
<h4>json_fileパスあってる？</h4>

```ruby:
mport os

json_file_path = "url.json"  # これが意図しない場所に作られるかも
absolute_path = os.path.abspath(json_file_path)

print(f"Pythonが作成したパス: {absolute_path}")

if os.path.exists(absolute_path):
    print("✅ ファイルが存在する")
else:
    print("❌ ファイルが見つからない")
```
<br>
<h4>データが渡されてるか確認 print (変数名)</h4>

```ruby:
data = []
for row in ws.iter_rows(min_row=2, values_only=True):  # 1行目がヘッダーならmin_row=2
    if all(cell is not None and cell != "" for cell in row):
        record = list(row)
    # record ={
        # "会社名": row[0],
    # }
    data.append(record)
    print(data)
```

<h3>関数を作る処理と、関数を作らん処理違い</h3>

```ruby:関数作るver
   1. 何度も同じ処理させたい
  例 : ファイルの読み込み / 解析/データ加工の処理したい 
  
  2 . 同じ処理させたい変数が、何個もある
  例：リストを2倍。
  def double(x): 
    return x * 2 
    numbers = [1, 2, 3, 4] 
    doubled_numbers = [double(n) for n in numbers] 
    print(doubled_numbers) 
    
    結果　2 4 6 8
    (N : データがある個数分繰り返す)
```


```ruby:関数いらんver
    一度しか使わん、単純な処理 
```

<br>
<h4>smtplibとimaplib 違い</h4>

```ruby :
  smtplib : 送信専用 
  imaplib : 受信メール検索専用
```

# for文　使い方例

```ruby:指定条件データが何番目にあるか、調べたい

def linear_search(lst, target):
    for i in range(len(lst)):  # リストのすべての要素を調べる
        if lst[i] == target:  # 要素が目標と一致したら
            return i  # インデックスを返す
    return -1  # 見つからなかった場合、-1を返す

# 使用例
my_list = [10, 20, 30, 40, 50]
result = linear_search(my_list, 30)
print(result)  # 2（インデックス）

```
excel　既にあるデータを調べたい

# 概要

```ruby:
調べたい　たくさん : pandas

調べたい　少し : openpyxl
```

# pandas

```ruby:
import pandas as pd

# CSVファイルを読み込む
df = pd.read_csv('sales_data.csv')

# 売上が1000以上のデータを探索
result = df[df['売上'] >= 1000]
print(result)

```

# openpyxl

```ruby:売上 : 1000円以上のもの探す
import openpyxl

# Excelファイルを開く
wb = openpyxl.load_workbook('sales_data.xlsx')

# シートを指定
sheet = wb['Sheet1']

# 売上が1000以上の行を探す
for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=1, max_col=2):
    # ここでは2列目が売上データと仮定
    if row[1].value >= 1000:  # row[1]は売上列
        print(f"商品: {row[0].value}, 売上: {row[1].value}")

```
AoyamaType



# 初めに

pythonで昨年の卒業生が作ったAoyamaTypeでタッチタイプの習得を行います．


# 手順<code>[/]</code>


## windows

-   [ ] wsl, fish, pipx, aoyamatypeインストール
    -   terminalを起動

```shell
> wsl --install
      Enter new UNIX username: XXXX
      New password: XXXX (表示されません)
      Retype new password: XXXX (表示されません)
```

パソコンの再起動が必要．

```shell
  > python3 --version
  > sudo apt update
  > sudo apt install fish
  > chsh -s /usr/bin/fish
  Password: XXXX (はじめに入れたPassword)

  > sudo apt install pipx
        ...
        After this operation, xxxx kB of additional disk space will be used.
        Do you want to continue? [Y/n] Y
  > pipx install git+https://github.com/37021463/aoyamatype.git
```

これでaoyamatypeが動くはず．

だめな人は以下を打ち込んでterminalを再起動．

```
  > pipx ensurepath
  > pipx completions
    fishのcommand
    register-python-argcomplete --shell fish pipx >~/.config/fish/completions/pipx.fish
    をcopy and paste
```

-   [ ] [AoyamaType](https://github.com/daddygongon/aoyamatype)
    -   [aoyama\_type\_data.zip](https://kwanseio365-my.sharepoint.com/:u:/g/personal/cru32369_nuc_kwansei_ac_jp/EQ-DTqOjdRNOj395Vw7qLPgBxgvuKKBZluN6THBqmQKXEA?e=RZHGta) をDL.

```shell
> explorer.exe .  #でexplorerを立ち上げて，
    - dlしたaoyama_type_datをそこへDrag&Drop
> aoyamatype -d ~/aoyama_type_data.zip
> aoyamatype -c
> aoyamatype 1 #から...50
> sudo apt-get install python3-tk
> pip install PyQt6 #が必要かも．．．
> aoyamatype -r
```


## mac

```shell
> python3 --version
= brew install macで検索
> /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
> /opt/homebrew/bin/brew install fish
> fish
> pip install git+https://github.com/37021463/aoyamatype.git

これ以降はいらないはず．
> pipx ensurepath
> pipx completions
  fishのcommandをcopy and paste
```

-   [ ] [AoyamaType](https://github.com/daddygongon/aoyamatype)
    -   [aoyama\_type\_data.zip](https://kwanseio365-my.sharepoint.com/:u:/g/personal/cru32369_nuc_kwansei_ac_jp/EQ-DTqOjdRNOj395Vw7qLPgBxgvuKKBZluN6THBqmQKXEA?e=RZHGta) をDL.

```shell
dlしたaoyama_type_dat.zipをterminalへDrag&Drop
> aoyamatype -d ~/Downloads/aoyama_type_data.zip
> aoyamatype -c
> aoyamatype 1 #から...50
> sudo apt-get install python3-tk
> pip install PyQt6 #が必要かも．．．
> aoyamatype -r
```


# 補足


## 視線追跡(Eye track動画)

-   [初心者](https://kwanseio365-my.sharepoint.com/:v:/g/personal/cru32369_nuc_kwansei_ac_jp/EQI-6D9pimpAhQhj2SQD5IYBnmym-Sto-bLVIa3iMMtzHA?e=5rwy1Q)
-   [達人](https://kwanseio365-my.sharepoint.com/:v:/g/personal/cru32369_nuc_kwansei_ac_jp/EYWKHFEghL5Pg09P3bhGg4UBU7wwJSzThQ_DAxzEoFNRCg?e=7OWkkm)


## [5時間10分\_キー入力習得法.pdf](https://kwanseio365-my.sharepoint.com/:b:/g/personal/cru32369_nuc_kwansei_ac_jp/EcP9a1gh_y9JjDZuJHmdoBQBqRuhxCyUigW5wg4_sk5ZYQ?e=XO0J37)


# 最終試験

最終試験は6/30にこの時間で行います．

-   aoyamatype -c

で60秒を切れば合格です．

タッチタイピングは，速さよりも正確性とか，リズムが大切で，キーの位置を覚えることを心がけてください．タッチタイプは，プログラマの仲間になる第一歩です．


# 課題

-   LUNAに初回のcheckの結果を報告して．



------
 - **source** ~/Desktop/lecture_25s/comp_a_25s/lectures/d2_aoyamatype/d2_aoyamatype.org
【Nuxt】ミドルウェアとレンダリングタイミングに関する知見

## 課題の概要

Nuxt アプリケーションでマルチステップのフォームを実装する際に、「前の画面の条件チェックに反していた場合は検知して画面描画前にリダイレクトしたい」という課題がよくあります。
例えば、入力画面 → 確認画面 → 完了画面という流れで、確認画面に直接アクセスされた場合や、入力内容に問題がある状態で確認画面に遷移しようとした場合に、適切な画面にリダイレクトする必要があります。
この記事では、Nuxt のミドルウェアを活用してこの課題を解決する方法について解説します。

## 実装した解決策

1. ストアに状態を保存
2. 専用ミドルウェアによるリダイレクト制御
3. 状態変化の正確な検知と同期

## 技術的な学び

### 1. ミドルウェアの実行タイミング

- Nuxt のミドルウェアはページレンダリング前に実行される
- 複数のミドルウェアは登録順に実行される
- リダイレクトが発生すると残りのミドルウェアやコンポーネントのセットアップは実行されない

```js
middleware: [
  'checkAuthentication',
  'validateAccess',
  'redirectIfValidationNeeded',
],
```

### 2. 状態管理とミドルウェアの連携

:::note warn
**重要**: ミドルウェアはコンポーネントのライフサイクル外で動作するため、ストア経由で状態にアクセスする必要があります
:::

ミドルウェアがコンポーネントのライフサイクル外で動作する理由は、Nuxt のレンダリングフローに関係しています。
ミドルウェアはページコンポーネントが初期化される前に実行されるため、Vue インスタンスやコンポーネントのデータ、computed プロパティなどには直接アクセスできません。

例えば、コンポーネント内で計算された値や条件をミドルウェアで参照しようとしても、そのタイミングではまだコンポーネントは初期化されていないため参照できないのです。

この問題を解決するために

- コンポーネント内の computed 値だけでは不十分
- Vuex ストアへの状態同期が重要
- ページ間で共有される状態はすべてストアに保存する設計が必要

```js
// コンポーネント側で状態をストアに同期
store.dispatch('form/setIsValidationRequired', result)

// ミドルウェア側で状態を取得
const isValidationRequired = store.getters['form/isValidationRequired']
```

このパターンにより、コンポーネントとミドルウェアの間で状態を適切に共有し、ページナビゲーションの制御を正確に行うことができます。

### 3. パフォーマンスへの影響

- ミドルウェアによるリダイレクトは初期レンダリング前に実行されるため効率的
- 不要なレンダリングを防止できる
- ユーザー体験の一貫性が向上

## 今後の設計指針

1. 状態変化を正確に検知するためのパターン

   - ミドルウェアでのみ使用する場合は、単純にストアに状態を保存し参照する設計で十分
   - コンポーネント側でも同じ状態を利用する場合は、状態変化を適切にストアに同期する仕組みが必要
   - (注：純粋にミドルウェアのリダイレクト機能のみが目的なら、複雑な条件分岐の結果をローカル変数に保存する実装は必須ではない）

2. ミドルウェア設計のベストプラクティス

   - 責務を明確に分離した小さなミドルウェアを作成
   - 実行順序を意識した配置
   - ストアとの連携を適切に行う

3. リダイレクト処理の標準化
   - セキュリティに関わるリダイレクトは専用ミドルウェアで実装
   - ユーザー体験を考慮した適切なリダイレクト先の選定

## 実装例

```js
// middleware/redirectIfValidationNeeded.ts
import { Middleware } from '@nuxt/types'
import { ROUTES } from '~/constants'

/**
 * 入力内容の検証が必要な場合は入力画面にリダイレクトするミドルウェア
 * ストアに保存された検証必要フラグを確認し、必要な場合はリダイレクトする
 */
const redirectIfValidationNeeded: Middleware = ({ store, redirect }) => {
  // ストアから検証が必要かどうかを確認（ゲッターを使用）
  const isValidationRequired = store.getters['form/isValidationRequired']

  // 検証が必要な場合は入力画面にリダイレクト
  if (isValidationRequired) {
    redirect(ROUTES.FormInput)
  }
}

export default redirectIfValidationNeeded
```

## まとめ

Nuxt のミドルウェアは単なるページナビゲーションの制御だけでなく、アプリケーションのセキュリティと一貫性を確保するための強力なツールです。特に以下の点が重要です

1. ミドルウェアの実行順序とタイミングを理解する
2. Vuex ストアとの連携を適切に行う
3. 責務を明確に分離した小さなミドルウェアを作成する
4. ユーザー体験を考慮したリダイレクト設計を行う

これらの原則に従うことで、より堅牢で保守性の高い Nuxt アプリケーションを構築することができます。
【JS】ゲームのMVCのイベント伝達

# MVC

Model, View, ControllerでMVC.
Modelはビジネスロジック、Viewは描画、Controllerは操作関連の処理を行う。

参照関係は 

* Controller -> Model
* Controller -> View
* View -> Model

Modelは参照先がないのが特徴。

つまりControllerを始点にしてViewを通りModelに終着するのがこのMVCの特徴。
ちなみに参照関係が上述とは違うMVCもあり、それはWebなどでよく使われている。

## Model, View, Ctrl

```js:
class MyCtrl {
    constructor () {
        this.model = new MyModel()
        this.view = new MyView(this.model)
    }

    update () {
        if (keyboard.isKeyPressed('Enter')) {
            this.model.blabla()
        }
        
        this.model.update()
        this.view.update()
    }

    draw () {
        this.view.draw()
    }
}
```

こーんな感じでControllerを作る。
Viewはこんな感じ。

```js:
class MyView {
    constructor (model) {
        this.model = model
        this.canvas = document.createElement('canvas')
        document.body.appendChild(this.canvas)
        this.ct = this.canvas.getContext('2d')
    }

    update () {
        // nothing todo
    }

    draw () {
        this.ct.fillStyle = 'red'
        this.ct.fillRect(0, 0, 100, 100)
    }
}
```

Modelはこう。

```js:
class MyModel {
    constructor () {
        this.count = 0
    }

    update () {
        // nothing todo
    }

    blabla () {
        this.count++
    }
}
```

## レイヤー間のイベントの伝達

さて、このパターンはModelで行き止まりだが、ModelからControllerへ何かを伝達したい時はあるものである。
つまり子から親に向かって命令を送る。
親から子に流れている処理に逆らってまるで鯉の滝登りのように子から親に命令という名の下剋上をするのである。

じっさいのMVCでどうやるのかは知らんが、とりあえず返り値は使えそうである。

```js:
class MyCtrl {
    update () {
        let events = this.model.update()

        for (let event of events) {
            switch (event.kind) {
            case EV_EXIT:
                this.end = true
                break
            case EV_NOTICE:
                this.view.notice(event.message)
                break
            }
        }
    }
}
```

上みたいにmodelから返り値でイベント列を受け取り、それを処理する。
modelのupdateで色々ビジネスロジックをするわけだが、そのロジックの中でコントローラーに通知したいイベントは上記のように返り値で上層に通知する。うーん、鯉の滝登り！

ModelはCtrlとViewの参照を持っていないので、CtrlとViewを操作することはできない。だが、返り値を使うことで上層レイヤーにイベントを通知、そして上記の`this.view.notice(event.message)`のような感じでイベントを通じてViewを呼び出す。

## おわりに

うーん、エレガント！　すばらしい！
MVCは不滅だ！ MVC！ MVC！
OpenSUSE で MINECRAFT

コロナ時代になる前に、「Ubuntu で MINECRAFT」
https://qiita.com/nanbuwks/items/df10bba9f0ed473827d7
の記事を投稿しましたが、改めて OpenSUSE で MINECRAFT を試してみました。


# OpenSuse Leap でMINECRAFT

## 環境

- OpenSuse Leap 15.6
- MINECRAFT Java Edition 1.21.5

# MINECRAFT 公式サイトからはダウンロードしない

Ubuntu の場合は MINECRART 公式サイトを今まで使いました。
https://www.minecraft.net/ja-jp/download
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3d79ffbb-3437-4af0-929b-859bfcd306be.png)

しかし OpenSUSE の記載はないので・・・

# OpenSUSE ディストリビューションパッケージ

以下がそうかな?
https://software.opensuse.org/package/Minecraft

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/91994a28-c575-4082-89b5-5a71b29eec80.png)

openSUSE Leap 15.6 の「コミュニティ提供のパッケージの表示」でダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f32ec27d-6c83-4278-9b9d-b1fe887314f9.png)
ダウンロードしたパッケージを開くとインストールが始まります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1034c50f-9b8f-4c3d-920a-62a15eb405fd.png)


その後、実行してログオンすると Launcher が開きます。左のメニューから 「Java Edition」を開きました。

![Screenshot_20250409_074716.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8a203ddb-f4a9-4d8b-9f29-b88fac1610fd.png)

MINECRAFT 画面が開くので必要な設定を行い、ゲームを開始します。

![Screenshot_20250409_074909.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/22996a64-9d8f-46f5-a38a-dab90f307615.png)

特に問題なく実行できました。

![2025-04-09_17.24.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d565c92c-400a-49b6-abda-33910780ad4a.png)
【卒業研究】ArduinoとCNNによるAI自動運転RCカーの開発

## ArduinoとCNNを用いて、学習〜推論〜自動制御まで一貫したRCカー自動運転システムを構築しました。


🔗 [GitHubリポジトリ](https://github.com/hyeon-marina/autonomous-car-ai-)

📝 開発の詳細や技術背景はZennにて公開中👇  
🔗 [Zenn記事（詳細解説）](https://zenn.dev/hyeon_marina247/articles/0b51e853cb8242)


## 🎓 プロジェクト概要

2023年の卒業研究で、**ArduinoとCNNを用いたAI自動運転RCカーの開発**に取り組みました。  
組み込み開発とAI（機械学習）を組み合わせ、実機ベースでのリアルタイム自動運転制御を目指しました。


## ⚙️ 技術構成と使用環境

- **ハードウェア**：
  - Arduino UNO（DC/サーボモーター制御）
  - Raspberry Pi（映像取得＋推論処理）
- **ソフトウェア技術**：
  - Python + TensorFlow（CNNモデル構築）
  - OpenCV（前処理・Canny Edge検出）
- **学習環境**：DonkeyCarシミュレータ + 実機RCカー


## 🛠️ 実装プロセス（概要）

1. **データ収集**  
   - RCカーを手動操作し、カメラ映像と操作データを蓄積  
   - 画像＋ラベル（左／直進／右）で学習用データを作成  

2. **CNNモデル学習**  
   - グレースケール変換、リサイズ処理後、方向分類モデルを学習  
   - モデル軽量化とリアルタイム推論に最適化  

3. **リアルタイム推論と自動制御**  
   - 推論はRaspberry Pi上で実行  
   - ステアリング出力はArduino経由でモーター制御に反映  

4. **モーター制御（Arduino側）**  
   - DCモーター：PWM制御で速度・方向を調整  
   - サーボモーター：角度指定による舵取り制御


## 🧪 結果と評価

- **シミュレータ走行**：安定した走行ラインを維持  
- **実機走行**：特定条件下で自動運転が可能に  
- 軽量な構成でも十分にAIによる制御が実現できることを確認


## 🔧 技術的工夫と課題

- CNNの構造をシンプルに設計 → 推論高速化  
- ROI＋エッジ検出で画像ノイズを低減  
- データセットに夜間・逆光・カーブなどを追加し、多様性を確保  
- 実機ではタイムラグ補正など細かな調整も実施


## ✍️ まとめ

この卒業研究では、**AI×組み込み技術の統合的な開発体験**を得ることができました。  
特に、**センサーデータとAIモデルをリアルタイムで組み合わせて実機制御**を行うという経験は、今後エンジニアとして大きな財産になると感じています。

将来的には、**日本の大手IT企業にてAI・制御技術を活かしたプロダクト開発**に携わりたいと考えています。


## ✅ 実行環境

- Raspberry Pi 4  
- Arduino UNO  
- Python 3.10  
- TensorFlow 2.x / OpenCV  
- DonkeyCarシミュレータ


## 🏷️ タグ

`#Arduino` `#RaspberryPi` `#自動運転` `#Python`  
`#TensorFlow` `#CNN` `#組み込み開発` `#卒業研究`
【KMPのAI開発体験向上】CursorでKotlin Multiplatformの開発効率が爆上がりした話 〜Project Rules導入編〜

# CursorでKotlin Multiplatformの開発効率が爆上がりした話 〜Project Rules導入編〜

こんにちは。  
最近、Kotlin Multiplatform (KMP) のモバイルアプリケーションの開発を、JetBrains FleetからCursorに切り替えてみました。  
結果として、**開発効率が爆発的に向上する手応え**を感じており、その中でも特に「**Project Rules**」の導入が鍵になったので、今回はその体験を共有します。

---

## なぜProject Rulesが必要だったのか？

Fleetでの開発からCursorに切り替えた直後、真っ先に感じたのが「**生成されるコードが既存の構成とズレている**」という問題でした。

- ファイルの配置がバラバラ
- 命名規則が統一されていない
- 既存のコンポーネントが使われていない

このままでは開発効率が下がるどころか、レビュー・保守のコストが爆上がり……。  
そこで辿り着いたのが、Cursorの**Project Rules機能**です。

---

## Cursorのルール機能3種類の比較

Cursorには以下の3つのルール設定方法があります：

| 種類              | 適用範囲        | 備考 |
|------------------|----------------|------|
| Rules for AI     | グローバル     | アプリ全体で共通のルールを設定 |
| `.cursorrules`   | プロジェクト単位（旧方式） | JSON形式で記述 |
| **Project Rules** | **プロジェクト単位（推奨）** | フォルダや拡張子ごとに詳細な設定が可能 ✅ |

特にこちらの記事がとてもわかりやすく基礎が整理されていましたので、詳細の説明は割愛させていただきます

https://zenn.dev/aimasaou/articles/ad3f8b499ebe91

私の課題は「Cursorアプリ全体でのルール」ではなく、「プロジェクト内でのルール違反」だったので、今回は**Project Rules**を選びました。

---

## Project Rulesの作成もCursorで

Project Rulesの作成って、正直ちょっとめんどくさそう……と思ってたのですが、ここもCursorにお任せ。

ある程度既存のコード構成があったため、主要ファイルを渡しつつ「このPJのルールを書いて」と依頼したところ、驚くほど整った形で返してくれました。

### 生成されたRuleの一部（抜粋）

- Architecture
- File Structure
- Naming Conventions
- Composable Rules
- State Management
- Resource Management
- Permission Handling
- Component Composition Rules

---

## 試行してみた

Project Rulesを設定した状態で、簡単なプロンプトを投げてみました：

> この会員情報編集ページを新規で作成する。既存のatomなどを利用して実装して

### 結果①：構造理解がまだ甘い…

- atomファイルの読み込みに失敗
- 新規ファイルのディレクトリ配置がズレてる

### 結果②：既存パーツを活かせていない…

Atomic Designを採用しているのに、新規atomを無駄に作ってしまっているケースが多発。

👎 **個人的スコア：50点くらい**  
正直、Copilot & 手入力の方が早いかも…というのが第一印象。

---

## 修正ポイントを追加

### 修正1：構造を言語化して渡す

CursorのChat欄では `@` を使ってフォルダを指定できるので、以下のように全体構造を言語化して伝えました。

### 修正2：ルールに明記したこと

- **既存のatom/moleculeの再利用を優先**  
- 「まず既存に使えるものがあるか確認してね」とルールに追加

---

## 再試行 → 劇的改善

再度、同じプロンプトで実行してみると…

🎉 **大成功！！**

- 正しいファイル構成に生成
- 冗長なコードもなく、必要最低限でスッキリ
- UI設計に必要なボタンなども網羅
- 既存atomをちゃんと使ってくれてる！

これはもう、**初期実装はCursorに任せてもいいかも…！**

1PRあたり30分〜1時間は確実に短縮できるレベルです。

---

## まとめ

今回の小さな改善だけでも、**「生成コードが既存ルールとズレる問題」**はほぼ解消されました。

- Project Rulesの設定は、たった10分程度でできる
- 体感で30分〜1時間の時短効果
- 今後の開発効率に大きな差がつく予感

---

## 今後の課題

もちろん、まだまだ改善余地はあります。

- Atomの再利用が徹底されない場合がある → もっと具体的なプロンプト？
- UIは画像指定とズレた形で生成される
- 人間側がプロンプトに何を指定すれば、ベストな形で生成されるのかのチューニングが必要（社内で共通した品質で利用できるよう、ある程度、テンプレートを用意したい）

---

## おわりに

AIにコーディングを“完全に”任せるのはまだ早いかもしれませんが、  
**「土台は任せて、手直しでクオリティを上げる」**という流れはもう始められるレベルまで用意できた感じがします。

同じような課題を持つ方の参考になれば幸いです！  
CursorのProject Rules、マジでオススメです。



## 🙋‍♂️ コメント歓迎！
Cursor × KMP で開発している方、
もしくはこれから始めてみようという方、
こんな方法やtipsおすすめだよという方、
もし気になることがあれば、ぜひコメントください！

体験共有、Tips、ノウハウなど、ゆるく話せたら嬉しいです〜！

---

## 一緒にプロダクトを育ててくれる仲間を募集しています！

現在、弊社では**正社員・業務委託・副業**問わず、  
Kotlin MultiplatformやUI/UXに興味のあるPdM・エンジニア・デザイナーの方を募集中です。

開発・デザイン・マーケを効率化しながら、使われるプロダクトを一緒につくっていきませんか？

▼詳しくはこちら  
採用情報ページ  

https://pouncing-canid-c69.notion.site/No-1-1d0e2ab33b92803cb0e2f6a5f6a9b848

公式HP

https://daysy-healthtech.com/

やっていることなどの詳細：note

https://note.com/sasasasaccccc
民主主義的観点によるSESへの私見

元イギリス首相　ウィンストン・チャーチル
「民主主義者は屈してはならない」

第二次世界戦でイギリスはナチスに欧州全土を支配されましたが、屈しませんでした。

3年間、東京で客先常駐としてIT業界で働いてきましたが、
いくつかの現場で暴言を受けたことがあります。

私は2つの現場で暴言に抗議して、その2つとも即日フリーランス契約が破棄されました。

私は「屈してはならない」という民主主義の哲学を気に入り、それをそのまま体現してしまったことを反省しています。

元FaceBook COO　シェリル・サンドバー
「自由は、与えられるものではなく、掴みとるものだ」

アメリカのハイテック業界でも同じ様な哲学を話されている方はいます。

私はこれからも屈しないという精神を持ちつつ、しなやかに対応することを心がける、気づきを与えてくれたSESに感謝します。
karpenter-provider-cluster-apiの実装状況

## 概要

KarpenterのCluster API統合「karpenter-provider-cluster-api」は、Cluster APIを通じたノードの自動スケーリングを可能にするプロジェクトで、現在はPoCの段階です。確認した所、現在の実装では、単一のコントローラーで監視できるワークロードクラスタは1つだけです。

## アーキテクチャ

karpenter-provider-cluster-apiは2つのクラスタと連携します：

1. **ワークロードクラスタ** - Podが実行される場所
2. **管理クラスタ** - Cluster APIリソースが存在する場所

## ソースコードから見た制約の理由

### 単一のワークロードクラスタ接続

```go
// pkg/operator/operator.go
func buildManagementClusterKubeClient(ctx context.Context, operator *operator.Operator) (client.Client, error) {
    if options.FromContext(ctx).ClusterAPIKubeConfigFile != "" {
        clusterAPIKubeConfig, err := clientcmd.BuildConfigFromFlags("", options.FromContext(ctx).ClusterAPIKubeConfigFile)
        // ...
        return mgmtCluster.GetClient(), nil
    }
    return operator.GetClient(), nil
}
```

### MachineProviderの初期化

```go
// pkg/operator/operator.go
func NewOperator(ctx context.Context, operator *operator.Operator) (context.Context, *Operator) {
    mgmtCluster, err := buildManagementClusterKubeClient(ctx, operator)
    // ...
    machineProvider := machine.NewDefaultProvider(ctx, mgmtCluster)
    machineDeploymentProvider := machinedeployment.NewDefaultProvider(ctx, mgmtCluster)
    // ...
}
```

MachineProviderとMachineDeploymentProviderはmgmtClusterのClientを使用して初期化されます。これにより、管理クラスタのkubeconfigを使った操作が実現されています。

### CloudProviderへのクライアント受け渡し

```go
// cmd/controller/main.go
cloudProvider := clusterapi.NewCloudProvider(ctx, op.GetClient(), op.MachineProvider, op.MachineDeploymentProvider)
```

CloudProviderは、ワークロードクラスタへのアクセス用にメインのクライアント（op.GetClient()）を使い、Cluster APIリソース操作用にMachineProviderとMachineDeploymentProviderを使用します。

## 影響

複数のワークロードクラスタを管理する場合、クラスタごとに1つのkarpenter-provider-cluster-apiのコントローラーが必要です。10個のクラスタを管理するには、10個のコントローラーが必要になります。

## まとめ

karpenter-provider-cluster-apiは現在、1つのインスタンスで1つのワークロードクラスタのみを監視できます。PoC段階における設計選択だと考えられます。
PowerShell ISE

### デバッグ時の便利操作
| ショートカットキー | 動作 |
|:-:|:-:|
|F5|スクリプト実行、デバッグ開始|
|F8|選択しているソースの実行|
|F9|ブレークポイントの設定|
|ブレークポイントが設定された行でF9|ブレークポイントの解除|
|Ctrl+Shift+L|ブレークポイントの一覧表示|
|F10|ステップ実行（関数呼び出しの場合、関数から戻るまで一度に実行）|
|F11|ステップ実行（関数呼び出しの場合、関数の中に入りステップ実行）|
|Shift + F11|ステップ アウト（関数から抜けるまで一度に実行）|
|Shift + F5|デバッグを停止|

### 変数の値の確認
- コンソール上で変数名だけを入力して Enter を押す
- 変数にマウスのカーソルを合わせるとポップアウトされる

### Powershellについて：$LAXTEXITCODEってなに？
- `$LASTEXITCODE` とは、PowerShell から外部コマンド（exeなど）を実行した後に、 そのプロセスの終了コード（exit code）を保持する特殊変数
- PowerShell の 内部コマンドレット（たとえば Get-ChildItem や Write-Host など） では更新されない

| 用語 | 意味（ざっくり） |
|:-:|:-:|
| プロセス  | コンピュータ上で動いている1つのプログラムのこと  |
| 内部プロセス  |  今動いている PowerShell の中で実行される処理（＝同じウィンドウ・ターミナルの中） |
| 外部プロセス  |  PowerShell が別に立ち上げて実行する「他のプログラム」（＝別の実行ファイル） |
【Excel VBAベーシック】プロシージャとは

## プロシージャ
　コードを実行するには、**プロシージャ**というものを作る必要がある。

### 定義
　処理の最小実行単位

### 補足
・F5で実行
・他のプロシージャから呼び出すには、Callステートメントを使う

### プロシージャの書き方
```vba:書き方
Sub プロシージャ名()
  実行するコード
End Sub
```

　「Sub」（サブ）で始まり「End Sub」（エンドサブ）で終わることから、**Subプロシージャ**と呼ばれる。「Sub」と「End Sub」の間にコードを書く。言い換えると、コードを実行出来るようにするには、コードを「Sub」と「End Sub」で囲う必要がある。

※プロシージャにはSubプロシージャ以外にも、Function（ファンクション）プロシージャなどがある。Functionプロシージャは、Excelの関数と同様に、値を返すことが出来るのが特徴である。また、Subプロシージャはマクロの一覧に表示されるが、Functionプロシージャは表示されない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/6b2ad0a1-49e7-43ea-9340-fed7127d9788.png)


 ## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
この1冊で合格! 永井雅明のExcel VBA ベーシック テキスト&問題集 単行本 – 2025/2/26
永井 雅明 (著)
p.38
2025/4/10　応用技術進捗どうですか②

## はじめに
初めてIPA資格を受けるので、そこまでの軌跡を記録しようと思ってます。
[前の進捗記事](https://qiita.com/gravellander/items/1ba2f111c43728b6bf16)

## 投稿主のスペック
インフラエンジニア3年以上経験
■保有資格
・AWS SAA
・Lpic304
・AWSセキュリティスペシャリスト

## 進捗4月 応用技術過去問道場 午前

![スクリーンショット 2025-04-10 162131.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740433/cfa776b3-c14d-4e07-a3cf-6cadb039ab47.png)

午前中の試験は過去問を解きまくって、だいたい7割ー9割ほど取れるようになりました。

1月は2割ぐらいだったので、だいぶ成長しました。
心配で勉強しまくっていたら、4000問解いてました。

私は容量良くないので、Youtubeで解説を見たり
この問題を後輩にどう説明したらわかりやすいか、などをイメージして解きました。

アルゴリズムと数学はほぼ捨ててます笑

## 進捗4月 応用技術過去問道場 午後

![スクリーンショット 2025-04-10 164845.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740433/6b6b1d28-437f-4d29-9610-9d6124d06aae.png)
<strong>
【注意】
データベース＆システムアーキは解説動画みながら解いているので高い点数になってます
<strong>





午後試験では、以下をメインとして選択して、サブも一応作ってます。
【<strong>メイン</strong>】

●<strong>情報セキュリティ</strong>　←必須
●<strong>ネットワーク</strong>
●<strong>システム監査</strong>
●<strong>プロマネ</strong>
●<strong>サビマネ</strong>

【<strong>サブ</strong>】
●<strong>システムアーキテクスチャ</strong>
●<strong>データベース</strong>
●<strong>経営戦略</strong>
# 各午後試験の肌感[メイン]
以下に解いてみた個人的感触をお伝えします。

## 情報セキュリティ
セキュリティ資格を保有しているので、イメージしやすい。
初見問題でも7割は安定して、たまーにケアレスミスで3割とかになってます（（

本番ではこいつは90％にして得点源にしようと思ってます。

## ネットワーク
あまり　おすすめ　されている記事は見ませんが、インフラエンジニアならイメージしやすい

むしろインフラエンジニアだからこそ、ここを得点源にします。

ただ範囲はばちこり広いので、業務でやってない人は難しいかも
情報セキュリティと被る部分もあるので、僕は選択します。


初見でも7-9割取れるので、本番は90%取れるように勉強続けていきます

## システム監査

自分がシステム監査人になったつもりで、本文の字句を抜き出すことが多い。
答えが本文にあるので、解きやすかったです。
こちらも初見で90％ぐらい取れるので、ここを得点源にしてます。

## プロマネ・サビマネ
定番の国語力勝負の分野
その日の問題が自分にアジャストするかで変わるので、何とも言えませんが

午前の知識をここで昇華できるので
勉強して楽しい分野ですね。

あー　午前の問題は実際の話だとこうなるのかー！　っていう感じです。

この楽しさ　が　知識の定着につながってますね

# 各午後試験の肌感[サブ]
以下に解いてみた個人的感触をお伝えします。

## システムアーキテクスチャ
その日の問題によって傾向が変わるため、つかみづらい。
ネットワーク寄ってたり、組み込みによってたり…
<strong>計算問題が出てきたりするんですけど、
その1問目の計算を間違えると、後の問題が全滅するのもあるの<strong>

当日見て決めようかなと思います。解いてるんですが、正直捨ててます


## データベース

みんなおすすめしていて、出題範囲も狭いんですが

ＳＱＬ文がほんとにわからなくて、しっくりこないので

こちらも解いてはいますけど、捨ててます。

解説動画見たり、講義を見たりしましたが、よーわからんかったです。

筑波大学にある、データベース講義がYoutubeに上がっています。

後は自分でＳＱＬを構築して打ってみるとかですかね…
当日ぱっと見して、簡単そうだったらこちらにしようかと

## 経営戦略

プロマネ・サビマネどちらかｇ難しかったらこちらを選択。

たまに簿記みたいな話になるので、サブ要員

## 午後試験でメインとサブを設定している理由

その日の試験で難易度がばらついているんですが

やさしい　難易度　と　むずかしい　難易度　でバランスをとっているので

どの分野がむずかしくて、　どの分野がやさしいのか当日にならないとわからないため

メインとサブを設定して、当日切り替えようと思います。


## あとがき

もう試験まで10日となりましたが、AP合格して、10月のSCに向けて勉強頑張りたいと思います。

鉛筆と消しゴム持つの久しぶりだーーーーーー

受験票に証明写真いるなんてーーーー
証明写真機　新札に対応してないよおお！！！


## 覚えておくと便利なやつ

1K（キロ） = 10³ = 1,000

1M（メガ） = 10⁶ = 1,000,000

1G（ギガ） = 10⁹ = 1,000,000,000

計算するときゼロが3個だから、1,000だ！！ってなって楽です

1ミリ秒（ms） = 10⁻³ 秒 = 	0.001 秒

1マイクロ秒（μs） = 10⁻⁶ 秒 = 0.000001 秒

1ナノ秒（ns） = 10⁻⁹ 秒　= 0.000000001 秒



10 -6ってことは、前に0が6個付くんだ！！ってなるやつです。

これ便利
統計検定1級　2022　統計応用(理工学)　問2　解説

![img20250407_08493118.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/4bb1dd36-7035-4b16-8ae1-afe44872660d.jpeg)
![img20250407_08500683.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/8606021a-28b0-4c71-8662-1363dea2a014.jpeg)
![img20250407_08503279.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/8ca7d080-4fe5-4724-9553-79137f9fb24c.jpeg)
![img20250407_08505814.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/1da2f213-260c-4c28-9b19-fcabe333b03a.jpeg)
Db2 Warehouse as a Service:  インスタンスの停止と再開

2025年3月10日のアップデートでDb2 Warehouse as a Service(旧名: Db2 Warehouse on Cloud)のインスタンスが停止/再開できるようになりました。
参考: [What's New in IBM Db2 Warehouse on Cloud](https://www.ibm.com/support/pages/whats-new-ibm-db2-warehouse-cloud)の「10 March 2025」

インスタンスを停止させると、compute 課金がなくなりますので、使用していない場合のコスト削減になります。ただしストレージ料金は引き続き課金されますのでご注意ください。

当記事ではこのインスタンスが停止/再開の方法をWebコンソールで実施する方法を説明します。尚、Webコンソールの他にはREST APIで実施できるそうです。

# 1. インスタンスの停止(Pause)
### 1-1.左のナビゲーションメニューのスパナ🔧アイコンをクリックし、「Compute」タブをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ef5a6dc6-84ad-4cb2-ad8e-d6a690d875e0.png)

### 1-2. 「Pause compute」をクリックし、「Pause now」ボタンをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/2cfd8ed6-de25-4d28-9263-f52b36969002.png)

### 1-3. 警告画面が出てくるので、内容を確認し、問題なければ「Confirm」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ef365ea0-bde9-450d-af90-edc5c1bcd99f.png)


注意には以下のように書かれています：

- あなたのチームメンバーは、開始と同時にログアウトされます。　
- あなたのデータは変更されず、安全に保管されます
- 今後のすべての活動とスケジュールされたタスクは中断されます
- 一時停止中は、コンピューティングに対する課金は発生しません
- ストレージ料金は引き続き適用されます

またいま実行中のステートメントが確認できる画面へのLinkもありますので、不安な場合はLinkをクリックして確認後に実行してください:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c833c569-6fe5-462c-bf74-f2a1f9286c5b.png)

「Confirm」をクリック後、しばらくすると以下のような画面になり、インスタンスは停止されました:
![resume01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/1c2d6d53-9057-436e-938f-8810c290e991.jpeg)

# 2. インスタンスの再開(Resume)
インスタンスを再開します。
ログインすると以下の画面が表示されています:
![resume01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/1c2d6d53-9057-436e-938f-8810c290e991.jpeg)

### 2-1. 「Resume now」ボタンをクリック
クリックすると「Resume now」ボタンは消え、`Preparing to resume. This may take up to a few hours depending on the database size.`というメッセージが表示されます。
データベースのサイズに依存して、数時間程度かかると書かれています。
![resume02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/6328da47-068a-4621-8347-662eaccd8a78.jpeg)

もう少し経つと、通知でProgressが見られるようになります
![resume03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/655bf477-f43b-438c-8209-9149ab95e2a4.jpeg)

再開(Resume)が完了すると、通知にその旨メッセージが表示されます
![resume04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/7c994259-b33e-4852-855d-1d2e77824b50.jpeg)

その後、元のCompute画面に戻ります
![resume05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/68a2c535-af02-4bf4-98dd-cb76b4222224.jpeg)

ダッシュボード画面に戻ってみると、動き出したことがわかります
![resume06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/63cd57dd-e862-4b19-8f8c-e349c074133e.jpeg)


以上です。
Db2 Warehouse as a Service: LOADコマンドによるS3からのCSVファイルのロード

Db2 Warehouse as a Service(旧名: Db2 Warehouse on Cloud)では、S3からのCSVデータロード方法は4つあります。
1. 外部表によるデータのロード(INSERT INTO xxx SELECT * FROM EXTERNAL...)　
    - Db2 CLIを使用
    - 大量データの場合は高速
    - TIMESTAMP列がある場合は一旦VARCHAR列にする必要がある
    - こちらを参照:[Db2 Warehouse as a Service: 外部表によるS3からのCSVファイルのロード(INSERT INTO xxx SELECT * FROM EXTERNAL...)](https://qiita.com/nishikyon/items/db46b3c1fb99099a8a9a)
    - 

1. LOADコマンド
    - Db2 CLIを使用
    - TIMESTAMP列もそのままLOAD可能
    - **この記事で説明します**
    - 

1. Web GUIからのロード
    - 上記1、2の方法が両方可能
    - 外部表によるデータのロードの場合、TIMESTAMP列はエラーになる
    - こちらを参照: [Db2 Warehouse as a Service (Db2 Warehouse on Cloud): Webコンソールを使ったS3からのCSVファイルのロード](https://qiita.com/nishikyon/items/65c7f475a0279de217a1)
    - 
1. RESTAPIを使用したロード 
    - 以下を参考にしてください。ただしS3からのロードは`load_source`は`S3`に指定し、`server_source`の代わりに`cloud_source`をパラメータに指定し、アクセス情報をセットする必要があります。[API詳細](https://cloud.ibm.com/apidocs/db2-warehouse-on-cloud/db2-warehouse-on-cloud-v4#createloadjob)
        - [Db2 Warehouse on CloudのREST APIを使用したデータロード (python & curl)　の4. データロードジョブの作成](https://qiita.com/nishikyon/items/3cf88857245a6d084b63#4-%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AD%E3%83%BC%E3%83%89%E3%82%B8%E3%83%A7%E3%83%96%E3%81%AE%E4%BD%9C%E6%88%90)


当記事では2の「LOADコマンドによるS3からのCSVファイルのロード」について説明します。

参考: [Loading data from Amazon S3](https://www.ibm.com/docs/en/db2w-as-a-service?topic=s3-loading-data-from-file-amazon#loaddata_s3__LoadTheDataFromAmazonS3)

# 1.  実行方法
サーバー上でLOADコマンドを実行させるため、`CALL SYSPROC.ADMIN_CMD`を使用してLOADを実行します。

以下のテーブル定義のテーブルにロードするとします:
```sql:TEST_TIMESTAMP
"COL1" INTEGER , 
"COL2" TIMESTAMP , 
"TEXT" VARCHAR(30 OCTETS)
```


以下のCSVファイルをロードするとします(文字コードはUTF-8):
```py:CSVサンプル - test_timestamp.csv
371,"2024-09-05-09.35.17.753000","コメント"
372,"2024-09-05-10.35.17.753000","コメント"
```

この場合のコマンドサンプルは以下になります：
```sql
CALL SYSPROC.ADMIN_CMD(
'load from 
"S3::<S3エンドポイント>::
<アクセスキー>::
<シークレットアクセスキー>::
<バケット名>::
<S3のCSVファイルのS3のパス>" of DEL 
modified by codepage=1208 
timestampFormat="YYYY-MM-DD-HH.MM.SS.UUUUUU"
MESSAGES ON SERVER INSERT into  <テーブル名> ');
```

- `timestampFormat`はCSVの中身のフォーマットに合わせて設定しています。
- `codepage` 1208はUTF-8です。
- LOADのオプションはこちらを参考にしてください: https://www.ibm.com/docs/ja/db2/12.1.0?topic=commands-load#r0008305__title__10

- 

**以下の場合のコマンド例**:
- S3エンドポイント: s3.ap-northeast-1.amazonaws.com
- S3バケット名: woc-test-202504
- csvファイル: data/test_timestamp.csv
- ロード先テーブル: TEST_TIMESTAMP
- アクセスキー: xxxxxxxxxxxxxx
- シークレットアクセスキー: yyyyyyyyyyyyyyyyyyyyyyyyyyyy

```sql
CALL SYSPROC.ADMIN_CMD(
'load from 
"S3::s3.ap-northeast-1.amazonaws.com::
xxxxxxxxxxxxxx::
yyyyyyyyyyyyyyyyyyyyyyyyyyyy::
woc-test-202504::
data/test_timestamp.csv" of DEL 
modified by codepage=1208 
timestampFormat="YYYY-MM-DD-HH.MM.SS.UUUUUU"
MESSAGES ON SERVER INSERT into TEST_TIMESTAMP ');
```

以上です。
ハッカソン個人備忘録㉔：Alembicって何？スキーマ管理やその活用方法をまとめてみた

## はじめに

このドキュメントは、SQLAlchemy と Alembic を使った開発における基本的な使い方や、できることを自分用にまとめた備忘録です。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

Python アプリケーションにおけるデータベース操作を柔軟かつ安全に行うための参考として記録しています。

---

## 1. SQLAlchemy とは

SQLAlchemy は Python の ORM（Object Relational Mapper）ライブラリであり、以下の特徴を持ちます：

- Python クラスでデータベースのテーブル定義ができる
- SQL を直接書かずにクエリが作成できる（ORM機能）
- 必要に応じて生SQL文も実行可能
- 複数のデータベース（SQLite, PostgreSQL, MySQL など）に対応

### できること
- データベースとの接続管理
- モデル定義（テーブルを Python クラスで定義）
- クエリの作成（`session.query()` など）
- レコードの追加、更新、削除
- トランザクション管理

**参考文献**

https://zenn.dev/shimakaze_soft/articles/6e5e47851459f5

---

## 2. Alembic とは

Alembic は SQLAlchemy の開発チームが提供するマイグレーションツールです。DBスキーマのバージョン管理をコードベースで行えるのが特徴です。

### できること
- モデルの変更を差分として自動検出
- マイグレーションスクリプトの自動生成
- マイグレーション（upgrade/downgrade）の実行
- 複数のマイグレーションバージョンの管理

**参考文献**

https://zenn.dev/shimakaze_soft/articles/4c0784d9a87751

---

## 3. SQLAlchemy + Alembic を使うと何が便利になるか？

| 機能                            | 説明 |
|---------------------------------|------|
| テーブル設計を Python で完結     | SQL を書かずにテーブル作成が可能
| スキーマ変更を追跡・管理できる  | Alembic によってマイグレーションが容易に
| チーム開発でのスキーマ同期       | DBの状態をコードで管理することで、環境ごとの差異を防げる
| バージョンの巻き戻しも簡単       | downgrade 機能により、以前の状態に戻せる

---

## 4. 具体的な開発フロー例

1. **モデル定義**
```python
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
```

2. **Alembic 初期化**
```bash
alembic init alembic
```

3. **マイグレーションスクリプトの生成**
```bash
alembic revision --autogenerate -m "create users table"
```

4. **マイグレーションの適用**
```bash
alembic upgrade head
```

5. **コードの変更とマイグレーション**
モデルにカラムを追加→再度 `autogenerate` で差分検知→`upgrade` で適用

---

## 5. 補足：環境構築のポイント
- `alembic.ini` ファイルで接続先データベースを設定
- `env.py` ファイルで SQLAlchemy の `Base` を読み込ませる必要あり
- Docker や CI/CD 環境にも組み込み可能

---

## まとめ
SQLAlchemy と Alembic を使うことで、
- **Python コードでデータベース操作を完結できる**
- **スキーマ変更をバージョン管理できる**
- **チーム開発での DB 管理がしやすくなる**

開発や運用での柔軟性・安全性が大きく向上します。DB設計・運用をコードで統一的に管理したいなら、SQLAlchemy + Alembic の組み合わせは非常に有効です！