OmniAICreator/Qiita-1.07M huggingface dataset:
【Python初心者】timedelta・strftime・sleep で日付と時刻を操作する

今回は、日付や時刻を**ずらす・整形する・一時停止する**ための基本操作をまとめました。

- `timedelta` による日付・時刻の加減算  
- `strftime()` による文字列への変換（整形）  
- `sleep()` による処理の遅延  

## timedelta：日付や時刻の差分・加減算

`datetime.timedelta` は「日付や時刻のずれ」を表すオブジェクトです。  
たとえば「1週間後」「3日前」などを簡単に計算できます。

```python
from datetime import datetime, timedelta

now = datetime.now()
print("現在:", now)

# 1日後
print("明日:", now + timedelta(days=1))

# 3日前
print("3日前:", now - timedelta(days=3))

# 2時間30分後
print("2時間30分後:", now + timedelta(hours=2, minutes=30))
```

`days`, `seconds`, `microseconds`, `milliseconds`, `minutes`, `hours`, `weeks` などが指定できます。

## strftime(): 日付や時刻を文字列に変換する

日時を「指定フォーマットの文字列」に変換するには `strftime()` を使います。

```python
from datetime import datetime

now = datetime.now()

print(now.strftime("%Y-%m-%d"))          # 2025-06-15
print(now.strftime("%Y年%m月%d日"))      # 2025年06月15日
print(now.strftime("%H:%M:%S"))          # 14:23:00
print(now.strftime("%A"))                # Sunday（曜日）
```

### 主な書式指定子まとめ

| 書式 | 意味                   | 出力例       |
|------|------------------------|--------------|
| `%Y` | 西暦（4桁）             | 2025         |
| `%y` | 西暦（下2桁）           | 25           |
| `%m` | 月（01～12）           | 06           |
| `%d` | 日（01～31）           | 15           |
| `%H` | 時（00～23）           | 14           |
| `%I` | 時（01～12、12時間表記）| 02           |
| `%M` | 分（00～59）           | 23           |
| `%S` | 秒（00～59）           | 00           |
| `%f` | マイクロ秒（6桁）      | 123456       |
| `%A` | 曜日（英語）           | Sunday       |
| `%a` | 曜日（短縮形）         | Sun          |
| `%w` | 曜日（数値、0=日曜）    | 0            |
| `%j` | 年内の通算日（001～366）| 166          |
| `%p` | 午前/午後（AM/PM）     | PM           |

**ポイント：**  
- `%Y-%m-%d` や `%H:%M:%S` はよく使う基本パターン。  
- `%j` や `%p` のようなややマニアックなものも知っておくと便利です。

## sleep(): 処理を一時停止する

処理を一定時間止めるには `time.sleep()` を使います。  
引数には「秒数（float も可）」を渡します。

```python
import time

print("3秒待ちます...")
time.sleep(3)
print("再開しました。")
```

デバッグやAPIのリクエスト間隔の調整などにも使われます。

## おわりに

今回は `timedelta` / `strftime` / `sleep` を使った日付と時刻の操作を学びました。

特に `strftime()` の書式指定子は種類が多くて混乱しやすいですが、  
よく使うものから順に少しずつ覚えていこうと思います。
【HTML】title要素

**title要素**は、HTMLドキュメントのタイトルを定義するための要素です。
ブラウザのタブ名に反映されます。
title要素はhead要素内に1つだけ記述します。
ユーザにとってのわかりやすさや検索エンジン対策の観点から、title要素は必ず記述してください。
「Dockerログ確認の非効率さ」に気づいた話

# 背景
業務中にコンテナ内のログを確認する必要がありました。
本来であれば、CLIで `docker exec` コマンドなどを使って素早くログをチェックできたはずですが、コマンドの使い方を思い出せず、Docker DesktopのGUIからログを探すという非効率な方法を取ってしまいました。

# 問題点と気づき
コマンドの記憶があいまいで、都度GUIに頼る作業に時間がかかった
GUIではログの読み込みや操作に限界があり、操作スピードと精度に欠けた
CLI操作がルーチンになっていないことで、本来のスピード感ある調査ができなかった

▶ 日常的に使うべきCLI操作を習慣化し、思考停止せず手を動かせる状態を目指す必要があると痛感。

# 本来取るべきだった操作手順（CLIでのログ確認）

コンテナに入ってログを見る場合：
```dockerfile
docker exec -it <container_name> /bin/bash
tail -f /path/to/logfile.log
```

もしくは、直接ログ出力を追う場合：
```dockerfile
docker logs -f <container_name>
```

#### よく使うオプション：
`-f`: ログを追尾して表示（tail -f 的な動き）
`--tail 100`: 直近の100行だけ表示

:::note info
Graphical User Interface：画面上のボタンやメニューで操作する方式。
Command Line Interface：コマンドを入力して操作する方式。
Docker(コンテナ型仮想化ツール)：アプリを「軽量な箱(コンテナ)」にまとめて動かす技術。
:::

# 最後に
GUIは便利ですが、CLIを使いこなすことで「早く・正確に・自由に」調査や操作ができる環境を整えられます。
今後は日常業務の中で「CLIでまずできないか？」と自問する習慣を持ち、技術的な基礎体力を少しずつ積み上げていきたいと思います。
プロデル、調査 その44

# 概要
プロデルが、CLRらしいので、調べて見た。
練習問題やってみた。

# 練習問題
コマンドプロンプトの実行結果を取得せよ。


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/102350ec-e9ff-4663-9b38-05877bc2c82b.png)

# サンプルコード

```
WScriptShellというCOM型(「WScript.Shell」）を作る
WScriptShellからインスタンスを作ってsaとする

sa:Exec(「cmd.exe /k time  > dir.txt」)
結果ファイルは、「dir.txt」
結果ファイルというファイルが存在するなら
	結果データは、結果ファイルから読み込む
そして
結果データを報告する




```

以上。
「メズマライザー」のPhosphoribosylaminoimidazolesuccinocarboxamideを再現する


## あの曲に出てくるアレ。

ケモインフォマティクスや代謝経路を勉強していると、名前が長すぎて舌がもつれそうな化合物に出会います。 
例えば"Phosphoribosylaminoimidazolesuccinocarboxamide"。略してSAICAR。

れっきとした生体内代謝中間体です。 
この化合物をRDKitで再現し、その構造を見てみましょう。 

## 環境構築

RDKitはPythonの化学情報学ライブラリのデファクト。 
conda-forgeチャンネルから環境作成。

```bash
conda create -c conda-forge -n rdkit-env rdkit jupyterlab -y
conda activate rdkit-env
````

## Phosphoribosylaminoimidazolesuccinocarboxamide

SAICARのSMILESから分子を作り、構造を可視化してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170548/243dbf80-fd39-4931-8ae4-5c0f95f8df4d.png)

```python
from rdkit import Chem
from rdkit.Chem import Draw

smiles = "O=C(O)C[C@@H](C(=O)O)NC(=O)c1ncn(c1N)[C@@H]2O[C@@H]([C@@H](O)[C@H]2O)COP(=O)(O)O"
mol = Chem.MolFromSmiles(smiles)

# 分子の原子数を確認
print(f"原子数: {mol.GetNumAtoms()}")

# 分子イメージを表示（Jupyterならこのまま描画可能）
Draw.MolToImage(mol)
```


RDKitは複雑な生体分子も扱えて、様々な解析や分子設計に活用できます。
ここで立体配置を反映したSMILESを使うことで、実際の生物分子の形状に近いモデルを再現しています。

難解分子を身近に感じる一助になれば幸いです。
興味があればRDKitで他の代謝物も試してみてください。
「依頼の仕方」についての学びと改善

# 背景
ある業務で、別チームに対してAPIキーの作成を依頼する場面がありました。
その際、自分の都合を優先して日程を提示し、相手のスケジュールや状況を確認せずに依頼を進めてしまったという反省点がありました。

# 問題点と気づき
:::note info
1.相手の状況を確認せず、一方的にスケジュールを提示してしまった
2.自分の業務都合が優先され、相手への配慮や相談の姿勢が不足していた
3.結果として、相手に余計な負担をかけてしまった可能性がある
:::
▶ 今後は「依頼」ではなく「相談」の姿勢を大切にし、相手の優先度やリソース状況を尊重するコミュニケーションを心がけたいと強く感じました。

# どんなやり取りをすればよかったか？
### Before（実際にやってしまった例）
:::note alert
「来週までにこのAPI作ってもらえますか？」
→ こちらの都合だけでスケジュールを提示し、相手のタスク状況は無視していた
:::

### After（改善後の例）
:::note info
「こんにちは。現在○○の対応で、✕✕のAPIを作成いただきたいのですが、対応可能なタイミングや状況を教えていただけますか？
こちらとしては◯月◯日までに完了できると理想ですが、ご都合に合わせて調整させていただければと思っています。」
:::

### ポイント：
相手のタスク状況を確認
希望スケジュールは“理想”として伝える
最初から決めつけず、相談ベースで進める

# 今後に向けてのアクション
依頼時には、「いつまでに対応可能でしょうか？」と確認することをルール化
スケジュールを伝える際は、「〜までに完了できると理想ですが、調整可能です」とクッション言葉を入れる
できれば、相手の負担感や今のタスク優先度をヒアリングしたうえで話を進める

# 最後に
つい自分のスケジュールや納期に意識が向きがちですが、チーム間での信頼関係は「相手の状況を尊重する姿勢」から生まれると実感しました。
これからも「相手が動きやすくなる依頼の仕方」を意識し、協力しやすい関係を築いていきたいと思います。
wsl2上のUbuntuで、接続が切れる問題の調査

## 発生した問題

- windowでUbuntuを使って開発をしていたが、接続が切れてしまう
    - vsCodeでファイルが読み込めなくなる
    - Ubuntuのコマンドに以下のエラー
    
    ~~~
    仮想マシンまたはコンテナーからの応答が受信されなかったため、操作がタイムアウトしました。
    エラー コード: Wsl/Service/HCS_E_CONNECTION_TIMEOUT
    Press any key to continue...
    ~~~

## 試したこと

powershellで以下のコマンドを実行すると一時的に治るが、しばらくすると再発する。

~~~ 
wsl --shutdown
~~~

## 恒久対応

1. C:\Users\ユーザー名配下に、.wslcongigを作成

2. 以下の記述
    ~~~
    [wsl2]
    memory=8GB # PCのスペックに応じて、搭載メモリの半分以下くらい
    processors=4
    ~~~
3. powershellでwsl --shutdownを実行


これで再発することは無くなった！
XIAO ESP32S3でエッジAIによる歩行者検出システムを作り、MQTTで画像を送信して

## 自己紹介

はじめまして！今回がQiita初投稿になります。

私は現在IoT開発会社で働いている、開発が大好きな駆け出しエンジニアです。エンジニア歴はまだ1年半ほどで、正直まだまだ「アマチュア」の域を出ないかもしれません。大学時代には、化粧品の配合や飛行モデルの製作など、様々な分野の開発に触れてきました。

今の職場はIoT系の小さな会社で、開発環境は自前のPCを持ち込むほどカツカツですが（ほぼボランティアみたいな感じです）、それでも技術が好きで日々がんばっています。

ただ最近、会社の状況が少し不安定になってきたため転職を考え、いくつか履歴書を出しましたが……見事に全落ちでした

そこで「じゃあ自分が応募した業務内容にマッチしたプロジェクトを、アウトプットとしてまとめてみよう！」と思い立ち、この投稿を書いています

---

## 応募した企業の業務内容

以下は、私が応募した企業で求められていた仕事内容の一部です：

- 画像データに対するアノテーション・前処理・データ拡張の整備  
- 既存モデルの再学習に向けたデータセット構成・スクリプト改修  
- 推論処理の改善（精度・処理速度・誤認識の抑制）

---

## 作ったプロジェクトの概要

このプロジェクトでは、**ESP32S3** と **AIモデル** を組み合わせて「歩行者検出システム」を開発しました（いわゆるエッジAI）。  
本システムは、様々な環境下でリアルタイムに歩行者を検出でき、さらに**低消費電力**で動作します。

この開発を通して、以下のような技術を実践的に学ぶことができました：

- リソースの限られた小型デバイス上でのAIモデルの**最適化・デプロイ**
- エッジコンピューティングにおける**リアルタイム性や処理制限**への対応
- **MQTT通信**を使った画像データの送信（遠隔監視・データ収集）

AIモデルの訓練・デプロイには [**Edge Impulse**](https://www.edgeimpulse.com/) を使用し、画像データの前処理や拡張手法を通じて、モデルの**精度と安定性向上**にも取り組みました。

---

## 技術スタック

本プロジェクトで使用した主な技術構成は以下の通りです：

- **XIAO ESP32S3**  
  小型ながら高性能なマイコンで、エッジAI向けに最適。豊富なI/Oと低消費電力が魅力です。

- **Edge Impulse**  
  エッジデバイス向けに設計されたAI開発プラットフォーム。GUIやCLIでモデルの構築・訓練・デプロイが可能です。

- **MQTT**  
  軽量なIoT向けプロトコル。今回は検出した歩行者の画像をMQTT経由でクラウドへ送信するのに使いました。

---
## 写真

![Photo_25-06-15-16-36-00.348.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683749/0d767af6-b728-41a7-add5-02f7eff4e3ca.jpeg)
![Photo_25-06-15-16-35-12.301.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683749/df824ffc-a7e0-4325-843d-852cb30d6ac1.jpeg)
![ezgif-76aaa983b382f1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683749/7c89f4fc-30e9-4770-9f97-2c6a1ec368ad.gif)
![image260.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683749/89b002e4-3d96-4475-b34f-16599fa8c320.jpeg)

---
## 📝 最後に

まだ資料が揃っていない部分がありますが、これから少しずつ更新していくつもりです。（最近仕事が詰まりすぎてます…T_T）。  
この記事が誰かの参考になれば嬉しいですし、何かアドバイスやご意見があればぜひコメントで教えてください！

ここまで読んでいただきありがとうございました！
【Linux】ジョブとは

**ジョブ**とは、コマンドライン1行で実行された処理単位のことです。
ジョブはシェルごとに管理され、「**ジョブID**」が振られます。
1行のコマンドラインで複数のコマンドが実行された場合でも、その処理全体を1つのジョブとして扱います。

ジョブには「**フォアグラウンドジョブ**」と「**バックグラウンドジョブ**」の2種類があります。

**表：ジョブの種類**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/86d6f316-b096-48c3-b7aa-730f20616941.png)

ジョブを制御するコマンドは以下の通りです。

**表：ジョブを制御する主なコマンド**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/9a70d3e0-9a00-4e3d-b95b-5a82e1129da7.png)
GitHub上にあるプロジェクトから始メル際に使用するGitコマンド集

よく使うGitコマンドを以下にまとめてみた。

## リモートリポジトリのコピーを作成する
```
git clone <リポジトリURL>
```
- ローカルリポジトリの作成
- ワーキングツリー（ファイル群）のコピー
- originという名前でリモートの設定も登録される
※別の名前にしたい場合は、```git remote add <別名> <リポジトリURL>```を実行

## 変更をステージに追加する
```
git add <ファイル名>
git add <ディレクトリ名>
git add .
```

## コミット
```
git commit -m "メッセージ"
```

## 変更状況確認
```
git status
```

## 変更履歴確認
```
git log
```

## リモートにpush
```
git push <リモート名> <ブランチ名>
git push origin master
```

## 管理しないファイルについて
.gitignoreファイルにファイル名を追記する

## ファイルへの変更を取り消す
### ステージング前
```
git checkout -- <ファイル名>
git checkout -- <ディレクトリ名>
git checkout -- .
```

### ステージング後
```
git reset HEAD <ファイル名>
git reset HEAD <ディレクトリ名>
git reset HEAD .
```

## コミットやり直し
```
git commit --amend
```

## 最新取得
```bash:
git pull origin master ## 現在のローカルブランチにリモート(origin)の最新のmasterブランチを取り込む
```

## ブランチ作成＆切り替え
```
git checkout -b <新ブランチ名>
```

## マージ
```
git merge <リモート名/ブランチ名>
git merge origin/master ## 現在の作業ブランチにマージする
```

## 修正内容を退避する
```
git stash

git stash list ## 退避した作業の一覧を取得

git stash apply ## 最新の退避を復元する
git stash apply <スタッシュ名>

git stash drop ## 退避を削除する
```
データベーススペシャリストをとりたくて1

## 方針
- 6月、7月
    - SQLに慣れる
    - 午後Ⅱ対策
- 8月
    - 午後Ⅱ対策
    - 午後Ⅰ対策
- 9月
    - 午前Ⅱ対策開始
- 10月
    - 受験

## 6月上旬SQL対策
通勤時間でSQLの勉強。こればっかりは慣れなので、とにかくChatGPT先生に問題を出させて解く
毎日コツコツ1時間くらい時間とってやっている
SELECT文で関数使った場合にはgroup化が必須とか、サブクエリの使い方とか、having句とか基本的なことから慣れる。この時点で実務にも結構役立つ


## 6月上旬午後Ⅱ対策開始

まずテキストを買って、問題を読んで怪しい単語を列挙。説明できるように知識に落とし込む
説明できますか？

- 関係スキーマ
- 主キー
- 候補キー
- スーパキー
- 外部キー
- スーパクラス
- サブクラス

一年前に単語の意味があやふやで受けてしまった苦い記憶があるので固める。これも実務にはかなり役立つ
Javaの「参照の値渡し」は本当に安全？パラメータを書き換えても影響しないケース・するケースを整理して解説

# はじめに
Javaのメソッドにオブジェクト型の引数を渡すとき、「中身を変更すると呼び出し元に影響する？」「変数を上書きしたらどうなる？」といった疑問をもったことはありませんか。
この記事では、以下の4パターンにわけて「影響するか/影響しない」を整理します。
| 引数の種類 | 説明 |
|:-:|:-:|
|オブジェクト型|String、ユーザー定義のクラス、コレクション型などが含まれる。  |
|プリミティブ型|整数（int）、浮動小数点数（float）、文字（char）などの基本データ型。   |

# 1. ローカル変数（メソッド引数）を書き換えても影響しない
```java:Sample.java
public boolean checkCauseException(Throwable exception) {
    // 例外の cause をたどって SocketException があるか調べる
    while(exception != null) {
        if(exception instanceof SocketException) {
            return true;
        }
        exception = exception.getCause();  // ここでパラメータ変数を書き換えている
    }
    return false;
}
```
#### 影響しない理由
`exception`はメソッドのローカル変数（パラメータ変数）です。
Javaは「参照の値渡し」なので、オブジェクトの参照（住所）をコピーして受け取っているだけ。
つまり、`exception = exception.getCause()` のように参照を上書きしても、呼び出し元の変数は影響を受けません。

# 2. クラス変数（フィールド）を書き換えると影響する
```java:Sample.java
public class Sample {
    private Throwable cause;  // クラス変数（フィールド）

    public boolean checkCauseException() {
        // フィールドを直接使う    
        while(cause != null) {
            if(cause instanceof SocketException) {
                return true;
            }
            cause = cause.getCause();  // 直接クラス変数を書き換えている
        }
        return false;
    }
}

```
#### 影響する理由
`cause` はクラスの状態そのもの（フィールド）**です。
`cause = cause.getCause()` のように書き換えると、オブジェクトの内部状態が変化します。
結果として、他のメソッドや呼び出し元でもcauseの内容が変わってしまう可能性があります。

# 3. 配列やコレクションの中身を変更すると影響する
```java:Sample.java
String[] array1 = {"A", "B", "C"};
String[] array2 = array1;  // array2も同じ配列オブジェクトを参照している

array2[0] = "Z";           // 配列の1つ目の要素を変更

System.out.println(array1[0]); // "Z" と表示される

```
```java:Sample.java
List<String> list1 = new ArrayList<>();
list1.add("Apple");

List<String> list2 = list1;  // list2もlist1と同じリストを参照

list2.add("Banana");

System.out.println(list1.size());  // 2 と表示される

```

# 4. Javaでの参照の値渡しについて
```java:Sample.java
class TV {
    String channel = "NHK";
}

public class RemoteControlExample {

    static void changeChannel(TV remote) {
        remote.channel = "BBC";
        
        remote = new TV(); // 新しいリモコン（＝参照）を作る
        remote.channel = "CNN"; 
        System.out.println("メソッド内: " + remote.channel); // メソッド内: CNN
    }

    public static void main(String[] args) {
        TV myTv = new TV(); 
        System.out.println("呼び出し前: " + myTv.channel);      // 呼び出し前: NHK

        changeChannel(myTv);      
        System.out.println("呼び出し後: " + myTv.channel); // 呼び出し後: BBC
    }
}

```
### 処理の流れ
1.Javaは「参照の値渡し」なので、リモコンのコピーが渡されます。
2.コピーでTVの設定を変えれば本体に影響します（例：channel = "BBC"）。
3.でも新しいリモコンを作っても、元のリモコンには影響しません（例：channel = "CNN" は反映されない）。

### まとめ
1.メソッドに渡されるのはオブジェクトの参照のコピーです。
2.コピーを使ってオブジェクトの中身は変更できます。
3.ただし、参照そのものを新しいものに変えても、呼び出し元には影響しないです。
小さな学び

### 2025 06 15
#### ①AWS 通信　Cost
AWS上での通信コストに関して、なんとなくのイメージしか持っていなかったが、
以下のAWSブログ内容を整理し、理解してみる。
＜参考資料＞
https://aws.amazon.com/ko/blogs/architecture/overview-of-data-transfer-costs-for-common-architectures/

- AWSへ入る通信量は無料 (Direct Connect, Internet Gateway ...)
    - コストはデータ転送する際(out)やデータ転送される際(in)も発生
        - AZ間の通信のコスト(inとout)は同一　1a <-> 1c
        - リージョン間の通信のコスト(inとout)は違う　us-east1 <-> ap-northeast-1　
- あるVPCから同一リージョンのAWS Services(S3など)へInternet Gateway経由した通信料金は発生しない
    - NAT Gateway → Internet Gatewayを経由した際には NAT Gatewayのデータ処理料金は発生
    - あるVPCから***他リージョンのAWS Services(S3など)へInternet Gateway経由した通信料金は発生する***
    - VPC Endpointを利用し、安全に通信することが推奨されるが、通信量は***発生する***
- 同一AZ間の通信はコストが発生しないあるVPCから***他リージョンのAWS Services(S3など)
    - 他AZ間との通信はコストが***発生する***
- VPC Peeringを利用し、同一AZにあるVPC間の通信はコストが発生しない
    - VPC Peeringを利用し、他AZにあるVPC間の通信はコストが***発生する***
    - VPC Peeringを利用し、他リージョンにあるVPC間の通信はコストが***発生する***
- Transit Gatewayを利用し、他VPCと通信する際はAZに関係なくコストが***発生する***
- ALBの場合はターゲットが他AZにある場合、コストが発生しない
    - NLBの場合はターゲットが他AZにある場合、コストが***発生する***

#### ② VPC Endpoint
他リージョンのAWS Services(Cloudwatch、S3...)にはVPCエンドポイントを利用してアクセスすることはできない。同一リージョンのみ通信可能
RaspberryPiを使ってローカルAPを立てる

Raspberry Piで2系統Wi-Fiを同時利用します。1つはローカルAP、もう1つは家庭内ネットワーク用にWifiを立てます
別記事のRS-WFWATTCH2などのガジェットを外部からアクセスされないようにして使うことを想定しております　https://qiita.com/estima5633/items/43421d9dfe00e29ab22f
## 📝 はじめに
RaspberryPi OSをインストールし、wifi設定(wlan0)設定が終わったところから以下を開始します
Raspberry PiにUSB Wi-Fiアダプタを追加して、以下のような構成を実現しました：

- **wlan0**：家庭内Wi-Fiに接続（インターネットアクセス可能）
- **wlan1　追加）**：Raspberry Pi自身がWi-Fiアクセスポイント（AP）として動作
- **Samba共有**：wlan1で接続したPCやスマホからファイル保存 → wlan0側から閲覧・編集可能
---
## 📦 構成図
| PC/Phone | 

ｰｰｰｰ-samba共有
| Raspberry Pi |
----| wlan0: Wi-Fi for Internet |　
----| wlan1: Local AP |

## 🔧 使用環境
- Raspberry Pi OS Bookworm（Debian 12ベース）
- Raspberry Pi 3B+ / 4B / 5
- USB Wi-Fiアダプタ（例：Realtek RTL88x2xx系）
---
## ① Wi-Fiアダプタのドライバ確認とインストール
```bash
lsusb
ip a
```
ドライバ未認識の場合、以下で導入：
```bash
# 例：Realtek 88x2xx系
sudo apt install realtek-rtl88xxau-dkms
# または（カーネル互換性に注意）
git clone https://github.com/ulli-kroll/rtl8821cu
```

## ② NetworkManager をインストール
```bash
sudo apt update
sudo apt install -y network-manager
```
dhcpcd と wpa_supplicant を無効化し、NetworkManager に切り替えます：
```bash
sudo systemctl disable --now dhcpcd
sudo systemctl disable --now wpa_supplicant
sudo systemctl enable --now NetworkManager
```
確認：
```bash
nmcli general status
nmcli device status
```
## ③ wlan0でインターネットに接続
```bash
nmcli dev wifi list
nmcli dev wifi connect ＜家庭内SSID＞ password ＜Wi-Fiパスワード＞ ifname wlan0
```
## ④ wlan1をローカルAPとして起動
```bash
sudo nmcli dev wifi hotspot ifname wlan1 ssid MyAP password "password123"
```
確認：
```bash
ip a show wlan1
```
## ⑤ dnsmasqでAP端末向けにDHCP提供
```bash
sudo apt install -y dnsmasq
sudo nano /etc/dnsmasq.conf
```
以下を追記：
```ini
interface=wlan1
dhcp-range=192.168.10.2,192.168.10.50,255.255.255.0,24h
```
起動：
```bash
sudo systemctl restart dnsmasq
```
## ⑥ Sambaによるファイル共有
```bash
sudo apt install -y samba samba-common-bin
mkdir /home/＜ユーザー名＞/shared
chmod 777 /home/＜ユーザー名＞/shared
sudo nano /etc/samba/smb.conf
```
末尾に以下を追加：
```ini
[Shared]
   path = /home/＜ユーザー名＞/shared
   read only = no
   guest ok = yes
   force user = ＜ユーザー名＞
```
再起動：
```bash
sudo systemctl restart smbd
```

## ⑦ クライアントからアクセス確認
ローカルAP接続端末（スマホやPC）：
```vbnet
\\192.168.10.1\Shared
```
家庭内LAN側から（Raspberry Piのホスト名を指定）：
```lua
\\raspberrypi.local\Shared
```

## 💡 応用：クラウド連携（任意）
rcloneでOneDriveやGoogle Driveと連携してデータを共有する：


## ✅ まとめ
Raspberry Piに複数Wi-Fiインターフェースを持たせることで、
・一方をインターネットアクセス用
・一方をローカル通信・共有用APとして動作可能に

NetworkManager + dnsmasq + Samba でシンプルに構築できる

IoT、現場PC接続、災害時ローカル通信などのユースケースにも有効です
戻るボタンに処理を追加する

端末の戻るボタンが押された時に合わせて処理したいことがある時は`onBackPressedDispatcher` を使います。その使用方法をメモします。

`onBackPressed()` は非推奨になったので代わりに `OnBackPressedDispatcher` を使用していきます。
```kotlin
// 非推奨
override fun onBackPressed() {
    super.onBackPressed()
    // 処理を追加
}
```

`onBackPressedDispatcher` を使うと、簡単に戻る操作が実現可能です。Activityに、先ほど作ったコールバックを追加して使用します。OnBackPressedCallback(false) にすると戻るボタン無効状態になるので、任意のタイミングでtrueに設定してください。
```kotlin
private val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        Toast.makeText(this@MainActivity, "戻るボタンが押されました", Toast.LENGTH_SHORT).show()
        finish()
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    onBackPressedDispatcher.addCallback(this@MainActivity, onBackPressedCallback)
}
```

#### 参考
https://developer.android.com/guide/navigation/navigation-custom-back?hl=ja
Workaround for occasional implicit GPU detachment in Docker

## 課題

[Ubuntu 24.04 LTS](https://canonical.com/blog/canonical-releases-ubuntu-24-04-noble-numbat)のディストリビュートされているdocker.ioに対して、[Nvidia docker container](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html)でNvidia GPUを貼り付けたDockerコンテナを長期ランニングしていると、いつの間にかGPUが外れていることがある。

この事象が発生していると、Dockerコンテナのサービスが使用できなかったり、Dockerコンテナのサービス使用時にGPUの代わりにCPU負荷が急上昇したりする。そして、Dockerのログには、GPUが利用できないメッセージの出力があったりする。

例えば、[ollama/ollama](https://hub.docker.com/r/ollama/ollama)の場合、この現象が発現すると、以下に示すように`no CUDA-capable device`を含んだエラーメッセージが出力される。
![no-CUDA-capeble.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59920/a02474d1-a62a-4658-b153-014e5ccc73c3.png)

## 回避方法

この問題は[NOTICE: Containers losing access to GPUs with error:"Failed to initialize NVML: Unknown Error"#48](https://github.com/NVIDIA/nvidia-container-toolkit/issues/48)等で広く知られている。そして、その事象は、`systemctl daemon-reload`の実行によって簡単に誘発されることが記されている。また、同記事には「5. Workarounds」で3つの回避方法が提案されている。

1. nvidia-ctkの使用
2. 明示的なsystemd cgroup管理の無効化
3. dockerのダウングレード

今回は、この3つの方法の中、一番容易と思われる2で事態が解消されることを確認した。

以下に事象の発生の確認と回避方法の検証動画を示す。検証には、Dockerコンテナ内での`torch.cuda.is_available()`によるGPUの使用可否で確認した。

### 現象の確認

`systemctl daemon-reload`後、docker内の`torch.cuda.is_available()`が`False`となる。

![wrong.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59920/b79600d2-1049-476f-ae59-d25b9420b278.gif)

### 回避方法の効果確認

`systemctl daemon-reload`後**も**、docker内の`torch.cuda.is_available()`が`True`のまま。

![correct.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59920/d31d7baa-a7d2-4845-bee7-8e9e003fcfaf.gif)

## 注意

今回の回避策の検証では、DockerのCgroup Driverをsystemdからcgroupfsに変更することで実現している。つまり、Docker全体に影響することを意味する。
このため、製品やサービスへの適用する場合には、十分な見極めが必要と思われる。
DeskflowでMacの英数キーをWindowsでもMac風に使う方法

## はじめに

DeskflowでMacのキーボードからWindowsを操作していると、「英数キー」がMacみたいに動かず、Windowsでは二度押しで日本語入力に戻ってしまいます。  

## 解決策

### 1. AutoHotkeyをダウンロードしてインストールする
   - [AutoHotkey公式サイト](https://www.autohotkey.com)から「AutoHotkey」をダウンロードし、インストールしてください。

### 2. AutoHotkeyのスクリプトファイルを作る
   - メモ帳などで新しいファイルを作り、中に下のスクリプトをコピペして保存します。
   - ファイル名の最後は「.ahk」にしてください（例：`mac_ime.ahk`）。

    ```autohotkey
    #Requires AutoHotkey v2.0+
    ; InstallKeybdHook

    IME_SET(mode, winTitle := "A") {
        hwnd := WinExist(winTitle)
        if (hwnd) {
            ptrSize := A_PtrSize
            cbSize := 4 + 4 + (ptrSize * 6) + 16
            stGTI := Buffer(cbSize, 0)
            NumPut("UInt", cbSize, stGTI.Ptr, 0)
            hwnd := DllCall("GetGUIThreadInfo", "UInt", 0, "Ptr", stGTI.Ptr)
                ? NumGet(stGTI.Ptr, 8 + ptrSize, "UInt") : hwnd
        }

        return DllCall("SendMessage"
            , "Ptr", DllCall("imm32\ImmGetDefaultIMEWnd", "Ptr", hwnd, "Ptr")
            , "UInt", 0x0283 ; Message : WM_IME_CONTROL
            , "Int", 0x006   ; wParam  : IMC_SETOPENSTATUS
            , "Int", mode)   ; lParam  : 0 or 1
    }

    ; Deskflow経由macの英数キー
    ; 副作用でwinの全角半角キーがIMEオフの動きになる
    vkF4:: {
        IME_SET(0)
    }
    ```

### 3. スクリプトを起動する
   - 作った「.ahk」ファイルをダブルクリックして実行します。
   - タスクバーに「H」アイコンが表示されればOKです。

## 副作用について

この設定をすると、Windowsの「半角・全角キー」を押した時も必ずIMEがオフになります。  
つまり、日本語入力したい場合は「かなキー」や「変換キー」など、他のキーを使う必要があります。

## 技術的な背景の解説（補足）

なぜこんな設定が必要なの？

- DeskflowでMacの英数キーを押すと、Windows側では「半角・全角キー」として認識されます。
- Windows標準の動作では「半角・全角キー」はIMEのオン・オフが切り替わる「トグル」動作です。
- Macの「英数キー」は押すと**必ず**英数入力（IMEオフ）になるので、操作感が違います。

AutoHotkeyを使うことで、Windows側でもMacと同じように「英数キー」を押したら必ずIMEがオフになる動作にできます。  
ただし、Windowsのキーボードでも同じ設定になるため、副作用として「半角・全角キー」がIMEオフ固定になります。

---

## まとめ

この設定をすれば、DeskflowでMacのキーボードからWindowsを操作するときも、Macと同じ感覚で「英数キー」を使えるようになります。  

---
この記事を書いた過程はこちら

https://qiita.com/mu-zilch_321/items/f3a5d2230ccd0d390758
postで叩かれるはずのルートがgetで叩かれていた謎を解明したので残しておく。

## 問題の概要

APIのコールバック関数で、本来POSTメソッドで呼び出されるはずの処理がGETメソッドで実行され、500エラーが発生する問題に遭遇した。一見すると謎の現象だが、原因を調査すると意外なユーザー行動が関係していた。

## 発生した症状

- APIコールバック処理で500エラーが発生
- 正常に動作する場合と異常な場合が混在
- エラーログを確認すると、POSTで処理されるべき箇所がGETメソッドで実行されている

## 原因の調査

### 初期の仮説
最初は以下のような原因を疑った：
- APIプロバイダー側の仕様変更
- サーバー側のルーティング設定ミス
- リダイレクト処理での変換

### 真の原因
詳細な調査の結果、以下の流れで問題が発生していることが判明：

1. ユーザーがAPIを呼び出し、正常にPOSTでコールバックが実行される
2. **ユーザーがブラウザの戻るボタンを押下**
3. ブラウザが前のページに戻る際、**再度コールバックURLにアクセス**
4. この時、**ブラウザはGETメソッドでアクセス**
5. 古いコードに残っていた検証用のGETルートが実行される
6. 不完全な処理により500エラーが発生

## 技術的な解説

### なぜPOSTがGETに変わるのか

ブラウザの戻るボタンを押した際、以下の動作が発生する：

```
1. 最初のフロー（正常）
POST /api/callback → 正常処理 → リダイレクト → 完了ページ

2. ブラウザバック時のフロー（問題）
完了ページ → [戻るボタン] → GET /api/callback → エラー
```

ブラウザは履歴を辿る際、元のHTTPメソッドを保持せず、GETメソッドでアクセスする仕様になっている。

### 問題のコード例

```javascript
// 古いコード（問題の原因）
app.post('/api/callback', (req, res) => {
  // 正常な処理
  processCallback(req.body);
  res.redirect('/success');
});

// 検証用として残っていたGETルート
app.get('/api/callback', (req, res) => {
  // 不完全な検証処理
  validateCallback(req.query); // ここで500エラー
});
```

## 対処法

### 1. 不要なGETルートの削除
```javascript
// 検証用のGETルートを削除
// app.get('/api/callback', ...); // 削除

app.post('/api/callback', (req, res) => {
  processCallback(req.body);
  res.redirect('/success');
});
```

### 2. GETアクセスへの適切な対応
```javascript
app.get('/api/callback', (req, res) => {
  // 適切なエラーレスポンスまたはリダイレクト
  res.status(405).json({ 
    error: 'Method Not Allowed',
    message: 'This endpoint only accepts POST requests'
  });
});
```

### 3. 冪等性を考慮した設計
```javascript
app.post('/api/callback', (req, res) => {
  const transactionId = req.body.transaction_id;
  
  // 既に処理済みかチェック
  if (isAlreadyProcessed(transactionId)) {
    return res.redirect('/success');
  }
  
  processCallback(req.body);
  markAsProcessed(transactionId);
  res.redirect('/success');
});
```

### 4. フロントエンド側での予防策
```javascript
// ブラウザバックを無効化（必要に応じて）
window.history.pushState(null, null, window.location.href);
window.addEventListener('popstate', function(event) {
  window.history.pushState(null, null, window.location.href);
});
```

## 学んだ教訓

### 1. ユーザー行動の想定
- ユーザーは予期しない操作を行う可能性がある
- ブラウザの基本機能（戻るボタン等）への考慮が必要

### 2. 古いコードの管理
- 検証用やテスト用のコードは適切に削除する
- 不要なルートを残さない

### 3. エラーハンドリングの重要性
- 想定外のHTTPメソッドでのアクセスにも適切に対応
- 明確なエラーメッセージで問題の特定を容易にする

### 4. 冪等性の設計
- 同じ処理が複数回実行されても安全になるよう設計
- 重複処理の検出と適切な処理

## まとめ

APIコールバック処理では、ユーザーのブラウザ操作によって予期しないHTTPメソッドでアクセスされる可能性がある。特にブラウザの戻るボタンによる操作は、POSTリクエストをGETリクエストに変換してしまう。

この問題を防ぐには：
- 不要なルートの削除
- 適切なエラーハンドリング
- 冪等性を考慮した設計
- ユーザー行動の想定
Django のアプリケーションを pudb でデバッグ

# pudb のインストール
pudb と django-pudb3 をインストールする。
```bash:
pip install pudb
pip install django-pudb3
```


# テスト用アプリケーション
テスト用に以下の Web アプリケーションを作成する。

```python:hello/views.py
from django.shortcuts import render
from django.http import JsonResponse

def hello(request):
    print(request)
    obj = {}
    obj['code'] = 0
    obj['message'] = 'hello'
    obj['request'] = {}
    obj['request']['method'] = request.method
    obj['request']['path'] = request.path
    obj['request']['user_agent'] = request.META.get('HTTP_USER_AGENT')

    return JsonResponse(obj, safe=False)
```

# pudb でのデバッグ
## settings.py でのデバッグ設定
以下を追記する。
```python:settings.py
MIDDLEWARE = [
    ...
    'django_pudb.PudbMiddleware',
]

DEBUG_PROPAGETE_EXCEPTIONS = True
```


## アプリケーションへのブレークポイントの埋め込み
アプリケーションのデバッグを開始したい場所に pudb.set_trace() を埋め込む。
```python:hello/views.py
...
import pudb

def hello(request):
    pudb.set_trace() # break point
    print(request)
    obj = {}
    obj['code'] = 0
    ...
```


## アプリケーション実行
以下でアプリケーションを実行する。

```
python manage.py runserver --nothreading
```

アプリケーションを実行するとリクエスト待ちの状態になるため、デバッグしたいアプリケーションにリクエストを送信する。
```bash
curl 'http://127.0.0.1:8000/hello/
```

以下のように break point には * が表示され、これから実行する行には > が表示される。
```python:hello.py
  def hello(request):
 *    pudb.set_trace() # pudb
>     print(request)
      obj = {}
      obj['code'] = 0
      obj['message'] = 'hello'
      obj['request'] = {}
      obj['request']['method'] = request.method
      obj['request']['path'] = request.path
      obj['request']['user_agent'] = request.META.get('HTTP_USER_AGENT')

      return JsonResponse(obj, safe=False)
```

n で行を実行すると、> が次の行に進んでいく。
ctrl-x でソースコードのエリアとコマンドラインのエリアを切り替え、コマンドラインで変数名を入力すると、変数の値を表示することができる。
obj['mesage'] = 'hello' を実行した後には obj には以下の値が設定されている。

```text:
>>> obj
{'code': 0, 'message': 'hello'}
```


# 参考: pudb のコマンド例
| コマンド | 説明 |
| :-- | :-- |
| b | break point:　ブレークポイントの設定 |
| c | continue:　次のブレークポイントまで実行 |
| s | step into the function:　ステップ実行（関数の中に入る） |
| n | next:　次の行へ |
| m | モジュール一覧（import したもののみ） |
| q | 停止 |
| d | Breakpoints 欄でブレークポイントを削除 |
| ctrl-x | エリア切替 |
新卒3年目エンジニアの学習記録：学習16カ月目

# はじめに

エンジニア歴3年目のAKです。
先月に引き続き、今月に個人学習でやっていたことを記録していきます。
**活動記録なので、あまり技術関連で有用な情報はないかもしれません**。。

先月の記事です↓

https://qiita.com/AK_React/items/d4f35d10a090a29399e1

# 学習16か月目にやったこと

### <font color="Red">１．Macで開発環境構築</font>

私用PCをWindowsからMacに刷新したため、ゼロから開発環境構築を行いました。
MacではWSLのような互換環境を構築する必要はないので、Windowsよりもサクサク進みました。（特にDocker）

また、今後の開発作業を快適に行うため、下記も設定しています。

**1. brew**
Mac用のパッケージマネージャーです。
`Homevrew`という単語にも意味が込められているので、ぜひ調べてみてください。

https://brew.sh/ja/

**2. SourceTree**
Gitの操作をGUI上で行えるツールです。
ブランチの樹形図が見やすかったり、cherypickなど間違えやすい操作もボタンひとつでできます。

https://www.sourcetreeapp.com/

### <font color="Red">２．JavaScriptの基礎を振り返る</font>

コーディングは元々苦手意識がありましたが、色んなSEさんとお話をする中で「強い人は基礎が染み付いている」という自分なりの結論に至りました。
ということで、紹介してもらった下記の教材を隙間時間に読んでいます。

今までインプットはほとんどしてきませんでしたが、改めてやってみると「Async FunctionってPromiseを返していたんだ」とか、普段流れがちな気づきを発見できます。

私は一つの物事に関して深く探求するのが苦手なタイプですが、ここは逃げるわけにいかないので継続していきます。

https://jsprimer.net/basic/
# おわりに
今月は環境構築と戦ったり、基礎から学習をやり直したり、仕事も忙しかったり、身内に不幸があって弾丸で帰省したりと、体力的にも精神的にも削られた一ヶ月でした。
**特に、環境構築がうまくいかないって、心が折れる要因TOP3に入ってくる気がします。**
エンジニア3年目じゃなくて3カ月目の間違いじゃないかってくらい気分が落ちていたのですが、**こういうときこそ外のもくもく会に参加しまくったり、周りの人に相談しまくったりしてました**。
**SE何年目になろうが、人を頼れることって結構大切かもしれない**ですね。
Vim コマンド アルファベット順

# はじめに
こちらに、[vimコマンドがアルファベット順に並べられたドキュメント](https://vim-jp.org/vimdoc-ja/vimindex.html)がありますが、  
若干見づらいので自分が見やすい感じでまとめました。    
ヤンクやコピーなどの指定子が必要なものについては別記事を参照してください。  
当方、VSCodeのVim拡張を使用しています。
環境による違いはいい感じに読み替えてください。
気が乗ったらCtrlも載せます


# Vim コマンド 小文字
|コマンド|操作|
|---|---|
|a| カーソルの右端から<font color="red">**インサート**</font>|
|b| 前の単語の先頭へジャンプ|
|c| 指定されたものをカットしつつ<font color="red">**インサート**</font>|
|d| 指定されたものをカット|
|e| 単語の末尾へジャンプ|
|f| f[任意の1文字]で行内の[任意の1文字]へジャンプ|
|g| 指定された場所へジャンプ|
|h| 左移動|
|i| カーソルの左端から<font color="red">**インサート**</font>|
|j| 下移動|
|k| 上移動|
|l| 右移動|
|m| m[任意の1文字]でカーソル位置にジャンプ可能なマークを付ける<br>'[任意の1文字] マークがある行の行頭へジャンプ<br>`[任意の1文字] マークの位置へジャンプ|
|n| 検索時に次の検索結果へ移動|
|o| カーソル位置から下の行を改行して<font color="red">**インサート**</font>|
|p| カーソルの右端 or 下の行にペースト|
|q| マクロを記録する|
|r| r[任意の1文字]でカーソル位置の1文字を置き換え|
|s| カーソルの手前の1文字を削除してから<font color="red">**インサート**</font>|
|t| fの1文字手前版|
|u| undo|
|v| ヴィジュアルモードへ|
|w| 次の単語の先頭へジャンプ|
|x| カーソル位置の1文字を削除|
|y| 指定されたものをヤンク|
|z| z+[指定子]でカーソル位置を画面の任意の位置へ移動|

# Vim コマンド 大文字
|コマンド|操作|
|---|---|
|A| endキーかつ<font color="red">**インサート**</font>|
|B| 小文字と同じ|
|C| カーソル位置～行末をカットしつつ<font color="red">**インサート**</font><br>|
|D| カーソル位置～行末をカット|
|E| 小文字と同じ|
|F| 小文字と逆方向|
|G| 指定行へジャンプ<br>ファイル終端へジャンプ|
|H| 表示領域の一番上へジャンプ|
|I| homeキーかつ<font color="red">**インサート**</font>|
|J| カーソル位置の行と1つ下の行を結合|
|K| manコマンド|
|L| 表示領域の一番下へジャンプ|
|M| 表示領域の真ん中へジャンプ|
|N| 小文字と逆方向|
|O| カーソル位置から上の行を改行して<font color="red">**インサート**</font>|
|P| 小文字と逆方向|
|Q| 旧Exモード(VSCodeでは存在しない？)|
|R| リプレイスモードへ(insキーと同じ動作)|
|S| 1行削除してから<font color="red">**インサート**</font>(ccと同じ動作)|
|T| 小文字と逆方向|
|U| 謎|
|V| ヴィジュアルラインモードへ|
|W| 小文字と同じ|
|X| カーソル位置の1文字手前を削除|
|Y| 行全体ヤンク|
|Z| ZZ = :wq<br>ZQ = :q!|

# 参考文献
[とほほのVim入門](https://www.tohoho-web.com/vim/index.html)  
  
とほほさんには頭上がりません。
【ChatGPT】日本語の言い換え表現を列挙してくれるPromptです。


　どうも、カーブミラーです。

　今回は、日本語の言い換え表現を列挙してくれるPromptです。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　著作権法については
　　こちらを参照するのが
　　　良いのではないかと。

　文化庁レポートをもとにした
　　著作権法についての動画（約20分）
　　　[かいちのAI大学　【警告】ChatGPTの画像生成は危険です...【4o Image Generation】](https://youtu.be/8VLUnG-iyo0?si=rAfjMboqmNqppDGq)
***
　まずは、【ニュース】です。

　ChatGPTのDALL-E3ですが、
　　GPTsのDALL-Eで描画可能でした。

　しかし、
　　一昨日（2025/06/13）くらいから
　　　描画できなくなっています。

　継続しての生成の場合は
　　“現在、画像生成ツール（DALL·E）は
　　　一時的にご利用いただけない
　　　　状態です。”となります。

　また、
　　新規の場合で、
　　　簡単なら
　　　　アスキーアート生成されます。

　　　複雑なら
　　　　さらに細かいことを告げ、
　　　　　“画像生成した”とは言うが
　　　　　　画像は出てこない。

　　　速度からいって
　　　　DALL-E3には
　　　　　送られていないっぽい。

　このまま、
　　DALL-E3は
　　　なくなるのかもしれませんね😭
***
　では、【本題】です。

　今回は、
　　日本語の言い換え表現を
　　　列挙してくれるPromptです。

　“語彙力が足らない”と思っても
　　昨日のテストでは、
　　　全問正解に近い成績を
　　　　得られたかもしれません。

　それでも
　　“語彙力が足らない”感は
　　　あるわけで、
　　　　自分の言いまわしが
　　　　　“場面に合わない”とも
　　　　　　感じているかもしれません｡

　そこで
　　言いまわしを
　　　考えてもらうことにしました。

　　そうすれば、
　　　場面に合う言いまわしが
　　　　見つかるかもしれません。
***
　では、Promptです。
　　使い方は、Promptを送信して、
　　　自分の言いまわしを
　　　　入力送信するだけです。

```Text:日本語の言い換え表現列挙Prompt
あなたは日本語の言い換え表現を提示するアシスタントです。

目的：ユーザーが入力した日本語の文章を、意味を変えずに異なる表現に言い換え、語彙力・表現力を高めること。

制約条件：

ユーザーの入力文の意味や文脈を保ったまま、自然な日本語で3〜5通りの言い換えを提示する。

言い換えは、敬語／カジュアルな表現／書き言葉／話し言葉／文学的表現／簡潔な言い方 など多様にする。

すべての言い換えは箇条書きで、1つずつ文として完結させる。

表現の違いやニュアンスの差が分かるように、必要に応じて簡単な補足を加える。

言い換えに使用した語彙で難しいものがあれば、簡単に意味を説明する。


導入の例：
「文章を言い換えて語彙力を広げましょう。まず、あなたが言い換えたい日本語の文章を入力してください。」

例の出力（ユーザー入力：「彼はとても忙しそうだった。」）：

彼はかなり慌ただしい様子だった。

彼は多忙を極めていたようだ。

忙しさに追われているように見えた。

とても忙しそうにしていたよ。

彼の表情から、余裕のなさが伝わってきた。


言い換え練習を通じて、表現の幅を自然に広げられるよう支援してください。
```

　もちろん、
　　状況次第で
　　　言いまわしは変化します。

　ですので、
　　そこは自力で判断しましょう。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
WordPress の REACT での読み込み時のデバッグをするプログラム

WordPressの拡張プラグインを作っている際に、REACTで管理画面などを作っている時思った通りに動いてくれない場合があり、その場合にデバッグするコードを書いてみました。

```php
/**
 * Debugging function to log detailed information about JSON file handling.
 *
 * This function logs the script source, calculated hash, and checks for the existence of JSON files.
 * It is intended for debugging purposes to understand how WordPress handles JSON files for translations.
 *
 * @since 1.0.0
 */
function wc4jp_detailed_json_debug() {
	global $wp_scripts;

	$handle      = 'custom-script';
	$text_domain = 'custom-domain';
	$locale      = get_locale();

	if ( isset( $wp_scripts->registered[ $handle ] ) ) {
		$script     = $wp_scripts->registered[ $handle ];
		$script_src = $script->src;

		error_log( '=== JSON File Debug ===' );
		error_log( 'Script src: ' . $script_src );

		// WordPressがJSONファイルを探す方法を再現
		$relative_src = str_replace( content_url(), '', $script_src );
		$relative_src = ltrim( $relative_src, '/' );

		// 複数のパターンでハッシュを計算
		$patterns = array(
			$relative_src,
			str_replace( plugin_dir_url( __FILE__ ), '', $script_src ),
			'build/index.js',
			'/build/index.js',
		);

		foreach ( $patterns as $pattern ) {
			$hash          = md5( $pattern );
			$json_filename = "{$text_domain}-{$locale}-{$hash}.json";
			$json_path     = plugin_dir_path( __FILE__ ) . "languages/{$json_filename}";

			error_log( "Pattern: '{$pattern}' -> Hash: {$hash}" );
			error_log( "Looking for: {$json_filename}" );
			error_log( 'File exists: ' . ( file_exists( $json_path ) ? 'YES' : 'NO' ) );

			if ( file_exists( $json_path ) ) {
				error_log( '✓ FOUND: ' . $json_path );
				$content = file_get_contents( $json_path );
				error_log( 'Content preview: ' . substr( $content, 0, 200 ) );
				break;
			}
		}

		// 実際に存在するJSONファイルをリスト
		$existing_files = glob( plugin_dir_path( __FILE__ ) . 'languages/*.json' );
		error_log( 'Existing JSON files: ' . print_r( $existing_files, true ) );
	}
}
add_action( 'admin_enqueue_scripts', 'wc4jp_detailed_json_debug', 999 );
```

これで、エラーログのテキストファイルを見てデバッグしてみてください。
初めてEC2を作成したらAWSからメールが来たけど心配しなくていいらしい

新しく作成したAWSアカウントで初めてEC2インスタンスを作成したら、以下のメールがきた。


```
AWS をご利用のお客様

お客様は、最近追加の検証が必要な AWS のサービスをリクエストしました。
お客様のリクエストは AWS Asia Pacific (Tokyo) リージョンについて検証されました。
引き続き問題が解決しない場合は、サポートセンターよりご連絡ください

（中略）

Dear AWS Customer,

You recently requested an AWS service that required additional validation.
Your request has now been validated for AWS Asia Pacific (Tokyo) Region(s). 
If you're still experiencing difficulty, then contact us through the Support Center

```

そのリージョンで初めてEC2インスタンスを起動したときに送られてくるメールらしく
気にしなくてOKとのこと。
Windows で Docker Desktop その4

[Windows で Docker Desktop その3](https://qiita.com/intrajp/items/1662cc0405b9eab87d40)の続きです。

Pod 内で ps コマンドを実行してみます。
```
PS C:\Users\xxx\TKB\pods> kubectl exec hello-pod -- ps
PID   USER     TIME  COMMAND
    1 root      0:00 {MainThread} node ./app.js
   17 root      0:00 ps
```

Pod 内で curl コマンドを実行してみます。

```
PS C:\Users\xxx\TKB\pods> kubectl exec hello-pod -- curl localhost:8080
error: Internal error occurred: Internal error occurred: error executing command in container: failed to exec in container: failed to start exec "e440f1c581cc30c53d75a166f978d6d0fb1894477fa4009df450b5b3899ed8af": OCI runtime exec failed: exec failed: unable to start container process: exec: "curl": executable file not found in $PATH: unknown
```
sh コマンドならどうでしょうか。

```
PS C:\Users\xxx\TKB\pods> kubectl exec -it hello-pod -- sh
/src #
```

この Pod の Alpine Linux に curl パッケージを追加して、また実行してみます。

```
/src # cat /etc/*release*
3.21.3
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.21.3
PRETTY_NAME="Alpine Linux v3.21"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

/src # apk add curl
fetch https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.21/community/x86_64/APKINDEX.tar.gz
(1/9) Installing brotli-libs (1.1.0-r2)
(2/9) Installing c-ares (1.34.5-r0)
(3/9) Installing libunistring (1.2-r0)
(4/9) Installing libidn2 (2.3.7-r0)
(5/9) Installing nghttp2-libs (1.64.0-r0)
(6/9) Installing libpsl (0.21.5-r3)
(7/9) Installing zstd-libs (1.5.6-r2)
(8/9) Installing libcurl (8.12.1-r1)
(9/9) Installing curl (8.12.1-r1)
Executing busybox-1.37.0-r12.trigger
OK: 14 MiB in 26 packages

/src # curl localhost:8080
<html><head><title>K8s rocks</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"/></head><body><div class="container"><div class="jumbotron"><h1 style="text-align:center;">Kubernetes rocks!</h1><p style="text-align:center;">Check out my AI book.</p><p style="text-align:center;">          <a class="btn btn-primary" href="https://www.amazon.com/dp/1916585388">AI Explained: Facts, Fiction, and Future</a></p></div></div></body></html>/src #
```

今度は実行できました。

env コマンドを実行してみます。
```
/src # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
NODE_VERSION=23.8.0
HOSTNAME=hello-pod
YARN_VERSION=1.22.22
SHLVL=1
HOME=/root
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
/src # exit
PS C:\Users\xxx\TKB\pods>
```
[Windows で Docker Desktop その5](https://qiita.com/intrajp/items/e8f1e658ab9f0823ee76)に続く。

参考文献

Poulton, N. (2025). The kubernetes book (2025 ed.). Nigel Poulton.
ABC410回答メモ

# 0.はじめに
　先週は久々にDまで正解できましたが、今週は・・・。
　Ａ～Ｃは順調に正解できましたが、Ｄでブレーキ。
　Ｅもちょっと難しく、Ｄがなんとかならないかと
　いろいろ小細工しましたが正答には結びつかず時間終了。
　解説を見てもＤが解ける未来は見えませんでした。
　ただ、レートは+15の736と上向きでした。


# 1. A - G1
　リストを先頭から見ていき、リストの値がK以上である数をカウントし
　最後にカウントした数を出力して終了でACでした。

　https://atcoder.jp/contests/abc410/submissions/66721409


# 2.B - Reverse Proxy
　ややこしいけど、B問題らしく制約がゆるいので
　Xが0の時は箱の中での最小値を単純に求め、その値と同じ箱且つ、先頭に近い箱に
　ボールを入れるよう、効率を考えずに実装。
　【実装】
　　1.箱の状態を保持するリストB(N項目)を用意。最初は全項目０。
　　　合わせて回答用リストansを空で用意
　　2.以下Q回繰り返し(index-i)
　　　-1.X[i]が0の時
　　　　-1.変数LにＢの最小値をセット
　　　　-2.Ｂを先頭から見ていき(index-j)
　　　　　 B[j]がＬと同じ時、B[j]に1を加算し、ansにｊ+1を追加
　　　　　 →2-1-1のループを抜ける
　　　-2.X[i]が0以外の時
　　　　　 -1.B[X[i]-1]に1を加算し、ansにX[i]を追加
　　3.最後にansを出力して終了

　https://atcoder.jp/contests/abc410/submissions/66729549


# 3.C - Rotatable Array
　C問題なので、単純に列を循環させると時間切れになりそうなので
　一工夫。
　正数列Aはそのままずっと保持し、先頭の位置のみずらすようにしました。
　タイプ3の時、正数列は循環させず先頭の位置をずらすようにしました。
　タイプ１，2の時も、先頭の位置をずらす前提で、値を変更したり
　ひょじすることにより、時間を掛けずに問題を解くことができました。

　https://atcoder.jp/contests/abc410/submissions/66735800



以上
ミニPCでmicrok8sクラスタ

## 環境
* MAASサーバ
    * IP：192.168.100.50
* node1
    * OS：Ubuntu24.04
    * IP：192.168.100.8
* node2
    * OS：Ubuntu24.04
    * IP：192.168.100.9

## （不要）dockerのインストール
```sh
sudo snap install docker

# docker実行権限付与
sudo addgroup --system docker
sudo adduser $USER docker
```

## microk8sのインストール
```sh
sudo snap install microk8s

# 起動
sudo microk8s start
```
これを２台のサーバーで実行

## クラスタの作成
node1に参加させるためのコマンドを確認します
```sh
sudo microk8s.add-node
```
以下のように出力されるはず
```sh
From the node you wish to join to this cluster, run the following:
microk8s join 192.168.100.8:25000/3039a88b56eaa8aa4b37fcc6ee281bdf/f8d2731d0c54

Use the '--worker' flag to join a node as a worker not running the control plane, eg:
microk8s join 192.168.100.8:25000/3039a88b56eaa8aa4b37fcc6ee281bdf/f8d2731d0c54 --worker
```

node2でクラスタに参加します
```sh
microk8s join 192.168.100.8:25000/3039a88b56eaa8aa4b37fcc6ee281bdf/f8d2731d0c54
```
少し待つと，
Successfully joined the cluster.
と出力されてクラスタに参加できました

```sh
# エイリアス作成
sudo snap alias microk8s.kubectl kubectl

sudo microk8s.kubectl get nodes
```
とコマンドを打って確認すると
```sh
NAME    STATUS   ROLES    AGE   VERSION
node1   Ready    <none>   15m   v1.32.3
node2   Ready    <none>   77s   v1.32.3
```
しっかりノードが登録されていますね

## argoCDインストール
```
#　ネームスペースの作成
sudo kubectl create namespace argocd

# 公式マニフェストでデプロイ
sudo kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# サービスポート確認
sudo kubectl get svc argocd-server -n argocd

# パスワード確認
sudo kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
```

## 参考
* https://devops-blog.virtualtech.jp/entry/20220322/1647924202
OpenCVとONNXRuntimeを用いるためのC++環境構築

## Xcodeコマンドラインツールのインストール
C++コンパイラ（Clang）やGitなどの基本的な開発ツールをインストール
```
xcode-select --install
```
## Homebrewのインストール
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
Apple Silicon（M1/M2など）では /opt/homebrew、Intel Mac では /usr/local にインストールされる。
## CMakeのインストール
```
brew install cmake
```
CMakeはクロスプラットフォームなビルドツールでプロジェクト管理に使用

## OpenCVのインストール
```
brew install opencv
```
## ONNX Runtimeのインストール
```
brew install onnxruntime
```

これでうまくいかなかった場合はプロジェクトディレクトリに移動し、手動でインストール

```sh
# macOS ARM64用ONNX Runtimeをダウンロード（M1/M2/M3 Mac用）
curl -L -o onnxruntime-osx-arm64-1.16.3.tgz \
  https://github.com/microsoft/onnxruntime/releases/download/v1.16.3/onnxruntime-osx-arm64-1.16.3.tgz

# 解凍
tar -xzf onnxruntime-osx-arm64-1.16.3.tgz

# onnxruntimeという名前でシンボリックリンクを作成
ln -sf onnxruntime-osx-arm64-1.16.3 onnxruntime

# 構造を確認
ls -la onnxruntime/include/
```

Intel Macの場合は以下
```sh
# Intel Mac用
curl -L -o onnxruntime-osx-x86_64-1.16.3.tgz \
  https://github.com/microsoft/onnxruntime/releases/download/v1.16.3/onnxruntime-osx-x86_64-1.16.3.tgz

tar -xzf onnxruntime-osx-x86_64-1.16.3.tgz
ln -sf onnxruntime-osx-x86_64-1.16.3 onnxruntime
```
## IDEやエディタのインストール
VSCodeやCLionなど用途に合わせて選択。Xcodeも利用可能。

## プロジェクトディレクトリ作成
```
mkdir MyApp && cd MyApp
mkdir src include build
touch src/main.cpp CMakeLists.txt
```

## CMakeLists.txtに以下の記述をする
```cmake
cmake_minimum_required(VERSION 3.20)
project(MyApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)

# OpenCV
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

# ONNX Runtime - 手動指定
set(ONNXRUNTIME_DIR "/opt/homebrew/opt/onnxruntime")
include_directories(${ONNXRUNTIME_DIR}/include)
link_directories(${ONNXRUNTIME_DIR}/lib)

add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp PRIVATE ${OpenCV_LIBS} onnxruntime)
```
/opt/homebrew は Apple Silicon Mac のパスです。Intel Mac の場合は /usr/local/opt に置き換えてください。


## src/main.cppに以下のテストコードを記載
```cpp
#include <opencv2/opencv.hpp>

int main() {
    cv::Mat img = cv::imread("test.jpg");
    cv::imshow("表示テスト", img);
    cv::waitKey(0);
    return 0;
}
```

## CMakeビルド実行
```sh
cd build
cmake ..
make
```
## vcpkgによる依存関係管理
```sh
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh # macOS/Linux
./vcpkg install onnxruntime opencv4
```

## CMakeにvcpkgのパスを教える
cmake .. -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake


```cmake
cmake_minimum_required(VERSION 3.14)
project(MyApp)

# vcpkg経由でOpenCVを探す
find_package(OpenCV REQUIRED)

# ONNX Runtimeは手動でインクルードとリンクパスを指定
set(ONNX_DIR "/path/to/onnxruntime")

include_directories(${ONNX_DIR}/include)
link_directories(${ONNX_DIR}/lib)

add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE ${OpenCV_LIBS} onnxruntime)
```
vcpkgがパスを通してくれるため手動のOpenCV_DIRなどの設定が不要になる


# 今後
CVPKG_ROOTを環境変数に設定しておくことでCMakeのオプションを書く必要がなくなる
```
export VCPKG_ROOT=/path/to/vcpkg
```
~/.zshrcなどに記載しておくと便利

プロジェクトルートにvcpkg.jsonを置くとチーム開発がしやすくなる。
例
```json
{
  "name": "myapp",
  "version-string": "0.1.0",
  "dependencies": [
    "opencv",
    "onnxruntime"
  ]
}
```
この後に
```sh
vcpkg install
```
はじめてのCAD入門

# はじめてのCAD入門  

## 目次
1. [CADってなんだ？](#cadってなんだ)
2. [CADの歩み](#cadの歩み)
3. [2Dと3D、どっちがどっち？](#2dと3dどっちがどっち)
4. [CADソフトでできること](#cadソフトでできること)  
   1. スケッチ＆ドラフティング  
   2. モデリング  
   3. アセンブリ  
   4. 図面化  
   5. 解析  
   6. データ管理  
5. [代表的なCADソフト](#代表的なcadソフト)
6. [ファイル形式の話](#ファイル形式の話)
7. [CADを使うメリット](#cadを使うメリット)
8. [上達へのロードマップ](#上達へのロードマップ)
9. [まとめ](#まとめ)

---

## CADってなんだ？
CAD は “Computer-Aided Design” の略である。  
ざっくり言えば「設計を PC でやっちゃおうぜ」というツール群だ。  
手描きの図面より **正確**、**速い**、**直せる** ― これが強み。  
建築・機械・電気・土木・アパレル… とにかくモノづくり系ほぼ全部で使われている。

### 何が嬉しい？
- **精度**がバチっと決まる → 寸法ミスが減る。  
- **時間**が短くなる → テンプレやコピペで爆速修正。  
- **データ連携**が楽 → 解析ソフトや製造ラインとそのままつながる。

---

## CADの歩み
| 年代 | トピック |
| ---- | -------- |
| 1960s | MIT の **Sketchpad** が「最古の CAD」として登場。|
| 1980s | PC 向け 2D CAD（AutoCAD など）が広まり始める。|
| 1990s | 3D ソリッドモデリングが本格化（Pro/ENGINEER, SolidWorks ほか）。|
| 2000s | CAE/CAM と統合、クラウドの芽が出る。|
| 2010s | サブスク型＆リアルタイム共同編集が当たり前に。|

---

## 2Dと3D、どっちがどっち？
| 項目 | 2D CAD | 3D CAD |
| ---- | ------ | ------ |
| 表現 | 平面・断面の線画 | 立体モデル＋材質情報 |
| メリット | 学びやすい／軽い | 直感的／解析や CAM が楽 |
| デメリット | 立体感が伝わりにくい | PC スペック要求↑／習得コスト↑ |
| 主な用途 | 建築平面図・配線図 | 機械部品・BIM・家電デザイン |

---

## CADソフトでできること

### スケッチ＆ドラフティング
線・円・矩形などを寸法拘束付きで描く。修正しても寸法が自動調整されるのでラク。

### モデリング
- **ソリッド**: 押し出しとかで“肉厚”のある形を作る。  
- **サーフェス**: 自由曲面をグニャッと。車のボディとか。  
- **パラメトリック**: 寸法を数式で管理、あとから値を変えてもモデルが追随。

### アセンブリ
複数部品を組み付け、ジョイント拘束で動きを確認。干渉チェックもここでやる。

### 図面化
3D から投影図・断面図を自動生成 → 寸法・注記・部品表（BOM）を載せて完成。

### 解析
構造(FEM)、流体(CFD)、熱… 試作前に強度や流れをシミュレーション。

### データ管理
PDM/PLM とつながり、バージョンや権限を一元管理。チーム設計には不可欠。

---

## 代表的なCADソフト
| 分野 | 2D | 3D |
| ---- | --- | --- |
| 汎用 | AutoCAD, DraftSight | SolidWorks, Inventor, Fusion 360 |
| 機械 | — | CATIA, Creo, Siemens NX |
| 建築 | AutoCAD LT, JW-CAD | Revit, Archicad, Vectorworks |
| 無償/OSS | LibreCAD | FreeCAD, Blender(モデリング用途) |

> 💡 **クラウド派** は Fusion 360 や Onshape が手軽でコラボ向き。

---

## ファイル形式の話
- **DWG/DXF**: AutoCAD 系の鉄板フォーマット。  
- **STEP (ISO 10303)**: CAD 間の共通語。中立で安心。  
- **IGES**: ちょっと古いけど曲面保持に強い。  
- **STL**: 3D プリンタ用メッシュ。寸法は持たないので注意。  
- **ネイティブ**: SolidWorks なら *.sldprt 等、ソフト固有の形式。

---

## CADを使うメリット
1. **品質↑** - 解析で事前にミス潰し。  
2. **リードタイム↓** - パーツ流用＆パラメトリック修正で手戻り激減。  
3. **コスト↓** - 試作を減らし材料ムダもカット。  
4. **連携◎** - 製造・購買・営業が同じデータを見て話が早い。

---

## 上達へのロードマップ
1. **操作慣れ**: マウス・ビュー操作＆簡単スケッチ。  
2. **チュートリアル**: 公式サンプルで部品を作る。  
3. **小型プロジェクト**: 実機に近いモノをまるっと設計。  
4. **解析＆図面**: CAE→図面まで一気通貫。  
5. **ベストプラクティス**: 命名規則や履歴構成で“変更に強い”モデルに。

> 🚀 **ポイント**: “速さ”より“後から直せる構造”を優先すべし。

---

## まとめ
CAD は今や設計の必需品である。  
2D から 3D、オンプレからクラウドへと進化し続け、解析や製造ともシームレスにつながる。
まずは無償版や学習ライセンスで触り、自分のペースでスキルを積み上げよう。
「描いて終わり」じゃなく「変更に強いモデル」を意識すれば、実務でもガンガン活躍できるはずだ。
Claude Code インストール時にnodenvで苦しめられた話

Claude Codeをインストールしたはずなのに、`claude`コマンドが見つからないエラーに遭遇した話を備忘録として残しておきます。

## 問題の発生

### Claude Codeのインストール
公式手順に従って npm でグローバルインストールを実行：

```zsh
$ npm install -g @anthropic-ai/claude-code
```

### 問題発生
インストール後にコマンドを実行しようとするとエラー：

```zsh
$ claude
zsh: command not found: claude
```

公式手順通りにやったのに上手くいかない...なぜ？

## 原因と解決方法

### 原因
**nodenvを使用している環境では、グローバルパッケージをインストールした後に追加の手順が必要**

nodenvは「shims」という仕組みでコマンドを管理しているため、新しくインストールされたコマンドを認識させるために「rehash」が必要です。

### 解決方法
```zsh
$ nodenv rehash
```

### トラブルシューティング
もし以下のエラーが出た場合：
```
nodenv: cannot rehash: /Users/<user>/.nodenv/shims/.nodenv-shim exists
```

次のコマンドでshimsディレクトリを再作成：
```zsh
$ rm -rf ~/.nodenv/shims
$ nodenv rehash
```

### 動作確認
```zsh
$ claude --version
1.0.24 (Claude Code)
```

## nodenvのshimsとは？

### 公式説明（和訳）
> nodenvは、シムと呼ばれるディレクトリをPATHの先頭に挿入することで動作します：
> `~/.nodenv/shims:/usr/local/bin:/usr/bin:/bin`
> 
> 「リハッシング」と呼ばれるプロセスを通じて、nodenvはそのディレクトリ内に、インストールされているすべてのNodeバージョンにわたるすべてのNodeコマンド（node、npmなど）に対応するシムを維持します。

### 動作の流れ
1. `npm install -g @anthropic-ai/claude-code` でパッケージをインストール
2. **この時点では、shimsディレクトリに`claude`コマンドは存在しない**
3. `nodenv rehash` を実行
4. shimsディレクトリに`claude`用の実行ファイルが作成される

### 確認方法
rehash後、shimsディレクトリを確認すると：
```zsh
$ ls ~/.nodenv/shims
claude   node   npm   npx   ...
```

### shimの中身（参考）
`~/.nodenv/shims/claude`の内容例：
```bash
#!/usr/bin/env bash
set -e
[ -n "$NODENV_DEBUG" ] && set -x
program="${0##*/}"
if [ "$program" = "node" ]; then
  for arg; do
    case "$arg" in
    -e* | -- ) break ;;
    */* )
      if [ -f "$arg" ]; then
        export NODENV_DIR="${arg%/*}"
        break
      fi
      ;;
    esac
  done
fi
export NODENV_ROOT="/Users/<user>/.nodenv"
exec "/opt/homebrew/bin/nodenv" exec "$program" "$@"
```

## まとめ

**nodenv環境でnpmグローバルパッケージをインストールした場合は、必ず`nodenv rehash`を実行する**が必要ですね〜。勉強になりました。