OmniAICreator/Qiita-1.07M huggingface dataset:
AI利用した開発を実体験！cline を使ってみた & AI ToDoリストを作成

最近、AI利用した開発に挑戦してみたいと考え、AIとやり取りしながら開発できる「cline」を試してみました。さらにその経験を活かして、大きなタスクを自動で細分化してくれるAI ToDoリストも作成しました。この記事では、その過程で得た知見やポイントをまとめます。

## 1. cline を試してみた

### 1-1. なぜ cline？
- **AI利用開発を手軽に体験したかった**

最近はLLM（大規模言語モデル）を活用したシステム開発が注目を集めています。ChatGPTなどのWebインターフェースも便利ですが、開発環境内で直接AIと対話できる方法を探していました。そこで、お気軽に開発できると噂の「cline」を利用することにしました。

### 1-2. 導入は驚くほど簡単
- **VS Code に拡張機能をインストール**
- **APIキーを設定**

詳しくはこちらの記事を参照しました。
https://qiita.com/minorun365/items/b2990a7228e8cc4ed025

これだけでセットアップは完了します。複雑な環境構築や設定が不要で、文字通り数分でAI開発環境が整うのは大きな魅力でした。特にプログラミング初心者や、新しい技術を試すのにハードルを感じている方にとって、この手軽さは重要なポイントだと思います。

### 1-3. 使い心地と意外なデメリット
- **返信にやや時間がかかる**

思ったよりも処理待ちが長く感じました。特に複雑な質問や要求をした場合、レスポンスに10分以上かかることもありました。

- **マルチタスクになりがち**

処理待ち中に別のことをしようとすると、どうしても「マルチタスク」になってしまいます。AIの返答を待つ間に別のタスクに取り掛かり、返答が来たらそちらに注意を戻す、というサイクルが生まれます。

場合によっては集中力が途切れやすいデメリットも感じました。返答を待っている間に別の思考に深く入り込むと、AIからの返答に気づいても文脈の切り替えに時間がかかります。待ち時間をうまく活用できる人にとってはメリットかもしれませんが、タスクを同時並行で行うのが苦手な人にとってはストレスになるかもしれません。

## 2. AI ToDoリストを作った理由
clineを試す中で、「AIをもっと日常的なタスク管理に活用できないだろうか？」と考え、AI ToDoリストのプロトタイプを作ってみることにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958152/1f98307e-7276-4a83-90d7-588760fb21e7.png)

### 2-1. 課題：大きなタスクは手がつきにくい

例えば「ブログ記事を書く」というタスクだけをToDoリストに書いても、そのタスクの大きさに圧倒されて、どこから着手したらいいか分からなくなり、モチベーションが上がりません。

そこで以下の機能があると効果的だと考えました：
- **大きなタスクを自動的に細分化する**
- **前後関係や必要なステップを順序立てて提示する**

これにより、大きなタスクも小さな達成可能なステップに分解され、着手しやすくなるのではと考えました。

### 2-2. タスク細分化のロジック
- **タスク名をAIに渡す**
- **必要なサブタスクをAIが生成する**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958152/9df6e3a2-9a09-4f52-a646-03cbdcc4ddbb.png)


例えば「ブログを書く」と入力すると、AIは以下のように細分化します：
1. テーマを決める
2. 構成を考える
3. 下書きを書く
4. 推敲する
5. 公開する

このように具体的で明確なステップに分けることで、「どこまで終わったか」「次に何をすればいいか」が見えやすくなり、モチベーション維持に役立ちます。また、大きなタスクを細分化することで、小さな成功体験を積み重ねられるため、達成感も得やすくなります。

## 3. 開発コストと子育てとの両立

### 3-1. 開発にかかった費用
- **約15ドル（約2,200円程度）**

AI APIの利用料金のみです。Claude-3.7などの高性能モデルを使用しても、プロトタイプレベルであればこの程度の費用で収まります。試験的に作る程度でこの金額なら、個人開発としてはまずまず許容範囲ではないかと思います。

### 3-2. 作業時間
- **開発自体は約4時間**

ただし、その間は子供と遊んでいる時間も、お風呂に入っている時間も、お酒を飲んでいる時間もclineは休まず仕事してくれていましたので、実質的に開発に集中したのはもっと短かったと思います。

- **マルチタスクの難しさ**

clineの応答を待っている間に子供と遊んだり別の作業をしたりと、一見効率よく見えますが、気持ちの切り替えが難しい場面もありました。「AIの応答待ち」→「子供との遊び」→「改良点を伝える」→「またAIの作業」という切り替えは、思考の連続性を保つのが難しく、集中が途切れやすいのは要注意ポイントです。

## 4. まとめと今後の展望

1. **clineは導入が簡単だが、処理待ち時間があるので注意が必要**  
   AIとの対話は強力ですが、即時性を求める場面では向かない場合もあります。

2. **AI ToDoリストは、大きいタスクを細分化してモチベーションを保つのに有効**  
   特に先延ばしにしがちな複雑なタスクに対して効果的です。

3. **開発費用は約15ドル、短時間で子育てしながらでも作れるが、集中力の管理が課題**  
   AIツールを活用すれば少ない時間でも成果を出せますが、作業の分断には注意が必要です。

他のAIツールとの連携も試して、「AIと対話しながら自動でタスクを進める」というワークフローを目指していきたいと思います。例えば、カレンダーアプリと連携して空き時間にあったタスク提案をしたり、メールやチャットから自動的にタスクを抽出したりする機能が実現できれば、より便利になるでしょう。

以上が、今回のcline体験とAI ToDoリストの開発プロセスです。実際に試してみると意外な発見や課題が見つかるので、興味がある人はぜひチャレンジしてみてください。AIツールは日々進化しており、少しの工夫で私たちの生産性や創造性を大きく高めてくれると感じました。
AWS Key Management Service(KMS)について

## AWS Key Management Service(KMS)
AWS Key Management Service(KMS)はAWSが提供する暗号化キー管理サービスです。通常、暗号化を行う対象のサービス(S3やEBS、Redshiftなど)と連携して利用します。

## 主な機能
- 暗号化キーの作成と管理
データを暗号化・複合するためのキーを安全に作成・保存・管理できます。
- キーのローテーション
セキュリティを強化するために、暗号化キーを定期的に自動で更新できます。
- アクセス制御
IAMポリシーを使用して、誰がどのキーにアクセスできるかを詳細に制御できます。
- 監査と追跡
AWS CloudTrailと統合されており、すべてのキー使用を記録・監視できます。

## 暗号化の仕組み
### エンベロープ暗号化
KMSキー、データキーと呼ばれる2種類の鍵を使用してデータの暗号化および複合を行う方式

### KMSキーの種類
- AWSマネージド型
通常AWSによって作成・管理されるもの。ユーザーは削除できず連携したEBSやRedshiftなどのサービスで暗号化を利用したタイミングでAWSが作成します。
- カスタマーマネージド型
ユーザーが作成・削除および管理を行います。→作成した鍵を長期間利用するのはセキュリティ上危険なため、KMSでは鍵の自動ローテーションをサポート

## キーポリシー
KMSキーへ適用するリソースベースのポリシーです。鍵に対して、IAMユーザーまたはIAMロール、他のAWSアカウントからの操作可能な権限を設定します。

### 使用シーン
#### クロスアカウント
あるAWSアカウントで暗号化されたリソースを別のAWSアカウントで復号したい場合、KMS（Key Management Service）の暗号化鍵を複数のAWSアカウントで使用できます。暗号化されたAMIやデータベースのスナップショットなどを他のAWSアカウントと共有する際に利用します。
鍵を共有するには、共有する対象のAWSアカウントIDを鍵の使用者として追加します。共有できる鍵はカスタマーマネージド型のKMSキーのみです。AWSマネージド型のKMSキーはキーポリシーを編集できないため他のAWSアカウントと共有できません。

#### AWS CloudHSM(Hardware Securty Module)
専用のハードウェアデバイスを用いて暗号化鍵を生成・管理します。貸し出されるハードウェアはFIPS 140-2認定のハードウェアベースのキー保管をサポートしているため信頼性が高いです。
KMSがフルマネージドであるのに対しCloudHSMでは鍵の生成や保管・削除などのライフサイクルはユーザー自身が行います。運用面においても他のAWSユーザーと分離するためにAmazon VPC内にプロビジョニングする必要があるなどKMSよりもセキュアな運用が求められます。また専用のハードウェアを使用する分利用料金が高価になります。法令や規制等の要件で認定を受けたハードウェアで暗号化鍵を管理する必要があるようなケースに使用します。
【Python】requestsライブラリのインストール方法

# はじめに
こんにちは。
 BizOptimars の大杉です。
今回から、プログラミング初心者である自分の目線で、備忘録として学んだことを記していこうと思います。

本記事は Python におけるライブラリのインストール方法について書いていきます。

# ライブラリとは
一言でいうと、汎用性の高いプログラムをパッケージ化したもの です。
ひとまず、インストールすると便利な機能が使えるようになるもの と捉えていただいて大丈夫です。
詳しく知りたい方は別途調べてみてください。

おすすめ記事
https://qiita.com/_whitecat_22/items/3df18491c5f618c016d1

# インストール方法
### 追記
以下の手順では、コマンドプロンプトを使用してライブラリのインストールを行っていますが、VSCode のみを用いて行うこともでき、そちらの方が手間がかからず楽です。
VSCode のみの場合、画面上側のエディタ部分ではなく、その下にあるターミナル(TERMINAL)部分に、これから説明するpipのコマンドを書き込むことで、エラーを出すことなく実行してくれました。
教えていただいた方、ありがとうございます🙇‍♂️
*************************************

本記事ではrequestsライブラリを例として記載していきます。
インストール手順は以下の通りです。
1. コマンドプロンプトを起動
1. pip install requests と入力
1. 実行

#### 1. コマンドプロンプトを起動
Windows の検索機能で「コマンド」と入力し、コマンドプロンプトをクリックします。
#### 2. pip install requests と入力
```
pip install requests
```
上記のコマンドを入力します。
```
Microsoft Windows [Version 10.0.26100.3194]
(c) Microsoft Corporation. All rights reserved.

C:\Users\Sugi>pip install requests
```
画面の表示としてはこのようになります。
#### 3. 実行
エンターキーで実行します。
実行後、特にエラー等が出なければ完了です。
```
import requests
```
VSCode 等で上記のコードを実行し、requestsライブラリを使ってみてください。

# 注意点
冒頭でも触れましたが、pipのコマンドは Python のコードではないため、コマンドプロンプトもしくは、VSCode のターミナル等に入力しましょう。

# おわりに
今後も Python や AWS などについての記事を初心者目線で書いていく予定ですので、よければお付き合いください。
また、もし記事の文章に誤りがあった場合はご指摘いただけると幸いです。

# 参考
https://ai-kenkyujo.com/programming/language/python/requests-install/

# 更新履歴
2025/03/05
>install requests
VSCode 等で上記のコードを実行し、requestsライブラリを使ってみてください。
>
↓
>import requests
VSCode 等で上記のコードを実行し、requestsライブラリを使ってみてください。
>
・install →　import へ修正
・VSCode でもターミナルを使えばpipのコマンドがエラーにならない旨を追記
AIエンジニアが知っておくべき11のPythonライブラリ

自分メモ用です。以下サイトのただの要約です
https://www.kdnuggets.com/11-python-libraries-every-ai-engineer-should-know

# 11のライブラリ一覧

1. Hugging Face Transformers
2. Ollama
3. OpenAI Python SDK
4. Anthropic SDK
5. LangChain
6. LlamaIndex
7. SQLAlchemy
8. ChromaDB
9. Weaviate
10. Weights & Biases
11. LangSmith

## 各ライブラリの概要

### 1. Hugging Face Transformers
**用途**: 事前学習済みモデルとNLPタスクを扱うための強力なライブラリ。

**主な特徴**:
- BERT、GPT、T5など、多様なアーキテクチャに対応
- 数千の共有モデルが利用可能
- PyTorch・TensorFlow両対応

**学習のためのドキュメント**: [Hugging Face NLP Course](https://huggingface.co/course)

---

### 2. Ollama
**用途**: オープンソースのLLM（例: Llama、Mistral）をローカルで動作させるためのフレームワーク。

**主な特徴**:
- CLI/APIを提供し、簡単にモデルを実行可能
- モデルのカスタム調整が可能
- 量子化モデルのサポート

**学習のためのドキュメント**: [Ollama Course](https://ollama.ai/docs)

---

### 3. OpenAI Python SDK
**用途**: OpenAIの言語モデル（GPTシリーズ）をPythonアプリケーションに統合。

**主な特徴**:
- OpenAI APIに対応
- ストリーミングレスポンスをサポート
- トークン管理機能付き

**学習のためのドキュメント**: [OpenAI Developer Quickstart](https://platform.openai.com/docs/)

---

### 4. Anthropic SDK
**用途**: ClaudeなどのAnthropicモデルを活用するためのPython SDK。

**主な特徴**:
- チャットコンプリートAPI対応
- ストリーミングサポート
- Claude 3シリーズなどの複数モデル対応

**学習のためのドキュメント**: [Anthropic Python SDK](https://docs.anthropic.com/)

---

### 5. LangChain
**用途**: LLMアプリ開発を容易にするオーケストレーションフレームワーク。

**主な特徴**:
- チェーン・エージェントの構築支援
- メモリシステムを活用したコンテキスト管理
- ベクトルストア統合

**学習のためのドキュメント**: [LangChain Course](https://learn.deeplearning.ai/langchain)

---

### 6. LlamaIndex
**用途**: LLMとカスタムデータを接続し、データの取り込みや検索を容易にする。

**主な特徴**:
- PDFやSQLなどのデータコネクターを提供
- RAG（Retrieval Augmented Generation）対応
- 構造化出力の解析機能

**学習のためのドキュメント**: [LlamaIndex RAG Guide](https://learn.deeplearning.ai/llamaindex)

---

### 7. SQLAlchemy
**用途**: データベース操作をPythonで直感的に行うためのORM（Object Relational Mapper）。

**主な特徴**:
- 強力なORM機能
- SQLデータベースをサポート
- スキーママイグレーション対応（Alembic）

**学習のためのドキュメント**: [SQLAlchemy Tutorial](https://docs.sqlalchemy.org/en/latest/)

---

### 8. ChromaDB
**用途**: AIアプリ向けのオープンソース埋め込みデータベース。

**主な特徴**:
- シンプルなAPIで埋め込みデータを管理
- 永続化オプション（メモリ、Parquet、SQLite）
- LLMフレームワークと直接統合

**学習のためのドキュメント**: [Chroma Docs](https://docs.trychroma.com/)

---

### 9. Weaviate
**用途**: クラウドネイティブなベクトル検索エンジンで、セマンティック検索を実現。

**主な特徴**:
- GraphQLベースのクエリ対応
- テキスト・画像などのマルチモーダルデータをサポート
- リアルタイム検索

**学習のためのドキュメント**: [Weaviate Docs](https://weaviate.io/developers)

---

### 10. Weights & Biases
**用途**: 機械学習モデルの実験追跡・可視化ツール。

**主な特徴**:
- 自動ログ記録による実験管理
- モデルの可視化・比較
- GPU・メモリ監視機能

**学習のためのドキュメント**: [W&B Docs](https://docs.wandb.ai/)

---

### 11. LangSmith
**用途**: LLMアプリの本番監視と評価を支援するプラットフォーム。

**主な特徴**:
- LLMチェーンのトレース可視化
- プロンプト/レスポンスのロギング
- A/Bテストやコスト分析機能

**学習のためのドキュメント**: [LangSmith Docs](https://docs.langchain.com/langsmith)

---


# 所感

「AIエンジニア」って銘打ってるけど「LLMエンジニア」「NLPエンジニア」って感じですね。
個人的には画像、動画系だとultralytics + roboflowが便利すぎて、コーダーはもういらないなって思ってしまうレベルです。
Snowflake SnowPro Advanced: Architect(ARA-C01)、取ったどー

# はじめに
こんにちは、SnowのProです。
3/2、Snowflakeの認定資格である「SnowPro Advanced: Architect(ARA-C01)」、合格できました！
直後のツイート。↓

https://x.com/baihebu/status/1896131694014730580

2024/09/01にSnowPro Core(COF-C02)に合格しており、ほぼ半年後のAdvancedへのステップアップです。
SnowPro Coreに関する投稿はコチラ。

https://qiita.com/a-kamiya/items/bf009967d5051f0f4353

試験を申し込んだり結果管理しているCertMetricsの画面、Coreの横にAdvanced: Architectも表示されました。
![スクリーンショット 2025-03-03 111055.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/1a4a29aa-2eb8-4a49-8772-9cafefc638f6.png)


# 試験概要
問題数：65問
制限時間：115分
言語：日本語で受験可能
受験料：375USドル + 消費税10%
合格点：750点（1000点満点）
前提条件：SnowPro Core認定取得済み

# 勉強方法
Udemy一択です。
Snowflake Snowpro Advanced: Certification Exam Questions
Cris Garciaさんの模擬試験 ~~4つ~~のもの。

:::note info
2025/03/14現在、もう一つ模擬試験が追加になっていました！
模擬試験5つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/61f95a1c-0047-4b58-b243-957f40b61858.png)

:::

https://www.udemy.com/course/snowflake-snowpro-architect-certification-exam-questions/

会社のUdemyBusinessには出てこない講座なので課金しました。
しょっちゅうやってるUdemyセールで1,800円です。
2025/02/10に購入しました。
そこから約三週間の模擬試験の歩みは以下の表に。
| | 模擬試験1 | 模擬試験2 | 模擬試験3 | 模擬試験4 |
|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
|1回目 | 2/10 <font color=red>55%</font> | 2/12 <font color=red>64%</font> | 2/24 <font color=red>72%</font> | 2/26 76% |
|2回目 | 2/12 <font color=red>67%</font> | 2/23 84% | 3/01 92% | 3/01 87% |
|3回目 | 3/01 86% | 3/02 92% | - | 3/02 96% |
|4回目 | 3/02 95% | - | - | - |

9割超えるまで繰り返し（試験当日まで・・・）、間違ったところを解説や公式ドキュメントを読んで、時にはトライアルアカウントで試すなどしました。
模擬試験1がクセ強問題、ブラウザの翻訳機能で何を聞かれてるのかよくわからないというような問題がちょこちょこあって手こずりました。

他に、UdemyBusinessの方にある模擬試験ではない解説動画も一つ受講しました。
Snowflake Snowpro Advanced Architect || Masterclass ||
![スクリーンショット 2025-03-03 094517.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/4e76447f-0594-4521-b76e-899eac7d1622.png)

これは正直見なくてもよかったです。
SnowPro Coreで学んだこととの違いがわからないくらいです。
誇張なしで1つも新たな気づきとかありませんでした。

# 実際の試験
2/26に午前休を取得していてそこで受けようとしてたんですが、直前の2/24にまだ模擬試験3の1回目の結果が72%という微妙な感じだったので諦めました。
そして3/1にやっと、「ここまで来れば受かる」という自信を得たので、翌日の試験予約しました。
翌日なので近場には空きがなくてちょっと離れた試験会場になりました。

で、結局ですね、Cris Garciaさんの模擬試験4つをやっとけばOKでした。
<strong>結構そのまま出題されました。</strong>
<font color=Silver>開始から7問目までが「わかる、わかるぞ（既視感）」。
いいの、これ？って思いました。</font>

試験の感触としては以下の感じでした。
47問が自信あり。
13問が2択まではしぼったけどどっちか微妙。
5問が聞いたことも考えたこともないやつ。適当に回答。
結果は845/1000で合格！
単純計算だと65問中55問正解というイメージです。（正誤カウントしない問題もあるそうなので正確ではないですが）

# 認定証
認定証もデジタルではありますがもらいました。
![スクリーンショット 2025-03-03 092709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/903fb1b1-c89c-4d31-a28c-c9c4dff110ec.png)

# おまけ
2025年のWorld Tour TokyoではTシャツじゃなくて、パーカー？トレーナー？が貰えるのが今から楽しみです。

# 追記
試験後のLinkedInへのバッジ反映について投稿しました。

https://qiita.com/a-kamiya/items/63f535e5c0435aa59086

試験に向けての勉強場所について投稿しました。

https://qiita.com/a-kamiya/items/6c6e85a01875f78db1d8
Databricksジョブにおけるループ処理アプローチの比較


# For eachタスク

結構最近のジョブの機能に`For each`(それぞれ)タスクというものがあります。名前の通り、特定のタスクのそれぞれを処理するループを組むことができる機能です。

https://docs.databricks.com/aws/ja/jobs/for-each

こちらでウォークスルーしています。ループしたいパラメータをリストで定義すれば、ロジックを実装したノートブックに対するループ処理を簡単に実装することができます。

https://qiita.com/taka_yayoi/items/602bcd2a8d39fa2f555d

![capture.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/976c2424-486b-c4d4-3e4e-7f385cbec822.gif)

# SDKを用いた並列タスク

しかし、`for each`タスクの登場前でも(ある意味力技で)ジョブでループ処理を実装することができていました。タスクは直列、並列に組み合わせることができるので、異なるパラメータを受け取るノートブックを並列に配置されたタスクに設定すれば、ループ処理を行うことができます。ただし、多数のタスクを手動で設定するのは手間なので、SDKを用いてプログラムからタスクを設定することをお勧めします。

https://qiita.com/taka_yayoi/items/79e83aa1124226504892

![Screenshot 2023-12-10 at 15.04.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1574ac9f-adbd-f5cd-deb3-a43dbdf65850.png)

# アプローチの比較

これら二つのアプローチには一長一短がありますので、要件に基づいて選択いただくことをお勧めします。

|  | for eachタスク | 並列タスク |
|:--|:--|:--|
|  計算リソース | ループのそれぞれのイテレーションが割り当てられたリソースを共有します。[同時実行性](https://docs.databricks.com/aws/ja/jobs/for-each#for-each%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%92%E3%82%B8%E3%83%A7%E3%83%96%E3%81%AB%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)を上げるとリソースの競合が起きるので注意ください。  | タスクごとにリソースを再利用、あるいは別のリソースを割り当てることができます。  |
| 失敗タスクの再実行  | 特定のイテレーションを再実行する機能がないので、自前で修復処理を実装する必要があります。  | [ジョブの修復](https://docs.databricks.com/aws/ja/jobs/repair-job-failures#%E5%A4%B1%E6%95%97%E3%81%97%E3%81%9F%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%A8%E3%82%B9%E3%82%AD%E3%83%83%E3%83%97%E3%81%95%E3%82%8C%E3%81%9F%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E5%86%8D%E5%AE%9F%E8%A1%8C)で可能です。  |
|タスクの作成   | 引数のリストを作成するだけで簡単にループ処理を実装できます。  |  タスクに分けてループを実装する際、個別のタスクを多数作る必要があります。[SDK](https://docs.databricks.com/aws/ja/dev-tools/sdk-python)を用いてプログラム的に作成することをお勧めします。 |

簡単かつリトライの必要性のないワークロードであれば`for each`タスクがお勧めですが、リトライ処理やリソース最適化が必要であれば、タスクを組み合わせてループ処理を組んだほうが良いかと思います。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【応用情報】パスワード攻撃手法まとめ

## はじめに
応用情報技術者試験で出てくるパスワード攻撃手法についてまとめてみました。

## 表
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/4617951e-7fba-4aa9-8a71-d39d0e0faec7.png)

## おわりに
ここまで読んでいただきありがとうございます！
Addressables.CheckForCatalogUpdatesが動作しない問題

Unity6にてAddressablesを使ったリソース管理を実装しようと思い、ドキュメントを動作チェックをしていたところ、Addressables.CheckForCatalogUpdatesが想定した動きをしてくれません。

```csharp:AddressableSample.cs
IEnumerator CheckCatalogs()
{
    List<string> catalogsToUpdate = new List<string>();
    AsyncOperationHandle<List<string>> checkForUpdateHandle
        = Addressables.CheckForCatalogUpdates();
    checkForUpdateHandle.Completed += op => { catalogsToUpdate.AddRange(op.Result); };

    yield return checkForUpdateHandle;

    if (catalogsToUpdate.Count > 0)
    {
        AsyncOperationHandle<List<IResourceLocator>> updateHandle
            = Addressables.UpdateCatalogs(catalogsToUpdate);
        yield return updateHandle;
        updateHandle.Release();
    }

    checkForUpdateHandle.Release();
}
```
https://docs.unity3d.com/Packages/com.unity.addressables@2.2/manual/LoadContentCatalogAsync.html

想定した動きとはcatalogsToUpdate.Countにて1以上の値が返ることですが……

1. 環境AにてAddressablesを使ってリソースをビルドし、出力をアップロード
2. 環境Bにて実行してInitializeAsyncを呼ぶ(ついでにリソースを読み込み内容を確認
3. 環境Aにて1.の内容を変更してリソースをビルドし、出力をアップロード
4. (実行したままの)環境BにてCheckForCatalogUpdatesを呼ぶ

この手順でcatalogsToUpdate.Countは常に0が返します。

以下の方法で直接パッケージの中身を読んでみました。
https://someiyoshino.info/entry/2021/12/26/180355

するとCanUpdateContentの中で以下のコードを発見しました。
これは現状の動作的には==3であることが正しいはずです。

> CatalogLocation.Dependencies.Count==2

そこで検索したところ、以下のやり取りを発見
https://discussions.unity.com/t/addressable-checkforcatalogupdates-does-not-work/1516925/18

==3にする、もしくは執筆時の最新バージョン[2.3.16]をインポートすること(※)でCheckForCatalogUpdatesが想定した結果を返すようになりました。

今回チェックした時点のUnityのバージョンは[6000.0.35f1]なのですが、現状はPackageManagerを使ってインポートされるAddressableのバージョンは[2.2.2]なので、他にも困ってる人がいるかもしれないので記事にしておきます。

(※)
[project]/Package/manifest.jsonに記載されている"com.unity.addressables"のバージョンを書き換える
マウス不要！？Chrome操作で使える便利なショートカットキー

## 初めに
みなさんこんにちは！
いきなりですが、皆さんはChromeの操作でショートカットキーを利用していますか？
コピペやファイルの保存などで使うことはあるかと思いますが、Chromeの操作で使うイメージはないですよね？（いやいや使ってるよ。って人は、そっと閉じてください…。）
Windowsユーザー向けに、Chromeで使える便利なショートカットキーについて学んだので、忘備録として残そうかなと思い書いてみました！
ショートカットキーの操作に慣れ、周囲の人へドヤ顔で見せつけましょう！！

## 【開く・閉じる】
| 機能 | キー |
|:-|:-|
| 新規ウィンドウを開く | Ctrl + N |
| シークレットウィンドウを開く | Ctrl + Shift + N |
| 新規タブを開く | Ctrl + T |
| 閉じたウィンドウを開く | Ctrl + Shift + T |
| タブの複製 | Alt + D を押してAlt + Enter |
| 表示しているタブを閉じる  | Ctrl + W |
| 全てのウィンドウを閉じる | Alt + F4 |
| Chromeを全て終了 | Alt + Fの後にX |
| 履歴の表示 | Ctrl + H |
| ブックマークバーの表示・非表示 | Ctrl + Shift + B |
| 開発者ツールの表示・非表示| F12 もしくは Ctrl + Shift + I |

## 【移動】
| 機能 | キー |
|:-|:-|
| 次のタブへ移動（右周り） | Ctrl + Tab |
| 前のタブへ移動（左周り） | Ctrl + Shift + T |
| 特定のタブへ移動（1～8まで） | Ctrl + 1~8 |
| 一番右のタブへ移動 | Ctrl + 9 |
| アドレスバーにカーソル移動 | Ctrl + L |
| ページを1画面ずつ下にスクロール | Space |
| ページを1画面ずつ上にスクロール | Shift + Space |

## 【その他】
| 機能 | キー |
|:-|:-|
| ブックマークに登録 | Ctrl + D |
| 履歴の削除 | Ctrl + Shift + Delete |
| 再読み込み | F5 もしくは Ctrl + R |
| 1つ前へ戻る | Alt + ← |
| 1つ後へ進む | Alt + → |



## まとめ
皆さんいかがでしたか？
私も最初は不慣れでしたが、ショートカットキーを使うことで、少しずつマウス操作が減ってきました！
エンジニアの方は、使っていることが多いかと思いますが、そうでない方もどんどん利用しましょう！
cURLから学ぶ、良いコマンドラインアプリ実装のプラクティス

# curlから学ぶ、良いコマンドラインアプリ実装のプラクティス

`curl` は、標準的なコマンドラインHTTPクライアントとして広く使われています。HTTP通信の実装が一つの目標であるなら、`curl`のベストプラクティスを参考にするのは良い選択です。このブログでは、`curl`の有用な実装のポイントを紹介し、自分のCLIアプリに導入する方法を解説します。

---

## **1. 結構化されたCLIオプションデザイン**

### **プラクティス**
- 短いオプション (`-X`) と長いオプション (`--request`)を使用可能
- デフォルト値を持たせながら、ユーザーの自由度を確保
- `--help`や誤訳メッセージを見やすくする

### **例**
```sh
curl -X POST https://api.example.com/data -d "name=Tony"
```
- `-X` はHTTPメソッドを指定
- `-d` はボディーデータを送信

### **自分のHTTPツールで導入**
```sh
myhttp -X POST -d "key=value" https://api.example.com
```
シンプルな命令で、知らない人も使われやすい。

---

## **2. 統一されたI/O処理**

### **プラクティス**
- 標準入出力 (`stdin/stdout`)をサポート
- パイプを利用した同期操作
- `-d @file.json` のようなファイル入力を実装

### **例**
```sh
echo '{"name":"Tony"}' | curl -X POST -H "Content-Type: application/json" -d @- https://api.example.com
```
- `@-` は `stdin`からデータを取得

### **自分のHTTPツールで導入**
```sh
cat data.json | myhttp -X POST https://api.example.com
```
または:
```sh
myhttp -X POST -d @data.json https://api.example.com
```

---

## **3. 詳細なエラー処理**

### **プラクティス**
- 明確なエラーメッセージ
- `--verbose`オプションを用いて、HTTP通信を知る

### **例**
```sh
curl --verbose https://example.com
```

### **自分のHTTPツールで導入**
```sh
myhttp --verbose https://api.example.com
```
または:
```sh
myhttp --debug https://api.example.com
```

---

## **4. 環境変数のサポート**

### **例**
```sh
export HTTPS_PROXY=http://proxy.example.com:8080
curl https://example.com
```

### **自分のHTTPツールで導入**
```sh
export MYHTTP_PROXY=http://proxy.example.com:8080
myhttp https://api.example.com
```

---

## **まとめ**
| **プラクティス** | **自分のHTTP CLIに導入** |
|----------|------------|
| **オプションデザイン** | `-X POST -d "data" URL` などのフォーマットを参照 |
| **I/O処理** | `stdin/stdout` サポート |
| **エラー処理** | `--verbose` オプションを導入 |
| **環境変数の利用** | `MYHTTP_PROXY` をサポート |

`curl`のような優れたデザインに対応した、使いやすいCLIアプリを開発しましょう。
電脳少女プログラミング2088 -壊レタ君を再構築- の郊外のスラム街をPythonで解いてみた

どうもこんにちは！

paizaにて公開中の電脳少女プログラミング2088 -壊レタ君を再構築-にて、3問目です。
キャンペーンは終わりましたが乗りかかった船なのでできるだけ書いていきたいと思います。

https://ppg.paiza.jp/denno2088

# 問題
次は郊外のスラム街です。paizaランクはD相当。Pythonで解いていきます。

>郊外のスラム街にジャンク品を扱うお店があります。あなたはある商品を買おうとしましたがジャンク品なので値切ろうとしています。
値切りの戦略はまず半額を希望しそれが駄目な場合に半額から 100 増やした値段を伝えることにしました。ある商品の値段 n が与えられるので上記の戦略で半額の希望が駄目だった場合の額を出力してください。
入力は標準入力で商品の値段nが与えられます。

https://ppg.paiza.jp/denno2088/challenges/denno2088_c_d_03

# 方針と答えと結果

最終的な希望の値段を出力すればよいということで、$n ÷ 2 + 100$の答えを出力すればよいです。
~~~Python
price = int(input()) // 2 + 100
print(price)
~~~
結果がこちら。入力の半分に100足すのはいいけど、括弧をつけ忘れていて計算順番がおかしくなるとのこと。いや、括弧なくても想定通りの順番で計算するはずですが・・・

https://ppg.paiza.jp/denno2088?dynamic_ogp_image_uid=b2ba97ca-06dc-41ea-b2e4-58cfbae7160a&from=res

# コードを1行にまとめた場合
入力が１つだけなので、コードを1行にまとめた場合は以下。
~~~Python
print(int(input()) // 2 + 100)
~~~
結果がこちら。1行で処理したことを優先して褒めるようです。

https://ppg.paiza.jp/denno2088?dynamic_ogp_image_uid=81250864-f259-45cc-bedc-d188def1c8ad&from=res


ではでは。
【Swift】変数における値型と参照型の違いについて

# Swiftの値型と参照型の違い

Swiftには「値型（Value Type）」と「参照型（Reference Type）」の2種類のデータ型があり、それぞれ挙動が異なります。
変数を扱う際にこの違いを理解しておくことで、意図しないバグを防ぐことができます。

## 前提：変数と定数の基本
Swiftでは、データを格納するために「変数（var）」と「定数（let）」を使います。

- **var（変数）**: 値を変更できる
- **let（定数）**: 値を変更できない

```swift
var number = 10 // 変数なので値を変更できる
number = 20

let constantNumber = 10 // 定数なので値を変更できない
// constantNumber = 20 // これはエラー
```

この「変更できるかどうか」のルールは、値型と参照型の違いとも関連します。


## 値型（Value Type）とは

**値型は、変数がデータそのものを保持している型**です。
値型の変数を他の変数に代入すると、データはコピーされます。

### 値型に分類されるもの
- **構造体（Struct）**
- **列挙型（Enum）**
- **タプル（Tuple）**
- **標準ライブラリの型（String、Int、Boolなど）**

### 値型の挙動
```swift
struct MyStruct {
    var value: Int
}

var a = MyStruct(value: 10)
var b = a // `a`のコピーが作られる

b.value = 20

print(a.value) // 10
print(b.value) // 20
```
この例では、`b` に `a` を代入した時点で `a` のコピーが作成されます。そのため、`b` を変更しても `a` には影響しません。

### 値型のメリット
- **データの独立性が保たれる** → ある変数の変更が、他の変数に影響を与えない。
- **スレッドセーフ** → マルチスレッド環境でも安全に扱える。


## 参照型（Reference Type）とは

**参照型は、変数がデータのアドレス（メモリ上の位置）を保持している型**です。
参照型の変数を他の変数に代入しても、データそのものはコピーされず、同じデータを指す別の参照が作られます。

### 参照型に分類されるもの
- **クラス（Class）**
- **クロージャ（Closure）**
- **Objective-Cのオブジェクト（NSString, NSArray など）**

### 参照型の挙動（同じデータを指す）
```swift
class MyClass {
    var value: Int
    
    init(value: Int) {
        self.value = value
    }
    
}

var a = MyClass(value: 10)
var b = a // `a`と`b`は同じインスタンスを参照

b.value = 20

print(a.value) // 20
print(b.value) // 20
```
この例では、`b` に `a` を代入してもコピーは発生せず、`a` と `b` は同じメモリアドレスを指します。そのため、`b` を変更すると `a` も変更されます。

### 参照型の注意点
- **データが共有されるため、意図しない変更が起こる可能性がある**
- **マルチスレッド環境では同期処理が必要になる場合がある**


## よくあるバグの例

### 値型と参照型の誤解によるバグ

```swift
struct Counter {
    var count: Int = 0
}

func increment(counter: Counter) {
    var counter = counter
    counter.count += 1
}

var myCounter = Counter()

increment(counter: myCounter)
print(myCounter.count) // 0（変更されていない！）
```

このバグの原因は、**構造体（値型）はコピーされるため、関数内で変更しても元の変数には影響がない**ことにあります。

修正するには、`inout` を使って変更を反映させる必要があります。

```swift
func increment(counter: inout Counter) {
    counter.count += 1
}

var myCounter = Counter()

increment(counter: &myCounter)
print(myCounter.count) // 1（正しく変更される）
```

### 参照型の共有による意図しない変更

```swift
class Person {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
}

var personA = Person(name: "Alice")
var personB = personA

personB.name = "Bob"

print(personA.name) // "Bob"（意図しない変更が発生！）
```

このバグは、**クラス（参照型）はコピーされずに共有される** ために起こります。
値の独立性を確保したい場合は、`struct` を使うべきです。

```swift
struct Person {
    var name: String
}

var personA = Person(name: "Alice")
var personB = personA

personB.name = "Bob"

print(personA.name) // "Alice"（変更されない！）
```



## まとめ
| | 値型（Value Type） | 参照型（Reference Type） |
|---|---|---|
| 代入時の動作 | コピーが作成される | 参照が共有される |
| データの独立性 | 保たれる | 保たれない |
| var の影響範囲 | その変数のみ | すべての参照先に影響 |
| let の制約 | プロパティも変更不可 | 参照は変更不可だが、プロパティ変更は可能 |


特に「よくあるバグ」の例などは、swiftを経験していれば一度は遭遇する事象だと思います。
その際に「参照先が共有されてるのかな？」などの考えにすぐに至ることができれば、バグの解消もスムーズにできるかと思います。
WinUI3 ToolTipを扱いたい

:::note info
WinUI3のToolTipについて学んだ事をアウトプットしていきたいと思います。

何か追加情報があれば都度記事を更新していこうと思います。
:::

`ToolTip`は私が学んだ限りではあまりプロパティもなく、単純にツールチップを出力することが可能です。
各要素の属性として使用するか、子要素として使用するかの２パターンあります。

## 属性として使用する
各要素の`ToolTipService.ToolTip`属性を使用します。

```xml: MainWindow.xaml
<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="ToolTip.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ToolTip"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="ToolTip">

    <StackPanel Orientation="Vertical" Margin="50">
        <TextBox Text="紫咲シオン" Background="Violet" 
                 ToolTipService.ToolTip="魔界学校の優等生" />
    </StackPanel>
</Window>

```

![{8A1E0A2D-7532-4F38-B68B-0A73090C1CE6}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/d64a5709-f120-41db-9559-4f0dac1e2860.png)

## 子要素として使用する
これは単純に先ほどの属性がタグになるだけです。

この要素を使用することにより、属性を使用するタイプよりも細かな設定が可能です。
`Placement`でツールチップをカーソルから見てどの位置に出力するか設定できます。
`VerticalOffset`または`HorizontalOffset`を使用することでカーソルから出力するツールチップの位置までの距離を設定できます。

```xml: MainWindow.xaml
<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="ToolTip.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ToolTip"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="ToolTip">

    <StackPanel Orientation="Vertical" Margin="50">
        <TextBox Text="紫咲シオン" Background="Violet">
            <ToolTipService.ToolTip>
                <ToolTip Content="魔界学校の優等生"
                         Placement="Left"
                         HorizontalOffset="50" />
            </ToolTipService.ToolTip>
        </TextBox>
    </StackPanel>
</Window>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/a6e2b917-8dad-4fa8-89ef-625e1afe0093.png)

また、この形式でツールチップを使用する場合、ツールチップに画像なども使用することが可能です。

```xml: MainWindow.xaml
<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="ToolTip.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ToolTip"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="ToolTip">

    <StackPanel Orientation="Vertical" Margin="50">
        <TextBox Text="紫咲シオン" Background="Violet">
            <ToolTipService.ToolTip>
                <Image Source="E:\vs\WinUI3_Test\ToolTip\ToolTip\image1.jpg" />
            </ToolTipService.ToolTip>
        </TextBox>
    </StackPanel>
</Window>

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/c1cd9236-2357-4107-8c9a-eed20d118dcd.png)
Nextjsにsupabaseの導入方法

こちらではsupabaseについてと、導入方法について書いています
nextjsの設定が基本なのでsupabaseそのものの設定やテーブル作成は追々の予定です。

# supabaseとは

Supabaseは、オープンソースのFirebaseの代替として設計されたバックエンドサービスです。Supabaseを使用すると、リアルタイムデータベース、認証、ストレージなど、様々な機能を簡単に統合できます。以下にSupabaseの主な機能を紹介します
## データベース

Supabaseは、PostgreSQLを基盤とする完全に管理されたデータベースを提供します。SQLクエリを使用してデータを操作し、データベース機能を最大限に活用できます。

## 認証

Supabaseは、ユーザー登録、ログイン、パスワードリセット、ソーシャルログインなどの認証機能をサポートしています。

## リアルタイム機能

Supabaseは、データの変更をリアルタイムでリスンする機能を提供します。これにより、アプリケーションの状態をリアルタイムで更新できます。

## ストレージ

Supabaseは、ユーザーが画像やファイルをアップロードおよび管理するためのストレージソリューションを提供します。

## API

Supabaseは、RESTful APIやGraphQL APIを自動生成し、開発者がデータに簡単にアクセスできるようにします。

## オープンソース

Supabaseのコードベースはオープンソースであり、誰でもアクセスしてカスタマイズすることができます。

# 導入方法

## 1,インストール
対象のフォルダに移動して
Supabaseクライアントをインストールします。

```bash
npm install @supabase/supabase-js
```

## 2,環境変数の設定

Supabaseのプロジェクト設定からAPIキーとURLを取得し、Next.jsプロジェクトのルートディレクトリに.env.localファイルを作成して以下の内容を追加します。

```javascript
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
```

画像のようにプロジェクトに入って
projecysettings　→　DATA API び入り
NEXT_PUBLIC_SUPABASE_URLは Projectは ProjectURLのURLより
NEXT_PUBLIC_SUPABASE_ANON_KEYは anon publicより

![mosaic_20250303101456.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754121/3a068a5c-3c69-4d39-a372-6ba7c0a4ec66.png)


## 3,Supabaseクライアントの設定

libディレクトリを作成し、その中にsupabaseClient.jsファイルを作成して以下の内容を追加します。

```javascript
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);
```

## 4,データの取得と表示

ページコンポーネントでSupabaseクライアントを使用してデータを取得し、表示します。例えば、pages/index.jsファイルに以下の内容を追加します。

```javascript
import { supabase } from '../lib/supabaseClient';

export default function Home({ data }) {
  return (
    <div>
      <h1>Supabase Data</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

export async function getServerSideProps() {
  const { data, error } = await supabase
    .from('your_table_name')
    .select('*');

  if (error) {
    console.error(error);
    return { props: { data: [] } };
  }

  return { props: { data } };
}
```
golangでスマートにswapする方法

# 結論
以下のように変数aとbをswapできます。a, bは同じ型の前提。

``` swap_example.go
a, b = b, a
```

# 解説
golangの関数は複数の値を返せます[1]が、それを活用してこのような記載もできます。golangにはswap関数が用意されていませんが、このように簡単にswapできるからだと思われます。Google検索しても日本語の記事が出てこなかったため本記事を作成しました。

# 参考
[1] https://go.dev/doc/effective_go#multiple-returns
NextjsにPrismaの導入

Nextjsとデータベースを繋げる機能,prismaに関する記事です

# どういうものか
Prisma は、データベースとやり取りするためのモダンなツールセットを提供する次世代 ORM（オブジェクト・リレーショナル・マッピング）です。主に Node.jsおよび TypeScript プロジェクトで使用され、開発者が効率的にデータベース操作を行うのを助けます。以下は Prisma の主要な機能です

## Prisma Schema

Prisma は、独自のスキーマ言語（Prisma Schema）を使用してデータベースモデルを定義します。これにより、データベーススキーマの設計がシンプルかつ明確になります。

## Prisma Client

Prisma Client は、データベースに対してクエリやミューテーションを実行するための自動生成された TypeScript/JavaScript クライアントです。タイプセーフなクエリを簡単に書くことができます。

## Prisma Migrate

Prisma Migrate は、データベースの移行を管理するツールです。スキーマの変更をバージョン管理し、データベースの整合性を保ちながらスムーズに移行を行えます。

## Prisma Studio

Prisma Studio は、データベースデータを視覚的に操作するための GUI です。開発者はデータベースの内容をブラウズ、編集、管理することができます。


# 導入方法

## Prisma のインストール

Prisma をプロジェクトにインストールします。以下のコマンドを実行して、Prisma とそのクライアントをインストールします。

```bash
npm install @prisma/client
npm install prisma --save-dev
```

## Prisma の初期化

Prisma を初期化して、Prisma スキーマファイルを作成します。以下のコマンドを実行します。
これにより、prisma フォルダと schema.prisma ファイルがプロジェクトに追加されます。

```bash
npx prisma init
```

## データベースの設定

prisma/schema.prisma ファイルを開き、データベースの接続設定を行います。例えば、
SQLite データベースを使用する場合は以下のように設定します。

```javascript
datasource db {
  provider = "sqlite"
  // 使用するデータベースの種類
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

```

## データベースモデルの定義

schema.prisma ファイルにデータベースモデルを定義します。例えば、ユーザーモデルを追加する場合は以下のようにします。

```javascript
model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
}
```

## データベースのマイグレーション

データベースのマイグレーションを実行して、データベーススキーマを適用します。以下のコマンドを実行します。

```bash
npx prisma migrate dev --name init
```
## Prisma クライアントの生成

Prisma クライアントを生成します。以下のコマンドを実行します。
```bash
npx prisma generate
```

## Next.jsの場合で Prisma クライアントを使用

Prisma クライアントをインポートして、Next.js の API ルートやページコンポーネントで使用します。例えば、pages/api/users.js ファイルを作成し、以下のように Prisma クライアントを使用します。

```javascript
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  const users = await prisma.user.findMany();
  res.json(users);
}
```

これで、Next.js プロジェクトに Prisma を導入し、データベースと連携する準備が整いました。

# まとめた方法

## 1,初期化まで一括導入
```bash
npm install @prisma/client
npm install prisma --save-dev
npx prisma init
```

## 2,schema.prismaの定義(要編集)
```javascript
datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
}

```

## 3,マイグレーションでデータベース作成 ※ここでエラーが起きやすいので注意

```bash
npx prisma migrate dev --name init
```

## 4,Prisma クライアントを生成、これでデータの取出、追加、削除が可能に

```bash
npx prisma generate
```

# 便利ツール

## データベースを視覚的にわかりやすく

```bash
npx prisma studio
```

## Prisma スキーマのプッシュ

データベースにスキーマを直接反映させます。テスト環境での使用に適しています。
```bash
npx prisma db push
```

## Prisma スキーマのフォーマット

Prisma スキーマファイルを整形します
```bash
npx prisma format
```

## Prisma スキーマ(エラー)の検証

Prisma スキーマにエラーがないか検証します。
```bash
npx prisma validate
```
100.64.0.0/10 サブネット(Share Address Space:共有アドレス空間)

100.64.0.0/10(100.64.0.0〜100.127.255.255)のネットワークはキャリアグレードNAT（Network Address Translation)デバイスで使用するパブリックIPサブネット(Share Address Space:共有アドレス空間)で、[RFC6598](https://datatracker.ietf.org/doc/html/rfc6598)で規定されています。
共有アドレス空間は、キャリア/ISP内で自由に使用できますが、他のキャリア/ISPにルーティングしてはならないIPアドレスです。
共有アドレス空間は、プライベートIPアドレスに似た性格を持っていますが、キャリア/ISPでプライベートIPを使用すると、カスタマネットワークのプライベートIPアドレスと競合する可能性があります。そこで、共有アドレス空間は、キャリア/ISPでユーザのプライベートIPアドレスと競合しないIPアドレスとして使用されます。
例えば、ユーザAが社内ネットワークで10.10.0.0/16を使用していたとします。あるISPと契約して問題なくインターネットアクセスができていたとしましょう。ユーザAがISPを変更したとします。この時新しいISPがISP内で（ユーザデバイスのWAN側に10.10.0.0/16を使用していた場合、通常、ユーザAはインターネットにアクセスがきなくなります。
こういった状況を防ぐため、ISPが使用するIPアドレスはパブリックですが、他のキャリアも使用可能な共有アドレス空間（100.64.0.0/10)を使用します。ISPから外に出ていく場合は他の共有アドレス空間以外のパブリックIPにNATする必要があります。
AndroidでNetBSDを起動してみた

TCC8930はCortex-A9のようなのでNetBSDのポートを始めました。

コードはこれです。

https://github.com/yamori813/netbsd-src/commit/819fcd04915380b2e7b11a6c1cc2d96ef6a71339

SDKのヘッダーがBSDライセンスだったので、そのまま利用しました。

こいつ、動くぞ

https://dmesgd.nycbug.org/index.cgi?do=view&id=8263

lkにはimageのセキュリティチェックは入っていないようです。
MIT App Inventorによるマッチングアプリのおすすめ機能の実装方法（AIによる相性の分析）

## はじめに
MIT App Inventorでマッチングアプリ作ってみたいと思いますよね．．．どんなマッチングアプリを作成するかは別にして，中身はほとんど変わらないと思います．json schemaを使用してaiからの解答を制御します．


## アプリ概要
男女それぞれ10人のプロフィールをAIに渡し，相性がよさそうな組み合わせを提案してもらうアプリです．

## Gemini json schema
MIT App InventorでAIをAIを使用します．
AIからの解答の構造を制御するために，json schemaを利用します．

https://ai.google.dev/gemini-api/docs/structured-output?hl=ja

## デザイナー画面
![スクリーンショット 2025-03-03 021620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/4f5bdb24-9400-4631-84d2-82d37ca57d0b.png)


|機能|内容|
|:-:|:-:|
|Button_ai|クリックしたらAIでマッチングを行う|
|Button_reset|スクリーンをきれいにする|
|Lavel_info|相性がよさそうな組み合わせの表示|
|Web1|Geminiへのアクセス|

## ブロック画面
### 変数
#### apikey
ご自身のgeminiのapikeyに書き換えてください
![blocks (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/07e9bc30-4861-4f2b-8d4d-0b2137521faf.png)


#### URL
geminiへアクセスするためのURL
![blocks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/d496644d-dd48-4854-9d7f-615bcf8c7090.png)
```
https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=
```

#### 男のプロフィール
![blocks (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/954f4f69-fa42-4be7-91ff-3ce2dacb3d14.png)
```男のプロフィール
1. 田中 健太：24歳：カフェ巡り、読書：落ち着いた雰囲気で、色々な話をしたいです。
2. 佐藤 大輝：26歳：スポーツ観戦、ジム：アクティブなことが好きです！一緒に楽しい時間を過ごしましょう！
3. 高橋 優斗：22歳：映画鑑賞、音楽鑑賞：インドア派ですが、美味しいものを食べに行くのも好きです。
4. 伊藤 翔太：28歳：料理、食べ歩き：美味しいものを共有できる人がいいなと思っています。
5. 山本 拓海：25歳：旅行、ドライブ：色々な場所へ一緒に行きたいです。
6. 中村 悠真：23歳：カメラ、写真撮影：日常の風景を撮るのが好きです。写真好きな人と繋がりたいです。
7. 小林 涼介：27歳：ゲーム、アニメ：共通の趣味で盛り上がりたいです！
8. 吉田 隼人：29歳：サウナ、温泉：癒やしを求めています。一緒にリラックスできる人がいいな。
9. 加藤 蓮：21歳：ファッション、ショッピング：オシャレが好きです。一緒にお買い物に行きませんか？
10. 木村 颯太：26歳：お酒、バー巡り：美味しいお酒と会話を楽しみたいです。
```

#### 女のプロフィール
![blocks (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/dc8a5e0e-3e8b-4a14-b332-b0ecd5bf0d6e.png)
```女のプロフィール
1. 佐藤 遥：24歳：旅行、カフェ巡り：色々な場所へ一緒に行きたいです！美味しいものを食べるのも好きです。
2. 田中 美咲：26歳：映画鑑賞、読書：インドア派ですが、アクティブなことも好きです。共通の趣味で盛り上がりたいです！
3. 高橋 舞：22歳：料理、食べ歩き：美味しいものを共有できる人がいいなと思っています。
4. 伊藤 優香：28歳：スポーツ観戦、ジム：体を動かすことが好きです！一緒に楽しい時間を過ごしましょう！
5. 山本 莉子：25歳：音楽鑑賞、ライブ：音楽好きな人と繋がりたいです。好きなアーティストの話で盛り上がりましょう！
6. 中村 葵：23歳：カメラ、写真撮影：日常の風景を撮るのが好きです。写真好きな人と繋がりたいです。
7. 小林 詩織：27歳：ゲーム、アニメ：共通の趣味で盛り上がりたいです！
8. 吉田 菜々子：29歳：サウナ、温泉：癒やしを求めています。一緒にリラックスできる人がいいな。
9. 加藤 千尋：21歳：ファッション、ショッピング：オシャレが好きです。一緒にお買い物に行きませんか？
10. 木村 咲希：26歳：お酒、バー巡り：美味しいお酒と会話を楽しみたいです。
```

### when Button_ai. Click
Geminiにプロフィールを渡して，相性がよさそうなペアを見つけてもらう
![blocks (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/ff703689-2566-4a81-94ec-7e73a37c62c6.png)


### when Web1. GotText
Geminiから結果が返ってきた後の処理，Labelにペアと相性が合う理由を表示
![blocks (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/45c8315e-b503-4353-84db-c7ced73812ea.png)

### when Button_reset. Click
Labelを空白にする
![blocks (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/a35bb9a0-318d-41eb-aac7-29d099fce0d4.png)

## 実行結果
望んだ出力結果になりました！！
![Screenshot_20250303-022030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/c83bb853-8457-4445-9a61-b1f3f0c6a38a.png)

## おわりに
マッチングアプリに使えるかはわからないが，json schema便利ですね～～！
Vimと生成AIの組み合わせが目から鱗だった

普段つかっているVimで生成AIを活用できないかな、とふと思い調べたところ、うってつけのプラグインがあったので試してみました。
今回は[vim-ai](https://github.com/madox2/vim-ai)というプラグインを試しましたが、他にも[Github Copilot用のプラグイン](https://github.com/github/copilot.vim)などいくつかあるようです。

試して感じたのは、専用のチャットアプリで使うより、普段から頻繁に使うツールに生成AIが組み込まれると一番ありがたい、ということでした。
別のツールを行ったり来たりする必要がなく、Vimの中で全て完結するという動線が素晴らしいです。
他のアプリでも同じことが言えるかもしれないな、と思いました。

以降は具体的なセットアップ手順、使用イメージを載せていきます。

## セットアップ手順

:::note info
以降のセットアップ手順はWindows環境を想定した内容です。
:::

以下から最新のgvimをダウンロードします。
https://www.vim.org/download.php
私はgvim 9.1を使いました。

次にPython 3.10以上をインストールします。
gvim 9.1がサポートするPythonは3.11のため、私は3.11をインストールしました。
https://www.python.org/downloads/release/python-3115/

`vim-ai`プラグインをインストールします。
Vimのプラグイン管理に[dein](https://github.com/Shougo/dein.vim)を使っている場合、下記を`vimrc`に追記してインストールします。

```
call dein#add('madox2/vim-ai')
```

最後にAPI KEYを設定します。
OpenAIのモデルを使う場合 `~/.config/openai.token` にAPI KEYを保存します。
環境変数に設定する方法もありますが、詳細は下記をご参照ください。
https://github.com/madox2/vim-ai?tab=readme-ov-file#installation

これで準備が整いました。

## 使ってみる

いくつか用意されているコマンドがあります。
以下は`AI`、`AIEdit`コマンドを使っている様子です。

- `AI`: ノーマルモードで入力したプロンプトをもとに文章を生成
- `AIEdit`: ビジュアルモードで選択した内容と入力したプロンプトをもとに、選択範囲を上書きして文章を生成

Oracle Database用のDDL、DMLを生成
![ddldml.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33182/527e409c-1236-4aa4-8265-2045cb6bd1d1.gif)
プロンプト入力にVimのビジュアルモードを活用できる点がありがたいです。

簡単なプログラムを生成
![fizzbuzz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33182/11bcdc31-9a02-47c4-9bcb-f4eda1051bd6.gif)

`AIChat`コマンドを使い対話形式で文章作成してみます。

- `AIChat`: ノーマルモードでプロンプトを入力する形式のもと、チャット形式の連続した会話を実施

![mail.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33182/b1d2b6f0-c169-4002-930c-8587c16cd0dd.gif)
Vimの中に文章が生成されるため、作られたコンテンツをすぐにエディタ内で活用できます。

以上です。
その他のコマンドは[プラグインの公式ページ](https://github.com/madox2/vim-ai?tab=readme-ov-file#reference)をご参照ください。
OpenHandsを導入してAIアシスタントを活用する方法


## OpenHandsとは

OpenHandsは、AIアシスタントを活用してプログラミングやその他のタスクをサポートするツールです。Claude AIを搭載し、GitHubとの連携機能を持ち、開発作業を効率化します。

この記事では、Windows 11環境でOpenHandsを導入する手順を解説します。Windows 11が既にインストールされていることを前提としています。

## 導入手順

### 1. Dockerイメージのプルとコンテナの起動

まず、OpenHandsのDockerイメージをプルし、コンテナを起動します。

Windows PowerShellを開き、以下のコマンドを実行します：

```bash
# イメージをプル
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.27-nikolaik

# コンテナを起動
docker run -it --rm --pull=always `
    -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.27-nikolaik `
    -e LOG_ALL_EVENTS=true `
    -v /var/run/docker.sock:/var/run/docker.sock `
    -v ~/.openhands-state:/.openhands-state `
    -p 3000:3000 `
    --add-host host.docker.internal:host-gateway `
    --name openhands-app `
    docker.all-hands.dev/all-hands-ai/openhands:0.27
```

※ Windows powershellでは、バックスラッシュ（`\`）ではなく（`）を使用して複数行のコマンドを記述します。

### 2. GitHub Personal Access Tokenの取得

OpenHandsをGitHubと連携させるには、GitHub Personal Access Token (PAT) が必要です。

1. GitHubにログインします
2. 右上のプロフィールアイコンをクリックし、「Settings」を選択
3. 左側のメニューから「Developer settings」をクリック
4. 「Personal access tokens」→「Tokens (classic)」を選択
5. 「Generate new token」→「Generate new token (classic)」をクリック
6. トークンの名前を入力（例：「OpenHands」）
7. 以下のスコープを選択：
   - `repo` (すべてのリポジトリ権限)
   - `workflow` (ワークフロー権限)
   - `read:org` (組織の読み取り権限)
8. 「Generate token」をクリック
9. 表示されたトークンをコピーして安全な場所に保存（このトークンは再表示されないので注意）

### 3. API Keyの作成

OpenHandsはClaude AIを利用するため、API Keyが必要です。

#### Gemini APIキーの取得手順
1. **Google Cloud Platform (GCP) プロジェクトの作成**:
   - Google Cloud Platform ([https://cloud.google.com/](https://cloud.google.com/)) にアクセスし、Googleアカウントでログインします。
   - プロジェクトを作成します（まだプロジェクトがない場合）。プロジェクト名は任意で構いません。

2. **Gemini API の有効化**:
   - GCPのコンソール画面で、左上のメニューから「APIとサービス」 > 「有効なAPIとサービス」を選択します。
   - 「+ APIとサービスの有効化」をクリックし、検索窓に「Gemini API」と入力して検索します。
   - 「Gemini API」をクリックし、「有効にする」ボタンをクリックします。

3. **APIキーの作成**:
   - GCPのコンソール画面で、左上のメニューから「APIとサービス」 > 「認証情報」を選択します。
   - 「+ 認証情報を作成」をクリックし、「APIキー」を選択します。
   - APIキーが生成されます。このAPIキーはOpenHandsからGemini APIを呼び出す際に使用しますので、安全に保管してください。

#### Anthropic APIキーの取得手順
1. [Anthropicのウェブサイト](https://www.anthropic.com/)にアクセスし、アカウントを作成またはログイン
2. ダッシュボードから「API Keys」セクションに移動
3. 「Create API Key」をクリック
4. キーの名前を入力（例：「OpenHands」）
5. 生成されたAPI Keyをコピーして安全な場所に保存

### 4. OpenHandsの初期設定

コンテナを起動したら、ブラウザで以下のURLにアクセスします：

```
http://localhost:3000
```

初回アクセス時に、以下の情報の入力を求められます：

1. Claude API Key：ステップ3で取得したAPI Keyを入力
2. GitHub Personal Access Token：ステップ2で取得したトークンを入力

入力が完了すると、GitHubとの連携が確立され、OpenHandsを使用する準備が整います。

## OpenHandsの使い方

OpenHandsの基本的な使い方は以下の通りです：

1. ホーム画面からGitHubリポジトリを選択または新しいリポジトリを作成
2. リポジトリが読み込まれたら、AIアシスタントとチャットを開始
3. 自然言語でコードの作成や修正、質問などを行うことができます

例えば、以下のような指示を出すことができます：

- 「新しいReactコンポーネントを作成して」
- 「このコードのバグを修正して」
- 「このAPIの使い方を説明して」

AIアシスタントは指示に基づいてコードを生成したり、既存のコードを修正したり、説明を提供したりします。
オブジェクトのキーではなく、ラベルと認識される件について

## 結論：アロー関数は戻り値がObjectの時に()が必要

エラー内容
```
'color:' is defined but never used.eslintno-unused-labels
Unexpected labeled statement.eslintno-labels
```
## 原因
### オブジェクトと認識されず、ただ文字列が評価されている
```jsx
import './App.css';

const contentPinkStyle = () => {
    //文字列としては評価されているが、オブジェクトと認識されていない
    color: "pink",
    fontSize: "20px"
};

function App() {
  return (
    <>
      <p style={contentPinkStyle()}>しみともです</p>
    </>
  );
}

export default App;
```

## 解決策
### {}をオブジェクトだと認識されることが必要
```jsx
const contentPinkStyle = () => {
  return {
    color: "pink",
    fontSize: "20px"
  };
};

//もしくは

const contentPinkStyle = () => ({
    color: "pink",
    fontSize: "20px"
});
```
参考記事
https://jsnotice.com/posts/2019-06-06/

## しかし！単純にオブジェクトを変数として定義すればよかった
```jsx
const contentPinkStyle = {
  color: "pink",
  fontSize: "20px"
};

function App() {
  return (
    <>
      <p style={contentPinkStyle}>しみともです</p>
    </>
  );
}
```
家計簿アプリを作る＃５

![スクリーンショット 2025-03-03 084037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/294f3d83-ce36-4c18-9ba1-795ebe7b00c2.png)
👆の写真のようにpathとelementを付け加えます。

![スクリーンショット 2025-03-03 084254.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/5676ed49-53c5-46c0-8dce-351451a3af35.png)
srcの中にpagesフォルダを作り、その中に、Home.tsxを作成します。

![スクリーンショット 2025-03-03 084419.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/c0d68ba1-eb4b-477d-a13d-b19e561bfb53.png)
Home.tsxの中に、Reactのひな形を作成します。

![スクリーンショット 2025-03-03 084536.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/c69bde9b-1a8e-4305-835a-3e48d3265711.png)
Report.tsxも同じように作成します。
オープンソースカンファレンス2025 Tokyo/Spring参加レポート

# はじめに

インプリムのhmineです。  
ふだんはOSSのノーコード・ローコード開発ツール「[**プリザンター**](https://pleasanter.org/)」に新機能を追加をしています。

# 今回現地参加したイベント

2025/2/22（土）（2日目／最終日）に駒澤大学で開催された「[**オープンソースカンファレンス2025 Tokyo/Spring**](https://event.ospn.jp/osc2025-spring/)」に現地参加しました。

Open Source Conference（通称：OSC）は20年前から行われている、オープンソースソフトウェアに関わるコミュニティと企業が一体になって開催されるイベントです。（※イベントの説明文は「[OSCクロニクル](https://www.shuwasystem.co.jp/book/9784798072753.html)」のページを参考にしました。）

主目的としてイベントの協賛企業として参加し「[**Pleasanter Users Group**](https://www.pleasanter.org/)」のブース出展を行いました。

私個人としては技術情報の収集や、講師としての参加という面でも勉強になる一日でした。

# ブース出展 [**Pleasanter Users Group**](https://www.pleasanter.org/)

今回、左右に[プリザンター Users Community](https://event.ospn.jp/osc2025-spring/session/2012899) 様のブースと、[ラモ・テクノロジー](https://lamo-tech.com/news/open-source-conference-2025-tokyo-spring-exhibition/) 様のブースが配置され、とても賑やかな現場となりました。

**プリザンターのGitHubはこちらです👇**

https://github.com/Implem/Implem.Pleasanter

# データベースについての学び

展示の合間を縫って個別にブースへ伺いました。

**MyNA(日本MySQLユーザ会) 様**

今回のOSCでは、後述の講演のご手配をいただき大変お世話になりました。

**日本PostgreSQLユーザ会 様**
**Firebird日本ユーザー会 様**

PostgreSQLのスケーラビリティ向上に関して最近の動向、組み込みDBMSの世界観等についてお話をうかがいました。

**PingCAP株式会社 様**

大量のデータや高トラフィックのアプリケーションに適した分散型データベース「TiDB」について伺いました。

* **後日、PleasanterをTiDBで起動する検証記事をアップしてくださいました。**

https://zenn.dev/bohnen/scraps/68c773cf62a60e

実験結果から、現在のところ（2025年2月時点）、プリザンターの公式な起動手順でTiDBを使用することはできず、多少の工数をかけてプリザンター本体を改修する必要があるということがわかりました。

主にCodeDefinerのデータベース作成・マイグレート処理について、非互換なSQLを修正する必要がありそうです。

※今回はMySQLでデータベースを構築後TiDBに移行し、起動してくださったそうです。

---

プリザンターの機能追加の考え方では、現在のところ、3種類のデータベースで可能な限り同じ動作をするように開発を進めています。
ニーズによっては、互換データベースを含めて製品の強みに特化した機能開発を検討するのも興味深いと思いました。

プリザンターの利用者様のニーズでは、プリザンター運用開始後の次のステップとして、AIとの連携で更なる業務効率化を図りたい…という需要がありそうです。

https://qiita.com/pierusan2010/items/ff89c5cdca0e394bd83b

（つい先日公開されたAI連携の記事です！）

# 講師として参加しました

今回私は、MyNA(日本MySQLユーザ会) 様のご厚意で『[**Webアプリ「プリザンター」のMySQL/PostgreSQL/SQLServerマルチ対応**](https://event.ospn.jp/osc2025-spring/session/1982610)』の講師を務める機会をいただきました。

**〈講演内容サマリ〉**

1. 御礼 ～MyNA 様(日本MySQLユーザ会 様)とのつながりご紹介
2. プリザンター入門
   - プリザンターの本質はWebデータベース
   - 汎用性、速さ、環境選択の自由 を重要視している
3. Webアプリケーション概説
   - なぜWebアプリケーションで開発するのか？
   - Webフレームワークとプリザンター
4. DBとプリザンター
   - マルチDB基盤の解説
   - プリザンターのSQL検証と、残る課題

---

プリザンターのマルチDBの実行基盤はかなり整理されていると思います。
一方で、発行されるSQLの管理については改善の余地があります。

私が実際にMySQL対応を担当した4か月間は、「生SQLの互換性を検証する大変さ」を実感しました。
これから先は「アプリケーションから発行されるSQLを担保し続ける＝保守する大変さ」を背負うことになる…といったお話もしました。

ユーザー様に向けた機能追加はもちろんですが、開発者視点によるアプリケーション基盤の将来について、継続的に改善を進めていきたいと考えるこの頃です。

# プリザンター開発コミュニティができました。

私と同じように、

- データベースの製品の強みを生かした使い方を提案したい方
- アプリケーション基盤を提案したい方

そして、

- プリザンターが好きな方

我こそはと思う方のご参加をお待ちしています！

https://github.com/pleasanter-developer-community

# ありがとうございました！

駒澤大学様、関係者の皆さま、ありがとうございました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/dbd3bfd2-d80f-45ba-8d17-e7f2a465c4e3.png)

https://ospn.connpass.com/

とても楽しい一日でした。
プリント基板を活用したオーディオプレーヤーの製作

# はじめに
今回はオーディオプレーヤーを製作してみました。
以前ユニバーサル基板で作った物よりも小型化（薄型化）するため4層のプリント基板を設計し、PCBGOGO様に製造していただきました。また、初の試みとして部品の実装もお願いしました。この記事をお読みの方もよろしければ以下のリンクからPCBGOGOをお試しください。
また、回路図（準備中）やソフトウェアも載せますのでESP32でオーディオを再生してみたい方も参考になれば嬉しいです。
[![PCBGOGO](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/1a58932c-4f73-dae2-932e-739937adb187.jpeg)](https://www.pcbgogo.jp/promo/nichicon2)

# 今回のポイント
・初めて4層基板を設計し発注した。
・初めて部品の実装もお願いした。
・初めて基板のカラーを黒色にしてみた。
これらの点を踏まえてプリント基板をレビューしていきたいと思います。

# プリント基板の評価
製造していただいたプリント基板の写真を以下に載せます。
4層基板にしたことで今まで使っていた2層基板より部品の密度を上げることができ、64mm*77mmのL字型の基板に必要な回路を収めることができました。
また、黒色なので配線が目立たず部品の色とも合ってスマートな印象です。緑色の基板と比べて配線を追うのは少し難しいかもしれません。

### 表面
<!--（はんだメッキ、パターン、部品実装について）-->
表面には実装をお願いしたDACチップ(PCM5102A)が実装されています。
他にも[ESP32](https://akizukidenshi.com/catalog/g/g115675/)やLiPoバッテリーの充電回路などが配置されています。
部品実装の都合だと思いますが他のランドにもはんだが盛られていることがわかります。そのため、部品を載せてそのままリフローできるので良いと思いました。
端面処理やシルク印刷も綺麗で、フラックス等の汚れもなく好印象です。
![基板俯瞰.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/74015430-6c5a-4b82-b7df-ad5125392847.jpeg)

### 裏面
<!--（パターン、シルクプリント、端面処理など）-->
裏面にはmicroSDスロットやUSBシリアル変換IC(CH340G)等が配置してあります。
こちらも部品を実装するパッドやスルーホールが綺麗にできています。
![基板裏面.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/51ff059f-2fc0-4b44-ae1c-7555bbbf57d2.jpeg)

# 回路図
オーディオプレーヤーの回路図を以下に示します。
(準備中)

# ソフトウェア
ソフトウェアは[GitHub](https://github.com/nichiconLab/MP3Player-ESP32)に置いてあります。
エディタはVisual Studio Code、拡張機能でPlatformIOを使用しています。

# 完成したオーディオプレーヤー
基板が入っているケースは4インチのLCDを使えるように設計・製作したものです。GitHubに上げたプログラムは2.8インチのTFTディスプレイ[MSP2807](https://akizukidenshi.com/catalog/g/g116265/)に対応しています。
![組み込み後.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/20097df6-2f2d-4807-98e5-64e6d22cf371.jpeg)
4インチディスプレイ対応でケースのサイズは70mm*116mm*17mmになりました。
今回は薄型化を目標にして設計し、以前作った物よりも9mm薄くすることができました。
![完成写真.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/89202784-c4e7-46d6-b086-7b6211fe0c29.jpeg)

### 機能など
・16bit,48kHzまでのMP3形式に対応
・タッチパネルによる直感的な操作を実現
・Type-Cコネクタを通じて充電、ソフトウェアの書き込みが可能

# 今後の改良案
ソフトウェアの改良でハイレゾを再生できるようにすることが最大の目標です。ESP32のI2S関連の処理やオーディオファイルのデコードについてもう少し調べる必要がありそうです。
また、サイズについてはバッテリーのコネクタ等を変えることであと3mmは薄くできると考えています。最終的にスマホと同じくらいのサイズにすることを目指していきたいと思います。

# 最後に
記事の内容を参考にされる際は自己責任でお願いします。
オーディオプレーヤーの製作では初めて４層基板に挑戦し、一部の部品の実装も依頼しました。まともに動かなければ大きな損害なのでとても慎重に作業しましたが４層の複雑な配線になるとミスに気付きにくいので難しいです。
４層基板で部品の実装もお願いしたため個人で製造を依頼するには高額になりますが、PCBGOGO様の協賛のおかげで製作することができました。あらためて感謝申し上げます。
[![PCBGOGO](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/1a58932c-4f73-dae2-932e-739937adb187.jpeg)](https://www.pcbgogo.jp/promo/nichicon2)