OmniAICreator/Qiita-1.07M huggingface dataset:
みんなの銀行のSET（Software Engineer in Test）

ゼロバンク・デザインファクトリー株式会社(ZDF)の山口です。Application Development Headquarters/Engineering Division1/Backend G1のSETに所属しています。
SETは「Software Engineer in Test」の略で、テスト自動化を行うエンジニアやチームのことです。会社によっては独立したチームはなくQAの一員として活動していたり、SETではない別の呼び方をされていることもあります。また、会社ごとに役割やスコープも異なります。そこで今年度、みんなの銀行のSETとはどのようなチームを目指すのか役割や方針等を定義しました。その内容についてご紹介したいと思います。
これからSETとしてキャリアをスタートされる方やSETの組織構築を任された方、あるいは「SETってどんな仕事？」と疑問を持つ開発エンジニアや人事の方々などに参考になればと思います。

## これまでのSET
SETではこれまで、定期リグレッションテスト（※1）の運営・実行とそのテストケースを自動化することをメインで担当してきました。2024年にMagicPodを導入し（※2）担当していた範囲の自動化のスピードが上がったことと、SETのメンバが増えたことで他の領域にも活動範囲を広げられるようになり改めてSETがこれから何に取り組むのか、どのようなチームにしていくのかを定義することにしました。<br>
（※1）定期リグレッションテストでは、現状は障害時に顧客影響の大きい動線をテスト対象とし月に1〜2回実施しています。基本的にモバイル端末や行員画面を操作してのテストを実施しています。  
（※2）導入前はAppiumで自動化していましたが、開発者以外でも自動化や実行を行えることを目指し、ノーコードツールを導入しました。

## SETの取り組み方針
SETの取り組み方針は以下と定義しました。

|SETはSoftware Engineer in Testとあるように、テスト活動を対象に開発スキルを活かした取り組みを行う。ただし、テスト活動は特定のフェーズに留めない。みんなの銀行で工程定義されているUTやITa/ITb、STのみをテストとするのではなく「要件定義中のレビュー」や「実装中/ビルド時のコード解析」、「リリース後のモニタリング」など、品質を上げる活動全てをテスト活動として認識し全体を俯瞰して取り組む。<br>下記図のようにソフトウェア開発ライフサイクルの各工程でテスト活動を行うことで不具合や欠陥の早期発見を実現し、効率化を行う。（結果としてコスト削減に繋がる。）SETはその仕組み作りや開発プロセスの改善等を行っていく。|
|:-|

![set_img_v3 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013287/a918efdd-adf6-483e-be20-f70a49fe4145.png)



ポイントは、 **活動の対象は単体テストや結合テスト等のテストのみでない**というところになります。
要件定義や設計の段階から欠陥の発見を行うシフトレフトの考え方に加え、リリース後も実際の利用状況を踏まえたモニタリングや分析、本番環境での動作検証等を行うシフトライトの考え方も含め、SDLCの各フェーズでテストを行うことで全体として品質向上や効率化を行っていきたいと考えています。シフトレフトにおいては、AIやLLM(MCP)を活用した自動化や、開発への組み込みも視野に入れています。

## SETの立ち位置
SETの立ち位置は以下と定義しました。

|ソフトウェアの品質に関する専門性とソフトウェアエンジニアとしての開発やDevQAOpsの専門性を併せ持ち、プロダクト開発に関わる全チームとの連携を活かして品質と効率を高める独立したチーム。<br>※ 独立はするが、コミュニケーションを重要視し、グループやチーム関係なく頼ってもらえるような存在となる。|
|:-|

みんなの銀行には本記事を執筆している2025年4月時点、品質専門のチーム（QC、QA）や自動化・効率化観点ではDevOps、SREエンジニアがそれぞれ活動しています。SETが今回の定義で定めた役割に基づき活動するにあたって、各チームの担当領域と重複する部分も多いと考えられるため、コミュニケーションをとりながらSETとして積極的に貢献できる部分を明確化し、各チームと連携して取り組んでいきます。

## SETの役割
SETの役割は以下と定義しました。
|・不具合や欠陥の早期発見が可能な仕組み作りを支援し、プロダクトチームが開発に集中して速度と品質を向上できるようにする。<br>・すべてのエンジニアがプロダクト開発と品質の両方に責任と当事者意識を持って取り組める組織文化を築く。<br>※「不具合や欠陥」はコードの誤りのみでなく、要件定義の誤り、設計書のミス等も含まれる。|
|:-|

2つ目の記載について、SETがテストコードの全てを担当するのではなく、実際にテストコードを書くのはエンジニアで、SETはその仕組み作りをメインの業務とするという役割分担を考えています。SETは「SETの立ち位置」に記載の通り、開発スキルとQAの知識を持った集団のため、第三者目線ではなくエンジニアに寄り添って活動していきたいと考えています。

## 今後の展望

これまでは、冒頭に記載した定期リグレッションテスト関連の作業がメインで、他チームとの連携はあるもののチーム内で閉じる作業も多かったように思います。今回のSETの定義を実現するためには、これまで以上に他チームとの連携やコミュニケーションが重要になってくると考えています。SETのMVVのValueとして「プロダクト全体に責任をもつ」「相手の目線に立って価値を届ける」「現状にとらわれず、新しいものを取り入れる」を掲げています。この行動指針を忘れず、より良いサービスをお客さまに提供できるよう、他チームと連携し仕組み作りを行い貢献できればと思います。
具体的な活動についての内容や成果についてはまた別の記事でご紹介したいと思います。

## 用語
**MagicPod**  
ソフトウェアテストの自動化に特化した株式会社MagicPodが提供するサービス。ノーコードでWebアプリ・モバイルアプリのテストを作成可能。
**SDLC**  
ソフトウェア開発ライフサイクル（Software Development Life Cycle）
**UT**  
単体テスト（Unit Test）
**ITa/ITb**  
結合テスト（Integration Test）
**ST**  
システムテスト（System Test）
**QA**  
品質保証(Quality Assurance)
**QC**  
品質管理（Quality Control）
**SRE**  
サイト信頼性エンジニアリング（Site Reliability Engineering）
**MVV**
Mission・Vision・Value
個人的備忘録：Terraformディレクトリ整理の個人メモ（ファイル分割編）

## はじめに

本記事は、Terraformによるインフラ構成管理において、リソースごとにファイルを分割して整理する方法をまとめたものです。

:::note info
**以前のハッカソンで、1枚の `main.tf` に多くの記述をしてしまい、レビュー時に「コードレベルで分割した方が良い」との指摘をいただきました。**
:::

そこで、少し時間があったタイミングで、各リソースをファイル単位で整理する形に挑戦してみました。

この内容はあくまで個人の備忘録となり、箸書きのメモ程度ですが、今後Terraformを使う際や構成の整理をする際の一助になれば幸いです。

## Terraformディレクトリ構成の整理例

以下は、Terraformファイル一覧に基づいて整理したディレクトリ構成の一例です。

**実際のリポジトリ**

https://github.com/2025SpringTeamA/honda-test

```bash
terraform/
├── alb.tf                  # Application Load Balancer関連の設定
├── cloudfront.tf          # CloudFrontの設定
├── ecs.tf                 # ECSクラスターやサービス定義
├── internet_gateway.tf    # インターネットゲートウェイの設定
├── local_file.tf          # ローカルファイル出力など（例：Terraform output用）
├── main.tf                # メイン設定ファイル（entry point）
├── nat_gateway.tf         # NATゲートウェイの設定
├── provider.tf            # プロバイダー（例：AWS）定義
├── rds.tf                 # RDSインスタンスの設定
├── README.md              # プロジェクトの概要や使用方法など
├── route_table.tf         # ルートテーブル関連の設定
├── route53.tf             # Route 53（DNS）設定
├── s3.tf                  # S3バケット定義（静的ホスティングやログ保存など）
├── security_groups.tf     # セキュリティグループの定義
├── subnet.tf              # サブネットの設定
├── variables.tf           # 変数定義ファイル
└── vpc.tf                 # VPCの定義
```

このように、各リソースごとにファイルを分けて管理することで、構成が分割されており保守性や可読性が向上します。

## 補足：さらなるディレクトリ分けの提案

より大規模なプロジェクトやチーム開発を想定する場合、以下のようにカテゴリごとにディレクトリ分けすることも推奨されます。

```bash
terraform/
├── network/
│   ├── vpc.tf
│   ├── subnet.tf
│   ├── internet_gateway.tf
│   ├── nat_gateway.tf
│   └── route_table.tf
├── compute/
│   ├── ecs.tf
│   └── security_groups.tf
├── storage/
│   ├── s3.tf
│   └── rds.tf
├── delivery/
│   ├── alb.tf
│   ├── cloudfront.tf
│   └── route53.tf
├── provider.tf
├── variables.tf
├── main.tf
└── README.md
```

このような構成にすることで、担当領域ごとの管理がしやすくなり、チームメンバー間での役割分担も明確になります。

## まとめ

Terraformでの構成管理は、最初は1つのファイルにまとめたくなる気持ちもありますが、プロジェクトが大きくなるにつれて保守性が課題となります。

:::note warn
***今回のようにリソースごとにファイルを分割することで、各構成要素の把握がしやすくなり、レビューや運用もスムーズになります。***
:::

本記事はあくまで備忘録として残すものですが、Terraformを触る方々の参考になれば幸いです...！
モデルベース開発(MBD)概要

## はじめに
これからMBDを学習される方の参考になるような記事を書きたいと思います。 
今回は、MBDとは何か？何を使ってどのように開発するのか？を教育で学んだ内容を基に説明します。

## モデルベース開発(MBD)とは
モデルベース開発(Model Based Development)とは、制御装置と制御対象の機能をモデル化して活用する開発手法のことです。すなわち実機をモデルに代替し、シミュレーションを行って開発していくということです。実機レスで開発を進めることができるため、設計の初期段階から検証を行うことができ、開発効率や品質の向上、開発期間の短縮といった多くのメリットが得られます。
特に自動車のように、多数のハードウェア・ソフトウェアが関与し、高度かつ複雑なシステムで、なおかつ人命に関わるような安全性・信頼性が最重要視される領域では、MBDの効果が最大限に発揮されます。


実機での検証はV字工程における下流工程でしか実施できません。しかし、MBDを活用すれば上流工程で早期にシミュレーションを行うことが可能のため、仕様の不備などを少ない工数で迅速に取り除くことが可能になります。これにより、下流工程で不具合が発覚して大きな手戻りが発生し、余分な工数がかかってしまうリスクを大幅に低減することができます。  
また、シミュレーションを行うことで実機では、検証が困難な条件でも容易に行うことができます。  

モデルは「動く仕様書」として、設計者・制御開発者・ソフトウェアエンジニア間でのコミュニケーションや共通認識の形成を支援します。加えて、モデルを使った自動コード生成やテストの自動化も可能なため、品質の高い開発サイクルを短時間で回すことができます。

MBDでは、仕様の変更や設計の改善を繰り返しながら完成度を高めていくように行う繰り返し開発や、既存のモデルをベースに新しいバリエーションを効率的に展開するように行う派生開発が行われるため、一度作ったモデルを資産として扱い、継続的な効果が期待できます。
## モデルベースの開発環境
モデルの開発には、MATLAB、Simulinkが用いられます。MATLABは、数値解析、シミュレーション、データ処理等を得意とするプログラミング言語かつ開発環境です。そしてSimulinkは、MATLAB上で動くブロック線図ベースのモデリング、シミュレーションツールです。  
MATLABが誕生したきっかけは、とある大学の教授が学生にプログラミングの勉強をすることなく、数値解析や線形代数のアルゴリズムを簡単に試せるようにしたいと考えたところから始まったそうです。このような思想から生まれているため、MATLABもSimulinkも直感的な操作を行うことが出来ます。MATLABは数式を書くような感覚で数値計算ができます。ベクトルの大きさ(配列の要素を全て2乗して合計して、平方根をとる)を出したい場合は、以下のように記述するだけで完了です。
```
x = [1, 2, 3, 4];
y = x.^2;       % 要素ごとの2乗
norm = sqrt(sum(y)); % 合計
```
さらに、Simulinkもブロックを配置して線で繋ぐだけで動的システムの設計(モデルの作成)をすることができます。また、そのモデルから自動でコードを生成（ACG : Auto Code Generation）できます。そのため、十分にモデル検証をした後、そのモデルからコードを生成すれば、検証済みのコードを容易に得ることができます。  
このようにMATLABやSimulinkを用いることで、効率的かつ高品質なモデルベース開発を行うことが出来ます。

## おわりに
この記事を通して、MBDとは何か、どのような開発環境で行われているのかがイメージ出来ていただければ幸いです。今後も、自分なりの視点を大切にしながら、知見を共有できる記事を定期的に書いていきたいと思います。
ChatGPTの『プロジェクト』に既存のチャットやファイルが追加できない？

# どういうことか

「ChatGPTの『プロジェクト』とはなにか」という記事などを見ると「チャンネルやファイルをまとめておいてそれらを基準に会話できる」みたいなことが書いてあるが、普段使ってるアプリ版（Mac、iPhone）を見てもそんな機能が見つからない。新規でプロジェクト配下にチャットを作ることはできるんだが……。

## 結論

**Web版だとできる。**
――ということが機能紹介をしている記事のどれにも書いてなかったのでここに書いておく。
アプリ版では2025年4月段階だとできないが、将来的にはできるようになるかもしれない。

## 蛇足

本人（ChatGPT）に機能の説明をさせてみたけど「そういう機能はないよ」と返ってきた。うーん。
ボイスのキャラクターについても訊いたことがあったけどその時もデタラメを返してきた。自分の機能くらい説明してくれると助かるんだけどなぁ。
Node.js + IMAP + SpamAssassin でスパムメールを自動振り分けするツールを作った話

---
title: "Node.js + IMAP + SpamAssassin でスパムメールを自動振り分けするツールを作った話"
date: 2025-04-22
---

## 背景と目的

筆者はあるクラウド型のメールサービス（SpamAssassin が導入されている）を長年使用してきたが、年々迷惑メール（特に詐欺メール）の量が増加してきた。SpamAssassin によるスパム判定はされているものの、スパムフォルダに自動で振り分けられる仕組みはあるにはある。ただし、フィルタの感度を上げると誤検知のリスクが高まるため、あえて低めに設定していた。実際に `X-Spam-Status` のスコアを見ると、1点台などの軽微なスパム判定も多く、閾値の調整だけでは根本的な解決に至らなかった。

また、ブラックリスト登録による対策も行っていたが、送信元を変えてくるスパムも多く、いわゆる「もぐらたたき」になってしまい限界を感じていた。

これらの課題を解決するため、IMAP経由で受信ボックスを巡回し、SpamAssassinの付与する `X-Spam-Status` ヘッダーに基づいて自動的にメールを振り分けるスクリプトを Node.js で実装した。

本記事では、このツールの構成、実装のポイント、運用上の工夫について紹介する。

今回もChatGPT（武志くん）が文書化してくれました。

## 構成

今回のスクリプトは以下のような構成になっている：

- Node.js (v18) で実装
- IMAP クライアントには `imapflow` を使用
- スパム判定には `X-Spam-Status` ヘッダーの内容を参照
- スパムと判定されたメールは IMAP 上の専用フォルダ（例: `INBOX.SuspectedSpam`）に移動
- 誤検知を避けるため、送信元アドレスによるホワイトリスト機能を併用
- 移動前後で UID を再確認し、移動処理が正しく行われたかチェック

この構成により、既存のメールサーバ設定やSpamAssassinの閾値を変更することなく、クライアント側のスクリプトで柔軟に対応できるようにしている。

## 実装のポイント

### `X-Spam-Status` の解析

`X-Spam-Status` ヘッダーには、SpamAssassin による判定結果がテキスト形式で含まれており、例えば次のような内容になる：

```
X-Spam-Status: No, score=5.7 required=6.0 tests=HTML_MESSAGE,RDNS_NONE
```

この文字列から `tests=` 以下のスパム判定ルールを抽出し、複数の特定ルール（例: `HTML_MESSAGE` と `RDNS_NONE`）が同時にマッチした場合のみスパムと判定するようにしている。初期は `OR` 条件でマッチさせていたが、誤検知を避けるため `AND` 条件（`every()`）に変更した。

### 判定ルール `HTML_MESSAGE` と `RDNS_NONE` について

今回スパム判定に使用しているルールのうち、特に次の2つが効果的だった：

- **HTML_MESSAGE**  
  メール本文が HTML のみで構成されている場合に付与される。これは「表示されているリンクの文字列」と「実際のリンク先URL」が異なるなど、詐欺メールでよく使われる手法に悪用されやすいため。  
  一般的に、出所が不明な HTML メールは危険性が高く、隔離対象とする方針をとっている。一方で、企業からの通知など出所が明確な HTML メールではこの限りではない。

- **RDNS_NONE**  
  メールの送信元 IP アドレスに逆引き（rDNS）が設定されていない場合に付与される。正規のメールサーバであれば逆引きが設定されているのが一般的なため、rDNS が無い送信元からのメールは信頼性が低いとみなされる。

これらのルールはそれぞれ単体ではスパムと断定するには弱いため、**両方がマッチしたときにのみスパムと判定する**ようにしている（AND条件）。

### ヘッダの複数行対応

RFCでは、メールヘッダの値が複数行にわたる場合、改行の次の行は空白またはタブで始まると定義されている。そのため、単純な split では正確に抽出できない。ヘッダのパース処理ではこの点に注意し、継続行を適切に結合するようにしている。

### UIDベースでの移動と検証

スパム判定されたメールは IMAP の `MOVE` コマンドを使って専用フォルダに移動させる。`imapflow` では `client.messageMove(uid, dest, { uid: true })` を使うことで UID 指定の移動が可能。

移動直後に同じ UID のメールが `INBOX` に残っていないかを再検索し、失敗していた場合はログを残すようにした。

## 運用と結果

実際に運用を開始してから、1日で 70 通以上のスパムメールを自動で振り分けることができた。Webメール画面で手動で削除していた頃に比べ、心理的・時間的な負担が大きく軽減された。

ホワイトリスト機能も併用することで、必要なメールが誤ってスパムとして扱われるリスクも抑えている。

本スクリプトは Raspberry Pi 4 上で運用しており、`cron` を使って5分ごとに実行することでリアルタイム性もある程度確保できている。

IMAPでの運用のため、スクリプトによってメールが振り分けられると、どの端末（PC、スマホ）でメールを確認しても `INBOX` からは消えている。ただし、スマートフォンの通知機能などにより、振り分け処理が行われる前にスパムメールの通知が出てしまうことがある。この点については、メールアプリの挙動に依存するため完全な制御は難しいが、メールボックスを再同期（取り直し）すれば `INBOX` からは確実に消えている。

なお、これを完全に回避する手段として、該当アカウント宛のメールを一度中継サーバに自動転送し、そこでSMTPレベルでスパムチェックを行った上で別アカウントに転送するという方法も考えられる。ただし、これは構成が大掛かりになるため、今回の実装では採用していない。

## まとめ

SpamAssassin による判定スコアを活用しつつ、IMAP 経由でメールを動的にフィルタリングすることで、既存のメール環境に最小限の変更でスパム対策が可能になった。

本記事で紹介した構成は、SpamAssassin を使っている任意のメールサービスでも同様に応用できる。大量の詐欺メールに悩まされている方にとって、一つの有効な選択肢となれば幸いである。
Elixir OpenChain認定の発表 by José Valim

原文:https://elixir-lang.org/blog/2025/02/26/elixir-openchain-certification/
(監訳: 山崎 進 @zacky1972 )

この度、Elixirプロジェクトは、オープンソースライセンスコンプライアンスの国際標準である[OpenChain](https://openchainproject.org/)（[ISO/IEC 5230](https://www.iso.org/standard/81039.html)）に準拠したことを嬉しく思います。これは、サプライチェーンとサイバーセキュリティのベストプラクティスに関する業界標準を満たすための幅広い取り組みと合致するものです。

「Elixirの準拠に関する本日の発表は、コミュニティの成熟を示すもう一つの重要な例です。」とOpenChainのゼネラルマネージャーであるShane Coughlan氏は述べます。「最終的な上流であるプロジェクトが、コンプライアンスとセキュリティのためにISO標準を使用する頻度が高まっており、サプライチェーンの信頼性を長期的に向上させる方向にシフトしています。」

# OpenChainコンプライアンスが役立つ理由
OpenChain (ISO/IEC 5230)に従うことで、ライセンスコンプライアンスに関する明確な道筋を示すことができます。これは商用ユーザー、コミュニティユーザー共にメリットがあり、Elixirをより簡単に採用し、自信を持って統合することができます。

# Elixirユーザのための変更
Elixirには、成果物が署名される自動化されたリリースプロセスがあります。今回の変更により、このプロセスは以下のように強化されます：

- 今後のすべてのElixirリリースには、[CycloneDX 1.6以降](https://cyclonedx.org/specification/overview/)および[SPDX 2.3以降](https://spdx.org/rdf/terms/)の形式のソースSBoMが含まれる。
- 各リリースは、Source SBoMとともに認証されます。

これらの追加により、各リリースのコンポーネントとライセンスの透明性が高まり、より厳格なサプライチェーン要件がサポートされます。

# 貢献者のための変更
Elixirへのコントリビューションはこれまでとほとんど変わりませんが、より明確なガイドラインが追加されました：

- 寄稿はApache-2.0ライセンスのままです。他のライセンスは受け付けられません。
- プロジェクトは[Developer Certificate of Origin (DCO)](https://developercertificate.org/)を実施し、コントリビューションの所有権を明確にしました。

ライセンスに関する標準的な慣行はそのまま維持されるため、貢献者は手続き上の変更が最小限であることに気付くでしょう。

詳細は[コントリビュートガイドライン](https://github.com/elixir-lang/elixir/blob/main/CONTRIBUTING.md)をご覧ください。

# 誓約
これらのアップデートは[Erlangエコシステムファウンデーション](https://erlef.org/)と協力して行われ、堅牢なコンプライアンスと安全な開発プラクティスへの共通のコミットメントを反映しています。このマイルストーンをサポートしてくれた皆さんに感謝します。私たちはコミュニティの継続的な貢献に感謝し、この確立されたガイドラインのもとでElixirが成長し続けることを楽しみにしています。
出張先でのランチとお土産に悩んでいませんか！？ LINE Botで解決！！

# 自己紹介ときっかけ

はじめまして、こんにちは。  
小売業で、建築関係の業務に従事している”だいちゃん”と申します。

**ランチとお土産を提案してくれるLINE Bot**を作成しました(-ω-)/✨

仕事柄、経営者や他部署の部長とご飯を食べることが非常に多いことから、
入念にランチ先を調べていて、この**調べる時間を解消したい**なー
というきっかけから作成に至りました( *´艸｀)


# 使用したツール
- Make
- LINE Bot
- Google Spreadsheet

# ★完成品★
https://x.com/daidai1994d/status/1917110840622518404


### 機能概要

- 今回は、愛知県内の市町村単位で作成し、
市町村名を入れると、**お勧めのランチとお土産、ランチ先のサイトURL**が
送られてきます。
 →安城市などと、正式な市町村名を入れます！！
- 入力に誤りがあると、**正確に打ってね**と送られてきます。

## Make作成時の全体像

![全体像.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/2ab4029c-d713-440c-ae00-b3ee900c9792.png)
Google Sheetsを連携させて、書き込んだ情報から必要な情報を取得する仕組みです。

---

# （ステップ①）Google Spreadsheetの設定

![スプレッドシート.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/5633e233-6698-4ff1-9527-9fc39e7a7a96.png)

Google Spread Sheetsのデータを準備します。
今回は、一例として愛知県の市町村長名を入れ、
その各市町村のランチ情報と、お土産情報を記載しました。

---

# （ステップ②）Makeのモジュール構成
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/5e710d50-f1bf-4d71-a25e-8daf07bba9fb.png)


Makeで作成したLINE (Watch Events)の右側にGoogle Sheetsモジュールを入れ込み、必要な情報を記載します。
この場合、Google Spread Sheetsの市町村名・お土産例・人気ランチ店・URLのシートを設定し、シート1の市町村名のA列と同等のテキストに反応するようにします。


---

# （ステップ③）Routerの分岐設定
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/f874f989-c829-465c-882d-b39190ad68f4.png)

検索したい市町村名が完全一致するパターンと、
未登録＆完全一致しないパターンで、LINEの返信を変えたいので、
**Router**をつかってLINEの返信を分岐させ、
**LINE Send a Reply Messageを2個作成**します。

---

# （ステップ④）Routerの分岐設定

上の分岐は、市町村名が登録されている（完全一致する）場合の設定：

※**Add OR rule**を選択することがポイントです。

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/b41558da-6f9c-4e47-895a-004e897e079d.png)


下の分岐は、市町村名が登録されていない、完全一致しない場合の設定：

※**Add AND rule**を選択することがポイントです。

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/12aa0df8-2895-419e-807c-c04ed157e8cd.png)



---

# LINEでの返信設定
最後に、
**LINEに返信される内容の設定**を行います。

市町村名が登録されている（正確に一致する）場合：

※Textは、返信させたい**市町村名**、**お土産例**、**人気ランチ店**、**URL**を選択することがポイントです。


![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/cc278f68-4c05-4725-b0f2-33f45db97e1f.png)


市町村名が登録されている（正確に一致する）場合：
**町村名は正確に打ってねm(__)m 例：安城→安城市**と返信させます。

※今回は、直接入力で返信させたい言葉を記載することがポイントです。

![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051385/783b6237-c5d5-4b2f-b006-97e6818cc69e.png)


以上で完成です！！


# 終わりに

身近な私生活においても、
ちょっと足を延ばしたドライブなどの際には、
ランチとお土産の2つに悩むことがあり、同時に2つを調べることが出来るサイトなどはないのでは！？と思います。

是非、ツールを活用し、アレンジにチャレンジしてみて下さい( *´艸｀)✨
複数csvデータの処理

### 概要
Pythonで複数のcsvデータを重複なしで結合する
### Code
```sample.py
import os
import glob
import pandas as pd
from tqdm import tqdm #進捗が見える化


#メインの処理
def process(folderPath):
    #カレントディレクトリを指定
    os.chdir(folderPath)

    #結合ファイルパス
    mrgFilePath = 'merge.csv'

    #結合ファイルがあれば削除
    if (os.path.isfile(mrgFilePath)):
        os.remove(mrgFilePath)

    #ファイルパスを取得
    csv_files = glob.glob('*.csv')
    print(csv_files)
    print(len(csv_files))

    # csvデータを読み込んでlistに格納
    encodings = ["shift-jis","UTF-8","EUC-JP"]
    list = []
    for enc in encodings:
        try:
            #フォルダ内のcsvファイルを読み込んでDataFrameに格納
            for file in tqdm(csv_files):
                list.append(pd.read_csv(file,encoding=enc))
                # encodingを指定
                write_encoding = enc
        except: 
            pass

    #結合    
    df_mrg = pd.concat(list)
    # NaNを0にする
    df_mrg.fillna(0, inplace=True)

    #Time[s]列で重複チェックして、重複削除(最初の重複値は残す)
    if 'Time[s]' in df_mrg.columns:
        df_mrg.drop_duplicates(subset=['Time[s]'], inplace=True,keep='first')
    else:
        #0列目で重複チェックして、重複削除(最初の重複値は残す)
        df_mrg.drop_duplicates(subset=[df_mrg.columns[0]], inplace=True,keep='first')

    print('重複行' , df_mrg.duplicated(subset=['Time[s]']).sum())
    #csv書き込み
    df_mrg.to_csv(mrgFilePath,index=False,encoding = write_encoding) 


if __name__== "__main__":
    
    folderPath = r'C:\data'
    process(folderPath)

```

### 使い方

1\. リスト結合したいcsvファイルをどこでも良いので1つのフォルダに用意する

![スクリーンショット 2025-04-25 075256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940191/13a5552c-9fe9-4ebb-b575-2a75323f2d31.png)

2\. フォルダパスを指定する
```sample.py
if __name__== "__main__":
    
    folderPath = r'C:\data'
    process(folderPath)
```
3\. 実行
ターミナルにファイル名、数、処理進捗、重複数が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940191/b9a0e52a-5b3d-46df-9de0-729d85e681c5.png)
フォルダ内に結合データができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940191/0311a4cf-576f-47a1-872b-a51b8dcad157.png)
RAGで使用するPDFの前処理を検証（PDF→マークダウン形式）

# 内容
Amazon Bedrockを使用したRAGシステムを構築します。ベクトルDBに情報を保存する際、事前に適切な形へチャンク分割を行い、回答精度を高めたいと思います。下記の記事ではHTMLファイルの前処理の検証について記載しましたが、今回はPDFファイルの前処理について記載をします。

https://qiita.com/infra365/items/bff82bc8414c90c09edc

# 仕組み
まず、サンプル用のPDFファイルを準備します。このPDFファイルをPythonのPdfReaderでページ毎に読み込んでテキスト情報を取得します。取得したテキスト情報をAmazon Bedrockに送信後、整形処理の依頼を行います。この際、マークダウン形式での出力指示を行い、出力結果としてマークダウン形式のファイルを作成します。

![rag50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/823dc9f8-ab26-4c03-96bf-b66417e7cc7e.png)

# 実行
まず、サンプル用のPDFファイルを準備します。下記のファイルをダウンロードしてsample.pdfという名前に変更後、下記プログラムと同じディレクトリに保存します。

https://speakerdeck.com/toru_kubota/awsnoli-dian

下記が整形処理用のプログラムになります。まずsampl.pdfを読み込んで各ページのテキストを抽出します。

```python
import json
from pypdf import PdfReader
import boto3

bedrock = boto3.client('bedrock-runtime')

reader = PdfReader("sample.pdf")
texts = []

for i, page in enumerate(reader.pages):
    page_text = page.extract_text(extraction_mode="layout", layout_mode_space_vertically=False)
    texts.append(page_text)
```

Bedrockに問い合わせるためのプロンプトを定義します。

```python
def create_qa_payload(text):
    return {
        "messages": [
            {
                "role": "user",
                "content": (
                    "以下の入力テキストをMarkdown形式に整形してください。\n"
                    "- 出力に```markdown```などのコードブロックの記述は含めないでください。\n"
                    "- 整形されたMarkdown以外の出力（例: 承知しました、見出しの例など）は含めないでください。"
                    )
            },
            {"role": "user", "content": text}
        ],
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 4096
    }
```

各頁のテキストの整形処理を行います。テキスト情報からプロンプトを作成してBedrockに送信後、整形結果を取得します。

```python
concatenated_text = ""

for text in texts:
    payload = create_qa_payload(text)
    
    response = bedrock.invoke_model(
        modelId="anthropic.claude-3-haiku-20240307-v1:0",
        body=json.dumps(payload),
        contentType="application/json",
        accept="application/json"
    )

    result = json.loads(response['body'].read())

    print(json.dumps(result, indent=4))
    formatted_text = result['content'][0]['text'] if 'content' in result and len(result['content']) > 0 else 'No content found'

```

整形結果を一つの文字列に結合後、output.mdファイルを作成します。
```python
    concatenated_text += formatted_text + "\n"

output_file_path = "output.md"
with open(output_file_path, "w", encoding="utf-8") as f:
    f.write(concatenated_text)

print("Result saved locally to:", output_file_path)
```

作成されたマークダウン形式のファイルoutput.mdの出力結果の一部を記載します。

```md:output.md
# AWSの利点

- 間違った物理機器を買ってしまい怒られるのを回避

## AWSの特徴

- AWS責任共有モデル
- AWSグローバルインフラストラクチャ
- ビルディングブロック
# 前回のお話の簡単なおさらい

- AWS責任共有モデル
  - AWSと顧客がクラウド環境を利用する上での責任区分が定義されています。
  - ハードウェアはAWSの責任範囲ですが、データやアプリケーションは顧客の責任範囲です。
# 前回のお話の簡単なおさらい

- AWSグローバルインフラストラクチャ
  - 世界各地にリージョンとAZがあり、顧客は色々な地域のデータセンターを直ぐに利用することが出来ます。
# 前回のお話の簡単なおさらい

- ビルディングブロック
  - 様々なマネージドサービスが提供されており、
  - 顧客はサービスを組合せることによりシステムを構築します。
# AWSの特徴と利点

## AWSの特徴

- 責任共有モデル
- AWSグローバルインフラストラクチャ
- ビルディングブロック

## AWSの利点

- アジリティ
- 可用性の向上
- 運用費用の削減
# オンプレでシステムを構築する際の流れ

1. ハードウェア調達
2. 設置・ケーブリング
3. OSインストール
4. アプリインストール

このうち、AWS側でやってくれる部分は以下となります。

```
React + DockerでHello World

はじめまして、SE8年生の北山一郎です（誰？）
学習記録でもつけていこうかなと思いまして記念すべき一発目の記事です

## はじめに
- macOSです
- React触ったことないからHello Worldしてみよう
- 業務でDocker使ってるし勉強がてらDocker環境を作ろう
- フロントエンドはReact、バックエンドは考えてない
- ホストマシンにnodeとかあまり入れたくない
    - ホストマシンにNode.jsが不要
    - プロジェクト作成とコンテナ起動が1コマンドで完結
    - 既にプロジェクトが存在する場合はスキップ
    - Dockerfile/docker-composeがシンプルに
    - デメリットは初回のプロジェクト作成時に少し時間がかかる

## Docker環境作成

ディレクトリ構成
```
.
└── hello-world-react/
    ├── docker/
    │   └── react/
    │       └── Dockerfile
    └── docker-compose.yaml
```

Dockerfile作成
```Dockerfile
# ./docker/react/Dockerfile
FROM node:18

WORKDIR /app

ENV WATCHPACK_POLLING=true

CMD ["npm", "start"]
```

docker-compose.yaml作成
```docker-compose.yaml
name: hello-world-react

services:
  front:
    build: ./docker/react
    volumes:
      - ./app:/app
    ports:
      - "3000:3000"
```

コンテナ作成&起動
```bash
$ docker compose up -d --build
```

セットアップスクリプト作成
```setup.sh
#!/bin/bash

# appディレクトリが存在しない場合のみ実行
if [ ! -d "app" ] || [ ! -f "app/package.json" ]; then
    # 一時的なコンテナでReactプロジェクトを作成
    docker run --rm -v $(pwd)/app:/app node:18 bash -c "cd /app && npx create-react-app . --template typescript"
fi

# Reactアプリケーションを起動
docker compose up -d --build
```

スクリプト実行
```bash
# スクリプトに実行権限を付与
$ chmod +x setup.sh

# セットアップと起動を実行
$ ./setup.sh
```
[http://localhost:3000](http://localhost:3000)で動作確認
↓のページが表示されていればOK👍
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/36b36851-7bf4-4d63-a2a8-38b85f80060b.png" width="400">

## 「Hello World!!」を表示
`./app/src`配下に`HelloWorld.tsx`を作成
```diff
#app配下は大分略しています
.
└── hello-world-react/
    ├── app/
    │   └── src/
    │       ├── App.tsx
+   │       └── HelloWorld.tsx
    ├── docker/
    │   └── react/
    │       └── Dockerfile
    ├── docker-compose.yaml
    └── setup.sh
```
内容はシンプル
```HelloWorld.tsx
export const HelloWorld = () => {
  return (
    <div>
      <h1>Hello World!!</h1>
    </div>
  );
}

```
作成した`HelloWorld.tsx`を`App.tsx`に読み込ませる
```App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { HelloWorld } from './HelloWorld'; // ここを追加

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <HelloWorld /> {/* ここを追加 */}
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
```
[http://localhost:3000](http://localhost:3000)で動作確認
→のページが表示されていればOK👍
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/36b36851-7bf4-4d63-a2a8-38b85f80060b.png" width="300"> → <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/6041e4da-7ecd-4408-ac9c-529c3cff5530.png" width="300">

## まとめ
- Vue.jsの書き方に似てると思った
- こういう小さいプログラムだとViteなどのビルドツールは無しでも問題ない
- setup.shの`# 一時的なコンテナでReactプロジェクトを作成`でホストマシンを汚さずにプロジェクト作成ができた
- .mdの書き方に少し慣れてきた

## 今後のReact学習
ToDoアプリとか何か作る中でReactの特徴に触れていけたらなと
Geminiでバイオリンを使う魔法少女を描いてみた。

# 概要

Geminiでバイオリンを使う魔法少女を描いてみました。

# 実装

プロンプトと実行結果は以下の通りでした。

```
光のバイオリンを使う魔法少女を描いてください。
```

![光のバイオリンを使う魔法少女_20250425.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/d6bad7e3-29ad-4110-b984-32a6849b090b.png)


```
闇のバイオリンを使う魔法少女を描いてください。
```

![闇のバイオリンを使う魔法少女_20250425.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/139af816-a03a-47ff-ac18-42e3a9c6406c.png)


```
聖なるバイオリンを使う魔法少女を描いてください。
```

![聖なるバイオリンを使う魔法少女_20250425.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/bb3230e2-2b51-4948-9417-577695c8c5f0.png)

# まとめ

光の子は明るい感じですね。
何かの役に立てばと。
Chain-of-Thought（思考の連鎖）推論

# Chain-of-Thought(CoT)推論とは
Chain-of-Thought（CoT）推論とは、複雑な問題に対して「中間的な思考プロセス」を明示的にテキストとして生成することで、より正確な答えを導く手法。

人間が難しい問題を解くときに、「まずこう考えて、それからこうなって…」とステップを踏むように、AIにも「考えるプロセス」を促すことで、推論能力を向上させるのが狙い。

例えば、プロンプトで「12個のキャンディを3人で公平に分けると、何個ずつになりますか？」 という質問を送る時、普通の出力では「４」と帰ってくるが、CoT推論ありでは以下のように帰ってくる

> まず、12個のキャンディを3人で分けるということは、  
> 12 ÷ 3 = 4  
> したがって、1人あたり4個ずつになります。

# Chain-of-Thought(CoT)推論使ってみた
実際にChatGPT 4oを使って、Chain-of-Thought(CoT)推論を試してみる

問題は、京都大学の数学の問題を解かせてみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4062929/4393a074-9772-46eb-b781-e57695b95c82.png)

普通に画像だけを質問として与えた場合は以下の答えになった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4062929/f4a6cd2c-25c8-4c72-9d54-da1b773a7a65.png)

画像と共に「この問題、Chain-of-Thoughtで解いてください。つまり、順を追ってどう考えるかも書いて、最後に答えを教えてください。」というプロンプトを与えることで次のようになった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4062929/9478ebd3-b48c-45de-9cb9-6e8476fb7be8.png)

実際は、以下のような答えになるらしい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4062929/959b7465-6bf7-4dc4-812a-7917db16f0d2.png)

このように、プロンプトで少し文を足してあげるだけで、ChatGPTの答えの精度が上がることを確認できた。

# Chain-of-Thought(CoT)推論はどのような所で使われいるのか
今回、Chain-of-Thought(CoT)推論を見つけたのは、「The AI Scientist」の論文中である。

AIが研究アイデアの生成からコードの実行、論文の執筆、査読までを自動で行う「AI Scientist」フレームワークについての論文だ。

生成AIの発展とともに、いろんなことができるようになったが、論文を書けるようになったのは驚きだ。

私は、生成AIを使いこなせるようになりたいと思った。

# 関連リンク

「The AI Scientist」の論文

https://arxiv.org/abs/2408.06292?utm_source=chatgpt.com

京都大学の入試問題の問題・解説

https://mikiotaniguchi.com/main/center/main.htm
windows11で、sketchup6 その79

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
パイプを描く、rubyスクリプトを書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/adf8d23c-4ef6-40ff-b862-9ceceeb372e4.png)

# サンプルコード

```
def create_pipe
	model = Sketchup.active_model
	entities = model.entities
	radius1 = 4
	radius2 = 8
	center = ORIGIN
	normal = Z_AXIS
	segments = 24
	edges1 = entities.add_circle(center, normal, radius1, segments)
	edges2 = entities.add_circle(center, normal, radius2, segments)
	faces1 = (entities.collect { |ent|
		ent if ent.is_a? Sketchup::Face
	}).compact
	edges1[0].find_faces
	faces2 = (entities.collect { |ent|
		ent if ent.is_a? Sketchup::Face
	}).compact
	edges2[0].find_faces
	face_to_remove = faces2 - faces1
	face_to_remove[0].erase!
	face = entities.grep(Sketchup::Face)[0]
	face.pushpull -40
end
```

以上。
windows11で、sketchup6 その78

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
丸い穴を開ける、rubyスクリプトを書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b180cb91-72a2-4c3c-92d1-c931696406a1.png)

# サンプルコード

```
def create_donut
	model = Sketchup.active_model
	entities = model.entities
	radius1 = 4
	radius2 = 8
	center = ORIGIN
	normal = Z_AXIS
	segments = 24
	edges1 = entities.add_circle(center, normal, radius1, segments)
	edges2 = entities.add_circle(center, normal, radius2, segments)
	faces1 = (entities.collect { |ent|
		ent if ent.is_a? Sketchup::Face
	}).compact
	edges1[0].find_faces
	faces2 = (entities.collect { |ent|
		ent if ent.is_a? Sketchup::Face
	}).compact
	edges2[0].find_faces
	face_to_remove = faces2 - faces1
	face_to_remove[0].erase!
end
```

以上。
ある日のDaily Training

## はじめに

今週は私用でABC403に参加できそうにないので、代わりに昨日の[AtCoder Daily Training](https://atcoder.jp/contests/adt_top "AtCoder Daily Training")の結果を公開してみます。
難易度はEASYです。まだまだ灰色コーダーですし。
Xのハッシュタグ：#ADT_20250424_1

## AtCoder Daily Trainingとは？

- AtCoder Beginner Contest(ABC)に出題された過去問を1時間で解くトレーニング
- (現在は)火水木曜の夕方〜夜(1日3回)に行われている
- 難易度選択が可能だが、同時刻の複数難易度に同時参加することはできない
- レートは変化しないし、記録にも残らない。あくまでもトレーニング
- 詳細は上のリンク先を参照のこと

## A - Pawn on a Grid

#の数を数えるだけのかんたんなお仕事です。
全探索で行いました。

```cpp:A.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int h, w, ans = 0;
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < w; j++) {
      if (s[j] == '#') ans++;
    }
  }
  cout << ans << endl;
  return 0;
}
```

## B - Tires

末尾が"er"か"ist"の文字列を与えられるので、末尾の"er""ist"を返す問題です。

"er"か"ist"なので、末尾が"er"の場合に"er"と答えましたが、今考えれば文字列全体をreverseで反転させて"re"から始まることを確認すれば末尾が"er"ということなんですよね……。

```cpp:B.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  string s;
  cin >> s;
  if (s.find("er") == s.size() - 2) cout << "er" << endl;
  else cout << "ist" << endl;
  return 0;
}
```

## C - Who is missing?

カードデッキから1枚抜き取られたカードを判定する問題です。
今回はmapを活用しました。
カードを受け取る際のループ回数が$4N-1$なのは注意点です。

```cpp:C.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;
  map<int, int> a;
  for (int i = 0; i < 4 * N - 1; i++) {
    int ain;
    cin >> ain;
    a[ain] += 1;
  }
  for (int i = 1; i <= N; i++) {
    if (a[i] == 3) {
      cout << i << endl;
      return 0;
    }
  }
  return 0;
}
```

## D問題以降

私用のため時間がなくて解けませんでした。

## まとめ

- 速度はまだまだ遅い
- たまに理解不能な問題がある
- 圧倒的数理素養不足
- 要勉強・トレーニング

## その他

[アルゴ式](https://algo-method.com/ "アルゴ式")はじめました。

## 最後に

ここまで読んでいただき、ありがとうございました。
では、私用に行って参ります。
GitHub Copilot のコード補完をワークスペース単位でオフにする

# 🎯 結論
`./vscode/settings.json` を以下のように書く。
```json: settings.json
{
    "github.copilot.enable": {
        "*": false
    }
}
```

# 1. はじめに

最近は GitHub Copilot に頼り切った個人開発を行っており、コード補完の Tab キーを頭空っぽで押していることに気がつきました😅。就活のためにコーディングテスト対策を始めたとき、Tab キーの連打は流石にテスト勉強にならないと感じ、**ワークスペースごとにコード補完をオフにしたい**と思ったわけです。

![スクリーンショット (482).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668362/eb60db11-0972-4493-84c3-ca4d6f946c0e.png)


# 2. 手順

1. コマンドパレット（ `Ctrl` + `Shift` + `P` ）から「 `github copilot enable` 」などと検索し、"GitHub Copilot: Toggle (Enable/Disable) Completions" をクリックする

   ![スクリーンショット (486).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668362/6a920d0e-ae1b-410e-bd9e-d1096aea1a1f.png)

2. `.vscode` に `settings.json` が書き加わる

- 全体設定よりもワークスペースの `.vscode/settings.json` が優先される
- 以下は無くても問題ないと思われる

  ```diff: settings.json
  {
      "github.copilot.enable": {
          "*": false,
  -       "plaintext": false,
  -       "markdown": false,
  -       "scminput": false
       }
  }
  ```

:::note info
**コード補完のみ**のオフであり、**Copilot Chat** などは使えます。
:::

# 3. 応用

**特定のファイルだけ**のオン/オフができるので、例えば次のようなことも可能です。

**事例①**: 
- 原則コード補完はオフだけど、Python にまだ慣れてないから、Python だけコード補完オンにしたい

  ```diff: settings.json
  {
    "github.copilot.enable": {
        "*": false,
  +     "python": true
     }
  }
  ```

**事例②**: 
- 原則コード補完を使いたいけど、`.txt` や `.md` には要らないかな

  ```diff: settings.json
  {
    "github.copilot.enable": {
        "*": true,
  +     "plaintext": false,
  +     "markdown": false
     }
  }
  ```
個人学習用にGitHub Organization アカウントを作成した

## 背景

リポジトリが学習用とアプリケーションで混在しているのがややこしくなってきたので、学習用に作成したものをどうにかしたいとGeminiさんに聞いたら「学習用のOrganization作成したら？」と返ってきたので作成した話。

## 手順

1. 右上のユーザーアイコンから Your organizations を選択する。
1. 所属しているOrganizationsの一覧が表示されるので、SubHeaderの右にある New organization ボタンからGitHub で新しいOrganizationを作成する(個人学習用なのでfreeでOKです)。
1. 項目を埋めてOrganizationを作成する。

これで個人学習用のOrganizationが作成できたので学習用のリポジトリを移せば完了です。

ただ、このままだとVSCodeでリポジトリを使おうとしたとき Remote Repositories にプライベートリポジトリが表示されません。

### 対策

Organizations の settings のサイドバーに次の項目があるのでそれを選択します。

![oauth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4011379/2e9f245b-f747-40bb-b621-c1cf165e56f9.png)

ここの Third-party application access policy で Access restricted になっていたのでVSCodeが認証されなかったかんじです。ボタンを押すとアプリごとの承認が不要になるのでユーザーが承認しているサードパーティのアプリがアクセス可能になります。

![access-policy_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4011379/ef0e3f92-a1f3-4d60-9f8f-445ff10d3216.png)

この Remove restrictions ボタンを押すとメンバーなら誰でもサードパーティのアプリを入れられるので、メンバーの信用できない Organization だとセキュリティ的にだいぶ不味いんですが、個人学習用なので問題ないです。

これであとは Remote Repositories に http URL を入力してやれば VSCode でもちゃんと Organization のプライベートリポジトリが使用可能になります。
検索インデックスを使う場合、VSCode を承認した直後だと、検索インデックスに反映されてないので時間を置いて再試行してみてください。
【Rails初学者】Rails 8.0 の406エラーに対する対策 もう一度まとめておく

# Rails 8で発生する406エラーの原因と対処法まとめ

こんにちは。
現役看護師で、幼い子供を育てつつ、無謀かもしれませんがエンジニアを目指している母親です。
Rails 8以降では、**Chromeのデバイスモード**や**ローカル環境のアクセス**などで「406 Not Acceptable」エラーが発生するケースがあります。

本記事では、エラーの原因と、その対処法を2つを備忘録として再度載せます。

---

## どんなエラーが表示されたのか

Deviseでログインページ（例：`/users/sign_in`）にアクセスしたときに、
```
Rendering public/406-unsupported-browser.html Completed 406 Not Acceptable
```

と表示されて、ページが表示されないことがある。

---

## 原因

Rails 8（および Rails 7.2）から追加された以下の設定：

```ruby
# app/controllers/application_controller.rb
allow_browser versions: :modern
```

この`allow_browser`は、古いブラウザやUser-Agentが不明なアクセスをブロックする機能。

## ブロックされる主なケース

以下のような場合、User-Agentが "modern" でないと判断され、Rails 8 では406エラー（Not Acceptable）が発生。

- Chrome DevTools で「モバイル表示」にしたとき  
- IPv6やローカル環境など、User-Agentが不明とみなされたとき  

### 特に以下のブラウザバージョンは「modern」の基準を満たさず、ブロックされる可能性がありそう。

| デバイス例             | ブラウザバージョン |
|------------------------|--------------------|
| iPhone 14 Pro Max      | Safari 16.6        |
| Pixel 7                | Chrome 116         |
| Galaxy S20 Ultra       | Chrome 116         |


## 対処法1：ApplicationController側で制限を外す（開発中のみ）

```ruby
# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # allow_browser versions: :modern ← これをコメントアウトする
end
```

または環境ごとに条件分岐させて本番環境のみ有効にする方法もあるようです。
```ruby
if Rails.env.production?
  allow_browser versions: :modern
end
```

### メリット

- 本番では制限を有効にできる

### デメリット

- コメントアウトを忘れて本番環境に出すと古いブラウザも許可してしまう

---

## 対処法2：`development.rb`でUser-Agentチェックを無効化
```ruby
# config/environments/development.rb

Rails.application.configure do
  # 末尾に追加
  config.action_dispatch.allow_browser = ->(user_agent) { true }
end
```

この設定を入れると、開発環境で常にすべてのブラウザを許可できるようです。

### 設定後はサーバー再起動が必要になります。

```bash
# サーバー停止後に再起動
bin/dev
# または
rails server
```

## おわりに

今回紹介した2つの対処法のどちらかを実施することで、開発中に発生する406エラーは解消される可能性がありそうです。
以前、対処法2：`development.rb`で User-Agent チェックを無効化する方法のみを取っていましたが、他のやり方もあったので忘れないようにまとめました。
ISR SSG SSR CSRについて

# Next.js の 4つのレンダリング方式
### 1. SSG（Static Site Generation）
静的サイト生成：ビルド時にHTMLを作って保存しておく方式

```
🛠️ ビルド時にページを作成 → 📦 HTMLファイルとして保存 → 🌍 リクエスト時はそれを配信
```
特徴： ページはあらかじめ生成済み → 爆速表示

使いどころ： 内容があまり変わらないページ（ブログ、企業サイト、商品一覧など）

関数： getStaticProps

✅ メリット：

表示が超早い（CDNキャッシュOK）

サーバー負荷が少ない

⚠️ デメリット：

更新内容を反映するには再ビルドが必要（※ISRで解決できる）

### 2. ISR（Incremental Static Regeneration）
静的再生成：SSGの欠点をカバー！必要に応じて再生成する方式

```
📦 HTMLを保存 → ⏰ 設定した時間ごとにバックグラウンドで自動更新
```
特徴： 静的な速さを保ちつつ、一定時間ごとにデータを自動更新

使いどころ： 頻繁に変わるけど高速表示したいページ（ニュース記事、ランキングなど）

関数： getStaticProps + revalidate

✅ メリット：

SSGの速さ + SSRの新しさ → 両方の良いとこ取り！

### 3. SSR（Server Side Rendering）
サーバー側レンダリング：アクセスのたびにサーバーでHTMLを生成

```
👤 ユーザーがアクセス → 🌐 サーバーでHTML生成 → 📄 表示
```
特徴： 常に最新データが取得できる

使いどころ： ユーザーによって内容が変わるページ（マイページ、ダッシュボードなど）

関数： getServerSideProps

✅ メリット：

毎回最新のデータを表示できる

⚠️ デメリット：

毎回サーバー処理が発生 → SSGより遅い・負荷がかかる

### 4. CSR（Client Side Rendering）
クライアント側レンダリング：HTMLは空っぽ、ブラウザ側でJSが実行されて描画

```
📄 最初はHTMLスケルトン → 📦 JS読み込み後にデータ取得 → 🖼️ 描画
```
特徴： フロント側でのみ描画、React単体でもこの方式

使いどころ： SPA（シングルページアプリケーション）や動的ページ（ログイン後のページなど）

✅ メリット：

表示内容の変更が自由

APIで自由にデータ取得・更新できる

⚠️ デメリット：

初期表示が遅く、SEOに弱い

✅ 各方式のまとめ表
|   方式  |  表示速度  |    SEO   | データの新しさ | サーバー負荷 | 使いどころ |
|:-------|----------:|:--------:|:------------:|:---------:|:---------:|
| SSG     | ◎ 爆速    | ◎ 強い   | ✕ 古くなりがち | ◎ 低い     | ブログ・会社概要 |
| ISR     | ◎ 爆速    | ◎ 強い   | ◯ 自動で更新  | ◯ やや低め   | ニュース・商品ページ |
| SSR     | ◯ 速め    | ◎ 強い   | ◎ 常に最新    | △ やや高い  | ユーザー別ページ |
| CSR     | △ 遅め    | ✕ 弱い   | ◎ 常に最新    | ◎ 低い     | SPA、内部ページ |

 ### 🔍 ポイント：

表示速度を重視するなら → SSG / ISR

リアルタイム性を重視するなら → SSR / CSR

SEOが重要なら → SSG / SSR / ISR（CSRは不向き）

## 因みに。。。

Next.js 13〜14以降では、
Pages Router構成（page/）からApp Router構成（app/）へ変わり、
ページファイル自体がasync functionとして動けるようになった。

そのため：

getStaticProps = 1つの特別な関数 → 不要になった

ページ全体が async なので、 fetch() やファイル読み込みを直接書ける

https://qiita.com/aotatsu8/items/3950c116baef4d415f6f
https://qiita.com/aotatsu8/items/0accec38f971f1209935
令和７年秋季情報処理安全確保支援士受験計画

# はじめに
令和７年春季試験を受験したのですが、不合格だと思うので次回の試験に向けて再スタートを切ります。
只今、2025年4月25日で試験の直後ですが落ち込んでいる暇はありません。
試験の直後だからこそ分かる、苦手な分野や手薄な箇所を書き出しておこうと思います。

# 計画立案
何事も計画が重要です。とかく時系列は把握しづらく手遅れになって取り返しがつかなくなることが往々にしてあります。
まずはWBSを作成して工程全体を把握したいと思います。
工程には試験手続きや試験のために勉強する項目を書き入れたのですが、仕事や旅行など勉強できない期間等も書き入れて、勉強する時間配分を把握します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/709c2479-99b2-4c93-8d62-c3f966a556e7.png)

# 基礎力向上
午後の対策をしたいのですが、過去問をやっても全く完成度が上がりません。これは前回勉強していたときに感じていたことなのですが、何をやったらいいのか全くつかめなかったのですが、他の方の勉強方法を見ると基礎力をつけることが一番なようです。
また、午後の問題は長文を短時間で把握しなければなりません。問題文に書かれている状況や正確に情報を整理する方法を探求し身につけたいと思います。

# 苦手分野
令和５年までの過去問は午前Iの問題文は過去問とほとんど同じだったのですが、令和６年以降は問題文に変化が見られ出題形式もちょっとひねった問題文となっています。過去問を丸暗記したのでは、対策が手薄になってしまうためマネジメント系やストラテジ系の分野のキーワードを一度整理して覚え直したいと思います。

# 受験対策にあたり
今回の対策で２つほど取り組みたいことがあります。

## お金をかけない
企業では研修制度などで有料セミナーの補助金が出たり、企業内で主催される研修会が実施される場合もあります。しかし私は個人事業主の為、そのような研修を利用することができません。身銭を切って自腹でセミナーを受講することもできますが、自分だけの力でどこまで行けるのかを試してみたいので、極力お金をかけずに取り組みたいと思います。

## 実施記録を残す
これは受験対策以外にも通づることなのですが、「何をやったのか」記録を残すということは非常に重要なことです。あとから振り返って対策の網羅性を検証する際にも大変役に立ちます。学習の過程をこのQiitaにブログとして残していきたいと思います。

# ダメな自分を受け入れよう
最近は働き方改革や自己評価制度や実績ベース評価制度など、今までの指針とは一転した見えないプレッシャーと言うのが取り巻いていると思います。その中で自分を高めていかなければならないと感じる場面が応分にあると思います。
ただ、そんなことをしていたらストレスで精神がぶっこわれると思うんです。
自分はできないんだ、ダメなんだという前提に立ち戻って受験に取り組むことで、自分の苦手分野を発見したり、プレッシャーやストレスを排除したいと思います。

あと、下記のReHacQは神回だと思います。見たほうがいい。

<iframe width="560" height="315" src="https://www.youtube.com/embed/-gH_yMoQVE4?si=0ldlHQT3W-Wna2_C" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 最後に
前回、試験会場で感じた「コイツラと一緒に戦ってきたんだ」という新鮮な感覚を忘れずに、このさき半年間一人で取り組んでいきたいと思います。
ChatGPTを使ってライティングを向上させる方法ーExpressVPNより

※以下の内容はExpressVPNによる記事からまとめています。
https://www.expressvpn.com/blog/guide-how-to-use-chatgpt-to-improve-your-writing/#:~:text=Ask%20it%20to%20provide%20references,existing%20sample%20of%20your%20writing.


### 📚 ChatGPTでできること（おすすめの使い方）
#### 1.既存の文章の強化
誤字脱字、文法ミスの修正

- 文構造の改善

- 論理展開の明確化

#### 2. アイデア生成
- ターゲット読者になりきってもらう（例：「高校生の視点で」）

- “What if（もしも）” シナリオを考える

- 歴史上の人物や架空のキャラクターになりきって回答

- 隠喩や比喩を使って新しい視点を引き出す

- ランダムな単語・フレーズを生成して発想のきっかけに

#### 3. 語彙力アップ
- 類語・反意語を提案

- 定義や使用例を提示

#### 4. 文体を磨く
- 説明文、物語文、論説文などのスタイルに合わせた書き方を学ぶ

- SEOライティングなどのジャンル別トーンに適応

- 執筆前の構成案作成

### ✏️使い方のポイント：まずは「プロンプト」が命
曖昧な指示（例：「文章を添削して」）では不十分。文脈や意図を明確に伝える必要があります。

    🎯 良いプロンプトの例
    「英語学習のロードマップを作成してください。
    ・超初心者向け
    ・大人
    ・話すことを目的
    ・TOEIC750点を目標
    ・一日30分程度目安

### 🧰 ライティング技術別にできること

✨ 技術	🧠 ChatGPTの活用例
- 要約	重要な点だけを抜き出して短くまとめる
- 言い換え	難解な表現を平易な表現に置き換え
- 統合（統合的理解）	複数の情報を組み合わせて独自の主張に仕上げる
- 編集・校正	文法、スタイル、句読点などを改善
- ストーリーテリング	構成、キャラクター設定、起承転結のアドバイス
- 能動態・受動態の変換	より明快で活発な文にするための切り替え
- 対話文の作成	キャラ間の自然な会話文を生成
- 象徴表現（シンボリズム）	抽象的テーマを象徴する具体物の提案
- トーン調整	読者層や目的に応じた文体調整
- 論理のつながり	パラグラフ間の移行をスムーズにする接続語の提案

### プロンプト設計のやるべきこと・避けるべきこと

| ✅ やるべきこと                                | ❌ 避けるべきこと                                             |
|---------------------------------------------|--------------------------------------------------------------|
| “簡潔に”“具体的に”などの指示を出す            | 文化的・個人的な前提をAIが理解していると思い込む             |
| 文体・トーン（例：New York Times風）を指定     | 検証できない事実の提供を求める                                |
| 読者層を指定（例：プロ向け、学生向け）         | 引用や参考文献の信頼性を鵜呑みにする                          |
| 自分の文章サンプルを渡し、文体を模倣させる     | チャット内でトピックを頻繁に切り替える                        |
| 例やたとえ話を含める                          | 機密情報を入力する                                            |
| 明確な段階分けで依頼（例：まず導入だけ）       | 最初の出力をそのまま使う（試行錯誤が重要）                   |

### ⚠️注意点
AIを活用するのは、人間の力の強化や補助として捉えること。
あくまでもアイデアの補助であること。

考えを言語化するトレーニングは欠かせません！
日頃から、考えたことをまとめる癖づけをしましょう！

また、出力されたものは必ず正しいわけではないのでしっかりと調べて評価と判断をするように心がけ、決して鵜呑みにするのはやめましょう！
Next.jsのメリット

# Next.js の強みとメリット（比較で理解）
🚫 従来（Next.jsなし）の課題
❌ ページごとのルーティング設定が面倒（React Routerの設定が必要）

❌ サーバーサイドレンダリングは自前で構築が大変（Expressなどと組み合わせる必要）

❌ パフォーマンス最適化が手間（画像最適化、コード分割などを自力で設定）

❌ SEOに弱い（クライアントサイドレンダリングだとクローラーが読めない）

❌ ビルド時と実行時のコードが複雑に分離しやすい

## Next.js 導入後の改善ポイント
### 1. 📁 ファイルベースルーティング

Before: React Routerでルートを手動定義

After: pages/ フォルダにファイルを置くだけで自動ルーティング
```
/pages/index.tsx       →  /
/pages/about.tsx       →  /about
/pages/blog/[id].tsx   →  /blog/1, /blog/2 ...（動的ルーティング）
```
→ ページ追加・保守が圧倒的に楽！

###  2. ⚡ SSG & SSR によるパフォーマンス最適化
Before: CSRのみ → 初回表示が遅くなりがち

After:

SSG（静的生成）→ 爆速表示＆CDNキャッシュOK

SSR（動的レンダリング）→ 毎回最新データで表示
```
// SSG
export async function getStaticProps() {
  return { props: { posts: [] } };
}

// SSR
export async function getServerSideProps() {
  return { props: { user: {} } };
}

```
→ ページごとに柔軟に選べる！

### 3. 🔍 SEO対策に強い
Before: CSRだとGoogleが内容を読み込めずSEOに弱い

After: SSRやSSGでHTMLを返せるので、クローラーも正しく認識できる
→ ブログ、企業ページ、ECサイトでも安心！

### 4. 📦 画像最適化（Next/Image）
Before: 手動で画像圧縮、レスポンシブ対応も工夫が必要

After: <Image /> コンポーネントで自動最適化（WebP変換、遅延読み込みなど）

### 5. 🛠️ APIルートが使える
Before: 別サーバー（Expressなど）でAPI構築が必要

After: pages/api/ にファイルを置くだけでAPI完成！
```
// /pages/api/hello.ts
export default function handler(req, res) {
  res.status(200).json({ message: "Hello Next.js API!" });
}
```

### 6. 🌍 デプロイが簡単（Vercelとの親和性）
VercelにGitHub連携すれば即デプロイ

CI/CD、画像最適化、キャッシュなども自動でやってくれる

## 🏁 結論：Next.jsで何が変わる？


| 比較項目 | Reactのみ（Nextなし） | Next.jsあり |
|:-:|:-:|:-:|
| ルーティング  | 手動設定が必要  | ファイル名ベースで自動  |
| SEO対応  | 弱い（CSR）  | 強い（SSR/SSGで対応）  |
| サーバーとの連携  | 別構築が必要  | APIルート内蔵  |
| 表示速度  | 初回遅いことがある  | SSGで爆速、SSRで最新表示が可能  |
| デプロイ  | 設定が煩雑  |  Vercelと連携で簡単 |
【React×Vite入門】Macローカル環境でフロントエンド開発を始めてみた話

🎯この記事に書くこと
	•	Reactとは何か？なぜ使うのか？
	•	ローカルMac環境でReact + TypeScriptを使った開発環境を構築する手順
	•	create-react-app の代替として Vite を導入した経緯と感想
	•	エラー回避のための Node.js バージョン注意点
	•	就活用ポートフォリオ開発の第一歩としての位置づけ

👨‍💻 想定読者
	•	Webアプリ開発初心者（JavaScriptやTypeScriptを少し触ったことがある方）
	•	create-react-app ではなく Vite を使いたい人
	•	就活ポートフォリオとしてReactを学びたい大学生・大学院生
	•	Mac + VSCode 環境でReactを始めたい方

🔧 開発環境

項目 | 内容
PC | MacBook Air (Apple M1)
OS | macOS 14 Sonoma
Node.js | v18.15.0 → v18.20.2 に手動切替
npm | 9.5.0
エディタ | VSCode
パッケージ管理 | npm
使用テンプレート | Vite + React + TypeScript

🚀 なぜViteを使うのか？
Reactの学習を始めたばかりの私は、当初「create-react-app（CRA）」でプロジェクトを立ち上げようとしましたが、以下のような理由でViteへ乗り換えました。

CRAはすでに公式に「非推奨（deprecated）」になっている
起動が遅く、依存パッケージが古いためエラーが出やすい
最新の開発では、ViteやNext.jsが主流になっている
Vite = 超高速のReact開発テンプレート
開発サーバーの立ち上がりも爆速で、初学者にも優しい印象でした。

⚙️ 手順まとめ（React + Vite + TypeScript）
① 

Node.jsのバージョン注意
```
node -v
```
#=> v18.15.0（※一部パッケージでエラー）

Nodeのバージョン切替
```
sudo npm install -g n
sudo n 18.20.2
```

② 

ViteでReactテンプレートを作成
```
npm create vite@latest todo-frontend -- --template react-ts
cd todo-frontend
npm install
npm run dev
```
③ ブラウザ確認

Local: http://localhost:5173/

✅ 問題なく立ち上がれば成功！

🐛 詰まったポイント（初心者向け）
Node.jsのバージョンが古いと、正規表現やeslintでSyntaxErrorが出る
create-react-appだと非推奨パッケージで大量のエラーが出た
Anacondaなどが node コマンドに影響する場合があるため which node で確認必須

🎓 今後の展望（Next Steps）
タスクの一覧表示、追加、削除などの基本UIをReactで構築
状態管理（useState, useEffect）の習得
Tailwind CSSを導入してUI整備
RailwayやVercelへのデプロイ


📝 まとめ
項目 | 学んだこと
環境構築 | ViteはReactの最速環境構築に最適
トラブル対応 | Node.jsのバージョンは超重要
就活視点 | 

📚 参考文献
Vite公式ドキュメント： https://vite.dev
React公式サイト： https://react.dev
Qiita内の多数の入門記事

🔗 おわりに

本記事は、Web開発初学者としての学習記録であり、React + Vite を導入して開発環境を構築した初期ステップのまとめです。今後は API との連携や UI デザインの整備を進め、最終的にはクラウド環境へのデプロイまでを目指していきます。
gpt-image-1が無料で試せるサイト作りました【個人開発】

gpt-image-1が無料で試せるサイト(3回まで無料)
https://gpt-image.dev/


## はじめに
近年、AI による画像生成技術は大きく進化し、OpenAI がリリースした gpt-image-1 モデルはテキスト入力だけでなく、複数の画像を参照しながら高品質なヘッドショットを生成できるマルチモーダルモデルとして注目を集めています。  
しかし、API を直接叩くには環境構築やコード実装が必要でハードルが高いのも事実です。  
そこで登場するのが gpt-image.dev であり、誰でもブラウザだけで gpt-image-1 の性能を無料で試せるように設計されています。

## gpt-image.dev とは
gpt-image.dev は、OpenAI の gpt-image-1 API をバックエンドに利用し、複数のリファレンス写真から一貫性のある AI ヘッドショットを生成するシンプルな Web インターフェースです。  
ソースコードは GitHub でフルオープンに公開されており、ダウンロードして自分のサーバーにホストすることも可能です。

## 特徴
- **API キー設定**  
  「Set api key」ボタンから OpenAI API キーを簡単に設定できます。  
- **複数リファレンス画像**  
  同一人物の複数のヘッドショット写真をアップロードすることで、生成結果の一貫性を高めることができます。  
- **カスタムテキストプロンプト**  
  テキストプロンプトを自由に入力し、ヘアスタイルや表情など細かな指示を与えられます。  
- **インブラウザプレビュー**  
  生成された PNG 画像はフォーム下部に即時プレビューされ、ダウンロードも即座に可能です。  
- **gpt-image-1 モデルの特性**  
  gpt-image-1 はマルチモーダル対応で、テキストと画像を併用した高度な画像生成が可能です。  
- **グローバル対応**  
  API は世界中からアクセス可能で、組織の認証が必要な場合もありますが、基本的に無料トライアル枠で試すことができます。

## 使い方
1. `index.html` を任意の Web サーバーにホストします。  
2. 「Set api key」をクリックし、OpenAI の API キーをペーストします。  
3. 「Reference headshot photos」をクリックして、同一人物の写真を複数選択・アップロードします。  
4. テキストエリアに生成したいヘッドショットのスタイルや背景などを記述します。  
5. 「Generate」ボタンをクリックして POST リクエストを送信します。  
6. 生成されたヘッドショットがプレビューエリアに表示されますので、右クリック等で保存してください。

## 注意事項
- OpenAI API の無料枠には上限がありますので、試用中に枠を超えた場合は追加課金が発生する可能性があります。  
- アップロードする写真は同一人物のものをご用意ください。異なる人物の混在は生成精度の低下を招きます。  
- API キーの管理には十分ご注意ください。不正利用を防ぐため、公開リポジトリに直書きしないことを推奨します。

## 関連リンク
- [gpt-image.dev GitHub リポジトリ](https://github.com/GitHub30/gpt-image.dev)   
- [OpenAI 公式ドキュメント: GPT-image-1 モデル](https://platform.openai.com/docs/models/gpt-image-1)   
- [OpenAI 画像生成ガイド](https://platform.openai.com/docs/guides/images)   
- [Medium 記事: OpenAI’s GPT-Image-1 API 解説](https://medium.com/@types24digital/openais-gpt-image-1-api-create-stunning-images-for-your-apps-902c4f6745b1)   
- [Replicate: gpt-image-1 モデルページ](https://replicate.com/openai/gpt-image-1/api)   

以上の手順で、コード不要・環境構築不要で「gpt-image-1」を手軽に試せる gpt-image.dev をぜひご活用ください！
TypeScript × React で「型 '{ host: Host; }' を型 'Host' に割り当てることはできません」エラーが出たときの対処法

React + TypeScript で開発していると、以下のようなエラーに遭遇することがあります。

```bash
型 '{ host: Host; }' を型 'Host' に割り当てることはできません。
プロパティ 'host' は型 'Host' に存在しません。
```
このエラーが発生する背景と、具体的な解決方法についてまとめました。

# エラーの原因
このエラーは、「propsの型定義と実際の使い方が一致していない」ことが原因です。

たとえば以下のようなコードを想定します。

```TypeScript
type Host = {
  title: string;
  people_number: number;
};

const HostCard = (props: Host) => {
  return <div>{props.title}</div>;
};

// 呼び出し側
<HostCard host={host} />
```
このコードでは、HostCard の props の型として Host を使っています。つまり、props に直接 title や people_number を渡す前提になっています。

しかし、実際の呼び出しでは host という名前で一つのオブジェクトを渡しているため、「host プロパティは型 Host に存在しない」と怒られてしまいます。

# 解決方法
propsを渡すときに host={host} のように名前付きで渡すのであれば、型もそれに合わせて次のようにします。

```TypeScript
type Host = {
  title: string;
  people_number: number;
};

type HostCardProps = {
  host: Host;
};

const HostCard = ({ host }: HostCardProps) => {
  return <div>{host.title}</div>;
};

// 呼び出し側
<HostCard host={host} />
```
このように、propsの構造（ここでは { host: Host }）に合わせた型を定義することで、型の不一致エラーを解消できます。

propsの構造と型定義の関係
下記のように、コンポーネントの呼び出し方法に応じて適切な型定義を行う必要があります。


呼び出し方法	型定義の例
```TypeScript
<Component {...host} />	type Props = Host
<Component host={host} />	type Props = { host: Host }
```
# まとめ
props: Host としていると、呼び出し側で host={host} と渡すことはできない

props: { host: Host } という型にすれば、<Component host={host} /> という使い方ができる

呼び出し方に応じて、propsの構造と型定義を一致させることが重要

TypeScriptの型は強力ですが、propsの構造に敏感なので、意図に合わせて型定義を設計することが大切です。
結局pythonのwebフレームワークってどれ使えばいいの？

# こんにちは
Python教の皆さんごきげんよう
Python で Web アプリを作ろうと思ったとき、「結局 Django？Flask？FastAPI？」って迷いません？迷うと言ってください。
僕も調べるまではそれぞれ開発で本格的には使ったことがなかったので、どれがどう違うのかまったくピンと来ていませんでした。 ということで今回は備忘録代わりにまとめてみました。

# 先に結論

**用途による！**  

待って！！ブラウザバックしないで！!

凡庸な結論で大変申し訳ありませんが、それぞれ一長一短あるからこそフレームワークは同時に存在しているのです。銀の弾丸なんてねぇのです。
これから技術選定をする人にとって少しくらいは参考になるかと思うのでどうか見ていってほしいな、って...

# 比較フレームワーク

比較対象は **Django**、**Flask**、**FastAPI** の３つ。  
調べてみるとTornado や Sanic、aiohttp など他にも色々あるみたいですけど、正直僕は今日まで名前くらいしか知らず、エアプで語ると怒られそうなので、今回はこの3つを比較させてもらいます。 

## 人気度
データはDeepResearch君に集めてもらいました。便利だね😊

### GitHubスター数（2025年4月現在）

| フレームワーク | GitHubスター数⭐ |
| --- | ---: |
| Django   | 83.3 k  |
| Flask    | 69.4 k |
| FastAPI  | 83.7 k  |

 FastAPI は最近 Django とスター数で肩を並べたと報告されています
Flask はコミュニティが活発ですが、スター数は Django / FastAPI よりやや少ない状況です。

### PyPI月間ダウンロード数

| フレームワーク | 月間ダウンロード数 |
| --- | ---: |
| Django   | 21,006,637|
| Flask    | 108,001,579|
| FastAPI  | 86,917,112 |

### 開発者利用率

| 調査・年度                                  | Django | Flask | FastAPI |
| ---------------------------------------- | -----: | ----: | -------: |
| JetBrains “The State of Django 2024”     |    74 %  |  26 %  |    25 %  |
| Stack Overflow Dev Survey 2024           |    12 %  | 12.9 %|   9.9 %  |
| “A Year In Review: Flask in 2024” by MG   |    39 % | 39 % |   25 %  |


# フレームワークごとの特徴

## Django

Djangoは「バッテリー同梱」の代表格で、認証、管理画面、ORM、フォーム、国際化…とにかく最初から何でも揃っています。DjangoのORMは直感的に扱えて個人的に好きです。
大規模サービスや社内ツールを堅実に作りたいときには、非常に有用です。設定ファイルやディレクトリ構成の慣習がしっかりしているぶん、学習コストはちょっと高めな印象。

僕が気になったのは、やり方を覚えるまで「Django Way」に合わせる必要があるところ。でも、一度踏襲すれば手放せなくなる安心感があります。

## Flask

一方 Flask は軽量路線そのもの。ルーティングとテンプレートエンジンだけ押さえておけば動くシンプルさが魅力です。  
拡張（Flask-Login, Flask-SQLAlchemy など）は自分で選んで組み込むスタイルなので、必要なものだけ取捨選択できるのがいいですね。  

でも逆に、拡張を探したり組み合わせを考える手間はちょっと面倒。小規模プロトタイプや勉強には最適ですが、泥臭くライブラリ選定するのが苦手だと少しハードル高いかも。

## FastAPI

そして FastAPI。型ヒントから自動で OpenAPI ドキュメントを生成してくれる神フレームワークです。さらに ASGI ベースで async/await が使えるので、API サーバーとしてのパフォーマンスはピカイチ。  

僕は非同期処理に慣れていなかったけど、調べたらコード例がものすごくシンプルでとっつきやすかった。  
ただし、型アノテーション前提なので「型書くのめんどくさい！」という人にはツラいかもしれません。


# で？結局何を選べばいいの？

- 管理画面とか認証とか一式欲しい → Django
- 気軽に動くものを最小構成で作りたい → Flask
- API サーバー＆非同期処理が鍵 → FastAPI

…って感じで、用途がはっきりすれば実は迷わないのです。どれか一つ試してみて、「思ったより良かった」方向に合わせるのが吉。もちろん「好きだから使う」というのも素敵な理由だと思います。

# 実際にさわってみよう

まずは公式チュートリアルをちょちょいと動かしてみると、フレームワークごとの「手触り感」がかなり違います。  
実際のコードを少し書いてみるだけで、ライブラリ選びの感覚がグッと絞り込めるはずです。