OmniAICreator/Qiita-1.07M huggingface dataset:
QNAPでFastAPIを動かす

## 目的

家庭用NASのQNAPを持っているのでFastAPIで簡易的なおうちアプリケーションを作りたい。そんな時、QNAPには[Container Station](https://www.qnap.com/ja-jp/software/container-station)という環境があるので最終的にはDockerコンテナ等で動かせば良い。しかし、ある程度デバッグしながら育てていく場合はコンテナだとビルドが必要となるので普通にPython+FastAPIをホストOS(QTS)上で動かしたい。

## 事前準備

### SSH

QNAPにSSH接続するための設定はこちら

https://www.qnap.com/ja-jp/how-to/faq/article/ssh-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6-qnap-nas-%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%97%E3%81%9F%E3%82%89%E3%81%84%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B

### Python3

QNAPにPython環境を用意するにはこちら

https://www.qnap.com/ja-jp/how-to/faq/article/how-to-run-python-3-on-the-nas

Python3は `/opt/python3/bin/python3`にインストールされている。

## FastAPI インストール

### 仮想環境の作成

```sh
mkdir /somewhere/myapp
cd /somewhere/myapp/
```
```sh
/opt/python3/bin/python3 -m venv .venv
source .venv/bin/activate
python -V
```

### パッケージインストール

チュートリアルにある標準的なインストールだと`uvicorn`が利用している`uvloop`のインストールで失敗する。

```sh
pip install "fastapi[standard]"
```

なぜなら、

- `uvicorn`は高速化のためにCythonで書かれた`uvloop`を利用している
- PyPIにはQNAP環境向けのバイナリは配布されてないのでビルドが必要
- QNAPには基本的にはC言語のビルド環境がない
- よって`uvicorn[standard]`は簡単には使えない

なので生の`uvicorn`か`hypercorn`を使う。

```sh
pip install fastapi uvicorn
```
```sh
uvicorn main:app --host 0.0.0.0 --port 8000
```

あるいは

```sh
pip install fastapi hypercorn
```
```sh
hypercorn main:app --bind 0.0.0.0:8000
```

ここに結果は上げないが`ab`でみたところ、私の環境だと`uvloop`なしでも`uvicorn`の方が`hypercorn`に比べて若干パフォーマンスが良さそう。まあ、おうちサーバなのでどっちでも良い。

### コード編集(VS Code)

設定ファイルなどの編集程度ならばQNAPに入っている`vi`でも良いかと思うが、アプリケーションのコード編集にはVS Codeなどを使いたいと思う。その場合は、

https://qiita.com/hkato/items/f243467c11a02a887c65

しかし、やってみたところ、私のQNAPではおそらくメモリ不足なのか重くてよく落ちる。また、統合ターミナルはコンテナ内のターミナルなので、ここでQNAP自体のPython自体は実行できない。あくまでもファイル編集用。

## まとめ

QNAPでは、`uvicorn[standard]`でなく、生の`uvicorn`か`hypercon`上で実行すれば良い。
Canvaで画像加工して不要なものを消去する方法

私はCanvaの有料会員で、これを使って弊社オウンドメディアのサムネイルを作成したりしてます。
非常に便利なツールで、Photoshopより簡単に使えるところに魅力を感じまくりです。

今回はサムネイル作成の過程で、人物を消去する方法を理解したので忘れないようにメモを残していきたいと思います。

この記事では以下の画像を使って手順を作成していきたいと思います。
画像をダウンロードします。

https://pixabay.com/photos/handstand-man-beach-sea-ocean-2224104/


逆立ちをしている方の後ろにいるサーファーを消去したいと思います。
![handstand-2224104_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/3c35dcca-993c-4d80-8151-659da59e3bed.jpeg)

以下のサイトにアクセスします。

https://www.canva.com/ja_jp/features/magic-eraser/

画像をアップロードするを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/c20be9f8-07a9-4d97-834f-67c065b84251.png)

以下のような画面に遷移します。
丸い奴が加工するのに必要になるブラシと呼ばれるものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/ad64922b-904f-44a9-886c-a600aab0e62c.png)

消したいものを選択して以下のようにします。
削除するボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/c6cf3d3a-2dab-4551-9fa3-a518bca32d4f.png)

違和感なく消せていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/26551295-cc83-4da2-bfa2-1e323763ed3f.png)

実際の画像は以下です。
簡単ですね。Canva最高。
![名称未設定のデザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/30e4f781-0f5c-4ede-bf5a-40e0c86fb3c2.png)
MacOSでのDocker起動時の“com.docker.vmnetd”エラー

# 目的
今後自身の勉強も兼ねて調査する(かもしれない...)ため、備忘録として残す。

# 概要
Dockerインストール後、「マルウェアがブロックされました“com.docker.vmnetd”にはマルウェアが含まれているため開けませんでした」というエラーポップアップが消しても継続して出力される。
後述の解決策で解決はしたが、今後の詳細調査のため、とりあえず実施内容を備忘録として残す。


# 解決した方法

1. Docker関連プロセスとサービスの停止
    * ターミナルを開き、以下のコマンドを順に実行する。
    
        ```
        sudo launchctl bootout system/com.docker.vmnetd 2>/dev/null || true
        sudo launchctl bootout system/com.docker.socket 2>/dev/null || true
        sudo rm /Library/PrivilegedHelperTools/com.docker.vmnetd || true
        sudo rm /Library/PrivilegedHelperTools/com.docker.socket || true
        ps aux | grep -i docker | awk '{print $2}' | sudo xargs kill -9 2>/dev/null
        ```

2. 古いDocker Desktopの削除とゴミ箱の空にする
    古いDocker Desktopをアプリケーションフォルダからゴミ箱に移動し、ゴミ箱を空にする。

3. 最新版Docker Desktopのインストール
    以下から、バージョン4.37.2のインストーラーをダウンロードし、インストール。
    自分の場合は、これで解決できました。
    (https://docs.docker.com/desktop/release-notes/#4372)
AIが私の顔を評価する時代：「美しさ」を数値化することの意味


最近、「AIビューティーテスト」や「HowNormalAmI」というキーワードがSNSやGoogleトレンドで急上昇しているのをご存じでしょうか？  
見た目はただの遊びのように見えますが、実はその背後に深いテクノロジーと社会的なメッセージが隠されています。

今回は、この現象がなぜこれほど話題になったのか、そして私たちがAI時代において「美しさ」をどう考えるべきかを掘り下げていきます。

---

## 起点はアートプロジェクト：「HowNormalAmI」

話題の発端は、オランダの哲学者・アーティストである**タイメン・スヘップ（Tijmen Schep）**氏が制作した [HowNormalAmI.eu](https://www.hownormalamI.eu/) というサイトです。

このサイトは、AIが顔写真を分析し：

- 顔の美しさスコア  
- 推定年齢  
- BMI（体脂肪率）  
- 表情と感情  
- 予想寿命  

などを数値として提示してくれます。

しかし、これは単なる「美しさを測る」ツールではなく、**AIが持つ偏見やバイアスを可視化するための実験的なアートプロジェクト**として設計されました。

---

## SNSの拡散で「社会実験」が「バズ」に

もともと意識の高いメッセージ性を持ったプロジェクトでしたが、思わぬ形で話題となったのがTikTokやTwitchです。

人気インフルエンサー **@internetgav** が自身のAI評価結果をシェアしたことを皮切りに、多くのユーザーが自身の結果を投稿。  
さらにTwitchの有名ストリーマー **xQc** や **Cuffem** もライブ配信でこのテストを試し、そのリアクションが爆発的にバズりました。

「AIに『美しさ6/10』って言われた😂」「全然普通じゃないって評価された…」といった投稿が相次ぎ、楽しさ半分、ショック半分でSNSは大盛り上がり。

---

## AIが決める「美しさ」は本当に信じていいのか？

多くの人が「面白い！」と感じたこのトレンドですが、見逃してはいけない本質があります。

AIが私たちの顔を評価する時、**その判断基準は人間が用意したデータセット**に依存しています。  
たとえば、HowNormalAmIでは、大学生が他人の見た目を採点したデータが使われており、これがAIの「美しさ基準」となっています。

つまり、私たちはAIを通して「一部の価値観を数値化したもの」を見せられているに過ぎません。  
このプロジェクトは、その**偏見**や**アルゴリズムの危うさ**をあえて体験させることで、  
「私たちは本当にAIを信頼していいのか？」という問いを投げかけているのです。

---

## プライバシー重視で試せる代替サイト

AIの美的評価に興味があるものの、カメラの使用やデータ提供が不安…という方にはこちらのサイトがおすすめです👇

👉 **[https://aibeautytest.org](https://aibeautytest.org)**

このサイトは：

- 📸 写真をアップロードするだけで  
- ⏱ 数秒でAIが評価  
- 🔒 アカウント不要＆個人情報も不要  

と、シンプルかつプライバシーに配慮された設計になっています。

---

## 結論：「美しさ」は数値では測れない

AIがどれだけ高性能になっても、「美しさ」「個性」「価値」といったものは機械が完全に評価できるものではありません。  
今回のバズは、エンタメとしても楽しめる一方で、テクノロジーの限界や危険性を私たちに問いかけています。

気軽に試してみるのはOK。  
でもその結果に振り回されることなく、**本当の美しさは自分自身が決めるもの**だということを忘れずにいたいものです。

👉 **[https://aibeautytest.org](https://aibeautytest.org)**

---

*この記事は、テクノロジーと社会問題の交差点に関心を持つ方々へ向けて執筆しました。ご意見・体験談などぜひコメントでシェアしてください！*
CakePHPで一定時間ごとにユーザのストレージ利用量を計算する。

## やりたいこと
ユーザのストレージ利用量を一定時間ごとに計算して、DBに登録する。

## 方針
CakePHPのコマンドオブジェクトを使い、cron実行する。

## 環境
・PHP8.1
・CakePHP5

## コード
以下のコードを/src/Command/に設置すれば、コマンドから実行可能。

```php
<?php
// /src/Command/StorageCommand.php
namespace App\Command;

use Cake\Command\Command;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
use Cake\ORM\TableRegistry;

class StorageCommand extends Command
{
    public function execute(Arguments $args, ConsoleIo $io)
    {
        $usersTable = TableRegistry::getTableLocator()->get('Users');
        $users = $usersTable->find()->all();

        foreach ($users as $user) {
        //ユーザごとのファイル設置パス（任意）
            $userDir = WWW_ROOT . 'uploads/user_' . $user->id;

            $storageSizeMb = $this->getDirectorySize($userDir);

            $user->storage = $storageSizeMb;
            $usersTable->saveOrFail($user);
        }
    }

    protected function getDirectorySize($directory)
    {
        $totalSize = 0;

        if (!is_dir($directory)) {
            return 0;
        }

        $files = scandir($directory);

        foreach ($files as $file) {
            if ($file === '.' || $file === '..') {
                continue;
            }

            $filePath = $directory . '/' . $file;

            if (is_file($filePath)) {
                $totalSize += filesize($filePath);
            } elseif (is_dir($filePath)) {
                // 再帰的にサブディレクトリも含める
                $totalSize += $this->getDirectorySize($filePath);
            }
        }

        // バイト → MB（整数）
        return (int) floor($totalSize / 1024 / 1024); 
    }
}

```

## コマンド実行
下記をCronで定期実行する。
```
/usr/bin/php8.1 path_to_cake/bin/cake.php storage
```
## 参考
・CakePHP5公式：[コマンドオブジェクト](https://book.cakephp.org/5/ja/console-commands/commands.html)

## おまけ
無料でストレージ100Mまで利用可能です。
バグレポートツール「Altary」、ぜひ使ってみてください。
https://altary.io/
React Proxy設定

# Reactにおけるプロキシ（proxy）設定について

Reactでの**プロキシ設定**は、開発環境においてAPIサーバーとクライアント間の**CORS問題を回避するため**に使用されます。  
通常、Reactアプリはフロントエンドサーバー（例：`localhost:3000`）で実行され、APIはバックエンドサーバー（例：`localhost:8080`）で実行されるため、**ブラウザがクロスオリジンリクエストをブロック**します。  
これを解決するために、フロントエンドの開発サーバーがAPIリクエストを**プロキシとして中継**するように設定できます。

---

## 1. 基本的なプロキシ設定（CRAベースのプロジェクト）

CRA（Create React App）を使用している場合は、`package.json`に以下のように`proxy`オプションを追加できます：

（package.jsonの内容）  
```json
{
  "proxy": "http://localhost:8080"
}
```

これにより、Reactアプリから以下のようにAPIリクエストを送信できます：

```typescript 
fetch('/api/data');
// 実際のリクエストは http://localhost:8080/api/data に転送されます
```

Reactの開発サーバーが `/api/data` のリクエストを受け取り、`http://localhost:8080/api/data` にプロキシしてくれます。

---

## 2. 高度なプロキシ設定（カスタムプロキシ、複数のパスなど）

より複雑なプロキシ設定が必要な場合は、`src/setupProxy.js` ファイルを作成し、[`http-proxy-middleware`](https://github.com/chimurai/http-proxy-middleware) を使用できます。

### インストール

```terminal 
npm install http-proxy-middleware --save
```

### 設定例

（src/setupProxy.js の内容）  
```javascript
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:8080',
      changeOrigin: true,
    })
  );
};
```

### メリット

- 複数のパスをそれぞれ異なるサーバーへプロキシ可能  
- パスの書き換え（path rewrite）が可能  
- ヘッダーの変更など高度なオプションも対応  

---

## 3. 本番環境では？

このプロキシ設定は**ローカル開発サーバー上**でのみ機能します。  
本番環境では、以下のいずれかの方法を取る必要があります：

- バックエンドサーバーがフロントエンドとAPIを統合する  
- **リバースプロキシ**（例：Nginx）を使用してリクエストをルーティングする
- CORS対応ヘッダーをバックエンドに設定する
---

## ＊Nginxによるリバースプロキシ設定の例

### 目的
- Reactのビルド済み静的ファイルを `/` 経由で配信  
- `/api/` へのリクエストはバックエンドサーバー（例：`localhost:8080`）へプロキシする

---

### ディレクトリ構成（例）

- Reactビルド出力先：`PATH/react-app/build`  
- Nginx設定ファイル：`/etc/nginx/sites-available/react-app`

---

### Nginx設定例（`/etc/nginx/sites-available/react-app`）

```conf
server {
    listen 80;
    server_name your-domain.com;

    root /PATH/react-app/build;
    index index.html;

    # Reactアプリ（SPA）のルーティング
    location / {
        try_files $uri /index.html;
    }

    # APIリクエストのリバースプロキシ設定
    location /api/ {
        proxy_pass http://localhost:8080/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
```

---

### 設定の反映手順

1. 上記の設定ファイルを `/etc/nginx/sites-available/react-app` に保存
2. シンボリックリンクを作成：
```
ln -s /etc/nginx/sites-available/react-app /etc/nginx/sites-enabled/
```

3. Nginx設定のテスト：
```
sudo nginx -t
```

4. Nginxの再起動：
```
sudo systemctl restart nginx
```
巨大な数のかけ算（文字列処理）

最初は　`BigInt` でサクッと終わらせたかったけど、文字列処理がテーマだったので、文字列処理で掛け算をやっていく！


## <br>問題概要

数値を表す文字列 `S` と 1 桁の数値 `T` が与えられるので、`S * T` の結果を表す文字列を出力。

<Br>
入力例：

    987654321
    9

出力例：

    8888888889

<br>
https://paiza.jp/works/mondai/string_primer/advance_step12

<br><br>

## コード例：（BigInt使用例）
```js
const [A, B] = lines.map(line => BigInt(line));
console.log((A * B).toString());
```
🌀 楽だけど、これは“反則”！文字列処理がテーマだからNG！

<br><br>

## ✅OKコード（文字列処理）

```js
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

// 入力を配列に貯めておく
rl.on('line', (line) => lines.push(line));

rl.on('close', () => {
    const S = lines[0];     // 文字列としての大きな数
    const T = Number(lines[1]); // 数字（1桁）

    let carry = 0;          // 繰り上がり（最初は0）
    let result = "";        // 答えを作るための文字列

    // 文字列Sの末尾（1の位）から先頭（上位の位）に向かって処理
    for (let i = S.length - 1; i >= 0; i--) {
        const digit = Number(S[i]);   // 現在の桁の数字
        const product = digit * T + carry; // 現在の桁 × T + 前の繰り上がり

        const digitResult = product % 10;  // 1の位がその桁の答え
        carry = Math.floor(product / 10);  // 10の位以上は次の繰り上がり

        result = digitResult + result;     // 桁の答えを先頭に追加
    }

    // 最後に繰り上がりが残っていたら、それを先頭に追加
    if (carry > 0) {
        result = carry + result;
    }

    // 答えを出力
    console.log(result);
});
```
1. `S` の末尾から 1 桁ずつ取り出して、`T` を掛ける
1.  前回の繰り上がり（`carry`）を足す
1.  1の位を結果に、10の位は次の繰り上がりに
1.  全部終わったあとも `carry` が残ってたら、先頭に追加！

<br><Br>
## 気づきメモ

- `Number()`で文字→数値に変換（地味に忘れる）
- 繰り上がりは `Math.floor()` でOK！
- 文字列に桁を追加するときは `+ result`（逆順）
- `T === 0` の特別処理を忘れずに！

<Br>
## まとめ

「桁が多い＝ `BigInt`」じゃない！筆算風に組んでいけば、JSでも文字列だけでしっかり掛け算ができるとわかって大満足。


<br><br>[僕の失敗談(´;ω;｀)と解決法🐈](https://paizabeginner.wordpress.com/2025/05/10/%e5%b7%a8%e5%a4%a7%e3%81%aa%e6%95%b0%e3%81%ae%e3%81%8b%e3%81%91%e7%ae%97%ef%bc%88%e6%96%87%e5%ad%97%e5%88%97%e5%87%a6%e7%90%86%ef%bc%89/)
问题

## 1.在免费版idea中用tomcat启动jsp程序
步骤1.下载插件
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899383/a43f9d13-f123-42cc-82ee-229eddddd00d.png)
步骤2.添加配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899383/390a5877-7443-4315-895b-aa940e6defca.png)
## 2.
VBAは配列一択

Excelはセル、一つ一つに直接書き込むのは非常に遅いです（少ない読み書きなら気にならないですが）
VBAのループ処理で行えば数十秒かかる事も、
テーブルの列のセル一つに手入力で数式を書いてEnterを押せば構造化参照で一瞬の内に計算が完了します（コンマ何秒）。

つまり私たちがそれぞれのセルに読み書きをするのは非常に遅いです
が、
Excelの関数は計算を配列なのか、はたまたC++で処理をしているのか分かりませんが、
計算結果を数式の範囲に一気に貼り付けるのはコンマ何秒の世界で、非常に高速です。

```VBAでテーブルの範囲、またはセルの範囲を取り込むには

Dim 配列 as Variant
配列　= Range("テーブル名")

または
配列　= Range(アドレス)

たったこれだけです。

配列の値を取得する時に.Valueは入りません。

あとは配列をCellsと全く同じ操作感で処理をしてください。
セルの範囲を取り込んだ時、配列は1始まりなので安心してください。

行の最大値はテーブルならば

Range("テーブル名").Rows.Count
あるいはUbound(配列,1)

で最大行数が取得できます。
もうCells(Rows.Count,1).End(xlup).Row（しかもたった行番号を取得するだけ）は入りません。必要ないです。


配列の集計結果を貼り付けたい時は
テーブルならば
Range("テーブル名") = 配列
もしテーブルの行がない、少ない場合は念の為に
テーブルの範囲をリサイズするか、あるいは
Range("テーブル名").Resize(Ubound(配列,1),列数).Value = 配列

それか
Range(貼り付けたい所) = 配列

で貼り付けてください

以上
会社の目標設定に困った時の本質的アプローチ

> **この記事は、前回投稿した「技術ドリブンな組織でテスト担当者が目標設定を実務に落とし込み、顧客満足と自己成長を実現する方法」の内容をさらにブラッシュアップしたものです。より実践的かつ本質的な目標設定手法を私なりの考えでまとめました。**

## はじめに

会社やチームで目標設定を求められても「そもそも何をどう決めればいいのか分からない」と感じたことはありませんか？  
この記事では、目標設定の本質的な考え方と、実践的なフレームワークや手順をまとめます。  
あなた自身のモチベーションが上がり、納得感のある目標設定を実現したい方はぜひ参考にしてください。

---

## 目標設定の2つの型

- **発生型目標**  
  解決すべき課題を正確に把握し、ゴールに対する障壁を見つけ、その障壁を除くことを目標とする。

- **設定型目標**  
  現状をもとに個人が自発的に設定する。ストレッチ目標とも呼ばれ、意義や達成基準が曖昧になりやすい。

---

## 目標設定の出発点

「会社から目標を設定してください」と言われて考え始めるのは、まるで「紙のない状態で絵を描け」と言われるようなものです。  
紙がなければ、どこに何を描けばいいのか分からず、絵は宙に浮いた意味のないものになってしまいます。  
目標設定も同じで、まずは**自分自身の目的（人生の目標）を把握すること**が絶対に必要です。  

次に、自分の現状を正しく理解し、さらに会社の方針や目的をしっかり把握しましょう。  
この3つが揃って初めて、個人の目的と会社の目標をすり合わせ、モチベーションを保ちつつ、視座を高く持った現実的かつ意義のある目標設定が可能になります。

---

## 目標設定のためのフレームワーク

### SMARTの法則

| 項目         | 内容                                    |
|:-------------|:----------------------------------------|
| Specific     | 具体的で明確な目標                     |
| Measurable   | 測定可能な指標                         |
| Achievable   | 達成可能な現実的目標                   |
| Relevant     | 目的や方針と関連性があること           |
| Time-bound   | 期限が明確に設定されていること         |

SMARTの法則を活用することで、目標達成に向けた行動が明確になり、モチベーション維持や納得感のある評価につながります。

---

## 目標設定の手順

1. **自分自身の目的を把握する**  
   まずは自分が何を目指しているのか、人生のビジョンや価値観を明確にしましょう。

2. **現在の状況を整理し理解する**  
   自分の強み・弱み、現状の課題や環境を客観的に見つめます。

3. **会社の方針や目的を理解する**  
   会社のビジョンや中長期計画、期内の重点方針を把握し、自分の役割を認識します。

4. **個人の目的と会社の目標をすり合わせる**  
   自分の目標と会社の方向性を重ね合わせ、整合性のある目標を設定します。

5. **設定した目標とのギャップを書き出す**  
   目標達成に向けて不足している要素や課題を洗い出します。

6. **ギャップを埋めるためのTODOを考える**  
   行動計画を具体的なTODOレベルまで落とし込みます。

7. **達成期限を設定する**  
   いつまでに何を達成するのか、期限を明確に決めましょう。

---

## 目標設定のポイント

- **モチベーションが上がる目標を選ぶ**  
  自分が心からやる気になる目標でなければ、継続は難しいです。

- **目標は可視化し、指針として掲げる**  
  頭の中のビジョンをアウトプットし、目に見える形で整理することで、ギャップの理解や行動指針が明確になります。

- **自己分析と会社方針の理解が不可欠**  
  目的や土台がないまま目標を設定しても、意味のない宙に浮いたものになってしまいます。

---

## まとめ

- 目標設定は「会社から言われたからやる」ものではありません。  
- まずは自分自身の目的を明確にし、現状を理解し、会社の方針を把握すること。  
- その上で個人の目的と会社の目標をすり合わせて、モチベーションを保ちつつ意義のある目標を設定しましょう。  
- SMARTの法則などのフレームワークを活用し、具体的で達成可能な目標と行動計画を立てることが成功の鍵です。

---

あなたの目標設定がより実りあるものになることを願っています！
「wolframalphaのプロットで　縦横比を1:1にしたい。」をAI先生に聞きました。  

・ページの最後に実行例があります。
・縦横比の???大体です。

# (本日の)ChatGPT先生へ
#### 質問リスト
```
# 質問リスト
1. wolframalphaのプロットで　縦横比を1:1にしたい。
2. Wolfram Alphaで教えて下さい。
3. pgsql　は何ですか。wolframalphaで教えて下さい。
4. matlabはできませんでした。
5. matlab はできないのに、回答されるのは、どうしてですか。
```
#### (以下回答抜粋)
pgsql
```
`plot sin(x) from x=0 to 10, aspect ratio 1
```
または：
matlab
```
plot sin(x), x=0 to 10, y=-1 to 1, square plot
```
pgsql　は何ですか。wolframalphaで教えて下さい。
matlabはできませんでした。
>なるほど、Wolfram Alphaでは Matlab コードやオプション（たとえば axis equal）のようなものは直接使えません。Wolfram Alphaは Mathematicaベースの自然言語処理と計算エンジンなので、Matlabの構文は理解されないのです。

matlab はできないのに、回答されるのは、どうしてですか。
>なぜWolfram AlphaでMatlabのような回答がされるのか？
...

# Gemini先生へ

# copilot先生へ

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

https://qiita.com/mrrclb48z/items/b6351b48e47bcf6265c0


# 実行例 WolframAlpha 

https://mathmathmass.exblog.jp/34493999/

＞解答では図は不要ですが，求めた接線がちゃんと両方に接していることの確認はしておきましょう。
wolframalphaで確認しました。以下のプロット(グラフ)は、おいしい?ところが、わかりにくです。
wolframalpha1回目:縦横比がわかりにくいです。
https://www.wolframalpha.com/input?i=y%3Dx3%2Bx2-x-1%2Cy%3Dx2%2Cy%3D4x-4%2Cy%3D0%E3%80%80%E3%82%B0%E3%83%A9%E3%83%95&lang=ja
wolframalpha2回目:**???力技ratio5で対応しました**。y軸の数字不足です。
https://www.wolframalpha.com/input?i=plot+%28x3%2Bx2-x-1%2Cx2%2C4x-4%2C0%29+from+x%3D-4+to+4%2C+aspect+ratio+5&lang=ja

# (予定)sympyで
・mathjax
2025　九州大学 前期MathJax 文科系【１】　＜　大学入試数学問題集成 様
https://mathexamtest.web.fc2.com/2025/202510842/2025108420100mj.html#top-0106
Turbo C上でstdio.hが読み込まれない（忘備録）

## 問題
Turbo C上でstdio.hが読み込まれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/902de5d6-a877-49b4-9d9d-ec0cae6a3e2a.png)

## 解決
以下のように入力し、INCLUDEの場所を指定するとコンパイルできた。
```
tcc -S -IC:\TC\INCLUDE demo.c
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/76227667-ea26-4891-acc1-97118275095d.png)

## 環境
MS DOS　6.22
Turbo C 2.0
MX4SIO　MMCE

SONY PlayStation2

すぐに傷んでDISCを読めなくなるので少しでも長持ちさせるために
OPEN PS2 LOADER.ELFを使い

HDD - PS2実機のHdd
USB - PS2実機のUSB
SMB - WindowsのHdd共有

追加された
MX4SIO(MemoryCardSlotのMicroSDCard)から起動させる。
MMCE(MemoryCardSlotのMemCardPro2)から起動させる。

これ(OpenPS2Loader.ELF)でディスクを読めない本体でもゲームの起動はできます。

時々コピープロテクトのディスクがありますが
私は怖いのでISOは吸い出していません。

それは正式名称
Capcomの
(SLPM-66637)"Vampire - DarkstalkersCollection"
DVDからの起動しかしていません
実機のSCPH-37000で普通の
SONY社のPLAYSTATION2のHDD(B.B.Navigator)にインストールをする機能があるのでゲームを遊んでいます。
ISO.file
(DiskImageが吸い出せないのでストレスはあります)
あまりCD-DVD Driveからゲームを起動させると本体の音で分かりますが...
レンズが傷んでしまうと
CDもDVDも動きませんが、まだOpenPS2Loader.elfを使ってゲームを遊べるよとの報告でした。

psx-placeというところで、その辺の情報(OPL関連)がたくさんあるよ。

私の部屋はSCPH-37000Lが３台
SCPH-10000
SCPH-70000
SCPH-77000
ゲームは集めていますがあまりやりません。

ゲームの実行は500円くらいで買ったSCPH-77000を使っています。


PS2Linuxは動くのにHddとDVDが必要です。

PBPX-95501(PS2Linux)のDVDはpatchをあててDVD-Rにコピーしても動かないよ。
私も試していますが動いても動作しないよ。
ログイン画面までたどりつけません。

PS2を修理する業者さんもあるようで綺麗な状態の本体なら新品を買うよりも
リペアを依頼してまかせてみるほうが安いかもしれませんね。
リーダブルコード（第1章〜第2章）の学び

## はじめに

この章では「読みやすいコードとは何か？」という原則から、「名前に情報を詰め込む」ことでコードの理解がいかに早くなるかについて学びました。

## 理解しやすいコードとは？

書籍では、理解しやすいコードとは「**理解するまでにかかる時間が最も短いコード**」と定義されていました。
「できる限り早く理解できること」を意識することが大切だということで、自然と腑に落ちました。

## 名前に情報を詰め込む

具体的な手法として、変数名や関数名に意味を持たせることで、コードの意図が明確になり、
「ミスの発見も早くなる」
という話が印象的で一番の学びになりました。

理解の速さに加えて、ミスの発見速度も上がるということで、リーダブルコードちゃんと学ぶべきだなと強く感じました。

### 1. 意味のある名前をつける

* **動作の明確化**
  例：`get` → `fetch`（ネットワークアクセスが含まれるとわかる）

* **単位の明示**
  例：`time` → `time_s`（秒単位であることがわかる）

* **状態の明示**
  例：`data` → `unescaped_data`（未加工であることが明確）

### 2. 名前の具体性がバグの発見を助ける

例えば、戻り値の変数名を `retvalue` とするよりも、`sum_squares` とすれば、`sum_squares += val` のような間違いにもすぐに気付くことができる。具体的な名前があることで、「何が正しい形なのか」の認識がコード上で明確になる。

### 3. スコープに応じて名前の長さを調整する

* スコープが短い場合：短く抽象的でもOK（例：`i`, `val`）
* スコープが長い場合：具体的にすべき（例：`user_id_list`, `escaped_html_string`）

短いスコープに長い名前を使うと、冗長になってしまうこともあるため、バランスが重要だと学んだ。

### 4. フォーマットで情報を与える

* **クラスのメンバ変数の末尾に `_` をつける**

  これにより、引数やローカル変数とメンバ変数を区別でき、可読性が上がる。

## おわりに

『リーダブルコード』はプログラミングを始めたばかりの頃に読んだときは、その重要性をあまり感じませんでした。
しかし、ある程度の規模のコードを扱えるようになってきたため、変数名、関数名が、コード全体の理解に大きく影響することはわかります。

特にチーム開発や、数週間後に自分が再度読むコードにとっては「読みやすさ」はとても重要だと思います。
日々の実装から意識していこうと思いました。
AWS自動化はEventBridgeとMWAAのどっち？エンジニアが選ぶべき使い分け戦略を解説


<h2>「EventBridgeかMWAAか」で迷っているエンジニアへ</h2>
<p>
業務でAWSの自動化を進めたいが、<strong>EventBridge</strong>と<strong>MWAA（Managed Workflows for Apache Airflow）</strong>のどちらを使うべきか悩んだ経験はありませんか？<br>
「どっちでもできそうだけど違いが分からない」「スケジューラーとしてAirflowが良いと聞いたけど重たそう」など、<strong>選定における技術的な迷い</strong>は多くのエンジニアが抱える問題です。<br>
この記事では、<strong>AWSにおける自動化ワークフローの代表的2サービスの特徴</strong>を比較し、<strong>選定判断に役立つ実務的なポイント</strong>をまとめました。
</p>

<h3>背景：AWSにおける自動化の潮流と注目サービス</h3>
<ul>
  <li>近年、IaC（Infrastructure as Code）やDevOpsの普及により、<strong>自動化基盤の整備が必須</strong>となってきた。</li>
  <li><strong>EventBridge</strong>は軽量なイベントベースのトリガー管理に最適。</li>
  <li><strong>MWAA</strong>は複雑なワークフロー制御やデータパイプライン運用に最適。</li>
  <li>Qiitaでも「Airflow + MWAAでのETL構築」「EventBridgeによるLambda起動」の記事は安定して読まれている。</li>
  <li>実務では「疎結合 vs 統合管理」「柔軟性 vs 管理コスト」のトレードオフが頻出。</li>
</ul>

<h3>課題：EventBridgeとMWAA、なにが違って何が困る？</h3>
<p>
実際の現場では、以下のような具体的な悩みが挙がります：
</p>
<ul>
  <li><strong>EventBridgeは手軽だが、複雑な条件分岐・リトライ制御が面倒</strong></li>
  <li><strong>MWAAは柔軟だが、環境構築・コスト・デバッグの学習コストが高い</strong></li>
  <li>Lambda + StepFunctions + EventBridge の組み合わせと MWAA の役割が曖昧</li>
  <li><span style="color:red;">EventBridge + Lambda構成では再利用性・状態管理が課題になることも</span></li>
  <li><span style="color:red;">MWAAは起動時間や初期起動のラグでレスポンス要件を満たさない場合あり</span></li>
</ul>

<h3>解決策：ケース別の選び方と構成例</h3>
<p>
AWSでの自動化選定は「要件の重みづけ」が鍵です。以下に判断軸と構成パターン例を示します。
</p>

<h4>① 軽量なイベント駆動処理なら EventBridge + Lambda</h4>
<pre><code>
# CloudWatchアラーム通知をLambdaでSlack連携
EventBridge Rule → Lambda → Slack Webhook
</code></pre>
<p><strong>特徴：</strong>設定が簡単・低コスト・リアルタイム性あり</p>

<h4>② 複雑な依存関係・分岐ロジックが必要なら MWAA</h4>
<pre><code>
# S3にファイルアップロード後、ETL実行 → 検証 → DB反映の3ステップ
S3 Event → DAGトリガー（MWAA） → 複数タスク制御
</code></pre>
<p><strong>特徴：</strong>DAGによる依存管理・リトライ・Slack通知など運用補助が充実</p>

<h4>③ 中間パターン：Step Functions + EventBridge</h4>
<pre><code>
EventBridge Rule → StepFunctions → 複数Lambda分岐
</code></pre>
<p>シンプルだが依存関係やログ管理は自前対応が必要。</p>

<h3>ベストプラクティス：使い分けの戦略と注意点</h3>
<ul>
  <li><strong>処理が単純・短時間で終わる：EventBridge + Lambda</strong></li>
  <li><strong>処理が複雑・再実行や可視化が必要：MWAA</strong></li>
  <li><strong>状態遷移が必要：StepFunctionsを検討</strong></li>
  <li><span style="color:red;">MWAAは初期起動時間（1〜2分）がネックになるので定期ジョブ向き</span></li>
  <li>ログ出力・監視連携は早期から仕組み化（例：CloudWatch Logs, Slack通知）</li>
</ul>

<h3>まとめと今後の展望</h3>
<p>
AWSにおける自動化基盤構築は、<strong>「軽さ vs 柔軟性」</strong>という選択の連続です。<br>
EventBridgeはリアルタイム性やコスト面で優れ、MWAAは制御力と可視性で勝ります。<br>
選定の際には<strong>「処理の複雑さ」「運用者のスキル」「将来的な拡張」</strong>を意識すると判断がブレにくくなります。<br>
今後はAmazonが提供する<strong>Amazon States Language（ASL）</strong>の強化や、MWAAの起動高速化など、機能強化の動向にも注目です。
</p>
【論文解説】Word2vecに関連する論文について(CBOW・Skip-gram・Negative Sampling)

Word2vecに関連する論文はCBOWやSkip-gramについて取り扱った[Efficient Estimation of Word Representations in Vector Space](https://arxiv.org/abs/1301.3781v3)とNegative Samplingについて取り扱った[Distributed Representations of Words and -Phrases and their Compositionality](https://arxiv.org/abs/1310.4546v1)の二つが有名です。当記事では以下、この二つの論文を中心にWord2vecに関連する論文について解説をまとめました。


## 前提・基本知識の確認
### Word2vec以前の単語のベクトル化
### NCE(Noise Contrastive Estimation)
### 階層的ソフトマックス(Hierarchical Softmax)



## Word2vec
### CBOWとSkip-gram(Log-linear Models)
Word2vecの学習にあたっては「単語は文脈によって規定される」という分布仮説(distributional hypothesis)に基づいて目的関数が設定されます。Word2vecの学習にあたってのタスクはCBOW(Continuous Bag-of-Words)とSkip-gramの二通りに大別されます。それぞれ下図を元に確認すると良いです。

![Word2vec1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936087/36ad4553-751d-4c37-8cb0-1805f3ba77ed.png)
[Efficient Estimation of Word Representations in Vector Space](https://arxiv.org/abs/1301.3781v3) Figure.1

図より「文脈から単語を予測するのがCBOW」、「単語から文脈を予測するのがSkip-gram」であると読み取ると良いです。それぞれの計算の複雑さ(complexity)は下記のように計算できます。

```math
\begin{align}
Q_{\mathrm{CBOW}} &= N \times D + D \times \log_{2}{V} \\
Q_{\mathrm{Skip-gram}} &= C \times ( D + D \times \log_{2}{V} )
\end{align}
```

従来研究(NNLM)からのCBOWやSkip-gramの学習時間やパフォーマンスの改善は下記の表を元に確認すると良いです。

![Word2vec2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936087/623d42ee-bc0a-4795-9341-8a1f25760cdb.png)
[Efficient Estimation of Word Representations in Vector Space](https://arxiv.org/abs/1301.3781v3) Table.6


### Negative Sampling
[Negative Sampling](https://arxiv.org/abs/1310.4546v1)はWord2vecの学習の高速化にあたってボトルネックとなるSoftmax関数の計算を行わないように負例(Negative Sample)に基づいてlossを再構築した手法です。Negative Samplingのlossは雑音対照推定(NCE; Noise Contrastive Estimation)をベクトル表現(vector representation)のパフォーマンスが下がらないように単純化することで定義されたと理解すると良いです。

```math
\begin{align}
\mathcal{L} &= \log{\sigma \left( v_{w_{O}}^{\mathrm{T}} v_{w_I} \right)} + \sum_{i=1}^{k} \mathbb{E}_{w_i \sim P_{n}(w)} \left[ \log{\sigma \left( -v_{w_{i}}^{\mathrm{T}} v_{w_I} \right)} \right] \\
\sigma(x) &= \frac{1}{1+\exp{(-x)}}
\end{align}
```
Negative Samplingは上記のような目的関数(Objective)を定義します。まず第1項によって入力の単語の$w_I$と出力の単語の$w_O$のベクトル表現の$v_{w_I}$と$v_{w_O}$が類似するように学習が行われると理解すると良いです。次に第2項については$P_n(w)$はノイズの分布であり、この分布に基づいてサンプリングされた$w_i$に基づく内積が小さくなるように学習が行われます。また、$k$は負例のサンプリングの数であり、基本的には5〜20(大きなデータセットの場合は2〜5)が有用であるとされます。

負例のサンプリングにあたっては単語の出現頻度に基づくユニグラム分布$U(w)$の3/4に基づいてサンプリングを行うと良いと記載されています。確率分布は正規化定数の$Z$を用いて下記のように立式されます。

```math
\begin{align}
\frac{U(w)^{\frac{3}{4}}}{Z}
\end{align}
```
【SwiftUI】Task {}について学んだ

# はじめに
非同期処理実装中に知ったことをアウトプットします。
間違いがあればご指摘いただけると幸いです。

# 同期処理と非同期処理
### 同期処理とは
- 処理が**順番に実行**される方式
- 各処理が完了するまでプログラムが待機
- 実行が直列的なので、遅い処理があると全体がブロックされる（遅延が発生）
### 非同期処理
- 処理が**独立して実行**される方式
- 処理を並行して実行可能
- 時間のかかる処理があっても、他のタスクはブロックされない
- 実装が複雑になりやすい

# 🚀Tast {}とは
**新しい非同期タスクを生成し、その中で非同期処理を実行するための構造体**

一言で言うと
「この括弧 {} の中の処理を、独立した非同期の作業単位として実行してね」という指示

💡日常生活に例えて見ると・・・

「別のスタッフに仕事を頼む」イメージです。

- あなたがお店の店長さん（メインの仕事をしている人）だとします。
- お客さんから「この商品について詳しく調べてほしい」という時間のかかりそうな依頼が来ました。
↓

### 👉Task {} を使わない場合（もし同期処理だったら）：
- 店長（あなた）が自分でその調査を始めます。
- 調査が終わるまで、レジ打ちも、他のお客さんの対応もできません。お店の他の仕事が全部止まってしまいます。
➡️ これが UIフリーズ のような状態です。
### 👉Task {} を使う場合（非同期処理）：
- 「よし、この調査は別のスタッフ（Task）に任せよう！」 と考えます。
- Task { ... } で、調査の仕事（... の部分）を新しいスタッフに渡します。
- あなたはすぐに他の仕事（レジ打ちなど）に戻れます。 お店のメインの仕事は止まりません。
- 頼まれたスタッフ（Task）は、あなたとは別に、裏でこっそり調査を進めてくれます。 これが「独立した」「非同期の」作業です。
- 調査が終わったら、スタッフがあなたに結果を報告してくれます。
🔧 Android Chromeで困ったPDFバグ!?

### ～市場価格のPDFが正しく表示されない謎の現象～

---

### ■ はじめに

自分は農産物を少量ながら**市場に出荷しており**、定期的に青果市場の市況情報（PDF）をチェックしています。
ところが、**2025年5月初旬**から、妙な現象に気づきました。

---

### ■ 表示されるPDFが「違う」!?

市場の公式サイトで最新の市況PDFを開こうとすると…

* **URLは正しい市場のもの**
* **でも表示されるPDFは別の市場の内容**（全く関係ない別のPDF）

という意味不明な状態に。しかも**ドメインもファイル名も違う**のに、**表示される中身がなぜか同じ**なのです。

例：

* 表示したい → `https://oyasai.ne.jp/.../market.pdf`（2025年5月10日付）
* 表示される → 数日前に見た `https://nishikyusyu.co.jp/.../market.pdf` の内容

これは**4台のスマホでテスト**してみたところ、**2台で再現**しました。どちらも**Android版のChrome**です。

---

### ■ 状況の整理と確認したこと

* キャッシュ削除 → 効果なし
* スマホ再起動 → 効果なし
* EdgeやFirefoxで確認 → **正常に表示された**
* ファイル名は共通して `market.pdf`（←これがカギ？）

さらに調べたところ、**Chrome内部のPDFビューア（`chrome-native://pdf/`）が影響している可能性**が浮上しました。

---

### ■ ChatGPTの見解（要約）

> **原因はChromeのPDF表示処理にある可能性が高いです。**
> 特に「同名のPDFファイル（例：`market.pdf`）」を開くと、**Chromeが以前に見た同名PDFをキャッシュから表示**してしまうケースがあります。
>
> これはChrome v136.0.7103.87（2025年5月6日更新）以降で顕著に発生しており、**Chromium公式にもバグ報告が複数寄せられています**。
>
> ➤ [Issue 414914139](https://issues.chromium.org/issues/414914139)
> ➤ [Issue 415572411](https://issues.chromium.org/issues/415572411)

---

### ■ 一時的な回避策

| 方法                     | 内容                                 |
| ---------------------- | ---------------------------------- |
| 🔹 シークレットモードで開く        | キャッシュを使わないため、正しく表示されることが多い         |
| 🔹 別ブラウザを使う            | EdgeやFirefoxでは問題なし                 |
| 🔹 URLにクエリ追加           | `?v=20250510` などバージョンを区別する工夫（できれば） |
| 🔹 サーバー側でファイル名を日付付きに変更 | 例：`market_20250510.pdf`            |

---

### ■ 結論

今回の問題は、**Chromeの最新版におけるキャッシュの誤動作 or PDFビューアのバグ**によるものと考えられます。

PDFの表示がおかしいとき、**「キャッシュ」ではなく「Chromeの仕様変更」が原因**という可能性もあります。
しばらくはEdgeなどの他ブラウザで見るのが無難です。

---

### ■ おまけ：スマホ情報（発生した端末）

* 機種：**OPPO Reno7 A**
* Android：**13**
* Chromeバージョン：**136.0.7103.87**（2025/05/06更新）

---
※ この現象はCromeの更新で直ることを期待しています。 
2025/05/10
【Flutter】Androidのsdkmanagerが見つからない場合の対処(Windows)

flutterの環境を作ろうとしてハマったので覚え書き

## エラー内容

```sh
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    X cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    X Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/to/windows-android-setup for more details.
```

上記のsdkmanagerが見つからないし、まずもってAndroid SDKがない？

## 対処

1. Android Studioを起動
1. 右上の[...]から、[SDK Managar]を選択  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500161/29bfa117-4362-4a9e-8167-ab66d34302ad.png)
1. たしかここの[Edit]を選ぶとSDKがインストールできた、はず(画像はインストール済みの状態、ご容赦を)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500161/b40c4906-952c-497b-93a1-eb8833497f22.png)
1. [SDK Tools]タブの[Android SDK Command-line Tools(latest)]をチェック入れる  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500161/7368c106-7171-473a-ad7f-af224c17dc6e.png)
1. 下部の[Apply]ボタンでインストール！

## 後書き

今後もUIが変更されて意味のない情報になることが予想されます  
とはいえ現状困っている人の力になれれば幸いです
NFCカードでPAMを使いログインする仕組みを作った話

# NFCカードでLinuxにログインしてみた

## 💡 なぜ作ったのか

* パスワード入力が面倒だった
* 以前スマホにプッシュ通知を飛ばしてログインするものを作ったが不安定だった
* 新しいデバイスを触ってみたかった
* Linux対応のNFCカードリーダーが市販されていた
  * RC-S300/S1

https://www.yodobashi.com/product/100000001008711914/

## 🛠 やったこと

### 1. UIDを読み取るプログラムの作成

* `libnfc` を使ってNFCカードのUIDを取得
* RC-S300/S1にカードをかざすだけでUIDを表示

### 2. ユーザーとの紐付け処理

* `username[\t]UID` の形式でペアを記録したファイルを作成
* 起動時にこのファイルを読み込み、照合するスクリプトを作成
* コマンドライン引数でユーザー名を指定し、カードのIDがリストにあった場合はユーザー名が与えられたものと一致するかを確認するシンプルな仕様

### 3. PAMモジュールを実装

* Cで簡単な認証用のPAMを作成
* UID照合プログラムを呼び出すだけの構造
* 成功すればログインを許可、失敗すれば拒否

### 4. PAMの設定と動作確認

* `/etc/pam.d/common-auth` を編集
* 実際にカードをかざしてログインできることを確認

## ⚠ 気づいたこと・注意点

* スマホやマイナンバーカードは毎回違うUIDを返す
  * 認証用には使えない
* FeliCa Lite-Sなど、UIDが固定のカードが必要
* UIDは暗号化されていない
  * セキュリティは自己責任
  * 単体での厳重な用途には不向き
* リーダーのLinux対応は機種によって異なる
  * 購入前に調べることを推奨

## 🎉 まとめ

* カードをかざすだけでログインできるのは快適
* 自作のログイン体験としては大満足
* 次はチャレンジレスポンスや署名認証にも挑戦したい

### 📎 付録

https://github.com/m-m-n/nfc-reader

https://github.com/m-m-n/pam_nfc_auth

---

それでは良いLinuxライフを
Multipassでマウント時に所有者がnobody＆Permission Deniedになる問題の原因と解決策


# Multipass でマウント時に所有者が nobody＆Permission Denied になる問題の原因と解決策

## 問題の概要

Multipass で Mac のローカルディレクトリを Ubuntu インスタンスにマウントした際、以下の問題が発生。

- マウントしたディレクトリにアクセスできない（Permission denied）
- インスタンス内で`ls -al`コマンドの結果、ファイル所有者が`nobody`になっている

## 調査で判明した原因

### 1. Multipass の`--mount`は UID/GID マッピングが必要

- Mac 側の UID/GID が正しく伝わっていなかった
- マウント時に明示的な指定が必要

```bash
# 例
# Mac 側の UID/GID
id -u
id -g

# Multipass 側の UID/GID にマッピング
multipass mount --uid-map 501:1000 --gid-map 20:1000 /Users/example_user/shared_dir UBUNTU:/mnt/c/shared_dir
```

### 2. Mac 側で所有者情報が壊れていた

- `ls -al`の結果、マウント元のファイルの所有者が 777 など不正な UID になっていた
- おそらく色々触っている時に `chmod`誤って `chown`で叩いている...

## 解決手順

### Mac 側で所有者とグループを正しく戻す

```bash
sudo chown -R example_user:staff /Users/example_user/shared_dir
```
NextJS をロードバランサーの背後で動かすならば Keep-Alive を伸ばしましょう


# 事象: しばしば 502 Bad Gateway が発生する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/2a47ccb0-e96f-4175-9602-c8bff6aee877.png)

NextJS のアプリケーションを開発中にしばしば 502 Bad Gateway が発生していました。
アーキテクチャの構成は ブラウザ -> LB -> NextJS のような形になっていて、LB の背後に NextJS が動いています。

```mermaid
flowchart LR
    A[ブラウザ] --> B[LB]
    B --> C[NextJS]
```

# 原因: Keep-Alive タイムアウト

NextJS は NodeJS で動いているので、NodeJS の Keep-Alive タイムアウトが 5 秒に設定されています。
LB の Keep-Alive タイムアウトは 60 秒に設定されているので、LB が Keep-Alive を維持している間に NextJS の Keep-Alive タイムアウトが切れてしまい、502 Bad Gateway が想定よりも早く発生していました。
NextJS で Keep-Alive がタイムアウトしてしまうとアプリケーション側（NextJS 側）ではハンドリングができなくなってしまうので、LB 側で 502 Bad Gateway をブラウザに返す挙動になります。

```mermaid
flowchart LR
    A[ブラウザ] --> B[LB]
    B --> C[NextJS]
    C -->|Keep-Alive Timeout| B
    B -->|502 Bad Gateway| A
    D@{ shape: braces, label: "Keep-Alive: timeout=60s" } -.- B
    E@{ shape: braces, label: "Keep-Alive: timeout=5s" } -.- C
```

# 解決策: Keep-Alive タイムアウトを伸ばす

NextJS の Keep-Alive タイムアウトを伸ばすことで解決できることがあります。

- LB: Keep-Alive タイムアウト 60 秒（ここは特に変更しない）
- NextJS: Keep-Alive タイムアウト を 5 秒 から 61 秒に変更、Header タイムアウトを 62 秒に設定

### 📌 ポイント

- NextJS のタイムアウトは LB の Keep-Alive タイムアウトよりも少し長くする
  - NodeJS のソケット接続が少なくとも LB と同じ時間以上維持され、LB 側が早すぎる切断で 502 を返すことは避けられます。
- Header タイムアウトは Keep-Alive タイムアウトよりも長くする
  - ヘッダー受信の待機時間を Keep-Alive よりも少し長くすることで「ヘッダー受信に失敗した」というエラーを回避できます。

### 実装サンプル

NextJS でカスタムサーバーを使っている場合は、以下のように `server.keepAliveTimeout` を設定することで Keep-Alive タイムアウトを変更できます。

```javascript
const express = require('express');
const app = express();

// ... (ミドルウェアやルートの設定) ...

const port = 3000;
const server = app.listen(port, () => {
  console.log(`Express server listening on port ${port}`);

  // keepAliveTimeout の値を確認 (ミリ秒単位)
  const keepAliveTimeout = server.keepAliveTimeout;
  console.log(`Express server keepAliveTimeout: ${keepAliveTimeout} ms`);

  // headersTimeout の値も関連情報として確認できます
  const headersTimeout = server.headersTimeout;
  console.log(`Express server headersTimeout: ${headersTimeout} ms`);
});

server.keepAliveTimeout = 61000; // 61秒
server.headersTimeout = 62000; // 62秒 (keepAliveTimeout より少し長くするのが一般的)
```

# まとめ

NextJS に限った話ではないですが正しく Keep-Alive を設定しないと、予期せぬタイムアウトが発生することがある、という話でした。

# 参考ページ

https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Keep-Alive

https://github.com/vercel/next.js/discussions/22211

https://github.com/vercel/vercel/issues/11692

https://github.com/expressjs/timeout

https://expressjs.com/en/resources/middleware/timeout.html#as-top-level-middleware

https://zenn.dev/forcia_tech/articles/202305_http_keepalive
DockerfileにおけるCMDの記述形式の違い

# DockerfileにおけるCMDの記述形式の違い

Dockerfileに記述する`CMD`には、**シェル形式**と**Exec形式**の2つの記述方法があります。それぞれの違いや特徴を詳しく解説します。

---

## 1. シェル形式
以下のように記述します：

```dockerfile
CMD node server.js
```

### 特徴
- 実行時に`/bin/sh -c`を介してコマンドが実行されます。
- 実際には以下のように解釈されます：
  ```bash
  /bin/sh -c "node server.js"
  ```
- **シェルの機能**（環境変数展開、パイプ、リダイレクトなど）を利用できます。
- シェルのオーバーヘッドが発生するため、Exec形式よりわずかに遅い場合があります。

---

## 2. Exec形式
以下のように配列形式で記述します：

```dockerfile
CMD ["node", "serve.js"]
```

### 特徴
- コマンドが直接実行されます（シェルを介しません）。
- 実際には以下のように解釈されます：
  ```bash
  node serve.js
  ```
- **シェルの機能**（パイプやリダイレクト）は使えませんが、シンプルで安全です。
- オーバーヘッドが少なく、意図した動作が保証されやすい。

---

## シェル形式とExec形式の違い

| 特徴                | シェル形式 (`CMD node server.js`)          | Exec形式 (`CMD ["node", "serve.js"]`) |
|---------------------|-------------------------------------------|---------------------------------------|
| 実行方法            | `/bin/sh -c` 経由で実行                  | 直接コマンドが実行                   |
| シェルの利用可否     | 可能（環境変数展開、パイプなどが利用可）  | 不可                                 |
| 実行速度            | 若干遅い（シェルオーバーヘッドあり）       | 速い（直接実行）                     |
| 意図した動作の保証性 | シェルの解釈に依存することがある          | 高い（シンプルで予測可能）           |

---

## 使用例
### シェル形式の例
複数コマンドを実行したり、シェル機能を使用する場合に便利です：

```dockerfile
CMD node server.js && echo "Server started"
```

### Exec形式の例
シンプルかつ安全な方法でコマンドを実行する際に使用します：

```dockerfile
CMD ["node", "server.js"]
```

---

## どちらを使うべきか？
- **基本的にはExec形式を推奨**します。
  - 実行速度が速く、安全で意図した動作を保証しやすい。
- 環境変数展開やリダイレクト、パイプなど**シェルの機能が必要な場合**はシェル形式を選びましょう。

---

## まとめ
Dockerfileで`CMD`を記述する際は、用途に応じてシェル形式とExec形式を使い分けることが重要です。シンプルなコマンド実行にはExec形式を、複雑なシェル機能が必要な場合にはシェル形式を選ぶようにすると良いでしょう。

## 関連動画

https://www.youtube.com/watch?v=zbyMdaSGctg
TIL（Today I Learned）で学習の習慣化をはじめてみた話

## はじめに

最近、「TIL（Today I Learned）」という取り組みを知り、毎日学んだことをGitHubに記録していくという方法を見つけました。

学習習慣を可視化できる点に魅力を感じ、試しに自分でも始めてみることにしました。

## きっかけ

これまでの学習は、基礎的な知識を身につけるために主に書籍からのインプットが中心でした。

プログラムも書きたいと思い、Udemyのハンズオン講座を見始め、学習の定着のためにアウトプットとして何かを制作し、その学習記録を残そうと考えていました。

ちょうどその頃、GitHubの使い方も学び始めており、「GitHub 学習記録」と検索していたところ、TILという取り組みに出会いました。

もともとNotionで学習記録をメモしていましたが、せっかくならGitHubで可視化できたら面白いのではと思い、TILを始めてみることにしました。

## TILのはじめかた

以下のQiita記事を参考にはじめました。

https://qiita.com/nemui_/items/239335b4ed0c3c797add

https://qiita.com/shisshi_engineer/items/2edda14c742bfa9a8163

https://qiita.com/KoSaxophone/items/1438497e9fb5122ce784

## TILの記録ルール

TILのリポジトリの管理方法について調べたところ、いくつかのパターンがあることが分かりました。主に以下の2つです：

- 学んだ内容を技術ごとにメモしていく方式
- 毎日やったことを日付ごとに記録する方式

今回は学習習慣の可視化が目的だったため、後者の**毎日やったことを日付ごとに記録する方式**を選びました。

また、記録の粒度についても悩みましたが、内容にこだわりすぎず、まずは続けることを優先するため、**取り組んだ章名とキーワードを簡単に記録する**スタイルにしました。

ディレクトリ構成は以下のようにしています：

```
TIL/
├── 2025/
│ ├── 05/
│ │ ├── 2025-05-06.md
│ │ ├── 2025-05-07.md
│ │ └── ...
│ └── ...
```

## 感想

こうした取り組みは、最初は意気込んで始めるものの、途中でやらなくなってしまうことが多いと思います。

まずは**今月中に続けることを目標**に、無理せず楽しく続けられそうなら、今後も継続していきたいと考えています。
(メモ)ラズパイ　スマートタグ確認ツール

BLEAKを利用してスマートタグを鳴らすのがデフォルトらしい。
Perplexity AIを利用して調べて実装した。

```
import asyncio
from bleak import BleakScanner

async def main():
    scanner = BleakScanner()
    await scanner.start()
    await asyncio.sleep(5.0)  # 5秒間スキャン
    await scanner.stop()
    
    # discovered_devices_and_advertisement_dataプロパティを使用
    devices = scanner.discovered_devices_and_advertisement_data
    
    for address, (device, adv_data) in devices.items():
        print(f"デバイス: {device.address} ({device.name})")
        print(f"信号強度: {adv_data.rssi}")
        # 他のAdvertisementData属性にアクセス
        if adv_data.manufacturer_data:
            print(f"メーカーデータ: {adv_data.manufacturer_data}")
asyncio.run(main())
```
Tileで音を鳴らしてみようと試みたが
どうも認証する必要があるらしい
単純にならすことができないので断念した。
ollama 使ってみた感想

# ollama + mistral を使ってみた
# ollama + mistral の使い方

※グラボの VRAM 8GB くらい必要です、メインメモリは１６ＧＢ～

docker-compose.yaml

``` docker
version: '3.8'

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    runtime: nvidia

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "8080:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - open-webui:/app/backend/data
    depends_on:
      - ollama

volumes:
  ollama:
  open-webui:


```

docker インスタンスが起動できたら
`docker exec -it ollama bash`
としてインスタンスにログイン

```
ollama pull mistral
```

としてLLMモデルをインストールする

Windowsホストなら
http://host.docker.internal:8080
Linuxホストなら
http://localhost:8080
で WEB-UI からプロンプトが使えるようになります。

API使う時は

http://host.docker.internal:11434/api/generate
又は
http://localhost:11434/api/generate

POSTデータサンプル

```
  "model": "mistral",
  "prompt": "ロックは淑女の嗜みですか？",
  "stream": False,
  "options": {
    "temperature": 0.1,
    "top_p": 0.9,
    "num_predict": 512,
    "repeat_penalty": 1.1
  }
```


dockerでやる必要はないです、各自好きな環境でやってください。


## ブラウザから使うと挙動がおかしい
ブラウザＵＩから使うと回答方針？がキャッシュされるらしく回答の偏りが出てしまいます、ＡＰＩから使うと毎回考えた結果が返ってきます。
なんらかの実験をしたいならＡＰＩを叩きましょう


## 文章減らすと精度が高くなる
文章がビジネスメールであるか否か、という実験をやっていました
文章の読み方、結果回答のフォーマットなどを細かく指定するよりもシンプルに質問したほうが回答精度が高かったです


## 文末に回答形式を指示する
◯◯である確率を　0.0～1.0 で回答してください　と文頭で指示するよりも、文末で指示したほうがその通りにしてくれる確率が高いです

```
質問

～～文章～～

回答の指示（確率で とか、JSONで、とか）
```

## JSONとかの指示は守りきれない

次のようにプロンプトを作ります

```
ビジネスメールである確率を 0.0～1.0 で JSON で回答してください

-----添付文章開始-----
～文章～
-----添付文章終了-----

回答例：
{
  "probability": 0.0～1.0
}
```

このようにJSONで回答を指示した時に次のような応答でした

- JSON形式で正常な応答
- JSON形式（マークダウン？）で応答
- {"probability" .. と途切れたJSON
- 指示を無視して確率を数字だけで応答
- 指示を無視してコメントによる応答

APIでバッチ処理をして回答をDBに取り込むみたいな作業に向かないですね、対策として

```
「ビジネスメール」「ビジネスメール以外」で回答してください
解説や要約は不要です
```

このように指示を出すと
- ビジネスメール
- 「ビジネスメール」
- 「ビジネスメール」です
- 「ビジネスメール」です、なぜなら～～～
という回答パターンになり最悪でも「ビジネスメール」という単語は入れてくれるのでスクリプトで処理できますので、バッチ処理等に組み込めるようになります。



## 抽出処理
メールの人材や商材の紹介部分だけを抜き出すタスクはそこそこ上手くいきます。
プロンプトは次のように書きます

```
データ列挙部分の原文を抜き出してください

-----添付文章開始-----
～メール本文～
-----添付文章終了-----

```

このプロンプトでメール内にある価格、人材、商材、についてのデータ列挙部分だけを抽出できました。
挨拶文章に含まれる送信者の所属テンプレートまで含める時もあったりしますが、8割合格といって良いかなと思います。

抽出処理は結構いける感じです


## そこそこ使えると思う
商用利用もOKの mistral 7b のモデルですが、chatGPT4 と比べたら相当に劣る物ではあるのですが、使い方次第ではバッチ処理なんかに組み込めるかなという感じです。

めちゃくちゃ分かりやすい分類処理とか、なんらかの抽出処理であればなんとかという感じでした。


以上です
【HTML/React】ユーザーがアップロードした画像をリサイズする

# 背景
ユーザーがアップロードした画像をそのままレンダリングすると大きすぎるファイルだとこんな感じになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/d1626957-9c50-4e7e-bf86-eb908a6dcc7b.png)
↑デカすぎんだろ.

## コード
```javascript
    function resizeImg(file, maxWidth, maxHeight) {
        return new Promise((resolve) => {
            const img = new Image();
            const fileurl = URL.createObjectURL(file);
            img.src = fileurl;
            console.log(fileurl)

            img.onload = () => {
             // 比率を保ってリサイズサイズを決定
            const originalWidth = img.width;
            const originalHeight = img.height;
            const ratio = Math.min(maxWidth / originalWidth, maxHeight / originalHeight);
            const newWidth = Math.round(originalWidth * ratio);
            const newHeight = Math.round(originalHeight * ratio);

            const canvas = document.createElement("canvas");
            const context = canvas.getContext("2d");
            if (!context) {
                URL.revokeObjectURL(fileurl);
                resolve(null);
            }
            canvas.width = newWidth;
            canvas.height = newHeight;
            context.drawImage(img, 0, 0, newWidth, newHeight);
            canvas.toBlob((blob) => {
                URL.revokeObjectURL(fileurl);
                resolve(blob); 
            }, file.type);
            };
            img.onerror = () => {
            URL.revokeObjectURL(fileurl);
            resolve(null); 
            };
        });
        }
```

### imgの部分
```javascript
const img = new Image();　//<img>タグを作成
img.src // 画像の読み込み用URL指定
img.onload // 画像の読み込みが成功したときに関数を実行
img.onerror　// 読み込み時にエラーが発生したときに関数を実行
```

### canvasの部分

```javascript
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
```

:::note
canvasとは？
画像を描画する仮想のキャンバス要素で画面には描画されない
:::

getContext("2d")で「2d描画のコンテキストを取得」


```javascript
canvas.width = width;
canvas.height = height;
context.drawImage(img, 0, 0, width, height);
```
引数に受け取ったピクセルでキャンバスの縦横を指定します。

:::note
drawImage(img, 0, 0, width, height)はキャンパスへ、画像を張り付ける関数
:::

```javascript
canvas.toBlob((blob) => {
  URL.revokeObjectURL(objectUrl); // メモリ解放
  resolve(blob); //Promiseにblobの結果を返す
}, file.type);
```
今回はPromiseの成功結果としてblobを返している。

canvas.toBlobの処理の流れは下記。

第二引数で指定されたfile.typeでキャンバスの描画データをblobへと変換
↓
変換データが第一引数（コールバック関数）に渡されて実行される

:::note
URL.revokeObjectURL(objectUrl);の意味

メモリ上にアクセス用の画像データが一時的に展開されているが、これはブラウザを閉じるまで保持されてしまう。
そのため、明示的にコード側で閉じる必要性がある。

URL.revokeObjectURL関数でメモリデータアクセス用のurlを指定することで削除可能
:::


## 受け取ったblobをファイルオブジェクトにする

```javascript       
const fileblob = await resizeImg(FileData, 400,600);
var resizedFile = new File([fileblob], FileData.name, { type: FileData.type });
```

このresizedFileをimgタグのsrcに渡すと良い。


## 実際にテスト

(html部分などについては割愛)

```javascript
const fileblob = await resizeImg(FileData, 400,600);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/129d8778-8883-4fb7-83a0-379da9cf7125.png)
↑サイズがコンパクトになった。
Lambdaがトリガーされた際に渡されるデータの中身を見てみた

## 概要
CloudwatchLogsによってLambdaがトリガーされた際に関数には、
どんなもデータが渡されているのかみていきます。

## 構成
以下のようなリソース群を作成していきます。
Lambdaのトリガーの際に連携されたデータを送信先のCloudWatchLogsで確認していきます。

![20250322.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686037/25dd459d-5b60-40ff-8c21-58fd31db2624.png)


## 構築
練習がてらCludFormationで構築していきます。
多いので以下にまとめています。

https://github.com/Snooze2929/get_awslogs

上記をS3に配置してCloudFormation実行とLambda関数にコードを参照させています。

## ログのプッシュ
サブスクリプションフィルタには「Error」の単語が含まっていた際に、Lambda関数を実行するようにしています。それを含めてログをロググループにプッシュしていきます。

```
aws logs put-log-events --log-group-name sender-log-group --log-stream-name sender-log-stream --log-events timestamp=$(date +%s%3N),message="Error test log"
```

## 結果

以下のような形式で送られてくるようです。
```
{
    "messageType": "DATA_MESSAGE",
    "owner": "AWSアカウントID",
    "logGroup": "送信元ロググループ名",
    "logStream": "送信元ロググループのログストリーム名",
    "subscriptionFilters": [
        "送信元ロググループのサブスクリプションフィルター名"
    ],
    "logEvents": [
        {
            "id": "ログイベントID(実際はランダムな数列が入っている)",
            "timestamp": 1746864558130,
            "message": "Error test log"
        }
    ]
}
```

今回の検証は以上になります。
ログ監視の設計構築の助けになれば幸いです。

お疲れ様でした。
Cloudflare Tunnel + WARP ClientでAdblockする方法（上級編）

# 背景

以前紹介した方法でほぼAdblockできるのですが、巻き添えで非表示になるWebサイトがあったりして、もっといい方法を見つけたので、その紹介です。

https://qiita.com/t2murata/items/eb9399c6437f2789e083

Listsを作る→DNS policyを設定の順で設定していきます。以下詳細な手順です。

# 手順

## 1. リストを作る

以下の手順を参考にCloudflare Zero Trustの中で「Lists」を作ります。

https://developers.cloudflare.com/cloudflare-one/policies/gateway/lists/

### ダウンロード

広告ブロックのドメインリストは、280blockerのドメインリストを用います。

https://280blocker.net/download/

例えばこちらをダウンロードします。（年月でファイルが更新されていきます。）

https://280blocker.net/files/280blocker_domain_202505.txt

### データ整形

このままだと取り込めないので、所望の形式に変換してきます。
VSCodeでtxtファイルを開きます。Ctrl-fで置換メニューを開き、正規表現で形式を変換していきます。

1. 空行を消します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/ffc9de0b-2689-4b33-88bc-0b6ae963c352.png)

2. コメント行を消します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/d92f6b11-8c3c-4d2d-9ff4-22a37c1195c2.png)

3. IPアドレスは後ほどエラーが出るので消します（ここだけ設定漏れちゃいますが・・・）
`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\n`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/123f29ce-a229-4631-8faf-5825203b8805.png)

5. `culass.com`、`mintybug.com`などの行で、ドメインの最後に空白スペースが入っていてエラーが起きたので、「空白スペース」を削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/2e93fe02-84a3-4286-96da-490967ffc5bc.png)
（参考：エラー）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/308f3592-a8ba-4815-a188-98f8da5ccbe9.png)

4. CSVに手動で拡張子を変更します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/f0e617c9-6614-4261-bfb2-88caff3bbcc7.png)

5. 1000件以上だとCloudflareでエラーが出るため、999行までのファイルに分割します（2800行程度あったので3ファイル）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/6087b91c-981a-4d63-853e-577c14092ece.png)

6. ヘッダー「value」を手動で追加します（各ファイル）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/98f41124-109c-4709-8cf9-d06eb58baab6.png)

## 2. リストをアップロード

Cloudflare Zero Trustのダッシュボードの中の「My team」→「Lists」に入り、「Upload CSV」を押します。

名前は適当に設定して、「Lists type」は「Hostnames」にして、アップロードします（3ファイル）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/e0d163f5-4d60-4065-99a7-7414e68dae28.png)

3つアップロードしたら以下のような画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/8d15087a-f77e-4bae-bb21-ef31563e69ea.png)


## 3. DNS policyを設定

ダッシュボードの「Gateway」→「Firewall policies」から「DNS policies」の中の「Add a policy」を押します。

名前は適当に設定して、「Build an expression」の中で、Selector＝Domain、Operator＝in listを選び、先ほど作成したリストを指定します。
orで3種指定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/680486ab-c9a7-4e53-b0b0-dd997872266e.png)

「Select an action」は「Block」にしておきます。最後に「Create policy」を押して作成完了です。

これで、Cloudflare WARP経由の通信がAdblockされて、快適になります！
Dependabotを用いてリポジトリの依存関係をセキュアに保つ方法

### まずDependabotとは
一言で言うと、GitHubのリポジトリ内で使用しているライブラリに関して現在、または今後報告されるバグや脆弱性があった場合に、プルリクエスト形式等で教えてくれるボットです。

具体的には、監視用の.github/dependabot.ymlファイルを用意し、その中に、どれくらいの間隔で（依存関係による）脆弱性をチェクするのか、どのライブラリを監視するのか等を記載しておくことで、定期的にボットがそのライブラリとCVE（Common Vulnerabilities and Exposures、日本語では共通脆弱性識別子と呼ばれるOSSごとの脆弱性を記録した識別）とを見比べて、問題がないかをチェックします。

| 項目     | 内容                                                |
| ------ | ------------------------------------------------- |
| 提供元    | GitHub（Microsoft）                                 |
| 主な目的   | 依存パッケージの更新通知・自動Pull Request作成                     |
| サポート言語 | npm, pip, Maven, RubyGems, Cargo, Go modules など多数 |
| 通知の種類  | 新バージョンのリリース、セキュリティアドバイザリー（GitHub Advisory DB）と連携  |


::: note info
CVEについて
CVE自体は脆弱性の識別子（名前）です。
脆弱性のタイプや深刻度によって分けられています。CVEをまとめたものに、下記があります。

1️⃣ NVD（National Vulnerability Database）
　 アメリカ政府（NIST）が運営する公式CVE集約DB
2️⃣MITRE CVE List（cve.org）
　 CVEのID発行元であるMITREの公式リスト
3️⃣GitHub Advisory Database
　 GitHub上のOSSパッケージ向けのCVE＋詳細アドバイザリを収録
4️⃣Snyk Vulnerability DB
　 Snyk社が運営する商用レベルのCVE＋独自脆弱性DB

:::


### 設定ファイル例
```yaml:yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "pip"
    directory: "/"  # requirements.txt のある場所
    schedule:
      interval: "weekly"

```

### Dependabot Alertで脆弱性を通知

これは、GitHub リポジトリで使っている依存パッケージにCVEなどの脆弱性が見つかったときに、自動で通知してくれる機能です。

GitHub の「Security」タブ内で、どのパッケージのどのバージョンに、どんな脆弱性があるかを一覧表示できます。

#### どんなときに表示されるの？
あなたのプロジェクトで使っているパッケージにGitHub Advisory Database（+CVE）に登録された脆弱性が該当するときにGitHub が自動で通知を作成

#### どこで見れる？
対象の GitHub リポジトリを開く上部メニューの「Security」をクリック.
左側メニューの「Dependabot」→ 「Dependabot alerts」を開く

#### 表示される情報（Alert 内容）
項目	説明
パッケージ名	例：lodash、urllib3、log4j など
影響バージョン	例：< 4.17.20（このバージョン未満は脆弱）
CVE番号／Advisory	例：CVE-2021-44228 や GitHub Advisory のリンク
深刻度	CVSSスコアや「Low」「Medium」「High」「Critical」などの区分
詳細リンク	GitHub Advisory DBへのリンク
対応状況	修正バージョンへの自動PRが出ているか／未対応か


#### 修正方法は？
脆弱性が発見されると、GitHubが自動で次のようなことをしてくれます.

自動Pull Requestを作成（Dependabot PR）
→ 修正バージョンにアップグレードした package.json / requirements.txt などを含む

CIが通ればそのままマージすれば OK


### おすすめの記事
#### Docsの解説
https://qiita.com/WisteriaWave/items/b37be9c3ebf1de37da0f
#### Docs
https://docs.github.com/ja/code-security/dependabot/working-with-dependabot