OmniAICreator/Qiita-1.07M huggingface dataset:
Tips：jinja2 で dict 内の文字列を ダブルクォーテーションで出力する

# jinja2 で dict 内の文字列を ダブルクォーテーションで出力する

jinja2 で `{"apple": 1, "banana": 2}` といった dict を出力したら `{'apple': 1, 'banana': 2}` というシングルクォーテーションで出力されてしまったので，ダブルで出力する方法を調べました．

モノによっては yaml のパースやその後の処理でシングルクォーテーションだと失敗したりします．
私の場合，nuclio で怒られました．

## 解決策
template の j2 ファイル内の置き換える部分に ` | tojson `を追加したらいけました．

## 具体例
### シングルクォーテーション

* template.j2
    ```plaintext
    item: {{ content }}
    ```
* replace.py
    ```python
    from jinja2 import Environment, FileSystemLoader
    
    # テンプレートファイルのあるディレクトリを指定
    env = Environment(loader=FileSystemLoader('./'))
    template = env.get_template('template.j2')
    
    # データを渡してレンダリング
    data = {
        "content": 
        [
            {
                "apple": 1, 
                "banana": 2,
            }
        ]
    }
    output = template.render(data)
    
    with open("output.yaml", "w") as f:
        print(output, file=f)
    ```
* 結果
    ```yaml
    item: [{'apple': 1, 'banana': 2}]
    ```
シングルクォーテーションになっちゃう．

### ダブルクォーテーション
`| tojson` を入れる．
* template.j2
    ```plaintext
    item: {{ content | tojson }}
    ```
* 結果
    ```yaml
    item: [{"apple": 1, "banana": 2}]
    ```
ダブルクォーテーションで出力できた．
【Gradio】画像生成

graidoを使用して簡単にWebアプリを作成できるらしいので、作成してみました。

環境
・Windows10
・Docker(Ubuntu)
・Python3.11
・visual stadio code

# ■事前準備
・gradioのインストール
　pip install gradio

・画像生成
　APIはgemini-2.0-flash（無料）を使用
 
# ■API共通部品作成
APIキーを設定
```
# API-KEYの設定
GOOGLE_API_KEY='取得したAPIキー'
client = cenaiC.Client(api_key=GOOGLE_API_KEY)
```

プロンプトを指示して、所定のフォルダに保存する
```
from google import genai
from google.genai import types
from PIL import Image
from io import BytesIO
import base64

# 画像出力
def getGenerateImage(text):

    contents = text

    # ファイルパスの設定
    path = 'image/gemini-generate' + Util.getDate('YYYYMMDD HHMMSS') + '.png'

    # 画像生成
    response = client.models.generate_content(
        model="gemini-2.0-flash-exp-image-generation",
        contents=contents,
        config=types.GenerateContentConfig(
        response_modalities=['TEXT', 'IMAGE']
        )
    )

    for part in response.candidates[0].content.parts:
        if part.text is not None:
            print(part.text)
        elif part.inline_data is not None:
            image = Image.open(BytesIO((part.inline_data.data)))
            image.save(path)
    
    return path
```


# メイン処理
```
# 画像生成（複数）
def generateImageSeq(text):

    list = []
    prompt = text

    # 指定回数描画（固定指定ですが。。)
    for i in range(5):
        path = utilG.getGenerateImage(prompt)
        list.append(path)    

    return list

# インターフェースの作成
# fn: 実行する関数
# inputs: 入力のコンポーネントの種類
# outputs: 出力のコンポーネントの種類
with gr.Blocks() as demo:
    with gr.Row():
        input_text = gr.Textbox()
        button = gr.Button("execute", scale=1)
        imageList = []
        for i in range(5):
            # 出力用の箱を５つ用意
            imageList.append(gr.Image())
            
    # 出力には出力した画像のパス一覧
    button.click(generateImageSeq, inputs=input_text, outputs=imageList)
    # Web UIの起動

# 画面起動
demo.launch()
```

ローカルホストにあくせす


![gradio.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253940/2bd2a5e8-7770-4c55-a8bc-8b85703fabcf.png)

# 起動結果
![ca.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253940/b9fa0480-9060-4726-8f6c-2c64804a0c96.png)

# 終わりに
簡単に画像生成結果をWebアプリに表示することができました。
Gradioには他のメディアにも対応しているようなので
色々試せそうです。
DataFamTokyo参加記録

# DataFamTokyoとは
Salesforceが主催するTableauの日本最大のオフラインイベント。

https://datafam-tokyo.salesforce-event.jp/public/application/add/32

オンサイトでのこの規模のイベントはなんと6年ぶりとのこと。イベントの模様を備忘もかねてまとめていきます。

# 総論
datafamとはTableauコミュニティを表す言葉なのですが、その名の通りコミュニティにしっかりフォーカスした内容でとても嬉しかったです。Keynoteの冒頭のコミュニティリーダーへのフィーチャーがありましたし(TCっぽくて凄くいいなと思いました。)、コミュニティメンバーの登壇もありました。Theaterではコミュニティメンバーによる多様なセッションが用意されていました（ほとんど満席で立ち見も出てたはず）。また後述しますがクロージングセッションでもコミュニティで素晴らしいVizを量産しているChasosoさん、Okamotoさんが作成したVizをもとに専門家が議論するという素晴らしいセッションもありました。

# Tableau Nextについて
Tableau Conference 2025に引き続きTableau Nextの話は注目を集めていました。日本語でのデモもありましたし6月には日本語対応がリリースされるとの発表もありより身近になったと思います。とはいえSalesfroceの利用が必要なので利用ハードルは高いですが。

Tableau NextはエージェントAI時代のBIツールということもありエージェント開発のスキルが求められるなと感じました。ダッシュボード構築とは異なるスキルなので、エージェント開発人材の育成というのは次の時代の課題になりそうです。

NTTデータさんのセッションではTableau NextおよびAgentforceのデモがあったのですが活用イメージがわく素晴らしいデモでした。特にAgentforceのデモは素晴らしい出来で、自前で開発されたとのこと。業務要件に合わせてエージェントを開発するのは一筋縄では行かなさそうなのでデータ整備も含めて専門的なスキル領域になりそうですね。

# なんと言っても大盛況でした
個別に興味深い中身はたくさんあったのですが参加人数の多さに驚きました。登録自体は2200くらいあったらしいので注目度の高さが伺えます。Tableau Conferenceでも8000登録くらいだったはず。ブースエリアも身動き取りづらいくらい人でごった返していましたし、ほぼ全てのセッションが満席近く人が入っていた気がします。

# セッション内容について

## Keynote
これはTCの内容とほぼ同じでした。でも日本語で聞けるのはありがたいです。事例もKDDIさんが登壇してくださりより身近に感じられました。Pulseはやっぱり便利そうですね。うちはServerなので使えてませんがプライベートで使ってみようと思います。

## パーソルさんのTableauを選んだ理由
データマネジメントを非エンジニアで回していくためにTableauが最適だったとのこと。様々なBIツールを使ってきたパーソルさんが選んだとのは大きな意味がある。

以下のポストで詳細を実況しています。

https://x.com/unbosoms/status/1927221840461676998?s=46

## Snowflake x AI x BI
tomoさんによるSnowflakeでのAIとBIの活用デモ。SnowflakeであればLLMの契約も不要でSQLに簡易な関数を入れるだけでLLMを使えるとのこと。これはすごい。TableauのカスタムSQLで呼び出すこともできるし、Slackのチャットボットを作ることもできるということで可能性を感じました。

以下のポストで詳細を実況しています。

https://x.com/unbosoms/status/1927236155088519421?s=46

## NRIさんの埋め込み分析事例
金融機関向けのダッシュボードを埋め込みライセンスで提供しているとんこと。自社サービスよりも使い勝手の良いダッシュボードを構築できてサービスの黒字化も達成しているとのこと。でも黒字化まで3年かかったというのは生々しく粘り強い取り組みを感じました。

以下のポストで詳細を実況しています。

https://x.com/unbosoms/status/1927252144551240125?s=46

## NTTデータさんのTableau Next & Agentforce

さすがデータさんと言える作り込まれたデモに引き込まれました。総論で書いた通りダッシュボード構築とは異なるスキルセットが求められそうです。もちろんデータをどう活用するかを決めるという共通部分はあると思いますが、UIがダッシュボードからチャットになるし、エージェントの調教という新しいスキルが求められるのは大きな違いですね。プロンプトエンジニアリングの重要性がエージェントAIの登場でますます高まる気がします。

以下のポストで詳細を実況しています。

https://x.com/unbosoms/status/1927266383445819631?s=46

## Tableauで解明！宇宙の謎と地球の未来

めちゃめちゃ面白かったです！一番興奮したセッションでした。テーマも小惑星の衝突確率というスケールの大きな話で興味深かったです。でもなにより専門家が用意したデータを特に前情報なく可視化してきたChasosoさんとOkamotoさんのデータ読み取りスキル、データ可視化スキルが凄まじく素晴らしいし、そのVizを下に専門家である兵頭さん竹内さんが詳しい解説や感想を述べてくれるという、Vizスペシャリスト×その分野の専門家という最高に贅沢な内容のセッションでした。

以下のポストで詳細を実況しています。
※兵頭先生のことを兵藤先生と書いちゃってます。すみません…

https://x.com/unbosoms/status/1927282934995632356?s=46

# おわりに
参加して本当によかったです！セッションからの学びも多かったですし、会場でいろんな人と情報交換できたのもよかった。最後には最高に面白いセッションで可視化の価値を再認識できました。Viz作りたくなりました。素晴らしいイベントに感謝！
AIに "視覚" を与える話題のAI搭載IDE用拡張機能「Stagewise」を使ってみた！

# はじめに
最近よく目に入ってくる **Stagewise** を実際に触ってみました！
この記事では、Stagewiseの大まかな概要、導入方法、使い方について解説します！

# Stagewiseって？

**Stagewise**は **AI搭載のコードエディタに「視覚」を提供する** 拡張機能です。
具体的には、フロントエンドのUIをコードAIエージェントに接続します。

## できること
ざっくりできることについて解説します！

Stagewiseを用いてフロントエンドUIをAIコードエディタに接続すると以下のようなことが可能になります。


- **ブラウザ上で要素を選択し、それに対してコードAIエージェントに指示が出せる**
- **AIエージェントにリアルタイムなコンテキスト（情報)** を提供できる
    - コンテキストには**DOM要素**、**スクリーンショット**、**メタデータ**など、豊富な情報が含まれる

上記のことから、**Stagewise** は開発者がAIを活用したコーディング体験を**向上**させ、AIによるコーディングワークフローを強化することができます！

# StagewiseをCursorに導入する
ここからは実際に**Stagewise**を**Cursor**に導入していきます！

## Cursorに拡張機能をインストール
まずはCursorの拡張機能をインストールします。
検索窓に **Stagewise**と検索すると出てきます。[こちら](https://marketplace.visualstudio.com/items?itemName=stagewise.stagewise-vscode-extension)からでもインストールできます。

![スクリーンショット 2025-05-27 8.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/9137c05b-d542-43cd-89a8-10e056c74a57.png)

## Stagewiseのセットアップ
Macの方は `cmd + shift + P`、　windowsの方は`controll + shift + P`でコマンドパレットを開いてください。
そこに **stagewise**と打つと、「Auto-setup the stagewise toolbar」というコマンドが出てくるのでそちらをクリックしてください。
![スクリーンショット 2025-05-27 8.13.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/a16687d4-f92e-454c-9911-5902ec62d2e2.png)

クリックすると、`Cursor Chat`にプロンプトが自動的に入ります。
自動的に入れられたプロンプトをもとに`Agentモード`でセットアップをしてくれます！
![スクリーンショット 2025-05-27 8.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/7afc5f46-7ef9-41b2-89a5-ff3a5a9a1cf4.png)

セットアップでは、以下が行われます（Next.jsプロジェクトの場合）

1. パッケージインストール: @stagewise/toolbar-nextをnpmでインストール
2. コンポーネント作成: components/stagewise-toolbar.tsxに開発環境専用のラッパーコンポーネントを作成
3. レイアウト統合: ルートレイアウトにStagewiseToolbarを追加

![スクリーンショット 2025-05-27 8.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/b72347ef-9fbf-4f18-b857-07dfcb1487e4.png)

これでセットアップは完了となります！

# 実際に触ってみる
開発画面には以下のようにセットアップ時に作成された`StagewiseToolbar`が表示されます。
ここにプロンプトを入力し、UIに対して変更を加えることになります！

![スクリーンショット 2025-05-27 22.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/bbfee00b-e202-4556-9d85-14a8b427a160.png)

## 実際の画面
![stagewise.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/dfdcf058-2da3-425d-9102-a7f4cd2a369d.gif)

操作については以下です！

1. 上記の動画のように、画面内から変更したい要素を選択し、選択した要素に対してプロンプトを入力します。
2. 送信ボタンを押すとCursorの`Chat`に自動的に最適化されたプロンプトが入力状態になりCursorのAIエージェントに指示を投げられます！

## 触ってみた感想
Stagewiseでは画面から直接要素を選択して指示を出すかなり直感的な操作で簡単にも関わらず、具体的な情報（DOM要素など）をコンテキストに含められるので出力もかなり安定する気がします:clap:

UIに対しての具体的な指示は言語化がかなりめんどくさいですが、Stagewiseでは「**これ**をこうやって！」と対面で人に指示を出すような感覚で行えるのが良いですね！



# まとめ

本記事では、AI搭載コードエディタに「視覚」を提供し、フロントエンドUIをAIエージェントに接続する拡張機能 **Stagewise** について簡単に解説しました！

**Stagewise** を利用することで、開発者はブラウザ上で要素を選択し、それに対する指示を直接AIエージェントに出すことが可能になります。
また、DOM要素やスクリーンショットといったリアルタイムなコンテキストをAIに提供することで、より精度の高いコーディング支援が期待できるのでぜひCursorやWindsurfを利用している方は使ってみてはいかがでしょうか！

# 関連
https://stagewise.io/docs
RHEL/CentOS の基本的な設定：ユーザ・グループ管理

RHEL/CentOSの基本的な設定 TOP

# ページ概要
RHEL/CentOSのユーザ・グループの管理について、基本的な操作・確認方法についてまとめます。

# ユーザ設定・管理

- 設定はroot権限が必要
- 権限やグループの設定は、再ログイン後に反映される

## ユーザ・グループの確認

- **ユーザ一覧(passwd)**

  ```
  # cat /etc/passwd
  ```
<br>

- **グループ一覧(group)**

  ```
  # cat /etc/group
  ```
<br>


- **シャドーファイル**

  ```
  # cat /etc/shadow
  ```
<br>


- **カレントユーザ**

  ```
  # whoami
  # id
  ```
<br>


- **カレントグループ**

  ```
  # groups
  # id
  ```
<br>


- **ログイン中のユーザ**

  ```
  # who
  ```



## user設定

- **ユーザ作成**

  - グループを指定する場合は事前にグループを作成する必要がある</span>
  - ユーザ名以外はオプション
  ```
  # useradd -u UID -g GID -m ユーザ名
  ```
<br>


- **ユーザをサブグループに追加**
  ```
  # usermod -aG グループ名 ユーザ名
  ```
<br>


- **ユーザのサブグループを削除**
  ```
  # gpasswd -d ユーザ名 グループ名
  ```
<br>


- **ユーザを削除**
  ```
  # userdel -r ユーザ名
  ```
  - オプション -r：ホームディレクトリも削除
  - ユーザ削除後に所属するユーザが1つもなくなったグループは勝手に消える



## パスワード変更

```
# passwd ユーザ名
```



## group設定
- **グループ作成**
  ```
  # groupadd -g 指定GID グループ名
  ```
<br>

- **グループ削除**
  ```
  # groupdel グループ名
  ```
VSCodeでVue 3 + Viteをブレークポイント付きでデバッグする方法【Debugger for Chrome不要】

## はじめに

Vue 3 + Vite で開発していて、
「ブレークポイントで止めたい」「`console.log()` が表示されない」と困ったことはないでしょうか。

この記事では、**VSCodeの標準デバッガーを使って Vue 3 + Vite アプリをデバッグする方法**を、最新の構成でまとめます。

ポイント：

* **`Debugger for Chrome` はもう使わない（非推奨）**
* VSCodeとChromeの**リモートデバッグ機能**で完結
* 毎回コマンドを打たずに済むエイリアスや自動化も紹介

---

## 前提

* Vue 3 + Vite プロジェクト（`npm create vite@latest`などで作成済み）
* Google Chrome（通常版でOK）
* VSCode（最新版）

---

## ステップ1：Viteの開発サーバーを起動

```bash
npm run dev
```

---

## ステップ2：Chromeをリモートデバッグモードで起動

通常のChromeでは VSCode から接続できないため、
以下のように `--remote-debugging-port=9222` オプションをつけて起動します。

### Mac の場合

```bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
```

### Windows の場合（例）

```bash
chrome.exe --remote-debugging-port=9222
```

---

## 面倒な人へ：エイリアスを作ると便利

Macの場合、以下を `.zshrc` に追記しておけば毎回楽です。

```bash
alias chrome-debug="open -na 'Google Chrome' --args --remote-debugging-port=9222"
```

```bash
source ~/.zshrc
chrome-debug
```

---

## ステップ3：VSCodeの launch.json を設定

プロジェクト直下に `.vscode/launch.json` を作成し、以下を追加：

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "pwa-chrome",
      "request": "launch",
      "name": "Vite: Chromeでデバッグ",
      "url": "http://localhost:5173",
      "webRoot": "${workspaceFolder}/src",
      "breakOnLoad": true
    }
  ]
}
```

ポイント：

* `type: "pwa-chrome"` → これが今の標準
* `Debugger for Chrome` 拡張は不要です

---

## ステップ4：デバッグ開始！

1. VSCode左の「実行とデバッグ」パネルを開く
2. 「Vite: Chromeでデバッグ」を選んで ▶️ 実行
3. Chromeが自動起動し、ブレークポイントで処理が止まります

---

## よくあるつまずき

### `<script setup>` で止まらない

* `setup`ブロック内は source map の都合で止まりにくいことがあります
  → 対応策：

  * 通常の `<script>` に一時的に戻す
  * `console.log()` 併用で様子を見る

---

### `console.log()` が出ない

* Chrome拡張（AdBlock / Grammarly / Vue Devtools など）が影響していることがあります
  → シークレットモードで確認する
  → VSCodeのデバッグモードでは影響を受けないためおすすめ

---

## おまけ：VSCodeの preLaunchTask で自動化したい人向け

```json
// .vscode/tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Start Chrome with debug port",
      "type": "shell",
      "command": "open -na 'Google Chrome' --args --remote-debugging-port=9222"
    }
  ]
}
```

`launch.json` にこれを追加：

```json
"preLaunchTask": "Start Chrome with debug port"
```

これで VSCode のデバッグ実行時に自動で Chrome が起動します。

---

## まとめ

* `Debugger for Chrome` は不要、**pwa-chrome が今の標準**
* Chrome をリモートデバッグポート付きで起動すれば VSCode から接続可能
* ブレークポイントで止まらないときは `<script>` に切り替え or `console.log()` 併用
* よく使うなら alias 登録や preLaunchTask で自動化が便利

---

Vue 3 + Vite 環境でも、VSCodeの標準機能だけで快適にデバッグできます。
「毎回 console.log 書くの疲れた…」という方は、ぜひこの方法を活用してみてください。
もっと早く知りたかったvscode上のGitHub Copilot Chatの送信キーの変更方法

# やり方
「キーボードショートカット」から「workbench.action.chat.submit」をenterから任意の物に変更する。
※agentの方はchatの所がeditの所を探して修正すること

# 困っていたこと
サイドバーとして出てくるGitHub Copilotのチャットとエージェントのパネル。
これとお話しているときに改行しようとして誤ってEnterを押してしまい送信されて行ってしまうのが鬱陶しかった。
ctrl + enter　とか　alt + enter　とかキー設定変えられないかと思って調べるのがめんどくさくて放置していた。
仮想環境設定

仮想環境を入れるために


```
python -m venv venv
```
アクティベートする

```
venv\Scripts\activate
```

アップグレード確認

```
python -m ensurepip --upgrade
```

インストールdjango
```
pip install django
```

pip最新ver
```
python.exe -m pip install --upgrade pip  
```



```
python -m venv venv
venv\Scripts\activate
python -m ensurepip --upgrade
pip install django
python.exe -m pip install --upgrade pip   
```

```
django-admin startproject mySite
cd mySite
python manage.py startapp myapp
```
PandasでWeb上の表データを取得する

表のスクレイピングに困ったことはありますか？

Webサイトで以下のような表があった場合、PythonのライブラリであるPandasを利用することで簡単にDataFrameとして取得することができます。

| 名前 | 年齢 | 出身 |
|:-:|:-:|:-:|
| 佐藤 | 24 | 埼玉 |
| 鈴木 | 53 | 神奈川 |


今回は、Pandasの`read_html`関数を使って、Web上のHTMLテーブルをサクッと取得する方法を紹介します。



# 🎯 `read_html`って何？

`read_html`はPandasの関数で、HTML内にある`<table>`タグの内容を、DataFrame形式で簡単に取得できます。

https://pandas.pydata.org/docs/reference/api/pandas.read_html.html

たった数行で記述できます。

```python
import pandas as pd

tables = pd.read_html("{取得したいWebサイトのURL}")
```

# 💡 基本の使い方

`read_html`の基本的な引数は次の通りです。

```python
pd.read_html(
    io,                 # URLやHTML文字列、ローカルのHTMLファイル
    match=None,         # 特定の文字列を含むテーブルだけ取得する場合
    flavor=None,        # "lxml" or "bs4" (パーサーを指定)
    header=None,        # ヘッダー行の指定
    index_col=None,     # インデックスに使う列の指定
    attrs=None,         # 特定の属性を持つテーブルのみ取得
)
```


# 🌸 その他のできること（一例）

## 特定のテーブルだけ取得したい！

例えば、「人口」という文字列を含むテーブルだけ欲しいときは、`match`引数を使います。

```python
tables = pd.read_html(url, match="人口")
```

## ローカルのHTMLファイルから読み込む

ローカルファイルのパスを指定するだけでOKです。

```python
tables = pd.read_html("sample.html")
```

## `<table>`の属性を指定する

HTML内でクラスやIDを指定してテーブルを抽出できます。

```python
tables = pd.read_html(url, attrs={"class": "wikitable"})
```


# 🐛 よくあるエラーと対処法

| エラー内容                             | 原因                | 解決方法                                                |
| --------------------------------- | ----------------- | --------------------------------------------------- |
| `ImportError: lxml not found`     | lxmlがインストールされていない | `pip install lxml` または `pip install beautifulsoup4` |
| `ValueError: No tables found`     | 対象のhtmlにテーブルが存在しない       | URLが正しいか確認 / `attrs`や`match`を見直す                    |
| `ParserError: could not parse...` | パーサーがうまく動作しない     | `flavor`引数で`bs4`や`lxml`を指定して試す                      |
コンパイルエラーとリンカーエラーの違い

### 最初に

ビルドエラーとリンカエラーの認識が曖昧だったので、備忘録として記録。

---

### ビルドとは？

- ソースコード → オブジェクトファイル（`.o`）→ 実行ファイル（`例:.exe,バイナリ`）を作成すること

---
### コンパイル（`.c → .o`）

#### 起きやすいエラーの例：

- 文法ミス
- 未定義の変数や関数の呼び出し
---
### リンク（`.o → 実行可能な形式のファイル`）

#### 起きやすいエラーの例：

- 宣言はあるけど定義がない
- 関数や変数の本体が見つからない

---

### まとめ
- コンパイルエラー → 文法ミスなど、ソースコード自体に問題あり
- リンクエラー → ソース上は問題ないが、呼び出し先の中身が見つからない
【CDK】CDK + ECS Fargateデプロイが完了しない問題

## 背景
AWS CDKを使用してみたかったため、Claude君に色々提案してもらいながら
Fargateによるマイクロサービスをデプロイするという作業を進めていました。
## 問題の発生
### 症状
- `cdk deploy`が82/86（ECS Service作成段階）で30分以上停止してしまった
- CloudFormationスタックがCREATE_IN_PROGRESSのまま停滞
- 試しに別ターミナルを開き、ECRにDockerイメージをプッシュすると、停止していたデプロイが突然再開・完了
## 原因
**「ECRイメージが存在しない状態で`desiredCount`を１にしていたため」**
```ts
this.service = new ecs.FargateService(this, "Service", {
	...
	  desiredCount: 1, // 1つのタスクを起動する
	...
});
```
`cdk deploy`時に、空のECRリポジトリが作成されますが、この時点ではまだイメージのプッシュは完了していません。
その後のフェーズで、ECSサービスが存在しないイメージを参照しようとし、待機状態となっていました。

そりゃ無い物を必死に探しても無いわけです。~~そこに無ければ無いですね。~~

タスク起動にはECRからのイメージ取得が必要ですが、
イメージがまだ存在していない状態だと、参照できず起動失敗となります。
よって、CloudFormationが無期限に待機してしまう状態に陥ります...。

本来求められる順序としては、
```
1. ECRリポジトリ作成（空）（初回`cdk deploy`）
2. Dockerイメージプッシュ
3. ECS Service作成（`cdk deploy`）
```

が正しいですが、今回は一回の`cdk deploy`の中で
```
1. ECRリポジトリ作成（空）
2. ECS Service作成 ⇒ イメージなしのため失敗 ⇒ 待機
3. （手動）別ターミナルでDockerイメージをプッシュ
4. イメージが参照できるようになったため解決
```
という流れになっていたため、正しくデプロイが出来ませんでした。

## CloudFormationの待機状態について
これに関しては公式[re:Post](https://repost.aws/ja/knowledge-center/cloudformation-ecs-service-stabilize)に記載がありました。

>Amazon ECS で作成したサービスは、AWS CloudFormation テンプレートで指定された状態から外れると安定化できません。サービスが目的のタスク定義を使用して必要な数のタスクを起動したことを確認するために、AWS CloudFormation は継続的に **DescribeServices** API を呼び出します。これらの呼び出しにより、目的の状態が達成されるまでサービスの状態を確認します。呼び出し処理には最大 3 時間かかる場合があります。

今回のケースに当てはめると、
```
1. イメージが存在しない → タスクが起動できない
2. 「目的の状態」が達成されない → CloudFormationが待機継続
3. 手動でイメージプッシュ → タスク起動成功 → 待機解除
```
という感じになります。
## 解決方法

### 1. 初回デプロイ時（ECRリポジトリ作成時）には`desiredCount`を0にする。
```diff_typescript
this.service = new ecs.FargateService(this, "Service", {
	...
-     desiredCount: 1, // 1つのタスクを起動する
+	  desiredCount: 0, // タスク起動なし
	...
});
```
### 2. デプロイを実施する。
```
cdk deploy
```
### 3. イメージをプッシュしておく
```
docker push ...
```

### 4. `desiredCount`を１にする
```diff_typescript
this.service = new ecs.FargateService(this, "Service", {
	...
-     desiredCount: 0, // タスク起動なし
+	  desiredCount: 1, // 1つのタスクを起動する
	...
});
```
### 5. 再度デプロイ
```
cdk deploy
```
## 最後に
生成AIも発達し、人がコーディングに使う時間も大きく減りつつある世の中ですが、
一気にサービスを作ったからと言って一度に全部をデプロイしようとせず、段階的なアプローチを取ることが重要だということを学びました。

また、AWS、CDKは触り始めて日が浅いですが、デプロイ時の処理順序やCloudFormationの安定化戦略など、少しレイヤーが深い部分を知見として得ることができたので、今回の問題に直面してラッキーだったと思います。

もし、補足や誤りのある部分がありましたら、遠慮なくご指摘ください！

## 参考
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html

https://aws.amazon.com/jp/blogs/devops/how-we-sped-up-aws-cloudformation-deployments-with-optimistic-stabilization/

https://repost.aws/ja/knowledge-center/cloudformation-ecs-service-stabilize

https://stackoverflow.com/questions/32727520/cloudformation-template-for-creating-ecs-service-stuck-in-create-in-progress
discord.jsで複数のスラッシュコマンドを作成

# 環境準備
Node.jsがインストールされている前提。

適当なフォルダを作って、そのフォルダへ移動する。
```bash
npm init -y
```
このコマンドで`package.json`を作成する。
```bash
npm install discord.js
```
discord.jsをインストール。

同じディレクトリに、メインとして使う`index.js`とトークンなどを書いておく`config.json`を作成。

複数のスラッシュコマンドを作成したかったが、日本語の情報がなかったので備忘録を兼ねて
rex0220 計算式プラグイン チェック時刻の自動セット

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、チェック時刻を自動セットしてみます。

# 概要

テーブルのチェック項目をチェックした時刻とチェック者（ログインユーザー）を自動セットします。
チェック項目は、計算式プラグインでレコード追加時に初期設定します。

![2025-05-27_21h25_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/cbeed47c-e1a6-4e29-b272-09ed45aed35d.png)

# 操作例

![2025-05-27_21h34_10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/bd8bb53e-61e5-4e1d-b991-ebe4247fd701.gif)


# 計算式プラグイン設定

- テーブル：　チェック項目を初期設定
- 日時：　チェック項目チェック時に日時をセット
- ユーザー選択：　チェック項目チェック時にログインユーザーをセット

![2025-05-27_21h29_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/6419b56f-c8e0-405b-9ad4-2748f90b0504.png)

```JavaScript:
OPTION: 循環参照を許可

// テーブル SUBTABLE
JSON_S(ARRAY(
  DIC("No",1, "チェック項目","チェック1" ),
  DIC("No",2, "チェック項目","チェック2" ),
  DIC("No",3, "チェック項目","チェック3" )
))

// テーブル.No NUMBER
// テーブル.チェック項目 SINGLE_LINE_TEXT

// テーブル.日時 DATETIME
IF(チェック,
  IF(NOT(日時), NOW(), 日時)
)

// テーブル.ユーザー選択 USER_SELECT
IF(チェック,
  IF(NOT(ユーザー選択),
    SET_CODE(LOGIN_INFO()),
    SEL_CODE(ユーザー選択)
  ),
  ARRAY()
)
```
AlmaLinuxをVirtualBoxで外部ネットワークに接続できなかった際の対処法

# 初めに
　今回は、VirtualBox上でAlmaLinux 9.5を起動した際に、インターネット接続ができないという問題に直面しました。

　具体的には、`ping 8.8.8.8` や `curl google.com` を実行しても応答が返ってこない状態でした。
　この記事では原因と対処法について書いています。
　
　同じような環境でネットワークに接続できなくて困っている方の参考になれば嬉しいです！


# 使用環境
　
- 仮想マシン：AlmaLinux 9.5
　ovaファイルからインポート
- 実行環境：VirtualBox（ネットワークは NAT + ホストオンリー）
　インポート時はアダプター１にホストオンリーアダプターのみ
　NATは後から追加
- 症状：仮想マシンが外部ネットワーク（インターネット）に接続できない
　NATのIPアドレスが192.168.x.xになっていて、10.0.2.xにならない
- デフォルトゲートウェイは設定済み

# 原因の分析
　
 ![Network設定画面（NATが10.0.2.xでない）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835880/09877eda-4ee4-45c5-88b8-3aa123eb9b0b.png)


 ＊enp0s3がホストオンリーアダプター（アダプター1）
 ＊enp0s8がNAT（アダプター２）

　画像のアダプター2がNATに設定をしているのに10.0.2.xになっていない。そのため外部と接続することができない。
 そこでチャットgptにたくさん質問をしていると、「DHCPが有効になっていない可能性がある」とのことだったので`nmcli` コマンドで接続設定を確認すると、DHCPが無効になっており、IPアドレスが手動（固定）で設定されていました。

```bash
nmcli connection show enp0s3 | grep ipv4.method
```
```
ipv4.method: manual
```
　この設定では、NAT側のDHCPサーバーからIPアドレスを自動取得できないため、インターネットとの通信ができなくなっていました。そのため、manualからautoに変更する必要があります。
　以下のコマンドでDHCPを有効化し、ネットワークサービスを再起動することで、DHCPが有効化にされ、10.0.2.xのIPアドレスが取得されます。
```
nmcli connection modify enp0s8 ipv4.method auto
```
　ネットワークサービスを再起動(OSを再起動しても大丈夫です)
```
sudo systemctl restart NetworkManager
sudo shutdown -r now
```
　しかし、ここで新たな問題に直面します。というのはDHCPが有効化されて外部と接続するための10.0.2.xが取得されているが、インターネット通信ができないという問題です。
 　そこでenp0s3（ホストオンリーアダプター）が優先してpingコマンドの処理にあてられていると考え、enp0s8（NAT）が優先されるよう値を変更したのですが、pingが通ることはありませんでした。

  ![アドレスの取得はできているのに通信ができない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835880/4b4635bb-9791-4f16-bd09-462d4897138d.png)


　原因を探すために、過去にLAMP環境を構築したマシンが残っていたのでそこで確認をするとOSのip route コマンドの実行結果など違いはありませんでしたが、アダプターがNATが1、ホストオンリーアダプターが2と逆に設定されていました。「関係ないだろうけど一応やってみるか」と思い変更して確認してみるとpingコマンドが成功し、外部と接続ができました。

　解決方法をまとめると、
 
 １.NATをアダプター１に、ホストオンリーアダプターをアダプター２に設定
 ２.デフォルトゲートウェイを設定
```
 sudo ip route add default via <ゲートウェイのIPアドレス> dev <インターフェース名>
```

 ３.DHCPを有効化
```
 nmcli connection modify <接続名> ipv4.method auto
```
 ４.NetworkManagerを再起動
 

# 疑問点
　何とかインターネット通信をすることはできましたが、いくつかの疑問点が残ってしまいました。
 
- なぜアダプターを変更すると成功したのか
- アダプター2に設定したNATは使用できないが、ホストオンリーアダプターが使用できるのはなぜか
- IPアドレスが取得できていたのにインターネット通信ができなかったのはなぜか

　VirtualBoxはアダプターの順序がDHCPの動作に影響を与える可能性があるというユーザの報告などがありました。（海外の投稿を翻訳してみたので間違っているかもしれない）

# まとめ

- VirtualBoxで外部ネットワークに接続するには、NATアダプター + DHCPが必要
- アダプター1にNATを設定する
- ip route で確認できるデフォルトゲートウェイの設定が必要
- `ipv4.method` が `manual` になっていると、自動でIPが振られずネットにつながらない
- `nmcli` で `auto` に設定すればDHCPが使えるようになる

　いくつかの疑問点が残ってしまいましたがインターネット通信をすることができてよかったです。
#102　AWS CodeGuru Reviewerを使ってコードレビューをしてみる

# はじめに
ソフトウェア開発の中でコードレビューは、コードの品質を保つために欠かせないプロセスです。しかし、手動でのレビューは時間とリソースを大量に消費します。そこで登場するのが AWS CodeGuru Reviewer です。本記事では、CodeGuru Reviewerとは何か、そしてセットアップ手順を解説します。

# AWS CodeGuru Reviewerとは？
AWS CodeGuru Reviewerは、機械学習を利用してコードレビューを自動化するサービスです。CodeGuru Reviewerは、JavaやPythonのコードベースを分析し、コードのバグや非効率な部分を指摘します。また、セキュリティの脆弱性やベストプラクティスに従っていない箇所についてもアドバイスを提供してくれます。

# 主な機能
自動コードレビュー: 機械学習モデルを活用して、コードの問題点を自動で検出。
統合: GitHub、Bitbucket、AWS CodeCommitなどのリポジトリと統合が可能。

# AWS CodeGuru Reviewerのセットアップ手順
AWS CodeGuru Reviewerを使用するには、いくつかのステップを踏む必要があります。以下にその手順を解説します。

① CodeGuru Reviewerのサービスを有効化
AWS Management Consoleにログインし、CodeGuru Reviewerのサービスページに移動します。ここでサービスを有効化します。
<img alt='aws-codeguru-reviewer-1' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-1.png'>
<br>

② リポジトリの接続 
CodeGuru Reviewerは、GitHub、Bitbucket、またはAWS CodeCommitといったリポジトリと連携します。今回はGithubに接続してみます。AWS Management ConsoleでGitHubを選択し、リポジトリへのアクセス許可を与えます。

・ソースプロバイダーにGithubを設定
<img alt='aws-codeguru-reviewer-2' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-2.png'>
<br>

・Djangoで作ったアプリのDevelopブランチを設定
<img alt='aws-codeguru-reviewer-3' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-3.png'>
<br>

・リポジトリを関連付けて分析を実行
<img alt='aws-codeguru-reviewer-4' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-4.png'>
<br>

⑤ 分析の実行
設定が完了したら、設定したリポジトリのブランチにあるコードの分析を実行してみ見ます。ステータスがPendingからCompletedになるまで待ちます。
※コードレビューにかかる時間はコード量によりますが、今回は数分程度で分析が完了しました。
<img alt='aws-codeguru-reviewer-5' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-5.png'>
<br>

⑥ フィードバックの確認
CodeGuru Reviewerの分析結果は、GitHubやAWS Management Console上で確認できます。指摘された問題点を修正し、コードの品質を向上させていきましょう。

・レビュー結果
<img alt='aws-codeguru-reviewer-6' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-6.png'>
<br>

・該当コード
<img alt='aws-codeguru-reviewer-7' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-7.png'>
<br>

※ちなみに[増分コードレビュー]には対象のブランチに対するプルリクエストが行われると自動で検知しコードレビューを行ってくれます。

<img alt='aws-codeguru-reviewer-8' src='https://www.nxted.co.jp/blog/img/107/aws-codeguru-reviewer-8.png'>
<br>

# まとめ
AWS CodeGuru Reviewerは、コードレビューのプロセスを大幅に効率化し、開発者がより高品質なコードを作成する手助けをします。セットアップも比較的簡単で、GitHubやBitbucketなどのリポジトリと統合することで、すぐに利用を開始できます。自動化されたレビューを活用して、チーム全体の生産性を向上させてみてはいかがでしょうか。
プリザンターのアナウンス機能のプチ改善【Ver. 1.4.16.0対応】

## はじめに
プリザンターのVer. 1.4.16.0から内部のCSSの実装が整理されよりスマートなスタイルや配色に一部変更されました。その影響で以前の記事で紹介したプリザンターの[アナウンス機能のプチ改善](https://qiita.com/pmc-ko/items/66324bcac5fde15da0b1)で使用しているスタイルがちょっと浮いてしまっている状態になってしまったので、今回はその部分をさらにフィックスしてデザインをマッチさせていきます。

## 変更してみた
前回のCSSをベースに変更を加えていきます。もとにするCSSはこちらです。

https://github.com/Implem/Implem.Pleasanter/blob/c2a6e137f6b9831c228590862f442aa0f4b265ac/Implem.Pleasanter/wwwroot/styles/site.css#L2945-L2979

```diff_css:Announce.css
[class^="announce-"] {
+   display: block;
-   margin-top: 4px;
    padding: 5px;
-   border-radius: 20px;
+   min-height: 32px;
+   border-bottom: 1px solid var(--base-border);
}

.announce-default {
-   color: #000;
+   color: black;
-   background-color: #fff;
+   background-color: white;
-   border: solid 1px #000;
}

.announce-info {
-   color: #fff;
+   color: white;
-   background-color: #00f;
+   background-color: blue;
-   border: solid 1px #00f;
}

.announce-success {
-   color: #fff;
+   color: white;
-   background-color: #008000;
+   background-color: rgba(0, 128, 0, 0.9);
-   border: solid 1px #008000;
}

.announce-warning {
-   color: #000;
+   color: black;
-   background-color: #ff0;
+   background-color: yellow;
-   border: solid 1px #ff0;
}

.announce-error {
-   color: #000;
+   color: white;
-   background-color: #f00;
+   background-color: rgba(255, 0, 0, 0.9);
-   border: solid 1px #f00;
}
```

色名の指定がHEXコードから色名指定に、`success`と`error`の濃色の場合に透過率が設定されているところが際になります。また、表示枠につけられている角丸めもなくなっています。

## まとめ
今回は、アナウンス機能の表示スタイルを最新版のDesignに合わせる方法を紹介しました。Ceruleanモードが追加されてモダンなデザインになりましたが、バージョンアップに従って細かく修正が入っていることがあります。自作の部分もこうやって最新バージョンに追従させると全体的なバランスが取れるので、皆さんが作っている自作スタイルもブラッシュアップしてみてください
技術的負債が溜まっちゃってるんですよぉ～

# なぁ～～にぃ～～～ ⤴⤴⤴？？？　やっちまったなぁ！！！？？？

男は黙って

「フルリファクタ」

男は黙って

「フルリプレイス」

そんな時間は、この世にないんですけどねぇ～

・・・ってなわけで、今回は技術的負債について見ていこか～

## 🧠 技術的負債の種類

ホンマはもっとあるやろうけど、ざっくり３つの種類に分けてみたで！こいつらが諸悪の根源やな。

| 種類                        | 例                                                              |
| --------------------------- | --------------------------------------------------------------- |
| 意図的な負債                | とにかくリリース優先。「あとでリファクタする予定やし！」        |
| 無意識の負債                | 知識不足や設計ミスによるもの（「その時はベストやと思ってた…」） |
| ツール/ライブラリ由来の負債 | 古いライブラリを使い続けて、アップデートできなくなってくる      |

ほんなら、意図的な負債から見ていくで～

## 💥 意図的な負債が止められないんですよぉ～

なぁ～～にぃ～～～ ⤴⤴⤴？？？　やっちまったなぁ！！！？？？

男は黙って

「リファクタ優先」

男は黙って

「品質優先」

そんなことしてたら、終電祭りなんですけどねぇ〜

### 🛠️ ほな、意図的な負債はどうすんねん

リリースを急がないといけない気持ちはみんな一緒や。

急ぐのが間違いやない。

やけど、焦ってリリースしても、後からアラート飛んできたり、ビジネス損害を生んだりして結局いいことあらへん。

ほんなら、リリース品質を担保するようにしよ。

それは lint や test でカバーできる。チームで合意取れた lint rule を追加したり、E2E test を導入したり、CI/CD で自動化した最低品質を守るようにしたらええんちゃうかな。

test は AI が得意な範囲やから、まだないんやったら Devin（AI エージェントで話題）や potpieAI（Jest や Storybook 自動化）とかのエージェント系 AI を使って書いてもらうのが良さそうやな。

せやから、リリース速度は落とさずに、品質を担保しよな。

## 💥 無意識の負債が止められないんですよぉ～

なぁ～～にぃ～～～ ⤴⤴⤴？？？　やっちまったなぁ！！！？？？

男は黙って

「技術書読破」

男は黙って

「公式ドキュメント読み漁り」

そんな時間があれば、飲みに行っちゃうんですけどねぇ～

### 🛠️ ほな、無意識の負債はどうすんねん

知識不足は慢性的なもので、これは常にキャッチアップし続けなアカン。メンタルの問題もあるけど、プライベートで時間取れへんこともある。

設計ミスはしゃあない。その時のベストでも、開発進んでいくうちに状況変わったりすることは多々ある。そんなん予測できひんしな。

でも、キャッチアップする機会を設けたり、設計を見直す機会を設けることはできるんちゃうかな？

ほんで、自分が得た知識を共有して、他の人の知識を分けてもらって、定期的に今の実装をみんなで振り返ったりして、ベースラインを上げていくことが、チームとしての成功パターンやと思うで。

AI は知識不足や設計ミスを補ってくれるから、copilot や chatGPT に相談するのが良さそうやな。

せやから、知識の差は、チームで補うのが一番効率ええで。

## 💥 ツール/ライブラリ由来の負債が止められないんですよぉ～

なぁ～～にぃ～～～ ⤴⤴⤴？？？　やっちまったなぁ！！！？？？

男は黙って

「Renovate」

男は黙って

「Dependabot」

だいたい保守するのがめんどくさくなって、放置されるんですけどねぇ～

### 🛠️ ほな、ツール/ライブラリ由来の負債はどうすんねん

定期的にライブラリアップデートをタスク化するのがええんちゃうかな。月に一回とか四半期に一回とか。

これを放置しすぎると、依存してるライブラリのせいで、上げたいライブラリのバージョンを上げられないから、放置してさらに古い依存が増えて・・・って感じで負のループに陥ってまう。

しゃあないけど、めんどくさい気持ちを抑えつつ、定期的にマイナーバージョンアップして、メジャーバージョンは気合いれてがっつりやっていくのがええんちゃうかな。

この辺はエージェント系の AI に頼むのも良さそうやな。テストまで一貫してお願いすれば、半自動化できそうやで。

せやから、定期的なバージョンアップで、未来の詰みを回避していこな。

## 🧾 最後に

実は、Facebook の motto って、途中で変わってんな。

もともとは

> “Move fast and break things”

って言ってて、スピード命やってんけど、途中でスパゲッティコードだらけで、「このままやとシステムを持続開発できひん」ってなったから

> “Move fast with stable infrastructure”

ってな感じで、堅牢な設計に基づいてスピード出そな～って変わってん。

スピード重視も大事やねんけど、品質を意識しないと、負債を溜めるだけや。

技術的負債って、何か一つの大きなことじゃなくって、小さい負債の積み重ねやねん。その返済も、一歩ずつ小さく刻んでいくしかないねん。

やから、「やっちまってる」コードを量産せんように、今日も品質大事に開発していこ。

「最近ちょっと負債気になってたな……」って人、
まずはひとつ、**小さく返す**ことから始めてみよな。

## 🛎 おまけの宣伝

文字列や配列の分割、地味に毎回書いてへん？

そこで、`divider` っていうユーティリティライブラリを作ってみたで〜
気に入ったら **☆** してくれたら、ワイがちょっと喜ぶ。笑

🔗 GitHub: [nyaomaru/divider](https://github.com/nyaomaru/divider)
🎮 Playground: [divider-docs.vercel.app](https://divider-docs.vercel.app/en)

他にも書いてるから、よかったら覗いてってな〜👇 
(qiita の記事は初手スパム扱いされてワイは悲しかった :crying_cat_face: )

https://qiita.com/nyaomaru/items/1c250e68b319719de844

https://zenn.dev/nyaomaru/articles/technical-debt-basics

https://zenn.dev/nyaomaru/articles/ai-era-npm-publish
Databricks Claude 4 Sonnetでマルチエージェントシステムを構築してみた

## はじめに

Databricksが最近、ますます注目を集めています。Claude 4のサポート開始に加えて、Mosaic AI Agent Framework、MLflow、Unity Catalogとの統合の強化など、AI開発基盤としての進化が目覚ましいです。

https://www.databricks.com/jp/blog/introducing-new-claude-opus-4-and-sonnet-4-models-databricks

今回は、公式ドキュメントのサンプルコードを参考に、Claude 4 Sonnetを使ったPythonコーディング支援マルチエージェントシステムを試しに構築しました。

https://docs.databricks.com/aws/ja/generative-ai/agent-framework/multi-agent-genie

## アプローチ

サンプルコードをそのまま動かすだけでなく、Claude 4 Sonnet単体にシステム構築を指示してみました。以下のようなプロンプトを一部使用してみました。

```
Databricks環境で、LangGraph、MLflow、Mosaic AI Agent Frameworkを統合した
Pythonコーディング支援マルチエージェントシステムを構築してください。
- LLMモデルはdatabricks-claude-sonnet-4を使用してください。
- 本番環境での使用を想定した、エンタープライズグレードの実装を提供してください。
- 最大限の機能性と相互作用を含む、完全に機能する実装を作成してください。
- 基本的な実装を超えて、段階的に開発からデプロイまで対応できる実用的で保守性の高いソリューションを
  提供してください。
```

## システム案

![qiita_dbrx_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635931/e0ee1805-1bc1-4877-a513-dcffec700fac.png)

### エージェント構成

- **Supervisor Agent**: リクエストのルーティング
- **Code Generator Agent**: Pythonコード生成
- **Code Reviewer Agent**: コード品質レビュー
- **Debugger Agent**: バグの特定と修正
- **Documentation Agent**: ドキュメント作成
- **Testing Agent**: テストケース生成

### 使用技術

- LLM: databricks-claude-sonnet-4
- オーケストレーション: LangGraph
- モデル管理: MLflow
- デプロイ: Mosaic AI Agent Framework

## 実装

さすがに、一発で完璧なコードは生成されませんでしたが、以下のような課題を段階的に解決していきました (継続改良中）。

1. **ライブラリバージョンの問題**: 古いバージョンのライブラリを使用したコードが生成され、最新のAPIとの不整合が発生
2. **再帰制限エラー**: LangGraphの再帰制限に達する問題で、エージェント間のルーティングロジックの見直しが必要
3. **長いコンテキストによるタイムアウト**: 複雑な処理で応答時間が長くなり、タイムアウト設定の調整が必要


## テスト

基本的な機能テストを実行し、エージェントが適切に動作することを確認しました：

- コード生成（バイナリサーチ実装など）
- コードレビュー（改善提案）
- デバッグ（エラー修正）
- テスト生成（単体テスト作成）
- ドキュメント生成（docstring作成）

## MLflowでの管理
MLflowでモデルの登録・管理を行い、エージェントの実行トレースも確認できました。

![qiita_dbrx_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635931/a78163c1-80ab-4b3c-b894-6b861673b3b8.png)

## デプロイメント
Unity Catalogにモデルを登録し、Model Servingエンドポイントとしてデプロイしました。
デプロイ後はReview App/Playgroundで動作確認を行い、マルチターン会話も正常に動作することを確認しました。

![qiita_dbrx_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635931/a9c0aaf6-d8dd-48e2-b9dc-1ea7437321a3.png)

## 感想

Claude 4 Sonnetは複雑な指示も理解して実装してくれますが、一度で完璧なコードを生成するのは難しく、明確な指示や対話的な修正プロセスが重要でした。この点は従来のLLMと大きく変わらない印象です。ただし、エラーメッセージを提示した際の問題特定や修正提案の精度は高く感じられました。今回はまだ、お試し程度ではありますが、マルチエージェントシステムを構築できたのは良い体験でした。

## 今後の展開

次のステップとしては、デプロイしたエージェントをDatabricks Appsで利用してみたいと思います。エージェントを手軽にアプリケーションに組み込むこともできて便利ですね。DatabricksとClaude 4については、さらに使いこなせるように理解を深めたいです。

https://docs.databricks.com/aws/ja/dev-tools/databricks-apps/

---
**参考リンク**
- [DatabricksにClaude Opus 4とSonnet 4の新モデルが登場](https://www.databricks.com/jp/blog/introducing-new-claude-opus-4-and-sonnet-4-models-databricks)
- [マルチエージェントシステムでのGenieの使用 | Databricks Documentation](https://docs.databricks.com/aws/ja/generative-ai/agent-framework/multi-agent-genie)
- [Claude 4 プロンプトエンジニアリングのベストプラクティス](https://docs.anthropic.com/ja/docs/build-with-claude/prompt-engineering/claude-4-best-practices)
ZIGSIMでスマホのセンサデータをProcessingで受け取る

# はじめに
ZIGSIMアプリをiPhoneにいれ、スマホとPCがローカルネットワークにつながっている状態で、スマホのセンサデータを取得するプログラムのメモです。（ここでは、ジャイロとタッチセンサを取得）
クオータニオンも取得できるので、姿勢制御なら、そっち使ったほうがいいですね。
加速度とジャイロから、Madgwickフィルタで、クオータニオンを計算して、精度やアルゴリズムの確認をするのにはいいかも。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/f9aa4b26-b6f2-4496-8128-61c233fb35ed.png)

```java
import hypermedia.net.*;

UDP udp;
float x,y,z;
float tx[] = {0,0,0,0,0};
float ty[] = {0,0,0,0,0};
float angleX, angleY, angleZ;

void setup() {
  size(600, 600, P3D);
  udp = new UDP(this, 50000);
  udp.listen(true);
}

void draw() {
  background(0);
  
  lights();
  camera(0, 0, 100, 0, 0, 0, 0, 1, 0);

  float dt = 1/60.0;

  angleX += x * dt;
  angleY += y * dt;
  angleZ += z * dt;

  pushMatrix();
  rotateX(angleX);
  rotateY(angleY);
  rotateZ(angleZ);
  fill(200);
  box(50);
  popMatrix();
  
  float cx,cy;
  cx = map(tx[0],-1,1,-50,50);
  cy = map(ty[0],-1,1,-50,50);
  fill(200,0,0);
  circle(cx,cy,5);
  cx = map(tx[1],-1,1,-50,50);
  cy = map(ty[1],-1,1,-50,50);
  fill(200,200,0);
  circle(cx,cy,5);
  

}

void receive( byte[] data, String ip, int port ) {
  if (data == null)return;
  String message = new String(data);
  JSONObject json = parseJSONObject(message);
  JSONObject gyroData = json.getJSONObject("sensordata").getJSONObject("gyro");
  x =-gyroData.getFloat("x");
  z = gyroData.getFloat("y");
  y = gyroData.getFloat("z");
  JSONArray touchData = json.getJSONObject("sensordata").getJSONArray("touch");
  for (int i = 0; i < touchData.size(); i++) {
    JSONObject touch = touchData.getJSONObject(i);
    tx[i] = touch.getFloat("x");
    ty[i] = touch.getFloat("y");
  }
  //println(x,y,z,tx[0]);
}
```


# 参考サイト

https://zenn.dev/zawaworks/articles/2101be9cd7ba30
コールバックは分かりやすく記述したい！

# コールバック関数とは？

コールバック関数とは、「別の関数に引数として渡され、あとで呼び出される関数」のことです。  
主に、配列操作やイベント駆動の処理などでよく使われます。

## コールバックの基本的な使い方

1. 通常の関数名を文字列で渡す方法
    ```php
    <?php
    // コールバック関数として使う関数
    function sayHello($name) {
        return "Hello, $name!";
    }
    
    // 配列と array_map を使ってコールバックを適用
    $greetings = array_map("sayHello", ["Taro", "Hanako", "Jiro"]);
    
    print_r($greetings);
    ```
    

    　

1. 無名関数（クロージャ）を使う方法
    ```php
    <?php
    $names = ["Taro", "Hanako", "Jiro"];
    
    // 無名関数をコールバックとして渡す
    $greetings = array_map(function($n) { return "Hello, $name!";  }, $names);
    print_r($greetings);
    ?>
    ```
    　

1. First-class Callable Syntaxを使う方法(php8.1以上)
    ```php
    // コールバック関数として使う関数
    function sayHello($name) {
        return "Hello, $name!";
    }
    
    // 配列と array_map を使ってコールバックを適用
    $greetings = array_map(sayHello(...), ["Taro", "Hanako", "Jiro"]);
    
    print_r($greetings);
    ```

結果
```
Array
(
    [0] => Hello, Taro!
    [1] => Hello, Hanako!
    [2] => Hello, Jiro!
)
```

## お判りいただけただろうか？（ホラー風）

一度だけの使い捨てのような関数はクロージャで良いと思いますが、複数の箇所で利用する場合は通常関数の方が使いやすいです。  
さて、本題です。

私は、phpの通常のコールバックは非常に分かりにくいと思っています。
だってこうですよ？

```php
function hi($name) {
    echo "Hi, $name";
}
$hi = 'hi';  // ここでは文字列 or 関数名
$hi('Taro'); // ここで初めてコールバック変数と分かる
```
分かっていればどうということはないんですが、関数名なのか文字列なのかの区別が使用する方法を見るまで分からないのです。
つまり、認知負荷が高いという事になると思います。

First-class Callable Syntaxの場合では、そういう問題はありません。
強いて言えば、新しい文法なので...ってなんや？！って事ですね。
```php
$hi = hi(...);  // ここでhiのコールバック変数と分かる
$hi('Taro');
```

と言う事で、表記方法が増えているので分かりやすいものを使ってみては如何でしょうか。

## おまけ

何でこの話になったかと言うと、最近wordpressを触る事になりましたが、フックの登録がこれなんですよ？
ぱっと見、２つの文字列渡しているようにしか見えないですよね？(熟達の人だと関数名にしかみえないのかですが）
```php
function xxx_post_list() { ... }
add_shortcode('shortcode_post_list', 'xxx_post_list');
```

```php
function xxx_post_list() { ... }
add_shortcode('shortcode_post_list', xxx_post_list(...));
```

私は、後者の方が分かりやすいです。

クラス関数の場合も同じように書けます。
```php
class CustomPost {
    public static function save_post(int $post_id, WP_Post $post, bool $update): void {}
}
add_action('save_post', CustomPost::save_post(...), 10, 3);
```
オーバーライドを整理する

## はじめに
javaのオーバーライドを深堀していたらややこしくなってしまったので、整理しておきます。

## コード例
```java
class A{
	List<Number> method(Number i){
		return new ArrayList<Number>();
	}
}

class B extends A{
	
	//例①
	List<Number> method(Number i){
		return new ArrayList<Number>();
	}
	
	//例②
	ArrayList<Number> method(Number i){
		return new ArrayList<Number>();
	}
	
	//例③
	List<Integer> method(Number i){
		return new ArrayList<Number>();
	}
	
	//例④
	List<Number> method(Integer i){
		return new ArrayList<Number>();
	}
	
}
```
Bクラス内に、親クラスAのmethodメソッドを実装した4例があります。

**例①：戻り値・戻り値のジェネリクス・引数の型すべて一致
例②：戻り値が継承元戻り値のサブクラス
例③：戻り値のジェネリクスが継承元ジェネリクスのサブクラス
例④：引数の型が継承元引数のサブクラス**

この中で、コンパイルが通る例はどれでしょう?
(すべて実装するのではなく、一つを選んで実装した場合と解釈してください)

正解は、**例①、例②、例④** です。

## 解説
オーバーライドの条件は以下です。

**メソッド名:**
スーパークラスのメソッド名と完全に一致
**引数:**
スーパークラスのメソッドのシグネチャ(引数の型、数、並び)が完全に一致
**戻り値の型:**
スーパークラスのメソッドの戻り値の型と一致、または、スーパークラスの戻り値の型のサブクラス

これをもとに、例を見ていきましょう。


**例①：戻り値・戻り値のジェネリクス・引数の型すべて一致**
＞**コンパイル可能**。
メソッド名・シグネチャ・戻り値型が完全に一致しているため、問題なくオーバーライドできます。

**例②：戻り値が継承元戻り値のサブクラス**
＞**コンパイル可能**。
ArrayListはListのサブクラスのため、こちらも問題なくオーバーライドできます。

**例③：戻り値のジェネリクスが継承元ジェネリクスのサブクラス**
＞**コンパイル不可**。
ここがややこしいところです...
ジェネリクス型は不変であるため、サブクラスであっても**互換性はありません**。
そのため、ArrayList＜A＞とArrayList＜B＞に関係はなく、コンパイルエラーとなってしまいます。

**例④：引数の型が継承元引数のサブクラス**
＞**コンパイル可能。ただし、オーバーライドではない。**
さらにややこしいところです.....
先述した通り、オーバーライドは**シグネチャの完全一致**が条件です。
そのため、型がサブクラスであったとしても関係なくオーバーライドにはなりません。
ただし、今回の場合**オーバーロード**が成立するため、コンパイルは問題なく通ることになります。

## おわりに
学べば学ぶほどややこしくなりますね、、
ここは基礎的な部分なので、しっかりと抑えたいと思います。
運用部署の先輩「Xのシェアリンクがアプリじゃなくてブラウザで開いてまうんやけどなんでなん？」

## 結論
```
https://x.com/intent/post?text=hogehoge
```
上記のURLを
x→twitter
post→tweet
に変更します
```
https://twitter.com/intent/tweet?text=hogehoge
```

こうすることで携帯で開いた時、ブラウザでログインを要求されることは無くなりました

やめたろうさんの記事に感銘を受けて自分も会話形式の記事を書いてみました！


## ことの発端
先輩「エルデンくんにコーディングしてもらったキャンペーンLPを公開したで！」

エルデン「ありがとうございます」

先輩「Xへのシェアボタンも置いてもらって」
先輩「ポスト投稿数に応じてプレゼントキャンペーンを実施や！」
先輩「人気のゲームやし...」
先輩「明日中に500投稿は軽くいってるんちゃうか！？＾＾」

有能後輩ニキ「先輩、独り言うるさいですよ」

## 翌日

先輩「OK、G〇〇gle、昨日公開したサイトのシェア投稿数は？」
**G〇〇gle「70やで」**


先輩「**ファッ！？**」
先輩「（3000は行く前提でサイト作ったのに、オオゴケやないか！？）」

有能後輩ニキ「先輩、顔色悪いですよ」

先輩「あかん、このままだとまずい」
先輩「先方に怒られてまう・・・＞＜」
先輩「今すぐSNSで拡散や！」
先輩「Xの広告アカウントでシェアリンク付きの画像を作って」
先輩「テスト投稿や！！（カタカタカタ...ッターン！）」

**X「ログインしてやー」**

先輩「**ファッ！？**」
先輩「なんでや！ログインはしてるで！？」
先輩「って、これブラウザで開いてるやんけ！」

有能後輩ニキ「先輩、独り言うるさいですよ」

先輩「他の会社と同じリンクフォーマットを使ってるのに！」
先輩「なんでや！」

有能後輩ニキ「...先輩、僕もAndroidで確認したんですけど」
有能後輩ニキ「アプリで開ける方は画像の下にtwitter.comの文字があって」

![スクリーンショット 2025-05-27 19.42.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572617/04f819fa-30f3-4821-a74c-61182bf253b7.png)

有能後輩ニキ「ブラウザで開いてしまう方は画像の下にx.comの文字がありました」
![スクリーンショット 2025-05-27 19.42.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572617/95ea430a-05ba-42e8-8a47-1cced2b0b895.png)

有能後輩ニキ「もしかしたらリンクの違いでこうなってるのかもしれないです」
有能後輩ニキ「旧式のリンクフォーマットに戻してみましょう」

先輩「え〜？」
先輩「関係ないと思うけどな〜」
先輩「どっちもクリックした後のリンクはx.comの方になってるんやで？」
先輩「ま、試しに一回やってみるか〜」
先輩「（カタカタカタ...ッターン！）」
### 先輩「**...ファッ！？！？**」


エルデン「（うるさいなこの人）」

先輩「アプリで開くやんけ！！」
先輩「有能後輩ニキ！ハグしてあげるからこっちにおいで！！」

エルデン「彼もう帰りましたよ」

**〜おしまい〜**
昔の写真がよみがえる！無料で使える画像補正AI「JUY.AI」を試してみた

> 先日、母の誕生日カードを作ろうとして、古い家族写真を見つけました。でも、それはぼやけて小さく、印刷には到底使えないものでした。いくつかの画像補正ツールを試しましたが、なかなか満足できる結果が得られませんでした。そんな中で出会ったのが「JUY.AI」というAI画像補正ツールです。

結論から言うと、「もっと早く知りたかった」と思うほどの実力。今回は実際に使ってみた感想と活用法を紹介します。

## JUY.AIとは？

JUY.AIは、2025年に登場した無料で使えるAI画像補正・拡大ツールです。アカウント登録なしですぐに使えるのが魅力で、画質の低い画像を高解像度にアップスケールし、ディテールを自然に補完してくれます。

![無料で使える画像補正](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091821/4cf0307e-6236-4d73-9f73-91b7e5c732a0.png)


## 主な機能

- **画像補正（Enhancer）**：ぼやけやノイズを自動で補正。  
- **画像アップスケール**：解像度を上げても画質が崩れない。  
- **写真修復（Repair）**：古い写真の傷や色あせを修復。  
- **バッチ処理**：複数画像の一括処理（有料プランのみ）。

![JUY.AI](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091821/f4321e2d-9d12-4c81-a0c1-abdebeabe62e.png)

## 実際に使ってみた結果

✔ **風景写真の補正**  
スマホで撮った山の写真が、まるで一眼レフで撮影したかのようなクリアさに。

✔ **ネットショップの商品画像**  
少しぼやけていた商品画像が、JUY.AIの補正でパリッとした印象に変化。

✔ **古い家族写真の修復**  
小さくて色あせていた昔の写真が、傷やシミが消え、顔の表情までくっきり。

## 料金プラン（2025年5月時点）

- **無料プラン**：月5枚まで補正可能、最大3000px/10MB  
- **ベーシック（$10/月）**：月500枚、修復・バッチ処理などすべて利用可能  
- **プロ（$30/月）**：2000枚/月、24時間サポート、最速処理など

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091821/764dbfeb-5a81-461b-bcf5-448d0e382bc9.png)


## こんな人におすすめ

- SNS用画像を綺麗にしたい方  
- 小規模ビジネスで商品画像を改善したい方  
- 古い写真を修復・保存したい方  
- ブログやウェブサイトの画像を整えたい方  

## 気になる点

- 混雑時は処理が少し遅い場合あり  
- 極端に小さい画像は不自然になることも  
- 無料プランではバッチ処理ができない  

## まとめ

JUY.AIは、無料なのに驚くほど高機能な画像補正ツールです。使い方も簡単で、登録不要。画像に関する悩みがあるなら、まずは試してみる価値アリです。

気になる方はこちらからどうぞ： 👉 [JUY.AI公式サイト](https://juy.ai/jp/)
再帰vs非再帰でベンチマークを取ってみた

x64、.net 8.0だと非再帰が再帰に負ける。
どうも、Stack<T>に突っ込むとかなり遅くなるようだ。
まさか二倍以上の差をつけられることになるとは…。
しかも、メモリー使用量も大差ない。

どうも、JITがかなり賢いらしく、再帰にも最適化がかかるらしい。

https://qiita.com/Tokeiya/items/171664489c7d6d4035c6

スタックオーバーフローを起こしたとか特別な理由がない限り再帰で書いた方がx64だといいようだ。

ベンチマーク環境：Core i7 14700、メモリー32GB DDR4
ベンチマークの内容：100文字✕100万行の追加、置換、列挙
コード：
https://github.com/oonyanya/FooList/commit/8e482c317a7e69866b9fd14d62029c4a391f314b

再帰あり
```
benchmark start
Allocated GC Memory:61,088bytes
add time:660 ms
Allocated GC Memory:199,684,816bytes
replace 1 time:3365 ms
Allocated GC Memory:199,700,584bytes
replace 2 time:4831 ms
Allocated GC Memory:345,444,168bytes
replace 3 time:3563 ms
Allocated GC Memory:345,444,192bytes
enumratotion time:738 ms
Allocated GC Memory:345,444,312bytes
clear buffer
Allocated GC Memory:84,368bytes
add line time:256 ms
Allocated GC Memory:41,046,248bytes
update line time:49 ms
Allocated GC Memory:41,050,104bytes
clear buffer
Allocated GC Memory:84,624bytes
Finished.Hit Any Key
```

再帰なし
```
benchmark start
Allocated GC Memory:61,088bytes
add time:705 ms
Allocated GC Memory:199,684,816bytes
replace 1 time:7208 ms
Allocated GC Memory:199,700,608bytes
replace 2 time:8871 ms
Allocated GC Memory:345,444,168bytes
replace 3 time:7759 ms
Allocated GC Memory:345,444,168bytes
enumratotion time:661 ms
Allocated GC Memory:345,444,312bytes
clear buffer
Allocated GC Memory:84,368bytes
add line time:246 ms
Allocated GC Memory:41,045,912bytes
update line time:65 ms
Allocated GC Memory:41,042,400bytes
clear buffer
Allocated GC Memory:84,648bytes
Finished.Hit Any Key
```
Webサイト作りで考えたこと（初期編）

## サイトについて
まだ工事中のためプロフィール等には載せませんがこちらです。
 [https://everyit.net](https://everyit.net)
 →まだ全くの未完成ですのでご容赦ください。
 
## 目的
- ITに関して気軽に調査の依頼を行えるサイトを作成する
- 構築を通した学習
- 今の技術のアウトプット

## 技術選定
今メジャーなクラウドであるAWSで構築したく、そこから考え始めました。
Amplifyに決めた後にもいくつか選択肢があったため記載してます。

### 構成：AWS Amplify
他に以下の構成も検討しました。
- S3＋CloudFront
- Lambda
- ECS

ただAmplifyを試してみたところ、意外とスムーズに構築できそうだったので、「これなら形にできそうだ」と感じて、この企画を本格的に進めることにしました。開始の手軽さは本当にすごいですね。シングルページでも、用途を考えるとAmplifyの機能範囲で十分カバーできそうです。

### フレームワーク：React
Vueなど他の選択肢もありましたが、正直どれもあまり触れたことはないため Amplifyのチュートリアルなどでもよく使われているReactを選びました。React独自の記述は何となく理解できたため、何とかなると信じたいですね。

### コードの記述：Typescript
Javascriptの方が得意ですが、本当は型がある言語の方が好きなため選びました。

## サイト名など
サイト名：ITなんでも調査屋
ドメイン：everyit.net
大きなプロジェクトに関わるより、調査自体に焦点があっている雰囲気を出しました。
ただ、サイト名は完全にピンときていないので変更する可能性はあります。

## 今後必要なもの
- アイコンやロゴなど、ブランディング要素の整備
- 各ページのコンテンツを考えます
・TOPページ
・自己紹介ページ
・依頼例ページ
・価格ページ
・依頼フォーム
- 上記ページのコンテンツを制作します
- サイトのデザインを整えます

## ぜひ導入したいもの
- 質問フォームまたは掲示板機能をつけ、匿名＋公開でやり取りできるようにしたいと考えています
- Google Analytics
- 事例一覧（まだまだ先）
Продвиньте свою карьеру в облачных технологиях с сертификацией Microsoft Azure Administrator Associate

Сертификация Microsoft Azure Administrator Associate (AZ-104) — это отличная возможность для IT-специалистов, стремящихся укрепить свои знания в области облачных вычислений. Этот сертификат подтверждает вашу способность управлять службами Azure, включая сети, хранилища, виртуальные машины и идентификацию, что делает вас ценным специалистом на современном рынке труда.

Чтобы эффективно подготовиться к экзамену AZ-104, многие кандидаты выбирают проверенные источники, такие как ExamsHome. С правильным подходом к обучению вы сможете с уверенностью сдать экзамен и сделать важный шаг к получению сертификации Azure Administrator.

Подробнее: https://www.examshome.com/provider/microsoft/path/azure-administrator-associate
LaTeXソースをGitHubで公開するときに個人情報を隠す

# はじめに
論文やレポートのLaTeXソースをGitHubのPublicレポジトリで公開したいけれど，本名や所属，謝辞などの個人情報は隠したいということはありませんか？
そんなときは，個人情報を別ファイルに保存して，`\IfFileExists`マクロを使うのが良いと思います

# 方法1
例えば，
```tex:main.tex
︙
\title{〇〇について}
\author{山田太郎}

% 本文
\begin{document} 
\maketitle
︙
```
というソースの`\author`を隠したければ，
```tex:author.tex
山田太郎
```
というファイルを作成し，
```tex:main.tex
︙
\title{〇〇について}
\author{
  \IfFileExists{author.tex}{
    \input{author.tex}
  } {
    非公開
  }
}

% 本文
\begin{document} 
\maketitle
︙
```
とします。そして，`.gitignore`に
```:.gitignore
author.tex
```
を追加すれば，GitHub上で個人情報を隠すことができます。
もちろん，自分のローカル環境には`author.tex`が存在するため，つねに完全なPDFを出力できます。
また，単にファイルを分割し`\input`だけを書くと，Gitからcloneしたときにエラーが出てしまい不便ですが，`\IfFileExists`を使って条件分岐すればそのような事態を回避できます。

# 方法2
複数箇所の個人情報を隠したい場合は，その都度ファイルを作っても良いのですが，以下のように
```tex:private.tex
\newcommand{\myname}{山田太郎}
\newcommand{\acknowledgement}{
    本論文の作成にあたり、ご指導くださった〇〇教授に深く感謝申し上げます。
    また、研究を支えてくださった研究室の皆様、日頃より励ましてくれた家族にも心より御礼申し上げます。
}
```
というファイルを作成し，
```tex:main.tex
︙
% Git管理用
\IfFileExists{private.tex}{
  \input{private.tex}
} {
  \newcommand{\myname}{【名前】非公開}
  \newcommand{\acknowledgement}{【謝辞】非公開}
}
︙
\title{〇〇について}
\author{\myname}

% 本文
\begin{document} 
\maketitle
︙
\section*{謝辞}
\acknowledgement
```
としておけば，1つのファイルに個人情報を集約できるでしょう。
もちろんこの場合，`.gitignore`には
```:.gitignore
private.tex
```
と書きます。

# おわりに
外部パッケージも含めると，より効率の良い記述方法がありそうですね。
もし見つかれば更新したいと思います。
[Build Games] Amazon Q Developer CLIを利用してゲームを作った on Mac #AWSCommunityBuilders


手順については、以下の記事が参考になります。
https://dev.classmethod.jp/articles/q-developer-cli-game-cbs/

ここでは詰まった点に焦点を当てます。

① qコマンドが使えない
② サインインに失敗する

### qコマンドが使えない
brew install 実行後にq chatコマンドが使えなかった。
本来cask（GUI上）でインストールしたので、GUIでアプリを開いた
そうすると、サインアップを求められるのでそれに従う

### サインインに失敗する
サインインの画面がしばらく出ずにフリーズした。これは再現できなかったので大抵の人は詰まらなそう

### 成果物
稚拙なゲームがはじめはできますが、対話を重ねてFBすると結構まともなのができてくる

GitHub
https://github.com/watanabe-tsuyoshi/pokerapp

ゲームの動画
https://x.com/tys_mnt/status/1927309585322262538

最初のぷr
```
pygameを利用してゲームを作成します。テキサスホールデムのゲームのサンプルを作ってほしいです。
細かいことはあとで指示するので、まずはプロトタイプをお願いします。全てローカルに保存してください
```
RaspberryPi Lakka

https://note.com/wabisuke94/n/ne3f849e43c37
https://note.com/wabisuke94/n/na388fff284de
https://geekyfab.com/entry/zero2w_gpicase
https://www.reddit.com/r/Lakka/comments/1dg8gvd/rasberry_pi_zero_2_w_which_build_to_use/
https://github.com/libretro/Lakka-LibreELEC/issues/1568
https://www.lakka.tv/get/linux/rpi/
https://zenn.dev/akibaburari/articles/82fd37eaa5237a
https://ayasuke2.exblog.jp/i23/