OmniAICreator/Qiita-1.07M huggingface dataset:
Streamlit入門 #1 体重管理する

# はじめに
以下の記事を拝見し、そんなに少ないコード行数でwebアプリ作れるのか！
と驚き、早速試してました。
python経験も浅く、webアプリの知識も0でしたが、
思ったよりもサクサク作れてStreamlitに感謝です。
迷ったところやエラーはChatGPTさんにも聞けるし、昨今の開発コスト・学習コストの低さには驚きです。

https://qiita.com/papasim824/items/1804bc1bd8d4c195d8a8

# 動作環境
* windows10
* VScode

# まず触ってみる
* venv環境なので、activateさせる
* streamlitをインストールし、サンプルプログラム新規作成後、ランさせる

```
.\venv\Scripts\activate
```
```
pip install streamlit
```
```:sample.py
import streamlit as st

st.write("hello world!!")
```
```
streamlit run sample.py
```
* こんな感じに表示されました（おお～）
    * コードを変更すると`Source file changed.`って教えてくれます。`rerun`で反映できます
* ちなみにスマホからもアクセスできました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2477708/a780bd2a-a8bb-42ea-a392-f015b4cb5734.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2477708/a30f991f-eb84-4f4a-b9b6-32161454adbe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2477708/d4ec2c88-51d0-4dc6-be27-8662f920715d.png)


# 体重管理アプリを作りたい
いまのところできたのはこんな感じ。

``` : ディレクトリツリー
body_make_app/
├── index.py // 入口、ページ管理
├── pages/
│   ├── manage.py // メインコンテンツ、目標に合わせてカロリーと目安を表示
|   └── profile.py // プロフィール設定、身長やら体重やら入力する
└── utils/
|   └── calculator.py // 汎用的な機能やら関数
└── data
    └── profile.json // プロフィール共通設定
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2477708/1bef17c0-09ef-43d5-9104-05d1c65d2602.png)

## やりたかったことや学んだ点
* 1回入力したデータは反映して維持してほしい、さらにページごとにデータを共有したい
* 具体的には `身長` や `年齢` ですね
    * ChatGPTに相談した結果
        * ページ間の共有に `st.session_state`を使用する
        * データは `json` に書き込んで、`st.session_state`に読み込んでおく

* 公式のリファレンスが親切でやりたいことも見つけやすかったです
    * 今回は、ページ切り替え（navigation）と、データをブロックでいい感じに表示する（metric）を使ってみました
        * [navigation](https://docs.streamlit.io/develop/api-reference/navigation/st.navigation)
        * [metric](https://docs.streamlit.io/develop/api-reference/data/st.metric)

## 感想
プライベートでただいま増量中なんですが、毎週ごとに増量のペース配分を把握したく。
エクセルで計算していたんですが、「もーちょっとシンプルにスマートにならないかしら、、」と少々気になっていました。
こういう体重管理アプリはド定番なので、世の中に色々便利なものがあるのですが
* 計算式をカスタマイズしたい
* 最低限の機能でもよい

と考えていまして、自分で作成するのがユーザ的にも都合がよく、
さらに勉強的にもなってよかったという次第です。

## 次
* コードはもうちょっと整理してから、気が向いたらアップロードします
* グラフなど可視化したいですね、あと見た目も工夫したい
M5STACK ATOM S3 ユーザーデモのソースコード在処と修正

ATOMS3の購入時に書き込まれているサンプルコードの在処と書き込み、編集方法について調べたので下記にまとめました。

![IMG_0080_edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997459/b46b5aba-59f4-402c-be64-576e92b813da.jpeg)


内容は下記の流れです。

- 初期化方法
- 導入方法
- 内容の大まかな解説
- ちょっとした修正


# 初期化方法
まずは購入状態への戻し方。

https://docs.m5stack.com/en/core/AtomS3

上記ページ下方の「AtomS3 User Demo」をダウンロード。

ATOMS3をPCに接続した状態でダウンロードしたATOMS3 DEMO.exeを実行します。

<p align="center">
 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997459/ca99bd49-8d40-4439-93b0-8554ce961147.png" alt="ATOMS3 初期化GUI画面">
</p>

上記ソフトウェア画面が起動するので、COMポートとボーレートを設定して「Burn」をクリックで書き込めます。

以上で購入時状態に戻せます。



# サンプルコード導入方法

https://github.com/m5stack/M5AtomS3-UserDemo/tree/main

上記に、購入時に書き込まれているユーザーデモ用のコードが置いてあります。
ちなみに、ユーザーデモの内容変更のためにはarduino IDEではなくVS codeとPlatformIOの導入が必要です。
導入の際は下記ページを参考にしました。

https://elchika.com/article/6a153bc2-318f-44c7-871b-0ddbdce2ca42/

PlatformIO導入後、PC内の任意の場所に上記ユーザーデモの内容をまるっとコピーします。
次に、PlatformIOのプロジェクト管理画面で「Add Existing」をクリックし、コピーしたユーザーデモのフォルダを開いてください。
プロジェクトのリストにユーザーデモが追加されるので、Openをクリックするとプロジェクトが読み込まれます。

ATOMS3をUSBケーブルでPCにつないだ状態で「PlatformIO:Upload」をクリックするとプロジェクトをビルド後、問題なければATOMS3にユーザーデモが書き込まれます。


# 内容のざっくり解説

https://github.com/m5stack/M5AtomS3-UserDemo/blob/main/src/main.cpp


上記がユーザーデモの内容です。ATOMS3を触ってみるとわかりますが、ユーザーデモの内容は以下の通りです。
- wifiスキャン
- I2Cスキャン
- UARTモニタ
- PWMテスト
- ADCテスト
- IR
- IMUテスト

上記はそれぞれ「class func_wifi_t」のような形でクラスとして定義されています。
ATOMS3の電源を投入すると電源投入時のアニメーションが再生された後、各デモを選択するランチャー画面が表示されます。
画面がボタンになっており、一度押すたびにデモの内容表示が切り替わります。
試したいデモの画面で長押しするとデモが実行されます。


```cpp

func_wifi_t func_wifi_scan;
func_i2c_t func_i2c_scan;
func_uart_t func_uart_mon;
func_pwm_t func_pwm_test;
func_adc_t func_adc_test;
func_ir_t func_ir_send;
func_imu_t func_imu_test;

func_base_t* func_list[7] = {&func_wifi_scan, &func_i2c_scan, &func_uart_mon,
                             &func_pwm_test,  &func_adc_test, &func_ir_send,
                             &func_imu_test};
}
```

コード内では上記のように各クラスがリスト化されていて、ボタンを押すたびにリストのインデックスが加算されて画面表示が変わっています。




# ちょっとした修正

```cpp
void setup() {
    M5.Display.setRotation(2);
}

```

こんな感じに書くと、画面の向きを180度回転できます。
初期値だとUSBケーブルを画面下側に刺す向きになりますが、画面上側から刺したかったため上記変更を追加しました。



これでATOMS3のユーザーデモコードをベースに色々修正や変更ができるようになりました。
Claudeを使ってToDoアプリを作り、Netifyでビルドした

# 前提
表題の通り。Claudeは3.7 Sonnetを使用した。
当方はデザイナーのため、普段はコードを積極的に書かないのだが、コードの学習・UIの学びとして試みを行った。

# 参考にした記事

https://qiita.com/YasutomoNakajima/items/39ee62a8e2110acc1e3d
https://qiita.com/shozzy/items/dadea4181d6219d2d326



# ビルドしたアプリ
シンプルToDoリスト

https://todolist-marumi.netlify.app/

# 学んだこと
:::note info
NetifyとGitHubの連携
:::
:::note info
Claudeを使って書いたコードのビルド／デプロイ
:::
:::note info
デプロイ後のコードを参照してFigmaに読み込み、デザインデータとすること
:::

# 感想
しばらくコードを保守くらいでしか使っていなかったが、AIを導入することでコードをやや身近に感じることができた。この感覚を忘れずに自主制作としてもう少し試行錯誤してみたいと思う。
oapi-codegenを用いたコード自動生成

## 目的
oapi-codegenを使ってコード自動生成する

https://github.com/oapi-codegen/oapi-codegen/tree/main

## 準備
1. `openapi.yml` 作成
    ```
    openapi: 3.0.0
    info:
      title: Go API template
      version: 0.1.0
    
    servers:
      - url: http://localhost:8888/api/v1
    
    paths:
      /album/{id}:
        get:
          summary: find album by id
          parameters:
            - name: id
              in: path
              required: true
              schema:
                type: integer
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/AlbumResponse'
    
    components:
      schemas:
        Category:
          type: object
          properties:
            id:
              type: integer
            name:
              type: string
              enum:
                - food
                - music
                - sports
          required:
            - name
      
        AlbumResponse:
          type: object
          properties:
            id:
              type: integer
            title: 
              type: string
            Category:
              $ref: '#/components/schemas/Category'

    ```
1. oapi-codegenインストール
    ```
    go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
    ```
1. GoのバイナリをPATHに追加
    ```
    export PATH="$(go env GOPATH)/bin:$PATH"
    ```
1. インストール確認
    ```
    % oapi-codegen --version
    github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen
    v2.4.1
    ```
1. `config.yml` 作成
    ```
    package: API
    generate:
      models: true
      gin-server: true
      client: true
      embedded-spec: true
    output: api/api.gen.go
    ```
1. 自動生成実行
    ```
    % oapi-codegen --config=./api/config.yml ./api/openapi.yml
    ```
`api.gen.go` が生成されていれば成功
「コード×AI」 ソフトウェア開発者の生成AI向き合い方

[コード×AI - ソフトウェア開発者のための生成AI実践入門](https://amzn.to/3EkHKP2)

GitHub Copoilotを始めたので、何か参考になればとこの本を読み始めました
感想や重要な箇所を更新していく予定です

## 1章 生成AIがエンジニアリングの常識を変える
この章で気になったのは`1.5 AIは優秀なエンジニアだけのものではない`
以前読んだ本で生成AIによる伸びしろは優秀な人でなく、
不得意な人であることはエンジニアも変わらない

生成AIの強みである即時フィードバック性と個別化学習により、
ジュニアエンジニアの学習効率を上げることができる
確かに先輩に何度も聞くのが引ける場合も、AIなら気にせず聞ける

経験豊富なメンターとしてAIを使うことができ、
`該当コードをステップバイステップ解説して`という風に思考のプロセスを学んだり、
解説やメリット/デメリットといった背景を合わせて出力させるとよい

#### 続きは今後更新していきます
脱・机上セキュリティ！開発未経験CSIRTが挑むWeb技術習得記


はじめまして、[spooonn@X](https://twitter.com/spoooonn)と申します。 
私は現在30代半ばで、**ユーザ企業のCSIRTに所属して5年目のセキュリティエンジニア**です。

本記事では、**Webアプリ技術習得に向けた半年間の学習計画と、それに挑む決意を記します。**

---

私はこれまで、以下のような**上流工程のセキュリティ業務**に携わってきました：

- セキュリティガバナンスの制定・管理  
- セキュリティ脅威・脆弱性情報の収集・発信  
- 脆弱性検査状況の管理  
- セキュリティ対策の企画・運用状況の管理  

いわゆる「**全体を管理する側**」であり、**実際に手を動かすことはほとんどありませんでした**。

元々は施工管理系の業務に従事していて、**インフラ運用経験ゼロでCSIRTへ異動**し、  
NW機器、開発、サーバ構築など**に携わった経験はほとんどない**という状況でした。

セキュリティのスペシャリストを目指していこうとIPA高度情報処理資格やCISSPの取得など、**座学では頑張ってきたつもり**ですが…  
**「実際にコードを書いたりインフラを触った経験はゼロ」**。  
なので、現場担当者との会話で、技術の話についていけないことも多く、  
**「自分には技術的なスキルが不足している」**という現実に薄々気づいていました。  
しかしながら、なまじ実績も積み上げてきて、普段の業務は最低限回っていることに甘えていました。

---

そんなある日、上司からこう言われました。

> 「このままではspoooonn君はセキュリティエンジニアとしてのキャリアアップは厳しい」

その一言をきっかけに、ようやく重い腰を上げる決意ができました。

---

> **「“技術をしっかり理解できる上流セキュリティエンジニア”になりたい」**

---

まずは関心が強く、業務でも関わりが深い**Webセキュリティ**を選び、  
以下のゴールを目指して**半年間の学習計画**を立てました。  
この記事はその**決意表明**でもあります！

---

# 🎯 ゴール：自分のWebアプリを診断して、修正できるようになる！

最終ゴールはこれです：

> **ただ動かすだけじゃなく、「脆弱性を見つけて、自分で直せる」まで行くこと！**

設計・開発スキルについては、Qiitaの[この記事](https://qiita.com/mackeee-orange/items/afbed5ec3816d4af2e58)で紹介されている  
**“ジュニアレベル”のエンジニア**を目指しています。

---

# 🧩 サブゴール（マイルストーン）

- ✅ **HTML/CSS/サーバサイドなどWeb開発の基礎を習得する**  
- ✅ **ポートフォリオとしてWebサイトを構築・公開する**

---

# 🧭 ロードマップ（半年スパン）

| フェーズ | 期間 | 学習内容・活動 | 使用予定ツール/教材 |
|---------|------|----------------|--------------------|
| **Web構築基礎** | 4〜6月 | HTML/CSS、PHP or Python、Linux、Git、Web技術の基礎 | 書籍 / Udemy / 公式ドキュメント |
| **ポートフォリオ作成** | 7〜8月 | Flask or Laravel を使ったWebアプリ、メール送信、自宅サーバ公開 | Flask/Laravel、Postfix、Dovecotなど |
| **セキュリティ診断** | 9〜10月 | OWASP Top 10をベースに脆弱性診断 → 自分で修正 | OWASP ZAP、Burp Suite、DevTools |
| **応用・拡張** | 11月以降 | Docker、CI/CD、AWS再構築など^1^ | Docker、GitHub Actions、AWSなど |

^1^ Webアプリ開発＋運用を、実務に応用するための発展編

📌 **参考にしたロードマップ：**  
[【図解】未経験から最短でWebエンジニアになるロードマップ【完全版】 - YouTube](https://youtu.be/O9D18lhLa2Y?si=wV72HSie_c-EvsHL)

---

# 💡 学習スタンス・ルール

- **学習メモや記録を残す（Qiita・Twitter・Notion）**  
- セキュリティ習得が目的。**アプリの完成度は最低限でOK**  
- 教材は極力使わず、**調べ学習＋公式ドキュメントを重視**  
- 完璧を求めすぎず、**まず「やってみる」ことを優先**

---

# 🫱 この記事が届いてほしい人

- セキュリティエンジニアだけど**実装経験がない人**  
- 上流中心で、**技術的な不安を抱えている人**  
- 「何かしなきゃ」と思っているけど、**一歩踏み出せない人**

---

# ✍️ 今後の発信予定（Qiita連載テーマ）

- 【構築編】自宅サーバでWebアプリを立ち上げた記録  
- 【診断編】OWASP ZAPで自作アプリを診断してみた  
- 【修正編】脆弱性をどう直したか  
- 【失敗編】構築・設定でつまずいたポイントと解決策  

📡 学習の進捗は[@spoooonn](https://twitter.com/spoooonn)でもゆるく発信していくので、ぜひ覗いてみてください！

---

# 🚀 最後に

私はまだまだ技術的には未熟なセキュリティエンジニアです。  
でも「わからないからやらない」ではなく、**「わからないからやってみる」フェーズに入りました。**

この挑戦が、**同じように悩んでいる誰かのきっかけになれば**と願っています。  
そして自分自身も、**“技術に強いセキュリティエンジニア”へと成長していけるよう努力していきます。**

---

# 🙌 Let's Hack, Build and Learn.
「なぜDockerコンテナにAlpineを入れるの？」から始まった、カーネルとユーザー空間の理解

## DockerコンテナにAlpineを使う理由

Dockerを使って開発していると、`Alpine` や `Debian`、`Ubuntu` などのベースイメージを選ぶ場面があります。

でも、「そもそもDockerはLinux上で動いていて、コンテナもLinux上で動くのに、なんでまたAlpineとかUbuntuを中に入れるの？」という疑問が湧いてきました。

この疑問をきっかけに、**Linuxのカーネルとユーザー空間は別物である**という設計思想を理解することができました。この記事では、その理解を整理して共有します。

### 最初の疑問

Dockerで環境構築をしていると、コンテナのイメージに `FROM alpine` や `FROM ubuntu` を指定することがあります。しかし、DockerはLinux上で動いているはずです。それなら、

**「すでにLinuxがあるのに、なぜAlpineやUbuntuを追加する必要があるの？」**

という疑問が湧いてきました。

### カーネルとユーザー空間は別物

調べてわかったこと、Linuxには2つの空間があるということです。

| 空間       | 内容                                                                 |
|------------|----------------------------------------------------------------------|
| カーネル空間 | Linuxカーネルそのもの。プロセス管理やI/Oなどの低レベル制御を担当する「脳」 |
| ユーザー空間 | `/bin`, `/lib`, `/etc` など、アプリケーションやユーザーが使うツールが配置される「作業場」 |

アプリケーションは直接カーネルにアクセスできません。代わりに「システムコール」を使って、カーネルに依頼します。これ自体は理解していました。

### Dockerの仕組み

DockerはホストOSのLinuxカーネルをそのまま使用し、ユーザー空間だけを**コンテナごとに分離**します。そのため、**コンテナにはカーネルは含まれていません**。

つまり、AlpineやUbuntuを入れる理由は、**アプリが動作するために必要な最小限のツールセットを提供するため**でした。

ここで、カーネル（システム全体を管理する部分）に対して、さまざまなユーザー空間のソフトウェアが存在し、それがディストリビューションであることが見えてきました。

### ディストリビューションとは？

Linuxカーネルは多機能で、特定の用途に合わせて、どの機能を有効にするか、無効にするかを選ぶことができます。これにより、カーネルは非常に柔軟で、さまざまなシステムや用途に対応できるようになります。

Ubuntu、Alpine、Debianなどの「ディストリビューション」は、Linuxカーネルに加えて、どんなユーザー空間（アプリケーションやツール、ライブラリ）を含めるかを決めるものです。これにより、それぞれのディストリビューションが特定のニーズ（例えば、デスクトップ環境、軽量化、安定性重視など）に適した環境を提供します。

Dockerで使用する場合、通常、「ユーザー空間」だけを利用するイメージを使います。コンテナはホストOSのカーネルを共有するため、コンテナ内にはカーネル自体は含まれません。

### まとめ

最初、ぼは「OSは1つの塊」だと思っていました。しかし、今では、**カーネル（脳）とユーザー空間（道具箱）は分けられているのが当然**だと理解できるようになりました。

Dockerは、この設計思想を活かして、**1つのカーネル上で複数のユーザー空間を動かす**という軽量で効率的な仕組みを実現していると理解することができました。
「ChatGPTを使うときに気をつけるべきこと」のメモ書き


## このドキュメントの対象読者

本ドキュメントは個人的なメモを兼ねた整理です。
あえて挙げるなら、ChatGPTをある程度使い慣れていて、より効果的に活用したい人向けの内容です。

---

## ① ChatGPTの得意なこと・苦手なこと（大前提）

### 得意なこと
- 静的な知識の整理（例：アルゴリズム、ネットワーク構成、コマンド解説）
- 構造化された説明や要点の要約
- コードのテンプレート生成や修正提案
- 文調・形式に応じた文章の生成（例：マニュアル文、ログメッセージ、Markdown）

### 苦手なこと
- 時事性の高い内容（例：クラウドの仕様変更、ライセンス体系、最新UIなど）
- 長くて複雑なコードや数式（見た目は正しくてもバグが紛れがち）
- 文化的背景・感情・意図の深い理解（皮肉・遠回し表現など）
- 医療・法律・契約などの高度専門分野（誤情報リスクあり）

---

## ② 押さえるべきポイント（運用上の注意）

### （1）致命的：最優先で意識すべきこと
- ChatGPTの本質は学習データを基に確率でプロンプトの文章の続きを作成しているだけであるということを認識しておく。なので当然誤った情報を返してくることがある。
- ChatGPTの知識には更新の遅れがあるため、特に仕様変更が多い分野では古い情報が返ることがある。「2025年4月時点の情報が欲しい」といった指定があると正確性が上がる
- 仕様や前提が違うときは、その場で明確に指摘・修正を伝える（ズレを放置しないことで軌道修正が効く）

### （2）優先：意識すると効果が高いこと
- 回答の指示を明確にする（例：「提案してください」「Markdownで出力」「要点のみ知りたい」「Qiita向けに整形して」など）
- 文脈・Contextを明確にする（目的・背景・対象などの前提をなるべく明確に）
  - 技術系の話題では使用環境（OS、クラウド、ツールなど）を伝える
  - 目的や使い道を伝える（例：画面表示用／マニュアル向け／口語調がよいなど）
  - 想定する読者やスキルレベルを伝える（例：初心者向け／自分用メモ／チーム共有用）
  - 自分の理解状況や困っているポイントを伝える（例：用語は知っているが使い方に不安がある）
  - 制約や前提条件を伝える（例：特定の言語が使えない／クラウド利用不可 など）

---

## ③ ChatGPTを現実的にうまく使うためのヒント

- 最初の質問が曖昧でも問題ない  
　→ 会話を通じて徐々に前提や意図を明確にしていけばよい  
　→ **最初から完璧な質問を目指す必要はない。考えすぎて手が止まるより、まず投げて会話で整える方がずっと効果的**
　※でもダラダラ会話を重ねるとどんどんアホになっていくのでできれば短期決戦

- 回答の方向性がズレていたら、その都度修正・補足すればよい  
　→ ChatGPTは「ズレたまま突き進む」ことがあるため、微調整が大事

 - すでに作ったものレビューやアイディア出しは気軽に  
　→ 取り入れるか取り入れないかは人の判断を介するので
　→ コードのレビューは気軽に投げてる。そうゆう書き方もあるのかー、などの知見が得られることも。

- 検索エンジンと使い分けよう  
　→ ChatGPT：背景の説明や方針の提案など、会話で深めたいときに有効  
　→ 検索：**ChatGPTは情報が古い可能性がある。**最新仕様や正式情報は検索で確認すべき

---

## ④ ChatGPTと検索エンジンの比較：考え方のヒント

| 観点 | 検索エンジン | ChatGPT |
|------|----------------|----------|
| 対応 | キーワードマッチで既存ページを表示 | 質問に対して即時に文章を生成 |
| 設計思想 | 検索ワードの選び方が命 | 質問の構造・前提・目的の明確さが命 |
| 調整方法 | キーワードを変えて再検索 | 会話の中で前提や方向性を修正できる |
| 向き・不向き | 検索力が求められるが正確性は高め | 柔軟性が高いが、時事性や厳密性に弱いことがある |
【型パズル】TypeScriptにおけるオブジェクト型の継承について


みなさん！型パズルやってますか？？
今回はオブジェクト型の結合についてまとめます。

とはいっても複雑な Utilitiy型 を生成するのは、私の分野ではないので...
`utility-types` という型パズルのピースを増やしてくれるライブラリを使います！

https://github.com/piotrwitek/utility-types


## 二つの型の結合

まずはコードから。

### AND と OR 

```ts
type A = { a: string, b: number }
type B = { a: number, c: boolean }

type AandB = A & B;
// {
//     a: never
//     b: number
//     c: boolean
// }

type AorB = A | B
// {
//     a: number
//     c: boolean
// } | {
//     a: string
//     b: number
// }
```

まずは TypeScript 標準の `AND` と `OR` のコードです。

`AND` の場合、`a` が `string` と `number` どちらか一意に決定できないため、`never`型になってしまいます。
そのため、どんな値も挿入できない使えない型になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/8983201e-4183-44b5-9373-d187367c3786.png)

一方 `OR` の場合、`a` をキーにして二種類の値の組み合わせを挿入することができる型になります。
一般的には、こちらの使い方が多い気がしますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/e0ced6f9-5624-43cf-8358-42f17f35b21f.png)



### AND の拡張（Overwrite と Assign）

```ts
import { Assign, Overwrite } from 'utility-types'

type A = { a: string, b: number }
type B = { a: number, c: boolean }

type AoverwriteB = Overwrite<A, B>
// {
//     a: number
//     b: number
// }

type AassignB = Assign<A, B>
//  {
//    a: number
//    b: number
//    c: boolean
//}
```

次に `Utility-Type` で拡張したオブジェクト型の結合を紹介します。

`Overwrite<>` は、 `A` を基準に `B` の型で上書きするものです。
A と B どちらにも存在するキー `a` を上書きします。

`Assign<>` は、 `A` に対して `B` の型を上書きするものです。
A に対して、Bにあるキーを上書きしていきます。
ちょうど `Object.assign()` と同じ挙動ですね。



## で、何が言いたいの

重要なのは `Assign` です。
ライブラリ作成分野にて、型のベースを作成するとき、A and B、A or B を行うことは頻繁にあると思います。
その時、単純に and を使うことがふさわしくない場面が存在します。

実例を作ってみます。
`X` をベースとして、 `type` に応じて挙動を変えるロジックをイメージしてください。

```ts
import { Assign, Overwrite } from 'utility-types'

type X = { type: string, show: boolean }
type Y = { type: "int", value: number, precision: number }
type Z = { type: "bool", value: boolean }

type XandY = X & Y
// {
//     type: "int";
//     show: boolean;
//     value: number;
//     precision: number;
// }
    
type XandYandZ = (X & Y) & Z
// never

type XorYorZ = (X | Y) | Z
// {
//     type: string
//     show: boolean
// } | {
//     type: "int"
//     value: number
//     precision: number
// } | {
//     type: "bool"
//     value: boolean
// }

type XoverwriteYoverwriteZ = Overwrite<Overwrite<X, Y>, Z>
// {
//     type: "bool"
//     value: boolean
// }

type XassignYassignZ = Assign<Assign<X, Y>, Z>
// {
//     type: "bool"
//     show: boolean
//     value: boolean
//     precision: number
// }
```

引数で使用する共通の型が使いたいときは `OR` を使いますよね。

**`OR` で型を結合すると、ベース型にある `show` が引き継がれません。**

継承のような動きを行いたい場合は `Assign` を使う必要があります。
`Assign` の結果を確認すると、継承先で欲しそうな型が出てきてますよね。

TypeScript の `Or` は、単純な足し算であることに注意です。

> ちなみに `Assign` の挙動は、
> T→Uの差分をPick、U→Tの差分の差分をPick、更にTとUの共通項をPick。
> その後それぞれのAndを取って、結果のキーをPickする。
>
> という泥臭いことをやってます...すごい...
Geminiで技を使う魔法少女を描いてみた。

# 概要

Geminiで技を使う魔法少女を描いてみました。

# 実装

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

```
炎の技を使う魔法少女を描いてみてください。
```

![炎の技を使う魔法少女_20250413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/77856e70-f0e5-4c89-8643-e9e76bcb31bd.png)

```
氷の技を使う魔法少女を描いてみてください。
```

![氷の技を使う魔法少女_20250413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/46c77e28-6431-4f2f-8d22-f6665fecd319.png)

```
電撃の技を使う魔法少女を描いてみてください。
```

![電撃の技を使う魔法少女_20250413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/b39f82fc-c284-42ca-8ad0-1d02f5247353.png)

いい感じで描けました。炎の子がおすすめです。

# まとめ

何かの役に立てばと。
お世話になったチュートリアルたち

これまで技術のキャッチアップの役に立ってきたチュートリアルたちです。
技術分野関係なく何でもかんでも詰め込みました！！

# React
### React 公式チュートリアル
みんな大好きReact公式チュートリアルです。

大切なポイントはこれに全部載ってるせいで、Reactに関する記事を書いても「これ公式チュートリアルの下位互換だな…」ってなります(泣)。

https://ja.react.dev/learn

# Next.js
### Next.js 公式チュートリアル
Next.js + PostgreSQLでダッシュボード風アプリを作ります。

本格的なwebアプリの開発ができて楽しいですが、前提知識 (React、Tailwind、SQL…) を求められるので難易度やや高です。

https://nextjs.org/learn

# TypeScript
## サバイバルTypeScript
TypeScriptのあらゆる機能・構文が解説されています❗️

チュートリアルもついていますが、自分はよく構文や仕様を調べるのに使っています。

https://typescriptbook.jp/


# Rust
### the book
公式チュートリアルです。 (名前が格好良い)

Rustを始める人は、とりあえずこれをやればかなり言語を理解 + 書けるようになります❗️

↓ 原本

https://doc.rust-lang.org/book/

↓ 非公式の日本語翻訳版

https://doc.rust-jp.rs/book-ja/

### Rust by Example
the bookと対を成す公式ドキュメントです。

the bookをExampleベースで書いた風になっていて、1からやると言うよりは字引のように使っています。

↓ 原本

https://doc.rust-lang.org/rust-by-example/

↓ 非公式の日本語翻訳版

https://doc.rust-jp.rs/rust-by-example-ja/

### rustlings
5 7kスターが付いてるハンズオン形式のRustチュートリアルです。
各チャプターのコンパイルエラーを直していく形で、オリジナルのCLIツールを使いながら進めていきます。

めちゃめちゃ完成度高いです！Rustの主要な概念をアウトプット形式で学べますが、CLIに慣れている必要はあります。

https://github.com/rust-lang/rustlings

### proc macro workshop
情報の少ないRustの手続きマクロ (procedural macro) の貴重なチュートリアルです。これをやればある程度手続きマクロが書けるようになります。

宣言マクロ ( `macro_rules!` で作るマクロ) を上のthe bookなどである程度学んでから取り組むのがおすすめです。

難易度は高めです！∣🚩

https://github.com/dtolnay/proc-macro-workshop

# Git
## サル先生のGit入門
昔お世話になりました。

これでGitの概要を掴みつつ、後は実際に使いながら慣れるのがオススメです！

https://backlog.com/ja/git-tutorial/

# Vim
## vimtutor
Vimについてるチュートリアルです。実際に操作しながら使い方を学べます！！

vimを開いて`:vimtutor`と打つことで開けます。

# Arwes
Sci-fi風のUIが作れるReactフレームワークです🛸

めちゃめちゃかっこいいので試してみて (推し)

https://next.arwes.dev/


# 随時更新予定
Railsチュートリアル7章：user作成後にredirectする理由

railsチュートリアルの7章では、実際にブラウザからリクエストを送信し、ユーザー登録ができるようにします。
その際、UsersControllerのcreateメソッドは以下のようにしました。

```ruby:users_controller.rb
def create
    @user = User.new(user_params)
    if @user.save
        flash[:success] = '<メッセージ>'
        redirect_to @user # user詳細にredirectする
    else
        render 'new', status: :unprocessable_entity
    end
end
```

チュートリアル内ではざっと以下のように説明されています。
1. redirectなどの処理がない状態でブラウザからリクエスト
1. → エラーとなり、原因はcreateに対応するviewファイルがないこと
1. ただ、webアプリではcreateなどの操作後は詳細ページなどにリダイレクトするのが一般的で、そちらを採用する

という感じです。
画面の動き的にもしっくりくるのであまり気にしていませんでしたが、ふとどうしてリダイレクトが一般的なのだろうと思い調べたので、記憶定着 & 備忘録としての記事になります。

# なぜ、user作成などの後はredirectするのか?

結論、**リロード（など）をした場合に再度postメソッドを送信してしまう心配がない** ため、安全であるということかなと思います。

ここで、redirectをした場合としなかった場合のリクエストの流れが重要になります。
### redirectをしない場合
例えば、createに対応するviewファイルがあったとします。その場合、以下のような順序でcreate viewが表示されます。
1. クライアント（ブラウザ）から、user作成リクエスト(POST)が送信される
1. UsersController#createで、user作成が成功し、create viewが返される
1. クライアント側でcreateページが表示され、終了

という形です。この場合、**1度のリクエストで全てが完結します**。

### redirectの場合
では、次にredirectをした場合をみます。
1. クライアント（ブラウザ）から、user作成リクエスト(POST)が送信される
1.  `UsersController#create`で、user作成が成功し`Users#show`にもう一度リクエストしてね！（リダイレクトしてね！）というレスポンスが返される
1.  クライアントは、それに従いユーザー詳細ページをリクエスト（GET）する
1.  `Users#show`でshow viewが返される
1.  クライアント側でshowページが表示される

このように、ブラウザの操作では一度のみリクエストしているように見えるものの、動作的には**2度のリクエスト**がなされ、終了します。

### じゃあ、どうして安全なの？
というところですが、ブラウザでのリロードは「**前回のリクエストを再送信する**」という動作をします。よってredirectをしない場合、画面をリロードすると前回のリクエストである「User作成リクエスト（Post）」をもう一度実行することになります。
すると、意図せず再度リクエストをするといったことが発生しやすくなり、安全ではありません。
ブラウザで「再度送信しますか？」などのアラートがと出るのは、こういった動作で再リクエストしようとしている時、危ないから確認してね、という注意喚起ですね。
※上記の通り、表示されているurlにgetを送るといった動作でないことに注意でしょうか。

ところがredirectを利用すると、最後のリクエストがgetメソッドとなり、リロードした際意図せずデータを作成してしまう、などのいわば事故が発生しなくなります。
ですのでベーシックなwebアプリでは、基本的にDBへ変更のあるリクエストが完了した際はリダイレクトをするのが一般的、ということだと思います。

また、そのことを`PRG（Post - Redirect - Get）`パターンと言ったりもするそうです。

## 余談
ではもし、create後に「完了ページ」のようなものを特別用意したいといった場合はどうするのだろう？と思いましたが、単純に`UsersController#complete`メソッド + complete テンプレートを作成し、そこにredirectすれば良い、ということでした。
確かに。
【ChatGPT＋4o Image Generation】で元画像を3Dアイコンにします。


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

　今回は、4o Image Generationで、元画像を3Dアイコンにします。

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

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

　今回は、
　　4o Image Generationで
　　　元画像を3Dアイコンにします。

　3Dアイコンとは、
　　立体的なデザインが
　　　特徴のアイコンです。

　奥行きや影、ハイライトを
　　活用して平面上に
　　　立体感を表現したものです。

　これにより、
　　デザインがよりリアルで
　　　魅力的に見える効果があります。

　主な特徴と用途:

　　デザイン性: 
　　　ぷっくりとした形状や
　　　　光沢感があり、
　　　　　視覚的なインパクトが強い。

　　用途: 
　　　Webサイトやアプリ、
　　　プレゼン資料、
　　　ホーム画面のカスタマイズ
　　　　など幅広く利用されます。
***
　3Dアイコンにする手順。
　❶モデルがGPT-4oであることを確認
　❷元画像をアップロード
　❸下記Promptを入力
```Text:3Dアイコン化Prompt
3Dアイコンにして
```
　❹送信

　どのようになるか
　　というと

元画像
![Polish_20250412_223945176.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/0a0cc36d-9ccd-4d6d-a775-f87e29c07f81.png)


3Dアイコン
![file_0000000038ac61f688461fee850e3209_conversation_id=67fb1876-da84-8007-b2c0-1be33e885e86&message_id=db9cd51a-e6de-4b50-9018-f74b4aa70a9f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/239823ec-4def-42a4-8757-0246113beaf3.png)


　といった感じになります。

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

　今回は、ここまで。
C_TS422_2023 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（7/100）

【7日目】
トピック 2：SAPS/4HANA生産計画の概要（1/5）

≪問題7≫
B品目とC品目の計画にかかる労力を削減しようとしています。推奨される計画手法は以下のどれですか。
□消費主導型計画
□チェックなしマニュアル計画
□アドバンスト計画
□資材所要量計画

≪解答≫
■消費主導型計画
□チェックなしマニュアル計画
□アドバンスト計画
□資材所要量計画

≪解説≫
B品目とC品目は、一般的に消費主導型計画（Consumption-BasedPlanning）によって管理されます。この計画手法は、在庫レベルに基づいて自動的に補充を行うもので、需要の予測が困難な品目に適しています。
symbol-shoestringで Nodeの作成に失敗した時に使えるやーつ！

どうも　僕です
shoestring0.2.1が出来て
bootstrapNodeからの移行もしよっかなって人向け！

あれ作業ディレクトリで
setup命令とか　upgrade命令で
**しくじると命令が通らなくなってファイルとかディレクトリ全部消さなきゃならないんだけどそれいちいち消すのめんどい！めんどすぎる！**
ので作りました

内容見てもらえば一目瞭然だと思いますが
ca.key.pemと shoestringディレクトリを残して後は全部捨てちゃうシェルスクリプトですよ

僕よく失敗するので結構これ使うんです
そんな人も他にいるかもなので　ここに置いときますね


```
#!/bin/bash
rm -rf data
rm -rf dbdata
rm -rf docker-compose.yaml
rm -rf docker-compose-recovery.yaml
rm -rf keys
rm -rf logs
rm -rf mongo
rm -rf rest-cache
rm -rf seed
rm -rf startup
rm -rf userconfig
rm -rf linking_transaction.dat
rm -rf unlink
rm -rf a
rm -rf https-proxy
rm -rf renew_voting_keys_transaction.dat
rm -rf docker-compose-recovery.yaml
```
市区町村コード一覧を作成する

# はじめに
オープンデータを利用して市区町村コードの一覧を作成してみます

# データソース
デジタル庁 レジストリカタログ
日本 市区町村マスター データセット

https://catalog.registries.digital.go.jp/rc/dataset/ba-o1-000000_g2-000002/resource/07b45993-c322-46e9-8010-bc54612bb67c



## 他に使えそうなソース
総務省
https://www.soumu.go.jp/denshijiti/code.html

- 郡名なし
- 政令指定都市の区名なし

日本郵便
https://www.post.japanpost.jp/zipcode/download.html

- 北方領土含まない
- 更新頻度は高い


# 環境
```terminal
~ % python -V
Python 3.11.9

~ % pip list | grep pandas
pandas             2.2.3
```
# 一覧作成
```python
import pandas as pd

# 公開データの読み込み
df = pd.read_csv('mt_city_all.csv', dtype={'lg_code':str}, usecols=['lg_code','pref','city','ward'])
# カラム名を調整（市区町村コードのカラムを"code"に変更
df.rename(columns={'lg_code': 'code'}, inplace=True)

# CSV作成だけなら不要ではあるが
df = df.fillna('') # 区名のない部分を補完
df.set_index('lg_code', inplace=True) # 市区町村コードをindexに

# CSV出力
df.to_csv('city_list.csv') # 市区町村コードをindexにしたので、そのまま出力
```


# 結果
![69dde5fb12574bc8f52d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4001795/7d4ad352-ce3d-4e6d-80f6-a22dfb1343dd.png)

# 郡名も追加
```python
import os, sys
import re

import pandas as pd

df = pd.read_csv('mt_city_all.csv', dtype={'lg_code':str}, usecols=['lg_code','county','pref','city','ward'])
df.rename(columns={'lg_code': 'code'}, inplace=True)
df.reindex(columns=['lg_code','pref','county','city','ward'])
df = df.fillna('')
df.set_index('code', inplace=True)
df.to_csv('city_list.csv')
```
![69dde5fb12574bc8f52d-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4001795/72977cfe-cd8d-487d-a5df-954c957370b8.png)
※一部抜粋
elixirのrequireってなに？

# はじめに
requireというコードが登場したがイマイチ理解できずに読み飛ばしていた。
コードをキチンと理解してるとは言い難い状況だったのでrequireが何なのかあると何ができるのかをまとめる。

# requireとは？
他のモジュールのマクロを使用することをElixirに伝えるためのもの

https://elixirschool.com/ja/lessons/basics/modules#require-6

# マクロとは？
メタプログラミングを可能とする。

# requireがあると何が嬉しい？
importが関数を利用するのに対してマクロを使用できるようにすることができる。
メタプログラミングを可能とするため、言語を自由に拡張することができる。

# コードの例

```elixir
iex(1)> Integer.is_odd(3)
** (UndefinedFunctionError) function Integer.is_odd/1 is undefined or private. However, there is a macro with the same name and arity. Be sure to require Integer if you intend to invoke this macro
    (elixir 1.18.2) Integer.is_odd(3)
    iex:1: (file)
iex(1)> require Integer
Integer
iex(2)> Integer.is_odd(3)
true
```

https://hexdocs.pm/elixir/alias-require-and-import.html#require

https://hexdocs.pm/elixir/Integer.html

# 結論
requireはマクロを利用できるようにする機能のこと
マクロを利用することでメタプログラミングが可能となり、言語を自由に拡張することができる。

# 残った疑問
コードで書いたIntegerは関数では？
だとするとわざわざrequireで呼び出す意味がないのでは？
またメタプログラミングというのは外部からインポートする性質のものでなく、requireを呼び出そうとしたユーザーが定義するものでは？

# その他
疑問点に対する指摘、誤字脱字についての指摘を頂けると幸いです。
理解を促進するための指摘は大歓迎です。

# 参考資料
Elixir実践入門

https://gihyo.jp/book/2024/978-4-297-14014-4
大嶋淑之 新潟｜フリーランス動画制作の魅力と地域密着型サービス

新潟県在住の動画制作クリエイター、大嶋淑之の活動に関する情報をご紹介します。新潟という地域でフリーランスとして活躍している彼のサービスや、地域の魅力を活かしたコンテンツ制作を深堀りしていきます。SEOを意識したキーワード「大嶋淑之 新潟」を使用し、新潟の自然や文化を背景にした動画制作サービスについてお伝えします。

# 目次

- [大嶋淑之について](#大嶋淑之について)
- [新潟での動画制作の魅力](#新潟での動画制作の魅力)
- [提供する動画制作サービス](#提供する動画制作サービス)
- [新潟の美しい風景を活かした動画制作](#新潟の美しい風景を活かした動画制作)
- [大嶋淑之の作品集と実績](#大嶋淑之の作品集と実績)
- [お問い合わせ・サービス利用方法](#お問い合わせ・サービス利用方法)

# 大嶋淑之について

大嶋淑之は、新潟県を拠点に活動しているフリーランスの動画制作クリエイターです。彼は映像制作を通じて、企業のブランドイメージ向上や、個人のプロジェクトに対するビジュアルコンテンツの提供を行っています。新潟の自然や文化にインスパイアされた彼の作品は、地域の魅力を最大限に引き出すものとなっています。

新潟に拠点を構えることで、地方ならではの温かいコミュニティと密接に連携し、個々のプロジェクトに寄り添う形で高品質な映像を提供しています。

# 新潟での動画制作の魅力

新潟は四季折々の美しい自然や、豊かな食文化、歴史的な街並みが魅力的な地域です。この土地で動画制作を行うことは、映像に深みを与えるための大きな要素です。特に、新潟の広大な田園風景や雪景色は、他の地域では味わえない独自の美しさがあります。

## 新潟の風景と文化を活かした動画

新潟の美しい山々、海、田んぼの風景、そして伝統的な祭りやイベントは、視覚的に魅力的なコンテンツを作成するための素晴らしい素材です。大嶋淑之は、これらの地域特性を活かし、他の地域にはない個性的な映像を提供しています。

# 提供する動画制作サービス

大嶋淑之は、新潟での地域密着型の動画制作を専門としています。彼のサービスは、企業向けのプロモーション動画だけでなく、個人のニーズにも対応しています。提供するサービスには以下のものがあります：

- **企業プロモーション動画の制作**  
  新潟で事業を展開する企業向けに、ブランドやサービスを紹介するプロモーション映像を制作します。地域に密着した内容を盛り込むことで、視聴者の共感を呼びます。

- **イベント・セミナー動画の撮影と編集**  
  新潟で開催されるイベントやセミナーを撮影し、参加者にとって価値あるコンテンツとして編集します。

- **SNS用のショート動画制作**  
  SNSマーケティングに特化した、短尺でインパクトのある動画制作。新潟の魅力や地域の文化をPRするためのコンテンツも対応します。

# 新潟の美しい風景を活かした動画制作

新潟は自然の宝庫です。四季折々に変化する風景を映像に活かすことは、特に映像制作において強力な武器になります。大嶋淑之は、この豊かな自然環境を映像制作に巧みに取り入れています。

例えば、冬の雪景色や春の桜、秋の紅葉など、どの季節に訪れても魅力的な素材が豊富にあります。新潟の農作物や地元の食材をテーマにした映像も、視覚的に魅力的で視聴者の心をつかむ内容となっています。

# 大嶋淑之の作品集と実績

大嶋淑之が手掛けた映像は、企業のブランディングや地域活性化のプロジェクトに貢献してきました。これまでに以下のような実績があります：

- 新潟の観光地を紹介するプロモーション動画
- 地元の食文化を紹介するショートドキュメンタリー
- 地域イベントやフェスティバルの撮影と編集

彼の作品は、新潟ならではの魅力を最大限に引き出し、視覚的に印象に残るコンテンツとなっています。

# お問い合わせ・サービス利用方法

大嶋淑之への動画制作の依頼やサービス利用については、以下の方法でお問い合わせください：

1. **メールでのお問い合わせ**  
   ご依頼内容や詳細をメールでお送りください。

2. **お電話でのご相談**  
   直接お電話いただき、具体的なプロジェクトについてご相談いただけます。

3. **SNSでの連絡**  
   大嶋淑之のSNSアカウントを通じて、気軽に連絡いただけます。
GitHub Copilot をVSCodeでうまく使用できなかった件  (Invalid copilot token: missing token: 403)

結論から行くと設定でCode suggestionを有効化できていなかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480378/b9dcdd9e-3e14-402e-8d6d-e677480fb4cd.png)

## 背景
GitHub Copilotを使ってみたいと思いトライアルでVSCodeに拡張していたのだが、
何度もこのエラーが出ていた

```
Invalid copilot token: missing token: 403
```
どうやらトークンが無効または欠落している場合に発生するらしい
解消のため推奨される対応をいくつか試したが駄目だった

## 試したこと
#### 1. GitHub Copilotアカウント確認
そもそもアカウントのGitHub Copilotが使えるようになっているかを確認
これは設定>Copilotの画面一番上のメッセージを見ればよい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480378/a8f764e4-34db-4ecc-a7d6-7e03ab056e7e.png)
赤枠の通りactivateされてる

#### 2. 再起動もろもろ
ネットでよくみる以下の再起動も行った
・VSCodeの再起動
・GitHubアカウントのLogout
・VSCodeのGitHubのアカウント接続を切って、再接続
・GitHub Copilotの拡張機能の再インストール
・VSCodeのアップデート

## 解決策
ネットの解決策試しても全然だめだったので、GitHubのCopilot設定のページを
1つ1つ見ていくと冒頭の設定箇所を見つけた
解消前はここが"Blocked"となっており、試しにAllowedへ変更して、
再接続してみたところ成功した

ネット推奨対応以外にもGitHubのCopilot設定で何か弾いてないか見てみると解決するかも
GitLab CI/CDのテンプレートとextendsで重複を解消！保守性を高めるyaml設計

## GitLab CI/CDのテンプレートとextendsで重複を解消！保守性を高めるyaml設計

### はじめに

GitLab CI/CDの`.gitlab-ci.yml`ファイルで、ジョブの記述が重複してしまい、保守性に課題を感じたことはありませんか？
この記事では、テンプレートと`extends`を活用して重複を解消し、より効率的で保守性の高いyaml設計にする方法を紹介します。

### 課題：重複した記述による保守性の低下

例えば、以下のように`artifacts`の設定などが重複している場合を考えてみましょう。

```yaml
collect_artifact_tag:
  stage: post_stage
  script:
    - echo $CI_COMMIT_BRANCH
  needs:
    - build
    - test
    - diff-check
    - lint-cppcheck
  artifacts:
    name: "collect_artifact"
    expire_in: 7 days
    paths:
      - mybinary
      - runlog.log
      - cppcheck_result.txt
      - cloc_diff.txt
      - diff.txt
  rules:
    - if: '$CI_COMMIT_TAG'

collect_artifact_else:
  stage: post_stage
  script:
    - echo $CI_COMMIT_BRANCH
  needs:
    - build
    - test
    - diff-check
    - lint-cppcheck
  artifacts:
    name: "collect_artifact"
    expire_in: 7 days
    paths:
      - mybinary
      - runlog.log
      - cppcheck_result.txt
      - cloc_diff.txt
      - diff.txt
  rules:
    - if: '$CI_COMMIT_TAG == null'
```

この例では、`artifacts`の`paths`や`needs`などが重複しており、変更があった場合に複数箇所修正する必要があります。

### 解決策：テンプレートとextendsの活用

このような重複を解消するために、テンプレートと`extends`を活用します。

1.  **テンプレートの定義**

    共通の設定をテンプレートとして定義します。

    ```yaml
    .template_collect_artifact:
      stage: post_stage
      script:
        - echo $CI_COMMIT_BRANCH
      needs:
        - build
        - test
        - diff-check
        - lint-cppcheck
      artifacts:
        name: "collect_artifact"
        expire_in: 7 days
        paths:
          - mybinary
          - runlog.log
          - cppcheck_result.txt
          - cloc_diff.txt
          - diff.txt
    ```

2.  **テンプレートの拡張**

    `extends`を使用して、テンプレートを拡張し、必要な箇所のみ上書きします。

    ```yaml
    collect_artifact_tag:
      extends: .template_collect_artifact
      artifacts:
        expire_in: 1 month
      rules:
        - if: '$CI_COMMIT_TAG'

    collect_artifact_else:
      extends: .template_collect_artifact
      artifacts:
        expire_in: 1 week
      rules:
        - if: '$CI_COMMIT_TAG == null || $CI_COMMIT_TAG == ""'
    ```

### まとめ

テンプレートと`extends`、変数を活用することで、GitLab CI/CDの`.gitlab-ci.yml`ファイルの重複を減らし、保守性を向上させることができます。ぜひ、これらのテクニックを活用して、より効率的なCI/CDパイプラインを構築してください。

---
VSCODEでGit Bashのhistory履歴を保存できるようにした

### 本記事の背景
Linux環境において、historyはデフォルトで自動的に保存されるように設定されているが、
VSCODE＋Git Bash for windowsを使う場合、VSCODEを再起動する度、履歴はクリアされてしまうので、少し不便である。本記事はこれを解消できる以下に手順を示す

### 解消手順
1. ホームディレクトリに .bashrc を作成（または編集）
1. 履歴の設定を .bashrc に追加
1. .bash_profileを編集
1. Git Bash を再起動 or source ~/.bashrc で反映
1. VS Code のターミナルで Git Bash を使う設定が正しいか確認

### 詳細
履歴の設定
```terminal
nano .bashrc 
```

```terminal
# ~/.bashrc に追記する内容

# 履歴ファイルの場所
HISTFILE=~/.bash_history

# history にタイムスタンプを記録する（epoch形式 or フォーマット付き）
HISTTIMEFORMAT="%F %T "

# 履歴に保存するコマンド数
HISTFILESIZE=10000
HISTSIZE=10000

# セッション中の履歴を即時保存
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
```
bash profileの編集
```
nano .bash_profile
```

```terminal
# ~/.bash_profile に追加（または修正）

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi
```
設定を有効にする
```terminal
. .bashrc
```

最後にVSCODEを再起動し、ターミナルでhistoryコマンドを確認し、保存されていることを確認する


### 結果
```terminal
history
    1  2025-04-13 11:10:26 cd game-by-pyglet/
    2  2025-04-13 11:10:26 python move_char.py
    3  2025-04-13 11:10:26 python main.py
    4  2025-04-13 11:10:26 python auto_move_char.py
    5  2025-04-13 11:10:26 touch main_app.py
    6  2025-04-13 11:10:26 python main_app.py
```
データサイエンスとビッグデータの違い

# はじめに

データサイエンスとビッグデータは、どちらも現代のデータ駆動型社会において重要な概念ですが、それぞれ異なる役割や目的を持っています。本記事では、両者の特徴や違いをわかりやすく比較し、その関係性についても解説します。

# データサイエンスとは？

データサイエンスは、**データから有益な知見を引き出すための学問的および実践的なアプローチ**です。数学、統計学、プログラミング、機械学習などを組み合わせて、データを分析・解釈し、意思決定を支援します。

### 主な特徴
- **目的**: データから洞察を得て課題解決や意思決定に活用
- **手法**: 機械学習、統計解析、データ可視化
- **データタイプ**: 構造化データ（例：表形式）から非構造化データ（例：テキスト、画像）まで幅広い

### 使用例
- 顧客行動の予測
- 医療診断の支援
- マーケティングキャンペーンの最適化


# ビッグデータとは？

ビッグデータは、**従来のデータ処理技術では扱えないほど大規模で複雑なデータセット**を指します。これには大量のデータを効率的に収集、保存、処理するための技術が必要です。

### 主な特徴
- **3V（Volume, Variety, Velocity）**:
  - **Volume（量）**: 膨大なデータ量（ペタバイト〜ゼタバイト規模）
  - **Variety（多様性）**: 構造化・半構造化・非構造化データ
  - **Velocity（速度）**: 高速で生成・処理されるリアルタイムデータ
- **目的**: 大規模なデータセットから価値ある情報を抽出
- **技術**: Hadoop, Spark, 分散処理システム

### 使用例
- ソーシャルメディア分析
- IoTセンサーからのリアルタイム監視
- 金融取引のリスク管理



# データサイエンスとビッグデータの比較

以下に両者をわかりやすく比較した表を示します：

| 特徴                | データサイエンス                            | ビッグデータ                              |
|---------------------|--------------------------------------------|------------------------------------------|
| **定義**             | データから知見や価値を引き出す学問的手法     | 巨大で複雑なデータセットそのもの          |
| **目的**             | 問題解決や意思決定支援                     | 大規模なデータセットの管理と処理           |
| **対象となるデータ**  | 構造化・非構造化問わず幅広い               | 主に非構造化・半構造化データ              |
| **スケール**         | 小〜中規模のデータでも適用可能              | 非常に大規模なデータセット                |
| **手法や技術**       | 統計解析、機械学習、可視化ツール            | Hadoop, Spark, 分散処理                  |
| **結果**             | 洞察や予測モデル                           | データそのものやその整理                  |
| **使用例**           | 顧客分析、医療診断                         | ソーシャルメディア解析、IoT監視            |



# 両者の関係性

### 補完的な役割
- ビッグデータは「原材料」として膨大な情報を提供し、その中から価値ある情報を引き出すためにデータサイエンスが活用
- 例えば、ビッグデータ技術で収集したソーシャルメディア投稿を基に、データサイエンス手法で感情分析やトレンド予測が行う

### 必要なスキルセット
- データサイエンティストはビッグデータ技術（Hadoop, Sparkなど）と統計・機械学習スキルの両方を持つことが求められる場合がある



# まとめ

### 主な違い
1. データサイエンスは「方法論」であり、ビッグデータは「対象となる巨大な情報」
2. データサイエンスは分析や洞察生成に焦点を当てる一方で、ビッグデータはその規模と多様性に対応する技術が中心

### 今後の展望
現代社会では膨大な量の情報が日々生成されています。これらの情報を効果的に活用するためには、ビッグデータ技術とそれを活用するためのデータサイエンスが不可欠です。両者を理解し活用することで、新たな価値創出や課題解決が可能になります。
GitLab CI/CD artifacts 有効期限問題、3つの解決策比較

## 回避策の比較と選択

本記事では、GitLab CI/CDの`artifacts:expire_in`で変数が使えない問題に対する3つの回避策（[別記事で解説](https://qiita.com/YusukeHarada/items/2df465de1d50f82f5fa1)）を比較検討し、最適な選択肢を提示します。

### 各回避策の比較表

| 比較項目 | rules によるジョブ分割 | API クリーンアップジョブ | 保存専用ジョブ |
| :--- | :--- | :--- | :--- |
| 概要 | ブランチ毎に異なるexpire_inを持つジョブを定義 | APIで条件に合う古いArtifactsを定期削除 | Artifactsを目的のexpire_inで再保存するジョブ |
| 実装の容易さ | 中〜高 (比較的容易) | 低 (API知識、スクリプト実装、Token管理が必要) | 中 (YAML構造とneedsの理解が必要) |
| YAMLの複雑さ/冗長性 | 中〜高 (ジョブが増え、共通化しないと冗長) | 低 (YAML自体はシンプル、複雑さはスクリプトへ) | 中 (ジョブ数は増えるが、役割は明確) |
| パイプライン実行時間への影響 | 小 (ジョブ数は増えるが並列実行可能) | ほぼ無 (別スケジュール実行の場合) / 小 (同パイプラインの場合) | 中 (ArtifactsのDL/ULオーバーヘッドあり) |
| 柔軟性/拡張性 | 中 (YAMLの範囲内での制御) | 高 (スクリプトで自由な条件設定が可能) | 中 (保存期間ポリシーを分離できる) |
| 管理コスト | 低〜中 (YAMLが複雑化すると管理コスト増) | 高 (スクリプトとTokenのメンテが必要) | 中 (ジョブ構成の理解が必要) |
| 前提条件/依存関係 | 特になし | API Token (適切な権限付与)、実行環境(curl等) | needsまたはdependenciesの利用 |

### KT法デシジョン分析表

Kepner-Tregoe法のデシジョン分析を用いて、客観的な基準で選択肢を評価します。

**目的:** ブランチ毎の Artifacts 有効期限を管理するための最適な回避策を選定する

**選択肢:**

* A: ジョブ分割
* B: API クリーンアップ
* C: 保存専用ジョブ

**評価基準:**

* **必須要件 (MUSTs):** これを満たさない選択肢は除外
    * ブランチ/条件に応じて異なる有効期限を実現できるか？
        * A: Yes / B: Yes / C: Yes (→ 全ての選択肢が必須要件を満たす)
* **希望要件 (WANTs):** 重要度に応じて重み付け (10点満点)、各選択肢を評価 (10点満点)

| 希望要件 (WANTs) | 重み (W) | A: ジョブ分割 (スコア S / 重み付け後スコア W\*S) | B: API クリーンアップ (スコア S / 重み付け後スコア W\*S) | C: 保存専用ジョブ (スコア S / 重み付け後スコア W\*S) | 備考 (評価理由など) |
| :--- | :--- | :--- | :--- | :--- | :--- |
| 1. 実装が容易 | 8 | 8 / 64 | 3 / 24 | 6 / 48 | AはYAMLのみ。BはAPI実装難。CはYAML構造理解。 |
| 2. YAML がシンプル/冗長でない | 7 | 6 / 42 | 8 / 56 | 5 / 35 | Aは冗長化リスク。Bは複雑さをスクリプトへ。Cはジョブ増。 |
| 3. 管理が容易 (メンテコスト低) | 9 | 7 / 63 | 4 / 36 | 6 / 54 | Bはスクリプト/Token管理負担大。A,CはYAML依存。 |
| 4. パイプライン実行速度への影響小 | 6 | 9 / 54 | 10 / 60 | 7 / 42 | Bは非同期なら影響無。CはDL/UL時間。Aはジョブ増だが並列可。 |
| 5. 特別な権限/ツールが不要 | 5 | 10 / 50 | 3 / 15 | 10 / 50 | BはAPI Tokenが必要。A,Cは基本的に不要。 |
| 6. 柔軟性/拡張性が高い | 7 | 6 / 42 | 10 / 70 | 7 / 49 | Bが最も柔軟。Cはポリシー分離。AはYAMLの範囲。 |
| **合計スコア** |  | **295** | **261** | **278** |  |

**分析結果:**

上記の重み付けとスコアリングに基づくと、選択肢 A (ジョブ分割) が最も高い合計スコア (295) となりました。これは、実装や管理の容易さ、特別な権限が不要な点が評価された結果です。

選択肢 C (保存専用ジョブ) が次点 (278) で、ポリシー分離のメリットがありつつも、やや複雑さとオーバーヘッドが考慮されました。

選択肢 B (API クリーンアップ) は、柔軟性が非常に高いものの、実装と管理のコスト、API Token の必要性が大きく影響し、スコアが最も低く (261) なりました。

**注意点:**

この KT デシジョン分析の結果は、設定した「希望要件」とその「重み付け」に依存します。実際のプロジェクトでどの回避策を採用するかは、プロジェクト固有の要件や優先順位に合わせて、重み付けや評価を調整した上で判断することが重要です。

## まとめ

**どの方法を選択すべきか:**

* **シンプルなケース:** ジョブ分割が管理しやすい。
* **ポリシー分離:** 保存専用ジョブが適している。
* **複雑な条件:** API クリーンアップが選択肢になるが、複雑さを許容する必要がある。
ハッカソン個人備忘録㉗：ポエム認証×AIチャット！ユニークなWebアプリの画面遷移図まとめてみた

## はじめに
本記事では、ユニークなログイン体験とチャット体験を提供するWebアプリケーションの画面遷移構成について整理します。

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

各画面の役割や流れを把握することで、開発やユーザビリティ改善に役立てることができます。

## 実際の構成イメージ（2025/04/13）

```画面遷移図.
トップページ
├─ 新規会員登録ページ
│   └─ 登録時のポエム選択
│   └─ ホームページ（マイページ）
│       ├─ チャット開始
│       │   └─ モード選択（三郎おじいちゃん / 美女（5回に1回アンガーママ））
│       │       └─ チャットページ
│       │           ├─ メッセージ（AI応答表示）
│       │           ├─ お気に入り登録
│       │           ├─ 感情選択 → BGM / 画像表示（追加機能）
│       │           └─ アンガーママモード（5回に1回ランダム）
│       ├─ お気に入り一覧ページ
│       ├─ 履歴表示ページ
│       ├─ ポエム更新ページ（自分のポエムのみ編集可能）
│       └─ アカウント削除ページ

├─ ログインページ
│   └─ ベーシック認証（ユーザー名・パスワード）
│       └─ ポエム認証（登録時に選んだポエム）
│           └─ ホームページ（マイページ）
│               ├─ チャット開始
│               │   └─ モード選択（三郎おじいちゃん / 美女（5回に1回アンガーママ））
│               │       └─ チャットページ
│               │           ├─ メッセージ（AI応答表示）
│               │           ├─ お気に入り登録
│               │           ├─ 感情選択 → BGM / 画像表示（追加機能）
│               │           └─ アンガーママモード（5回に1回ランダム）
│               ├─ お気に入り一覧ページ
│               ├─ 履歴表示ページ
│               ├─ ポエム更新ページ（自分のポエムのみ編集可能）
│               └─ アカウント削除ページ

├─ 管理者専用ページ（adminフラグ所持者のみ）
│   ├─ ポエム一覧・編集ページ（全ユーザー分）
│   └─ ユーザー管理ページ

└─ LLM接続機能（バックグラウンド連携）
    ├─ ポジティブメッセージ生成
    └─ 感情選択 → BGM
```


## トップページからの遷移
### トップページ
- アプリ紹介、ログイン・新規登録リンク付きのシンプルな導入画面。

## ユーザー登録・ログインの流れ
### 新規会員登録ページ
- ユーザー名・パスワードを入力し、会員登録を行う。
- 次のステップとして「ポエム選択」を実施。

### 登録時のポエム選択
- ログイン時に使用するポエム認証用ポエムを選択。
- 登録完了後、マイページへ遷移。

### ログインページ
- ベーシック認証（ユーザー名・パスワード）を実施。
- 認証成功後、登録時に選択したポエムによるポエム認証を行う。
- 認証通過後、マイページへ遷移。

## マイページとその機能
### ホームページ（マイページ）
- 以下の機能にアクセス可能：
  - チャット開始
  - お気に入り一覧
  - 履歴表示
  - ポエム更新
  - アカウント削除

## チャット機能の詳細
### チャット開始 → モード選択
- ユーザーは「三郎おじいちゃん」または「美女（5回に1回アンガーママ）」を選択。

### モード選択 → チャットページ
- AIによる応答が表示される。
- お気に入り登録が可能。
- 感情選択をすると、それに応じたBGMや画像が表示される（追加機能）。
- 美女モードでは、5回に1回「アンガーママ」が登場。

## マイページ内のその他機能
- **お気に入り一覧ページ**：登録したメッセージを一覧表示。
- **履歴表示ページ**：過去のやりとりを表示。
- **ポエム更新ページ**：自身のポエムを編集可能。
- **アカウント削除ページ**：アカウントの削除手続きを行う。

## 管理者専用ページ（adminフラグ所持者）
- **ポエム一覧・編集ページ**：全ユーザーのポエムを確認・編集。
- **ユーザー管理ページ**：ユーザーの情報を管理・編集。

## バックグラウンド機能（LLM接続）
- **ポジティブメッセージ生成**：ユーザーの状態に応じた応答生成。
- **感情選択 → BGM再生**：選択した感情に応じた音楽を自動再生。

## おわりに
このような画面遷移と機能の構成を整理することで、アプリ開発において「どこにどんな要素が必要か」「ユーザーがどのような体験をするか」が明確になります。

今後の設計や改善にも活かしていけるよう、引き続き整理・検討を進めていきます！
【Flutter】アプリで雪を降らせよう

![スクリーンショット 2025-04-13 10.52.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/c04ece59-f39f-4a9c-928b-a05b31734863.png)


# はじめに

https://2021.flutterkaigi.jp/#/

確か、FlutterKaigi2023年のWebサイトでアイコンが雪のようにふるものがあったような気がして、いいなと思っていました。今見たら雪っぽくはありませんが、アイコンがたくさんあっていいですね。

ふと、FlutterのPacakgesをあれこれ探してみたところ、個人開発に使えたら面白いと思えるものがあったのでご紹介しようと思いました。


# 雪を降らせることができるPacakgesについて

https://pub.dev/packages/snow_fall_animation/versions/0.0.1+2

雪以外にも絵文字なども降らせることができるそうですね。とても可愛くて僕は好きです。

実際に自分のアプリで使えそうなものを入れてみました。あくまでも参考程度に実装してみください。

```dart
SnowFallAnimation(
  config: SnowfallConfig(
    numberOfSnowflakes: 300,
    enableRandomOpacity: false,
    enableSnowDrift: false,
    customEmojis: ['❄️', '❅', '❆'],
    holdSnowAtBottom: false,
  ),
),
```

### 実装したUIはこちら


https://x.com/isekiryu/status/1911236759188591025


### 最後に
こちらのPRで作業をしました。

https://github.com/iseruuuuu/food_gram_app/pull/469

色々なPackagesが世界中の人たちが作り上げてく世界はとても良きですね。色々な人のアイデアを見れている気分になれます。
初心者向けVScode初期設定・ショートカットまとめ

# はじめに
今回、VScodeについて、
一番はじめに知っておくと便利なことについてまとめてみました！

ショートカットキー集などは多いため、
頻繁につかう設定や使い方のコツのみを厳選しています。

# 目次

1. [初期設定](#初期設定)
    1. 自動保存
    2. 手動保存時にフォーマット
2. [使い方のコツ](#使い方)
    1. 範囲選択でできること
    2. ショートカット

# 初期設定
1. VScodeの左下にあるアイコンから、設定を開く
2. Settings(Ctrl + ,)を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/454e3881-a0ac-418d-9498-e7d9b9e06455.png)
## 自動保存
1. 検索バーに「auto save」と入力
2. offから「afterDelay」に変更

→ 変更をするたびに保存がされます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/c89ea5f3-5a39-4956-a431-55b690790529.png)

## 手動保存時にフォーマット
1. 検索バーに「format on save」と入力
2. チェックボックスにチェックをつける

→ ctrl + S を押すと、フォーマットがされます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/c25c8165-3887-45eb-a4ad-54358e640517.png)


# 使い方のコツ

## 範囲選択でできること

範囲を選択した状態で、
`Alt + 矢印` -> 選択範囲をそのまま移動
![レコーディング-2025-04-13-103522.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/c2320fd4-081e-42df-ac70-79230ba36b6d.gif)


範囲を選択した状態で、
`Tab` -> 一気にTabを右に
`Shift + Tab` -> 一気にTabを左に
![レコーディング-2025-04-13-103739.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/94b9e566-ae57-45a4-9487-14f70431d401.gif)

範囲を選択した状態で、
`ctrl + /` -> 一気にコメントアウト or 一気にコメントアウト解除
![レコーディング-2025-04-13-103928.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/6ff5a03e-fc7e-4e7a-a734-d36a92b7197b.gif)

## ショートカット

`ctrl + F` -> ファイル内検索
`ctrl + P` -> ファイル自体を検索

`ctrl + Z` -> 1つ戻る
`ctrl + Y` -> 1つ先に


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/680da1eb-5296-4c03-9e1b-14656f76f5b3.png)

`ctrl + B` or `左から2番目のアイコンを押す` -> 左のエクスプローラーを開閉する
`ctrl + J` or `ctrl + @` or `左から3番目のアイコンを押す` -> ターミナルを開く



# おわりに

もしまだまだ使えるショートカットがありましたら、
コメントアイコンを押して、コメントおねがいいたします！

読んでいただきありがとうございました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954816/0e183eda-04aa-4901-9e38-81f618f3eb90.png)
CSP(Content Security Policy)とは？

## はじめに
CSPについて勉強して理解した内容をまとめる。

## CSP(Content Security Policy)とは？
Webブラウザに対してコンテンツの読み込みや実行を制御するセキュリティ機構
信頼されたリソースのみを読み込むことを強制することで、信頼されていないコードの実行を防ぐ

## CSPの効果
- XSS対策：インラインスクリプトや外部スクリプトの制限が可能
- データ送信制御：悪意のあるドメインへのデータ送信をブロック

## 基本的な設定
CSPはHTTPレスポンスヘッダで定義する。以下はCSPの設定例
```
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self';
```
- `default-src 'self'`
→ 全リソースのデフォルトの読み込み元を自分自身のドメインに限定する
- `script-src 'self' https://trusted.cdn.com`
→ JavaScriptは自ドメインと指定のCDNからのみ読み込みを許可
- `style-src 'self'`
→ CSSの読み込み元を自ドメインに限定（インラインスタイルは許可されない）

## よく使われるディレクティブ（制限の種類）
- default-src：全体のデフォルトソースを指定
- script-src ：JavaScriptの読み込み元を指定
- style-src：CSSの読み込み元を指定
- img-src：画像の読み込み元を指定
- connect-src：Fetch/XHR/WebSocket などの接続先を指定
- object-src ：`<object>`, `<embed>` などの使用可否を指定
- frame-src：`<iframe>` の読み込み元を指定
- report-uri / report-to：CSP違反時のレポート送信先を指定

## CSP有効化対応例1　（インラインスクリプト）
HTTPヘッダーのCSPに次のように記述しているとインラインスクリプト（HTML内に直接書かれたjavascript）はブロック対象になる

```
Content-Security-Policy: script-src 'self';
```

### インラインスクリプトの例
```html
<!-- onclick属性 -->
<button onclick="alert('message')">クリック</button>

<!-- scriptタグ -->
<script>
  console.log('message');
</script>
```

### CSPでインラインスクリプトを使う方法　（nonceの使用）
1 サーバーがランダムな文字列（例：abc123xyz）を生成
2 HTMLのインラインスクリプトに nonce="abc123xyz" をつける
```html
<script nonce="abc123xyz">
  console.log('message');
</script>
```
3 HTTPヘッダーのCSPに `script-src 'nonce-abc123xyz’` を含める
```
Content-Security-Policy: script-src 'nonce-abc123xyz';
```
4 ブラウザは、CSPで指定されたnonceを持つスクリプトのみを実行する

※nonceは毎回ランダムに生成される一意の文字列である必要がある（再利用しない）

## CSP有効化対応例2　（インラインスタイル）
HTTPヘッダーのCSPに次のように記述しているとインラインスタイルはブロック対象になる
```
Content-Security-Policy: style-src 'self';
```

### インラインスタイルの例
```html
<p style="color: red; font-weight: bold;">message</p>
```

### CSPでブロックされないようにするための方法
スタイルは 外部CSSファイルに切り出す

```css
.important-text {
  color: red;
  font-weight: bold;
}
```

```html
<p class="important-text">message</p>
```

## CORSとの違い
CSPとCORSはどちらもWebセキュリティに関する仕組みだが、目的や制御の対象が異なる。以下の表でその違いを整理する。
| 項目 | CSP（Content Security Policy） | CORS（Cross-Origin Resource Sharing） |
|------|-----------------------------|------------------------------------|
| 主な役割 | ブラウザでのリソース実行制御 | APIなどのリソースへのアクセス制御 |
| 動作主体 | **ブラウザ（クライアント側）** | **サーバー**（レスポンスヘッダで制御） |
| 主な目的 | XSS等の攻撃からの防御 | 外部ドメインからの不正アクセス制御 |
| 制御対象 | スクリプト、スタイル、画像、iframeなどの読み込み・実行 | JavaScriptによるAPIアクセス（クロスオリジン通信） |
| 設定場所 | `Content-Security-Policy` ヘッダ（またはHTMLの`<meta>`タグ） | `Access-Control-Allow-Origin` などのHTTPレスポンスヘッダ |
| 典型例 | `script-src 'self'`：自サイト以外からのJSを拒否 | `Access-Control-Allow-Origin: https://example.com`：特定サイトからのAPIアクセスを許可 |
| 主な用途 | フロントエンドのリソース実行を信頼できる範囲に限定する | 外部フロントエンドによるAPI利用を制限する |
| ブラウザの動き | 許可されたリソース以外は**実行自体をブロック** | サーバーが許可しなければ**レスポンスを遮断** |

### 違いのポイント

- **CSP** は「**何を読み込んで良いか**」を定義し、**実行そのものを制御** 
  → XSS対策、スクリプト制限、外部iframe制限などに有効

- **CORS** は「**どこからの通信を許可するか**」をサーバーが定義し、**データの受け渡しを制御**
  → APIの公開・制限、フロントエンドのセキュリティに必須

## 最後に
今回整理して、CSPに対する理解を少しは深めることができたと思う。
[Flutter] 久しぶりに、Melosを使ってみて陥ったミスについて



# はじめに
個人開発ではマルチパッケージ構成にしていなかったため、「Melos」を使う機会がありませんでした。そのため、気にせず過ごしていましたが、ミスというよりかはこんな仕様なんだということがあったので今後に同じようなことが無いようにと思い、記事を書くことにしました。
まだしっかりとわかっていないので、間違いなどがありましたら教えてください。

## 問題点
- `melos bootstrap`が動作しない不具合があった

## 問題の原因
- melosのバージョンとFlutterのglobalのバージョンが正しくないと動作しないらしい

## 解決策
- globalで使用していたFlutterを削除
    - `home/development/flutter`
- fvmをglobalで選択して、反映させる
  -  `fvm global 3.27.1` ←指定するバージョン


## 最後に
無意識に環境構築をやったり、復職した後は数ヶ月も会社のPCを開いてなかったため、色々と古い状態であったので、まあそのうちの一つかと思い、気楽に進めていこうと思います〜
Firebase Cloud Functionsのレスポンス速度を上げる方法

# はじめに
Firebase Cloud Functions は便利なサーバーレス機能ですが、私のプロジェクトにて、ユーザー体験を損なうレベルの遅延が発生していました。
今回はレスポンス速度を劇的に速くすることができたのでその内容を記事にします。

結論、リージョンをデフォルトの us-central1（アイオワ）から asia-northeast1（東京）へ変更するだけで、レスポンス時間が早くなりました。

# 開発者ツールで見てみる
Supabaseからデータを取得する処理が書かれた関数で0.87秒もかかっています。
![スクリーンショット 2025-04-13 2.27.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/4a05328c-d4cf-4540-a74c-ea6ac6c76524.png)

改善後は0.05秒まで早くなりました
![スクリーンショット 2025-04-13 2.03.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/c90041a2-819b-4314-a3bc-7ddb4dcf38f4.png)


# 速度改善後のコード実装例
### 1. バックエンド側 (Cloud Functions)
Cloud Functions V2 APIを使用した場合のリージョン設定方法です：
```ts
setGlobalOptions({
  region: "asia-northeast1",
})
```
を入れることにより、リージョンを変更できます。

```ts
import { setGlobalOptions } from 'firebase-functions/v2';
import { onCall } from "firebase-functions/v2/https";
setGlobalOptions({
  region: "asia-northeast1", // デフォルトの us-central1 から東京リージョンに変更
})

export const getData = onCall(
  {cors: true,}, 
  async () => {
    const { data, error } = await supabaseClient
      .from('users')
      .select('*')
    }
    return data
  }
)
```
特定の関数だけ異なるリージョンを指定したい場合は、個別に設定することもできます：
```ts
export const getData = onCall.region('europe-west1')(
  {cors: true},
  async (request) => {
    // 関数の処理...
  }
)
```

### 2. フロントエンド側 (Nuxtアプリの例)
クライアント側からのCloud Functions呼び出し方法です：

```ts
import { initializeApp } from 'firebase/app'
import { defineNuxtPlugin } from '#app'
import { getFunctions, httpsCallable } from 'firebase/functions'

export default defineNuxtPlugin(async () => {
  const firebaseConfig = {
    apiKey: fbApiKey,
    authDomain: fbAuthDomain,
    projectId: fbProjectId,
    storageBucket: fbStorageBucket,
    messagingSenderId: fbMessagingSenderId,
    appId: fbAppId,
    measurementId: fbMesurementId
  }
  const app = initializeApp(firebaseConfig)

  const cloudFunction = getFunctions(app, 'asia-northeast1') // asia-northeast1を指定

  const getExternalData = httpsCallable(cloudFunction, 'getExternalData')
  
  const result = await getExternalData({
    resourceName: 'items',
    limit: 5
  }) 
  console.log('データ取得成功:', result.data)
})
```

# まとめ
Firebase Cloud Functionsのパフォーマンス問題は、多くの場合適切なリージョン設定だけで大幅に改善できます。
私の実装では、東京リージョンへの変更だけでレスポンス時間が速くなり、ユーザー体験が格段に向上しました。

# 追伸
私の環境で初回呼び出しのみレスポンスが遅い状況が発生しています。
Cloud Functions関数はアイドル状態で待機し、呼び出されると起動している状態が続くようです。
ここの改善ができたらまた記事にしようと思います。