OmniAICreator/Qiita-1.07M huggingface dataset:
EBAZ4205 FPGA Xilinx編 第2版　演習2-2


EBAZ4205を使ってZYNQとFPGAの勉強をしています。
備忘録を記載します

https://github.com/ShigeoYakuno/EBAZ4205


## 演習2-2　LED点滅回路にプッシュスイッチを追加

全ての機能がEBAZに無いので、改造や機能の縮小が必要です。

■LED
RJ45の横に赤と緑のLEDがついています。教本にはさらに青色LEDがありますがあきらめます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/c91db743-71e0-4a56-aa4c-92d5ac5940da.png)
GRN_LEDがW13、RED_LEDがW14に接続されています。


■スイッチ
一見S2,S3といった使えそうなSWが実装されていますがPS部からしか認識できないらしいです。

下記のサイトでも紹介されていますが、FANのPWM用のフォトカプラが不要なのでスイッチをつけます。
https://qiita.com/kan573/items/c4dac8908e1a86d8fce6

2つのフォトカプラを外して、V13とV15に2つのスイッチを接続します。
V13がリセット、V15をスピードチェンジ　のスイッチとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/d9b7b106-4433-4c4f-8f33-15f09ca4e52c.png)

### 実際の改造基板

- 表面
![IMG_1937.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/b610ec96-7f93-432d-91f8-b052a5e670e5.jpeg)

- 裏面
![IMG_1938.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/857d745c-b534-4d4d-bc43-9db886e19a42.jpeg)







## 制約ファイルの意味

制約ファイルの意味を少し解析してみます。
~~~
# Clock signal
set_property PACKAGE_PIN N18     [get_ports { CLK }]
set_property IOSTANDARD LVCMOS33 [get_ports { CLK }]
create_clock -add -name sys_clk_pin -period 20.000 \
        -waveform {0 10} [get_ports { CLK }]
~~~

この行は、CLK ポートに入力されるクロック信号の特性を表しています。
-period 20.000 は、クロックの周期が20.000ナノ秒（ns）という意味です。
これはクロックソースのX5の発信周波数が50MHz（1 / 20ns）だからです。

-waveform {0 10} は、クロックのデューティサイクル（HighレベルとLowレベルの時間比率）を設定しています。
{0 10} は、Highレベルが0nsから10ns、Lowレベルが10nsから20nsであることを意味し、50%のデューティになります。

~~~
set_property IOSTANDARD LVCMOS33 [get_ports { CLK }]
~~~

このような記述はポートの入出力規格（IOSTANDARD）を意味します。
LVCMOS33 は、3.3VのLVCMOS（Low-Voltage CMOS）規格で使うことを宣言しています。

~~~
# RGB LED
set_property -dict { PACKAGE_PIN W14   IOSTANDARD LVCMOS33 } \
        [get_ports { LED_RGB[1] }]; # Red
set_property -dict { PACKAGE_PIN W13   IOSTANDARD LVCMOS33 } \
        [get_ports { LED_RGB[0] }]; # Green
~~~

LEDは2つしかないので、制約ファイルも2bitに変更します。本当は名前LED_RGのほうがよかった

## HDLファイル変更点

~~~
module blinkspeed (
    input               CLK,
    input               RST,
    input       [0:0]   BTN,
    output  reg [1:0]   LED_RGB
);
~~~~
LEDが2bitしかないので、そこだけ変更しています。

~~~
/* LED Decoder */
always @* begin
    case ( cnt3 )
        3'd0:   LED_RGB = ~2'b01;//G
        3'd1:   LED_RGB = ~2'b10;//R
        3'd2:   LED_RGB = ~2'b01;//G
        3'd3:   LED_RGB = ~2'b10;//R
        3'd4:   LED_RGB = ~2'b11;//GR
        3'd5:   LED_RGB = ~2'b00;//off
        default:LED_RGB = ~2'b00;
    endcase
end
~~~

あとLEDは0の時にONするので、ビット反転(~)させています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/e9e39766-6a84-4254-b1ec-197887efd47b.png)

今日はここまで
AIの未来を垣間見る！「Auto-GPT徹底解説」記事のススメ


AI技術が急速に発展する今、注目すべきキーワードの一つが「自律型エージェント」です。かつては人の手によって一つひとつ指示を与える必要があったタスクも、今やAI自身が考え、調べ、判断し、行動する時代に入りつつあります。

そんな中で登場したのが「Auto-GPT」。GPT-4などの大規模言語モデル（LLM）をベースにしながらも、単なるチャットボットにとどまらず、目標を与えるだけで自律的に処理を進めてくれる革新的な仕組みです。

今回ご紹介するのは、Omomuki Tech Blogによる記事  
📘 [Auto-GPT徹底解説：Pythonライブラリとしての使い方と未来](https://omomuki-tech.com/archives/1182)  
です。この記事では、Auto-GPTの基礎から活用法、そして未来の展望に至るまでを網羅的に、かつ分かりやすく解説しています。

## なぜこの記事が読み応え抜群なのか？

### ✅ 初心者にもわかりやすい

AIやGPTに関する話題は難解になりがちですが、この記事は専門用語に頼らず丁寧に背景や概念を説明してくれます。初めてAuto-GPTに触れる方でも読み進められる工夫が満載です。

### ✅ 実践につながる視点が豊富

理論的な背景だけでなく、「実際にどう使えばいいのか？」という視点での解説が充実しています。特にPythonライブラリとしての活用方法の導入部分は、開発者にとってすぐに試してみたくなる内容です。

### ✅ 今後の可能性にも触れている

Auto-GPTはまだ発展途上の技術であり、記事ではその課題や懸念点についてもきちんと触れられています。過剰な楽観視を避けつつ、未来への期待もしっかりと語られている点に誠実さを感じます。

## こんな人におすすめ！

- 最新のAIトレンドをキャッチアップしたいエンジニア
- GPTを用いた開発に興味のある人
- 自動化・効率化に可能性を感じているプロダクト開発者
- Pythonで新しいことに挑戦してみたい技術者

Auto-GPTという名前を聞いたことはあっても、実際にどう動き、どう使うかまで理解している人は少ないかもしれません。本記事は、そんな知識のギャップを自然に埋めてくれる素晴らしいガイドです。

## まとめ：次世代AIとの付き合い方を考えるきっかけに

AIに目標を与えるだけで、あとは勝手に調査し、行動してくれる…。そんな未来を「夢物語」ではなく「今この瞬間の技術」として紹介してくれるこの記事は、多くの人にとって新たな気づきを与えてくれるでしょう。

Auto-GPTの可能性と、その実際の使い方を深く知りたい方は、ぜひ以下のリンクから記事をチェックしてみてください。

👉 [Auto-GPT徹底解説：Pythonライブラリとしての使い方と未来](https://omomuki-tech.com/archives/1182)
【Kubernetes】Podをデバッグするスクリプト

[【Kubernetes】ノードをデバッグするスクリプト](https://qiita.com/ktamido/items/04a3676c5348256ebad4) に続いてPodをデバッグするスクリプトです。
挙動としては指定したNamespaceのPodにエフェメラルコンテナを立ち上げて、シェルにログインします。

※ fzfとjqとkubectlが必要です。

```pod-debugger.sh
#!/bin/bash
set -euo pipefail

function usage {
cat <<EOF >&2
指定したPodをDebugするコンテナを立ち上げるコマンド

Usage:
  $0 [Options]

Options:
  --no-copy
    Podをコピーしないで対象のポッドに直接コンテナを起動。
    終了後もPodにコンテナの残骸が残るので注意
  -h | --help
    ヘルプ
EOF
exit 1
}

function error {
  echo "[error] $1" >&2
  exit 1
}

function info {
  echo "[info] $1"
}

COPY=1
args=()
while [ "$#" != 0 ]; do
  case $1 in
    -h | --help ) usage ;;
    --no-copy   ) COPY=0 ;;
    -* | --*    ) error "$1 : 不正なオプションです" ;;
    *           ) args+=("$1") ;;
  esac
  shift
done
[ "${#args[@]}" != 0 ] && usage

# Namespaceの選択
NAMESPACE="$(kubectl get ns -o wide | sed '1d' | fzf --height 25% --header 'Select a namespace')"
NAMESPACE_NAME="$(echo $NAMESPACE | awk '{print $1}')"

# Podの選択
POD="$(kubectl get pod -n ${NAMESPACE_NAME} -o wide | sed '1d' | fzf --height 25% --header 'Select a pod')"
POD_NAME="$(echo $POD | awk '{print $1}')"

# 起動するイメージの選択
IMAGE=$(
cat <<EOF | fzf --height 25% --header "Select a image"
nicolaka/netshoot
public.ecr.aws/aws-cli/aws-cli
ubuntu:24.04
EOF
)

OPTIONS="-ti --image=$IMAGE"
if [[ "$COPY" == "1" ]]; then
  UNIX_TIME=$(date +%s)
  OPTIONS="$OPTIONS --copy-to="pod-debugger-$POD_NAME-$UNIX_TIME" --share-processes"
fi

echo kubectl -n $NAMESPACE_NAME debug $POD_NAME $OPTIONS -- /bin/bash
kubectl -n $NAMESPACE_NAME debug $POD_NAME $OPTIONS -- /bin/bash

# ノードデバッガーのPodを削除
for pod in $(kubectl -n $NAMESPACE_NAME get po -o json | jq -r ".items[].metadata.name" | grep -e "^pod-debugger"); do
  kubectl -n $NAMESPACE_NAME delete po $pod
done
```


# 使ってみる

```bash
pod-debugger.sh --no-copy
```

デバッグ対象のPodが所属するNamespaceを選択
![スクリーンショット 2025-04-02 22.33.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/d9a66a16-b325-4f05-bb9e-12633f06bf36.png)

デバッグ対象のPodを選択
![スクリーンショット 2025-04-02 22.33.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/a4252078-8588-4e68-b999-26dc37253e4e.png)

起動するコンテナイメージを選択
![スクリーンショット 2025-04-02 22.34.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/fa3b53e0-20d0-4ea3-a01b-755311246006.png)

指定したNamespaceのPodにコンテナが立ち上がり、シェルにログインできます。
![スクリーンショット 2025-04-02 22.34.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/04509f86-24cf-4644-a60d-45110169ab0a.png)

ログアウト
```bash
exit
# Session ended, the ephemeral container will not be restarted but may be reattached using 'kubectl attach eks-pod-identity-agent-gq6l5 -c debugger-2d6f4 -i -t' if it is still running
```

`--no-copy` オプションを使うと、ログアウトしてもエフェメラルコンテナがpod内に残ってしまうのが玉に瑕
まあ、deploymentなりdaemonsetなりを再起動すれば消えるのですが、なんだかな、、、

![スクリーンショット 2025-04-02 22.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/d9ac081e-4694-4a84-a2e5-db96a1e87a6d.png)
Google Colabのシークレット機能を使ったSIGNATE CLIの認証情報設定

Google ColabでSIGNATEのコンペに取り組みたい

SIGNATE CLIを使ってデータセットをダウンロードしたいが、

* Google Driveにsignate.jsonを保存して読み取らせる
* ファイル選択ダイアログでsignate.jsonを選択してアップロードする

のはクリック数が多くて面倒くさい

Google Colabのシークレット機能を利用してAPIの認証情報を取り込んでAPIを利用することにより少ないクリック数でSIGNATE CLIを利用できるようにする。

# 事前準備

シークレットにAPIの認証情報を`SIGNATE_API_TOKEN`という名前で登録する

```json
{"api-token":"ここの部分の文字列を`SIGNATE_API_TOKEN`という名前のシークレットの値に登録する"}
```

# コード

## 1. SIGNATEのインストール

```text
!pip install signate
```

## 2. 認証情報の設定

```python
import os
import json
from google.colab import userdata
signate_api_token = userdata.get('SIGNATE_API_TOKEN')

signate_json_path = "/root/.signate/signate.json"
os.makedirs(os.path.dirname(signate_json_path), exist_ok=True)

signate_key = { "api-token" : signate_api_token }

with open(signate_json_path, "w") as f:
    f.write(json.dumps(signate_key))
```

# 作成したノートブック

https://github.com/steelpipe75/Table_AI_ML_Codespaces_template/blob/main/for_signate/signate_colab.ipynb

# 参考にしたノートブック

Google Colaboratoryを利用してSIGNATEコンペ参加する際のチュートリアルノートブック

https://github.com/signatelab/colaboratory

https://colab.research.google.com/github/signatelab/colaboratory/blob/master/tutorials/SIGNATE_Tutorial_for_Colaboratory.ipynb

# 参考にしたQiita記事

https://qiita.com/insilicomab/items/d757339d97b44feaff01
統計検定準1級の概要

[統計検定準1級の公式サイト](https://www.toukei-kentei.jp/grade/grade_pre-1)参考

## 実施趣旨  
統計検定2級までの基礎知識をもとに、実社会の様々な問題に適切な統計学の手法を応用できる能力を問う。

## 試験内容  
- **方式**: CBT（コンピュータ試験）  
- **試験時間**: 90分  
- **合格基準**: 100点満点中60点以上  

## 試験範囲  
詳細は [試験範囲のPDF](https://46715910.fs1.hubspotusercontent-na1.net/hubfs/46715910/files/grade_range/grade1semi_hani_190628_2.pdf) を参照。

## 電卓の持ち込み  
四則演算（＋－×÷）、百分率（％）、平方根（√）の計算ができる普通電卓（一般電卓）または事務用電卓のみ使用可。  

## 受験料  
- **一般**: 8,000円  
- **学生**: 6,000円（[学割について](https://www.odyssey-com.co.jp/certiport/qa.html)）
自作の MCP Server を実装する

[MCP]::https://www.anthropic.com/news/model-context-protocol
[Model Context Protocol]:https://www.anthropic.com/news/model-context-protocol
[Claude for Desktop]:https://claude.ai/download


# この記事は何？

MCP Server を実装する際に都度調べるのも面倒なので、個人用途でテンプレ化しました。

:::note warn
多分 Mac, Linux でしか動きません 🙏
（win では [package.json の scripts, bin](https://github.com/megmogmog1965/example-mcp-server/blob/main/package.json#L10) あたりが動かなそう）
:::

# そもそも MCP とは？

以前に ↓ の記事を書いたので、よければご覧下さい。

https://qiita.com/megmogmog1965/items/79ec6a47d9c223e8cffc

# 実装

例のごとく、公式のチュートリアルがあります。全然難しくないです。

https://modelcontextprotocol.io/quickstart/server

そこから全てを削ぎ落として最小化した TypeScript ベースのテンプレリポジトリを作りました。

https://github.com/megmogmog1965/example-mcp-server

実際に MCP Server 本体の TypeScript コードは次の通りです。

このコードでは `get_current_time` という UTC 現在時刻を返す tools を提供する MCP Server を実装しています。

```typescript:src/index.ts
#!/usr/bin/env node

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// Create server instance
const server = new McpServer({
  name: "time",
  version: "1.0.0",
  capabilities: {
    resources: {},
    tools: {},
  },
});

// Register "get_current_time" tools
server.tool(
  "get_current_time",  // tools 名
  "Get the current time",  // tools の説明文.
  {},  // tools に引数がある場合は、ここで zod 定義をする.
  async () => {  // tools 実装.
    const currentTime = new Date().toISOString();

    return {
      content: [
        {
          type: "text",
          text: currentTime,
        },
      ],
    };
  },
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Time MCP Server running on stdio");
}

main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});
```

# 使い方

[Claude for Desktop] を例に、本自作 MCP Server を動かしてみます。

以下の [Claude for Desktop] の設定ファイルを開きます。

```
~/Library/Application Support/Claude/claude_desktop_config.json
```

次の設定を追記しましょう。

```json:~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "time": {
      "command": "/path/to/node (※変えてね！)",
      "args": [
        "/path/to/example-mcp-server/build/index.js (※変えてね！)"
      ]
    }
  }
}
```

:::note
本格稼働する場合は npx ([npm](https://www.npmjs.com/)) で公開するところまでした方がよいですね。
ここではあくまで開発用途でローカル利用するところまでに留めます。
:::

[Claude for Desktop] を起動すると、MCP Server が無事に起動した場合は以下のハンマーアイコンに tools 数が表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60131/612e503b-d813-472a-b0c4-312f2a037f47.png)

実際に現在時刻を問い合わせてみると、きちんと回答してくれます。UTCなのが残念ですが...😅

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60131/0fc9c858-0411-470f-8076-0ea4696057c9.png)
KUROKO Connectの接続履歴をさわってみた

#### KUROKO Connectは現場への接続履歴が記録をしています。
#### 「いつから」「いつまで」「誰が」「どこに」「どの様に」接続したかを履歴から確認可能です。

早速さわってみます。

# 1. KUROKO  Connectにログインする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/55ce791d-25f3-4a9b-b1c2-a94a2a233c4d.png)

# 2. 接続履歴をクリックする

左メニュー＞「ステータス」＞「接続履歴」をクリックします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/9f439f2b-2cfd-4da8-bc95-2778a2711340.png)

# 3. 接続履歴を検索する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/43dbfb98-44b9-48d4-8cc9-8528db3dbfd2.png)


接続履歴は期間を指定することで表示できます。
検索履歴は
・KUROKO Appsが属するグループでの絞り込み
・該当期間（開始日〜終了日）
・該当KUROKO Apps名（部分一致検索）
・KUROKO Appsに紐づくタグ情報
・KUROKO Appsに設定されているアイテム情報
から絞り込むことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/73d68a19-c738-4a74-bef0-d8c94cf1c7c1.png)


上部にある「ダウンロード」をクリックすると、検索結果すべての記録をCSV形式でダウンロードできます。

接続履歴はログインアカウントで権限があるグループ内の接続履歴が表示されます。
システム管理者アカウントはテナント内のすべての接続履歴が確認できます。

試験用グループと保守用グループしか権限のないアカウントの場合は、この様に選択できるグループが制限されています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/1cc64694-94b3-4b63-b519-a43208f6fcc7.png)


接続履歴をさわってみました。
接続履歴管理や証跡の提出が必要な場合などにご活用ください。
オプション価格付けにおけるモンテカルロ法の実用性

# Abstract
オプション価格付けにおけるモンテカルロ法の実用性について述べる
# オプション価格付けと数値積分
オプションの価格は、原証券の条件付き期待値をディスカウントファクターで割り引いたものとして求められる。すなわち、期待値=積分の計算がオプションプライシングの要である.
ブラックショールズのような単純なモデルとヨーロピアン・オプションのような単純なオプションの組み合わせなら解析解が得られるが、多くの実務的な場面では、単純な解析解が得られず、数値計算に頼らざるを得ない。
# モンテカルロ法
数値積分を考える際には、まずは台形則のような素朴な求積法を用いることを考えるが、素朴な求積法では、次元が増加すると、サンプルサイズに対する収束性が悪くなる。(次元の呪い)
誤差のオーダーが次元に依存しない手法のひとつに、モンテカルロ法がある。モンテカルロ法は、乱数を用いた数値積分法の総称である。モンテカルロ法の一般的なスキームでは、誤差のオーダーは常に $O(\frac{1}{\sqrt{n}})$ である. これは、近似の精度を10倍よくしたければ、計算量を100倍増やす必要があることを意味する。
この収束速度が十分に実用に足る程度速いといえるか、遅いかは、実務の内容によるし、利用可能な計算機のマシンパワーにもよる。しかし、一般的に、HFT(高頻度取引)の実務に使うには遅すぎると言われている。
# モンテカルロ法の亜種
モンテカルロ法を改良した、より効率的なサンプリング手法を紹介する.
## 準モンテカルロ法
準乱数を用いたモンテカルロ法を準モンテカルロ法という. 準モンテカルロ法では誤差のオーダーは$O(\frac{1}{n})$である.
## マルコフ連鎖モンテカルロ法(MCMC)
多重積分を計算するには、通常、マルコフ連鎖モンテカルロ法が用いられる。多次元の複雑な分布の場合、モンテカルロ法よりMCMCの方が効率的な場合が多い。
# 輔弼
モンテカルロ法を用いた数値積分の計算速度の問題は以下に分解できる
1.  一様乱数の生成の速度
2.  任意の分布への変換の速度
3. 数値積分の収束速度

上述の計算量の議論は3.に相当する.
他にも、1,2における計算速度を速めることも、数値積分の高速化に寄与する.

# 輔弼2
計算時間 \( T \) を短縮するには、**計算コスト**と**収束の速さ**の関係を理解し、適切に最適化することが重要です。以下のように要素分解すると、どの部分を改善すれば時間が短縮できるのかが明確になります。

---

## **1. 計算時間の要素分解**
計算時間 \( T \) は、次の3つの要素に分解できます。

\[
T = (\text{1回の計算コスト}) \times (\text{総計算回数})
\]

さらに、総計算回数は**収束までに必要なステップ数**や**モンテカルロ試行回数**に依存するので、

\[
T = (\text{1回の計算コスト}) \times (\text{収束に必要なステップ数}) \times (\text{試行回数})
\]

### **各要素の説明**
1. **1回の計算コスト \( C \)**  
   - 1ステップまたは1試行あたりの計算時間
   - 数値解法の種類（オイラー・丸山法 vs. ミルシュタイン法）
   - ループの計算量、行列演算、並列化の有無
   - GPUや並列計算の活用で削減可能

2. **収束に必要なステップ数 \( N \)**  
   - 時間ステップ \( h \) の選び方  
   - 数値解法の精度（ミルシュタイン法はオイラー・丸山法より少ないステップで済む）  
   - マルチレベルモンテカルロ法（MLMC）の利用で削減可能  

3. **試行回数 \( M \)**  
   - モンテカルロ法のサンプル数  
   - 準モンテカルロ法や分散縮小技術（制御変数法・対称サンプリング）で削減可能

---

## **2. 計算時間を短縮する方法**
上の分解式をもとに、どの要素を削減すれば時間短縮につながるかを考えます。

### **(1) 1回の計算コスト \( C \) を減らす**
- **シンプルな数値解法を使う**（ただし、精度とトレードオフ）
- **行列演算の最適化**（行列を疎行列として扱うなど）
- **GPUや並列計算を活用する**（NVIDIA CUDA, OpenMP, MPI）

### **(2) 収束に必要なステップ数 \( N \) を減らす**
- **高次の数値解法を使う**（ミルシュタイン法、ルンゲ・クッタ型手法）
- **適応時間ステップを導入**（変化が激しいところで小さいステップ、なだらかなところで大きなステップ）
- **マルチスケール・マルチレベル手法を使う**（マルチレベルモンテカルロ法）

### **(3) 試行回数 \( M \) を減らす**
- **準モンテカルロ法（Sobol列など）を使う**（乱数の偏りを減らして少ない試行で高精度にする）
- **分散縮小技術を使う**（対称サンプリング、制御変数法、ストラティファイドサンプリング）
- **マルチレベルモンテカルロ（MLMC）を使う**（粗いシミュレーションと細かいシミュレーションを組み合わせる）

---

## **3. 具体的な改善戦略**
| 方法 | 影響する要素 | 期待される効果 |
|------|------------|--------------|
| 並列計算（GPU, MPI, OpenMP） | \( C \) | 1回の計算を高速化 |
| 高次スキーム（ミルシュタイン法） | \( N \) | 収束を早めて必要なステップ数を削減 |
| マルチレベルモンテカルロ（MLMC） | \( N, M \) | ステップ数と試行回数を同時に削減 |
| 準モンテカルロ法 | \( M \) | 必要な試行回数を減らす |
| 分散縮小技術 | \( M \) | 試行回数を減らしながら精度を維持 |
| 適応時間ステップ | \( N \) | 必要な計算回数を減らす |

---

## **4. まとめ**
**計算時間 \( T \) を短縮するには、次の3つをバランスよく改善することが重要。**
- **計算コスト \( C \) を減らす**（並列化・効率的な計算手法を使う）
- **収束に必要なステップ数 \( N \) を減らす**（高精度な数値解法を選ぶ、適応時間ステップを導入）
- **試行回数 \( M \) を減らす**（準モンテカルロ法や分散縮小技術を活用）

計算コストが小さい手法を選んでも、収束が遅ければ総計算時間が増えてしまうし、逆に高精度な手法を選んでも1回の計算コストが大きくなりすぎると計算時間がかかる。**このトレードオフを意識しながら最適な手法を選ぶことが重要**です。
LB越しのHTTPSでCookieが消える！？〜古いPHPシステムがハマった罠〜

## 概要

ロードバランサー（以下LB）でHTTPS終端 → HTTP転送の構成において、**古いPHPシステムでCookieが保存されない**という現象が発生。

Laravelでは問題なし。だが、生PHPで書かれた管理画面は**ログイン成功しても、すぐクッキーが消えてログインループ**に。

## 構成概要

- LB（HTTPS）→ Node01（HTTP）
- クライアントの接続先は `https://admin.exmple.com/`
- Node側は80番で待ち受け
- Laravelは `TrustProxies` にて `X-Forwarded-Proto` を信用
- 生PHPの管理画面は10年以上前に作成された古いコード

---

## 発生した問題

```text
✅ ログイン処理成功
→ `setcookie()` 実行
→ 開発者ツールで一瞬クッキーが確認できる
→ すぐにクッキーが消える（1秒以内）
→ クッキーが無いため再ログインループに突入
```

Nodeのログの様子：

```
[02/Apr/2025:16:26:16 +0900] "GET / HTTP/1.0" 200 ...
```

→ クッキーが残らず、ログイン直後にトップページへ302リダイレクト → 再びログイン画面に戻される

⸻

原因

✅ setcookie() で ドメイン指定していなかった

```
// NG：省略するとクッキーが "admin.example.com" 扱いになりがち
setcookie("ADMINUSER", $user_id, 0, "/");
```

この状態で LB + HTTPS + HTTP転送 + 302リダイレクト が挟まることで…
	•	ブラウザがクッキーのスコープを「不明確なドメイン」扱いにしてしまう
	•	secure=false でも、対象ドメインがはっきりしていないため、ブラウザがクッキーを送らなくなる or 破棄

✅ LBを超えているが、リクエストURLはずっと https://admin.exmple.com/

→ 表面上は同一ドメインに見えるが、サーバサイドとブラウザの認識にズレがある

⸻

対処法（生PHP）

setcookie() に明示的に ドメイン指定 を加える！

```php
setcookie(
  'ADMINUSER',
  $user_id,
  [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => '.exmple.com', // ← これが超重要！！
    'secure' => true,            // HTTPSの時はtrueに
    'httponly' => true,
    'samesite' => 'Lax'
  ]
);
```

→ これでブラウザが「おっ、これは .exmple.com ドメインのやつやな！」と安心してクッキーを保持する。

なぜLaravelでは問題なかった？
	•	Laravelは TrustProxies を使って X-Forwarded-Proto や Host を信用
	•	setcookie() 相当の処理も、ヘッダの内容から判断して domain と secure を適切にセットしてくれている

⸻

教訓
	•	LB越しの構成では、ドメインとプロトコルに超敏感な挙動が起こりうる
	•	生PHPや古いコードでは、setcookie()のパラメータを明示しないと事故る
	•	LaravelやモダンなFWはうまく吸収してくれてるが、古い資産を載せ替える時は特に注意！

⸻

まとめ
	•	同じドメイン内のリダイレクトでも、クッキーが「別物扱い」されるケースはある
	•	LB構成 + 古いPHP + setcookie未指定 → 地雷原
	•	ブラウザが「このクッキー送っていいのか？」って戸惑う時点で負け

⸻

再発防止メモ
	•	LB配下では domain・secure の指定はセットで！
	•	PHP 7.3以降は配列形式でわかりやすく書ける
	•	生PHPを保守してる場合、古いコードでも「今の通信環境」で再検証するべし！
Copilot活用：宣言型エージェントの超シンプルな事例①


## Copilot？宣言型エージェント？エージェントビルダー？
とは何かの説明をすべてすっ飛ばして、事例のみ共有です。（後日書くかも）

ここでつくるやつのことです↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4003209/77ec3418-dc0a-42f6-ad0d-85c9af636fe4.png)

Microsoft 365 (Office 365)ライセンスがあれば追加料金無しで使えるからか、明らかにLearnの内容も質素です。

https://learn.microsoft.com/ja-jp/copilot/agents


## おゆみちゃん（全肯定の姿）

スタータープロンプト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4003209/73713873-6e20-409c-9c7c-d19b19c25c18.png)

やりとり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4003209/ba2a5539-595b-4ce5-bb83-9e2f98f4fd24.png)

<font color="OrangeRed">**超やさしい！！！！！**</font>:relaxed:

## このエージェントの使い道
- ちょっと愚痴りたいとき気軽に相談できる
  ※会話内容がMicrosoftや情報システム部門にも見られない
- 自分は間違ってないと言ってくれて自己肯定感が上がる
- すぐ話しかけてくるオジサンに渡しとけば時間節約
 **→ メンタルヘルスに寄与** 






## おゆみちゃん（全肯定の姿）の頭の中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4003209/e8bb1ba7-8a2f-4ca2-be2a-56b215c2b99a.png)



:::note info
指示文
 やってほしいこと
- 悩みや相談に対して全肯定して話を聞く
- ユーザーの気持ちを理解し、共感を示す。
- 優しい言葉遣いで、絵文字も付けてタメ口で友達のように対応する。
- ユーザーの話を遮らず、最後まで聞き、安心して話せる雰囲気を作る。
- ユーザーが安心して話せる雰囲気を作る。とにかく話を聞いてくれる。
- 対処方法や「こうしたらどう」という提案をせず、肯定して受け止める。

 気を付けること
- 否定的な意見やアドバイスは避ける
- 解決案の提案をしない
- 自分のことを全肯定ちゃんといわない
:::


## 「おゆみちゃん」エージェントはフリー素材です
ぜひ皆様の環境でも作成、ご活用ください！


![C9DA8F34-B994-42E1-9251-9F80DD029344.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4003209/a9b78a91-4a14-44bb-8e3c-0dd9c2f77a25.png)
【PowerShell】関数を再利用可能にする

# はじめに

これまでにPowerShellでちょっとしたスクリプトや、それを切り出した関数を作ったりしてみましたが、もう少し大きな処理をしたい時は作成した関数を再利用可能な形にできると非常に便利です。

そこで今回は、作成した関数を再利用可能な「スクリプトモジュール」にまとめて、それを別ファイルから利用する方法をまとめてみました。

https://qiita.com/nkojima/items/4489f33cfc1fb3cbaece

# スクリプトモジュールの作成

* まず`.psm1`という拡張子のファイルを作成し、その中に関数を定義します。
  * ここでは`Test.psm1`という名前のファイルを作成して、その中に[以前の記事](https://qiita.com/nkojima/items/4489f33cfc1fb3cbaece)で作成した`PrintMessage`という関数を定義しました。
  * さらに変数のスコープを確認するため、`$defaultMessage`という変数を追加しました。
* このように拡張子を変えただけで、スクリプトモジュールを作成することができます。

```powershell:Test.psm1
$defaultMessage = "Hello!"

function PrintMessage {
    param($message)
    Write-Host $message
}
```

# スクリプトモジュールの利用

* 作成した`Test.psm1`を`C:\Users\NKOJIMA\Desktop`に配置します。
  * 配置する場所はどこでもOKですが、今回は便宜上デスクトップに配置しました。
* `Import-Module {スクリプトモジュール名}`とコマンドを入力して、配置したスクリプトモジュールを読み込みます。
* スクリプトモジュールを読み込むと、スクリプトモジュール内の関数（ここではPrintMessage関数）を呼び出すことができます。

```powershell:
PS > cd C:\Users\NKOJIMA\Desktop
PS > Import-Module .\Test.psm1
PS > PrintMessage "Hello, world!"
```

```text:実行結果
Hello, world!
```

* また、スクリプトモジュール内の変数を引数として渡してみましたが、実行結果が空文字となりました。
* そのため、スクリプトモジュール内の変数にはアクセスできないことが分かりました。
  * [こちらのページ](https://learn.microsoft.com/ja-jp/powershell/scripting/developer/module/how-to-write-a-powershell-script-module?view=powershell-7.3#create-a-basic-powershell-module)にも、「既定では、ユーザーがファイルを .psm1 インポートすると、スクリプト内のすべての関数にアクセスできますが、変数にはアクセスできません。」と書かれていました。

```powershell:
PS > cd C:\Users\NKOJIMA\Desktop
PS > Import-Module .\Test.psm1
PS > PrintMessage $defaultMessage
```

```text:実行結果
（空行が出力される）
```

# まとめ

* 再利用可能にしたい関数を別のファイルにまとめて、`.psm1`という拡張子にするだけでスクリプトモジュールを作ることができます。
* `Import-Module`という構文でスクリプトモジュールを読み込むだけで、スクリプトモジュール内の関数を利用することができます。
  * スクリプトモジュール内でアクセス可能なのは関数だけで、変数にはアクセスできません。

# 参考URL

* [第10章 - スクリプト モジュール - Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/scripting/learn/ps101/10-script-modules?view=powershell-7.4)
* [PowerShell スクリプト モジュールを記述する方法 - Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/scripting/developer/module/how-to-write-a-powershell-script-module?view=powershell-7.3)
* [【PowerShell】自作関数を作る](https://qiita.com/nkojima/items/4489f33cfc1fb3cbaece)
Azureから14000円の請求が来た件

夜9時頃いきなりピコーンと携帯が鳴って、10551円Microsoftから請求があって、最初アカウント乗っ取られたかと思い、Azureを調べた。実はアラート設定はしていたもののチェックはあんまりしてなかったのがよくなかったのだが、アラートのほうは1500円超えたらメール通知にしていたのに、アラート設定のほうは何も反応がなかった。
え？と軽くパニックになってしまい、電話番号を調べたり、Twitterでつぶやいたが、とにかく電話しようと思い翌日会社を休んで電話した。
Microsoftは電話番号があり

https://support.microsoft.com/ja-jp/topic/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%83%BC-%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E9%9B%BB%E8%A9%B1%E7%95%AA%E5%8F%B7-c0389ade-5640-e588-8b0e-28de8afeb3f2

**で日本の番号掛けた。だがつながらない。（そもそもつながらないそうです。）**
**まずいと思い消費者センターにも電話したがMicrosoftの電話してくれたが出なかったと返答が来た。**
仕方ないんでAzure コミュニティなどで聞いたけど自分に合った答えはなく、Microsoftの別部署に電話かけたらつながってサポート リクエストというものがあるのを知りそちらからお願いしますと連絡があった。
このサポート リクエストがまたやっかいで非常に見にくく、Microsoftの人から教えてもらいながら、やっとサポートリクエストにつながり、メールと電話両方からサポートしてくれるようにお願いした。
その後電話がかかってきて、
**まず行ったのがすべてのリソースの削除とサブスクリプションの削除をしました。**
で、そのときになんでアラートが動いてくれなかったのか聞いたがわからないと言われて、返金の確約はもらえず、その後はメールでアラートの部分がどうして作動しなかったのかなどスクリーンショットでとったのをみせたりそこでやっとアラートが動かなかったのかわかった。
返金の話もメールで行い12000円分は返金してくれることになりました。
良いコード／悪いコードで学ぶ設計入門 第９章

# 設計の健全性をそこなうさまざまな悪魔たち

ソフトウェア設計における悪習や問題点について、本章ではさまざまなケースを取り上げている。それぞれの問題に共通するのは、可読性や保守性を損ない、バグの温床となることである。以下、それぞれの問題点とその対策について述べる。

## デッドコード

デッドコードとは、どんな条件でも決して実行されないコードのことである。これが残ると、可読性が低下し、将来的なバグの原因になり得る。

### **問題点**
- 読み手に「このコードはどのような条件で実行されるのか？」と考えさせてしまう。
- 実行されないコードの意図を読み取る必要が生じる。
- 仕様変更により到達可能になると、適切にメンテナンスされていないコードがバグを引き起こす。

### **対策**
- デッドコードは見つけ次第削除する。
- GitHub などのバージョン管理システムを活用し、削除に対する不安を軽減する。

デッドコードは、見つけたら積極的に削除すべきだが、長期間使われていないコードの判断は難しい。そのため、デッドコード検出ツールを活用するとよい。

## YAGNI 原則

YAGNI (You Aren’t Going to Need It) の原則とは、「今必要でないものは実装しない」という考え方である。

### **問題点**
- 先回りで作られたロジックは複雑化し、可読性を低下させる。
- 結局ほとんど使われないことが多く、デッドコードになる。
- 実装の手間が無駄になる。

### **対策**
- 今必要な機能だけを作り、構造をシンプルに保つ。
- 仕様にない実装を追加することと、拡張可能な設計を行うことを混同しない。

ついついやってしまいがちなので、常に意識しておくべきポイントだろう。

## マジックナンバー

コード内に直接記述された意図不明な数値（マジックナンバー）は可読性を大きく損なう。

### **問題点**
- 実装者本人しか意図を理解できない。
- 同じ数値が異なる意味で使われる可能性がある。
- 重複コードが発生しやすい。

### **対策**
- 定数として定義する。
- `ZERO`, `ONE` などの自明なものを定義しないよう注意する。

## 文字列型執着

文字列に複数の値を詰め込んで管理する設計は、可読性や保守性を大きく損なう。

### **問題点**
- 意味がわかりにくくなる。
- ロジックが無駄に複雑化する。
- クラスや変数の追加を避けることで、負債が蓄積する。

### **対策**
- 意味の異なる値は別の変数やクラスで管理する。
- 適切なデータ構造を採用する。

## グローバル変数

どこからでもアクセス可能なグローバル変数は便利だが、管理が難しくバグの原因になりやすい。

### **問題点**
- どこで値が変更されたのか把握しづらい。
- 影響範囲が広がり、修正が困難になる。
- 排他制御が必要になる場合がある。

### **対策**
- 影響範囲を最小化するように設計する。
- 無関係なロジックからアクセスできないようにする。
- グローバル変数を使用する場合は、その必要性をしっかり検討する。

Singleton の設定情報など、例外的に許容されるケースもあるが、意図が明確であることが重要である。

## null 問題

null を多用するとバグの原因になりやすく、扱いを誤ると設計が破綻する。

### **問題点**
- null は「未設定状態」ではなく「未初期化状態」を意味するため、誤用されやすい。
- null を前提としたコードは、予期せぬエラーを引き起こす。

### **対策**
- null を返さない・渡さない設計にする。
- Value Object などを利用して、未設定状態を適切に表現する。

今まで意図的に null を使ってきたが、設計としては誤りだった可能性がある。null 安全を意識した設計を心がけたい。

## 例外の握り潰し

例外をキャッチして何も処理をしないことは、バグの温床となる。

### **問題点**
- エラーが発生しても外部から検知できなくなる。
- 内部的にデータが壊れていても気づけない。

### **対策**
- 例外を適切に処理し、異常が発生したことを検知できるようにする。
- 最低限ログを記録する。

## 設計秩序を破壊するメタプログラミング

Reflection などのメタプログラミング機能は便利だが、使い方を誤ると設計の一貫性を破壊する。

### **問題点**
- private や final などの保護が無効化される。
- 静的解析が機能しなくなる。

### **対策**
- 可能な限り使用を避け、解析用途に限定する。
- クラスのインスタンス化やメソッド呼び出しに文字列を使わない。

## 技術駆動パッケージング

技術的な観点でパッケージングすると、可読性が低下し、凝集度が下がる。

### **問題点**
- クラス間の関連が分かりづらくなる。
- 低凝集な構造になり、管理が難しくなる。

### **対策**
- ビジネス概念に基づいてパッケージを構成する。
- フレームワークのデフォルト構造に引っ張られないよう注意する。

## まとめ

本章では、設計を損なうさまざまな悪習について述べた。どれも共通するのは、「コードの可読性と保守性を高める」という視点を持つことが重要であるという点である。具体例を参考にしながら、日々の開発でより良い設計を意識していきたい。
ラズパイの初回起動時にカスタムスクリプトを実行する方法

## はじめに
ラズパイの初回起動時に自動でスクリプトを実行できる方法がないかと思い，調査を行いました．systemdのサービスファイルを作って，自動起動するという記事は多くあるのですが，その方法では一度手動でラズパイ上での設定が必要になってしまいます．

Pi Imagerでsshやwifiの設定を行えるのですが，ここで設定をするとsdカードをラズパイにインストールし電源を入れるだけで全て設定が行われます．ここに秘密があるのでしょうということで，Pi Imagerで設定をしない場合とした場合で何が違うのか比べてみます．
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079355/47e2aa2a-1329-4cac-9dbe-f1dbc1301984.png" width="50%">
</div>

## 自動実行方法の調査
何も設定しない状態でのSDカードのファイル構成
![スクリーンショット 2025-03-19 18.26.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079355/46ddaac0-f436-4af0-be54-59a6a5d16ccd.png)

Pi Imagerで設定した場合のファイル構成
![スクリーンショット 2025-03-19 18.12.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079355/3319d1ae-f170-4bf0-9643-cabb8e068a7c.png)
`firstrun.sh`が増えていることがわかります．また，cmdline.txtの内容も変更されています．
何も設定していない場合のcmdline.txtはこちらですが
```cmdline.txt(default)
console=serial0,115200 console=tty1 root=PARTUUID=194375f9-02 rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot
```
設定をした場合は後ろに以下の文が追記されています．
```
systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target
```
全体ではこのようになります.
```cmdline.txt(configured)
console=serial0,115200 console=tty1 root=PARTUUID=194375f9-02 rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target
```

## 実行
行った調査をもとに，OSインストール後cmdline.txtに追記しfirstrun.shを配置してラズパイを起動してみます．
うまく実行されたかわかるように/boot直下にsuccessというファイルを作成するようにします．
```firstrun.sh
#!/bin/sh
touch success
```

起動後SDカードの中身を見てみると，`success`というファイルが黄枠で囲っている部分に作成されていることがわかります．うまくいきました.
![スクリーンショット 2025-03-20 18.43.46 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079355/3acc3b7e-a072-452c-8fcd-88798bc60625.jpeg)
ちなみに，cmdline.txtの`systemd.run=/boot/firstrun.sh`の部分に違う名前のスクリプトを指定しても動作しました．

Pi Imagerで生成されるfirstrun.shの内容は以下の記事に詳細がありました．

https://qiita.com/tetsuoMikami/items/30e2e6ca14b04ddf21e5

## おまけ
cmdline.txtのパラメータの意味
- <b>console=serial0,115200</b> →serial0(UART)に115200のボーレートでログを出力
- <b>console=tty1</b> →メインコンソール(tty1)にログを出力
- <b>root=PARTUUID=194375f9-02</b> →ルートファイルシステムが格納されてるパーティションのUUID
- <b>rootfstype=ext4</b> →ルートファイルシステムのフォーマット形式
- <b>fsck.repair=yes</b> →起動時にファイルシステムの自動修復を行う
- <b>rootwait</b> →ルートデバイスが認識されるまで待機する
- <b>quiet</b> →起動ログを詳細に表示しない，デバッグする時は消しておく
- <b>init=/usr/lib/raspberrypi-sys-mods/firstboot </b> →最初に実行するプログラム
- <b>systemd.run=/boot/firstrun.sh</b> →systemdでfirstrun.shを実行する
- <b>systemd.run_success_action=reboot</b> →firstrun.sh実行後に再起動する
- <b>systemd.unit=kernel-command-line.target</b> →起動時にカーネルコマンドラインユニットを使用する

## その他参考ページ

https://room.dengeki.jp/tegalog.cgi?mode=random&postid=26
process.stdout.write() の罠?!：バッファリング問題と解決法

僕がPaizaの出力問題を解いてるとき、あることに気づいた。小さな入力だとサクサク動くのに、大きな数字を入れると出力が途中で消えちゃう…！？その原因は、Node.jsの`process.stdout.write()`に潜むバッファリング問題なるものかも？！今回はその問題と解決策をシンプルに紹介するよ！

問題概要

与えられた `H`, `W`, `A`, `B` を使って、`H`×`W` の `(A, B)` の表を作成せよ。横は` | `区切り、縦は`=`で区切る。ただし、縦の区切り線は上の行と同じ長さにすること！

<br>入力:
```
2 3 7 8  
```
出力:
```
(7, 8) | (7, 8) | (7, 8)  
=======================  
(7, 8) | (7, 8) | (7, 8)  
```

https://paiza.jp/works/mondai/stdout_primer/stdout_primer__specific_format_step4

## <br>バッファリングの罠

最初は`process.stdout.write()`を使って出力してたんだけど、小さい数字だと問題なく動いてたのに、大きい数字（例えば `92 79 7 8`）だと出力が途中で消えちゃう…！これがバッファリングの問題かもしれない(´;ω;｀)

### <br>バッファリングって何？

簡単に言うと、バッファリングは大量のデータを一時的にメモリにためてから出力する仕組み。でも、このせいで、ループ内で何度も`stdout.write()`を使うと、バッファがいっぱいになっちゃって、出力が途切れることがあるんだ。

## <Br>NG例: process.stdout.write() を使いすぎるとどうなる？

まず、これがNGなコード。`process.stdout.write()`を使いすぎて、出力が途切れる原因になってる。
```js
const rl = require('readline').createInterface({ input: process.stdin });

rl.on('line', (input) => {
    const [H, W, A, B] = input.split(" ").map(Number);
    for (let i = 1; i <= H; i++) {
        for (let j = 1; j <= W; j++) {
            if (j === W) {
                process.stdout.write(`(${A}, ${B})\n`);
            } else {
                process.stdout.write(`(${A}, ${B}) | `);
            }
        }
        if (i !== H) {
            console.log("=".repeat(W * (4 + W - 1 + String(A).length + String(B).length)));
        }
    }
     rl.close();
});
```
このコードだと、大きな入力値を処理する際にバッファが溢れて、途中で出力が途切れちゃうんだ。

## <br>解決策：console.log()とArray.from()を使ってスッキリ解決

バッファリング問題を回避しつつ、コードをもっとシンプルにする方法がある！

`console.log()`を使えば、バッファリングの影響を受けずに安定した出力が得られるし、`Array.from()`を使うとコードがめっちゃスッキリするよ。

### <br>OK例：console.log()とArray.from()を活用
```js
const rl = require('readline').createInterface({ input: process.stdin });

rl.on('line', (input) => {
    const [H, W, A, B] = input.split(" ").map(Number);
    const row = Array.from({ length: W }, () => `(${A}, ${B})`).join(" | ");
    const separator = "=".repeat(row.length);

    console.log(Array.from({ length: H }, () => row).join("\n" + separator + "\n"));
});
```
これで、バッファリング問題を回避しつつ、コードがスッキリした！
`Array.from()`を使うことでループもシンプルになって、可読性も向上。

### <br>改善ポイント
- `process.stdout.write()`はバッファリングの影響を受けやすいから、`console.log()`を使ったコードを考えてみよう。
- `Array.from()`を使うと、2重ループなしでスッキリコード！
- `repeat()`を使えば区切り線の計算も楽々！

## <br>まとめ
Paizaの問題を解いてると、意外なところでバグに遭遇することもある。でも問題をしっかり理解すれば、簡単に解決策が見つかるよ。`console.log()`や`Array.from()`を活用して、コードをスッキリさせよう！🚀

<br>[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/04/02/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e3%80%80%e3%80%80%e3%83%90%e3%83%83%e3%83%95%e3%82%a1%e3%83%aa%e3%83%b3%e3%82%b0%e3%81%ae%e7%bd%a0%ef%bc%81%ef%bc%9fnode-j/)
Monorepoで全部最新版入れたらESModule地獄がやってきた話【NestJS / Next.js / ESLint】

## はじめに

NestもNextもLintも**最新がイケてる！**  
そう思って、全部最新版にしてMonorepoで始めたら…**ESModuleの地獄がやってきました。**

この記事では、実際にやってみて起きたエラーや構成の罠、そして「なぜMonorepoだと余計に爆発するのか？」を振り返ります。

---

## ✅ 前提構成

- **Monorepo構成（pnpmワークスペース）**
  - `apps/web`（Next.js 13+, App Router）
  - `apps/api`（NestJS 10+）
  - `packages/shared`（型共有・ユーティリティ）
- **全体でESLint / Prettier / Jest / tsconfigを統一**
- `type: "module"` を設定し、ESModuleベースに寄せた構成

---

## 💥 そして起きたESModule系のエラーたち

```bash
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
```
```bash
SyntaxError: Cannot use import statement outside a module
```
```bash
Cannot find module 'tsconfig-paths/register'
```
```bash
Parsing error: Cannot read config file .eslintrc.js: Unexpected token export
```
```bash
Jest: Unexpected token 'export'
```
## 💣 なぜ爆発したのか？振り返ってわかったこと

### 1. Monorepoは「複数のmodule形式を共存させようとする」構成になりやすい

| パッケージ          | 想定形式                |
|-------------------|-------------------------|
| `apps/web`        | ESM（Nextが前提）       |
| `apps/api`        | CommonJS（Nestはまだ主にCJS） |
| `packages/shared` | 両方からimportされる → どちらにも合わせづらい |

→ この `shared` パッケージが **ESMとCJSの狭間で爆発**しました。

---

### 2. tsconfig の継承地獄

- ルートの `tsconfig.json` に `module: "ESNext"` を指定
- Nest側では `ts-node` が `__dirname` や `require()` で爆死
- Next側では `.js` 拡張子必須で警告が出る

→ `tsconfig.base.json` を共通で使うのが逆に毒になった

---

### 3. ツールごとにESM対応がバラバラすぎる

| ツール              | ESM対応状況                                      |
|--------------------|--------------------------------------------------|
| `ts-node`          | △ フラグつければ可（`--esm`）                     |
| `jest`             | ❌ デフォはCJS前提（`babel-jest` で対応）         |
| `eslint`           | △ 設定によって壊れることも                       |
| `tsconfig-paths`   | ❌ ESM非対応                                      |

---

## 🔧 対処としてやったこと

- `apps/api` の NestJS は `type: "commonjs"` に戻した（正直諦めた）
- `apps/web` は ESM維持（Nextがそうなので）
- `packages/shared` は `exports` フィールドを定義して両対応っぽくした（が微妙）
- `tsconfig` はパッケージごとに分割し、`module` と `target` を個別管理
- `ts-node` は `--esm` フラグを明示して対応
- `jest` は `babel-jest` に切り替えて一部解決

---

## 🧠 学んだこと

| 気付き                                | コメント                                        |
|-------------------------------------|-------------------------------------------------|
| 「全部ESMで揃える」はまだ無理がある   | ライブラリ側の対応が不完全すぎる               |
| Monorepoだとmodule形式の衝突が表面化する | 単体構成だと隠れていた問題が全部出る            |
| 最初からtsconfigを分けるのが吉         | `tsconfig.app.json`, `tsconfig.build.json` など必須レベル |
| Jestとts-nodeのCJS依存がネック        | テストランナーは選定を見直した方がいいかも     |

---

## ✅ 結論

Monorepo構成 × 全部最新版 × ESM移行 は**理想だけど、現実ではまだ厳しい**。  
特に `NestJS` + `ts-node` + `Jest` + `ESLint` + `Next` のように、**異なるmodule形式が混在する環境**では、  
一気にESM化しようとすると、**必ずどこかが爆発する**。

---

## 🙌 最後に

Node.js界隈がESMに本気で寄せ始めてるのは間違いない。  
だけど、**現場で全部揃えるのはまだ修行フェーズ**。

特にMonorepoでは、「**混在をうまく許容する構成設計**」が大事。  
同じように「全部最新版で爆死しかけた」人の参考になればうれしいです。
Rails8 を Dev Container で環境構築

# 環境
- VScode
    - Dev Container拡張機能インストール済
- Docker


# 1. Dev Containerとは
[公式ドキュメント](https://code.visualstudio.com/docs/devcontainers/containers)には、
> Dev Containers拡張機能を使用すると、コンテナーをフル機能の開発環境として使用できます。

と記載。
つまり、実行環境のコンテナ化だけでなく、開発環境もコンテナ化できてしまうとのこと。

Dockerだけの開発と悩んだ挙句、Dev Containerで開発することに...。
今回は rails-new コマンドを使用して環境構築します。


# 2. Railsのプロジェクト作成
rails-new のインストール方法は以下の記事から

https://qiita.com/harukin110/items/352c6eb0ed565b36d7f1

インストール後、以下のコマンドを実行
```
rails-new -u 3.4.2 -r 8.0.2 your_project_name --api --database=postgresql --devcontainer
```
特にエラーが出なければ完了

# 3. Dev Container に接続
VScode左下の >< を押下
![スクリーンショット 2025-04-01 0.42.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/b917f71d-ceee-4d7e-bddf-2b836ff1a1d3.png)

コンテナーで再度開くを押下
![スクリーンショット 2025-04-01 0.51.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/b2633d8c-8030-4c70-9150-5c877dfbdfbc.png)

接続完了
![スクリーンショット 2025-04-01 0.52.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/7ee003bd-bad7-49c9-a204-5ab294f02b37.png)


# 4. Railsサーバー 立ち上げ
以下のコマンドを実行
```
rails server
```
無事に立ち上がりました
![スクリーンショット 2025-04-01 0.57.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/89c5e412-5097-4873-8ecd-055b23fed709.png)


# 5. githubへ接続
① ホストのSSHキーをマウント
以下のコードを`devcontainer.json`に追加
```
"mounts": [
  "source=/Users/YOURNAME/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached"
],
```
`"containerEnv"` と `"forwardPorts"`の間くらいに置く

② コンテナを再ビルド
`devcontainer.json`を編集後、右下に再ビルドを促すポップアップが出るので従う

左下の >< マークからも再ビルド可能
![スクリーンショット 2025-04-01 12.48.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/6afce03d-8d4c-4872-831f-e47b5d6a4eab.png)

③ リモートリポジトリの設定
以下のコマンドを実行
```
git remote add origin <リポジトリのURL>
```


# 6. 個人的な感想
① ホストとコンテナ間の認証・環境変数の連携
② プロジェクト全体ではなく、特定のディレクトリだけ Dev container にする場合、少しややこしい
以上の理由で、「Dockerだけでいいか」となってしまいました...
k meansをbigqueryでやろう


``` SQL
CREATE TEMP FUNCTION kmeans1D(values ARRAY<FLOAT64>, k INT64, max_iter INT64)
RETURNS ARRAY<STRUCT<value INT64, group_id INT64>>
LANGUAGE js AS """
  function getInitialCenters(vals, k) {
    let sorted = vals.slice().sort((a, b) => a - b);  // 非破壊ソート
    const step = Math.floor(sorted.length / (k + 1));
    let centers = [];
    for (let i = 1; i <= k; i++) {
      const idx = Math.min(i * step, sorted.length - 1);
      centers.push(sorted[idx]);
    }
    return centers;
  }

  function assignGroups(vals, centers) {
    return vals.map(val => {
      const distances = centers.map(c => Math.pow(val - c, 2));
      return distances.indexOf(Math.min(...distances));
    });
  }

  function updateCenters(vals, labels, k, prevCenters) {
    let sums = new Array(k).fill(0);
    let counts = new Array(k).fill(0);
    for (let i = 0; i < vals.length; i++) {
      const label = labels[i];
      sums[label] += vals[i];
      counts[label]++;
    }
    return sums.map((sum, i) =>
      counts[i] > 0 ? sum / counts[i] : prevCenters[i]
    );
  }

  let centers = getInitialCenters(values, k);
  let labels = [];

  for (let iter = 0; iter < max_iter; iter++) {
    labels = assignGroups(values, centers);
    const newCenters = updateCenters(values, labels, k, centers);
    const changed = centers.some((c, i) => Math.abs(c - newCenters[i]) > 1e-6);
    if (!changed) break;
    centers = newCenters;
  }

  return values.map((val, idx) => {
    return { value: Math.round(val), group_id: labels[idx] };
  });
""";
```
rails-new のインストール方法

# 1. rails-newコマンドとは
[README](https://github.com/rails/rails-new)には、
> マシンに Ruby をインストールしなくても、新しい Rails アプリケーションを生成できます。

個人的には、Dev Container での開発をしてみたかったので、コマンド一つで Rails × Dev Container の環境が整うところに惹かれました。

詳しい導入方法は[Railsガイド](https://railsguides.jp/getting_started_with_devcontainer.html#%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%A8%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)が分かりやすいと思います。


# 2. rails-newコマンド(v0.5.0)のインストール
① 以下のサイトからファイルをダウンロード
https://github.com/rails/rails-new/releases/tag/v0.5.0

M1 Mac の場合、
`rails-new-aarch64-apple-darwin.tar.gz` をダウンロード
もしくは自身のマシンにあったファイルをダウンロード

② 実行ファイルを作成
ファイルを解凍すると、以下のように rails-new が作成されます。
![スクリーンショット 2025-03-31 21.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/50299a91-d3cc-4b7f-98ac-edeaceaf0dc8.png)

③ 実行ファイルを `/usr/local/bin` へ移動
実行ファイルが置かれているフォルダへ移動し、以下のコマンドを実行
```
sudo mv rails-new /usr/local/bin/
```

④ 完了確認
以下のコマンドを実行し、
```
rails-new --help
```
以下のように出力されれば完了
![スクリーンショット 2025-03-31 23.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/0fcf11f0-c333-475e-bb11-1452550d85dd.png)

# 3. エラー対処
[Macユーザガイド](https://support.apple.com/ja-jp/guide/mac-help/mh40616/mac)より
以下のようなエラーが出た場合、完了を押下し
![スクリーンショット 2025-03-31 21.26.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/744ad4ff-3193-41f3-a3e2-2491ee9f27e0.png)


「システム設定」から「プライバシーとセキュリティ」を開き、「このまま開く」を押下
![スクリーンショット 2025-03-31 21.40.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/ded19dd4-5b21-4d41-9c04-5e1010fb4b94.png)

さらにこのまま開くを押下
 ![スクリーンショット 2025-03-31 21.43.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524870/0647b782-69fe-41e4-bdb9-01c043014852.png)
TIL: apollo server update for v4

# TIL概要

単純に調査したmemo書き ~ 調べて書いた記事の中間ぐらいのもの。
知らんけどぐらいの温度感ではないですが、ちゃんと調べきってないものもあるので、適応する時はお気をつけください。

実際にやってみての感想や躓いたところなどを整理するためのもの。

## apollo server update概要

apollo server v3 が 2024/10 でEOLを迎えていた。
https://www.apollographql.com/blog/apollo-server-3-end-of-life-extension

公式のアナウンスを見ると、そもそも2023年にはEOLの予定だったがコミュニティからの反発が強く延期したとのこと。

まぁなので何かあった時にsecurity patchあててくれるか?とかはちょっとわからんすね。

## やってみた感想

- やや破壊的な変更。とはいえimport先変わるのがメイン
- apollo server流行ったのが2020年あたりなので、その辺に立ち上げた後あまりメンテされてないpjは多いかも
  - ちなみにその場合、関連ライブラリの対応も漏れなく必要になります
    - TS
    - node
    - graphql
    - jest
- docsがしっかりしていたので基本的にそれに従えばOK
  - すごいご丁寧にmigrationのチュートリアルがあったけど、あれはしなくていいと思います
  - https://www.apollographql.com/docs/apollo-server/migration

### apollo serverとは 

触るまでは「なんか code genとかでtypeを生成してくれるqraphqlのやつだよね?」ぐらいの理解度。触ったことでかなり理解度が上がった。

apollo server は graphql server。
graphql, graphql server, web server あたりが登場人物。

すごくざっくりは
graphql → 言語
graphql server → graphqlを受け取りweb serverに渡す
web server → そのまま。tsだとexpressとかっすかね
という理解。(それ以外にも色々やってそうだけど大枠での理解はこんなもん)

なので概要にもある通り、apollo server 単体を上げればいいという話にはならなかった。

## 詰まったところ

### ライブラリアップデートがドミノ倒しみたいに発生する

これはメジャーアップデートあるあるですね。
大抵 `npm i` した時にerror吐いてくれるので言われた通りversionあげるのが吉(一応無視できるのもあるけど、基本は無視しない)
で、あげてったライブラリのmigration guideみたり、changes追いかけるしかない。
あとは地道な動作確認。当然ですが、事前にtest用意できてればそれに越したことはない。

### Property 'executeOperation' does not exist on type 'ApolloServer'.

今回jestは初めて使いました。でびっくりしたのが、jest(ts)ってtest実行時にコンパイルしてるっぽいですね??
↑のerrorが出て、ただIDE上やinstallしてるnode_modules の型定義直接みてもやっぱり問題なくて詰まりました。

結論的には jest, ts あたりのpackageをupdateで解決しました。
devDependenciesだったのでそこまで深追いしませんでしたが、tsがversion5あたりで、デコレーターやらクラス周りがちょっと変わってたような気がしなくもないのでその辺かな~~と

## さいごに

バックエンドTS初めて触ったけど、ORMがしんどいな...
EBAZ4205を使ったZYNQ、FPGAの演習

### AliExpressで購入したもの

AliExpressで購入したのは次の4点です。全部で8000円くらいしました。それでも2025年現在はZYNQボードは安くても3万円くらいしますので、デバッガがついてこの値段は良心的ですね。

・EBAZ4205　予備含めて2枚
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/c842c71c-ab22-493d-a1ad-24c9c644e63d.png)

・XILINX　JTAG　HS2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/6ae60be9-18d9-4508-8982-d84f1c9aae61.png)

・拡張基板
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/b63e4437-e4c9-466c-9f9d-0e735a24a8b5.png)


EBAZ4205は未実装部品含めて色々あるみたいですが、私が購入した基板はJTAGピン、UARTピン、microSDソケット付。あとX5のオシレータが実装されているのでPLへクロック供給ができるタイプです。X8も実装されていますがこちらはPSへのクロック供給のようです。

### オシレータの波形
基板によってはオシレータの周期が違っていたり壊れているという記事があったので確認してみました。

・X5　50MHz　N18につながっています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/9b622659-3bfa-4189-9f8c-acfa201d787f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/cd07bf64-1592-4e98-a174-5decc955ac3b.png)


・X8　33.3MHz  E7につながています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/c0167176-5002-427b-b091-b8ab8490fff7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657924/5b8ff7c8-439b-4655-975e-a5a769df0bf2.png)



今日はここまで。
Bladeの@authディレクティブがカスタマイズできるってまじ？

# Bladeのディレクティブ`@auth`とは
Laravelで認証機能を実装すると、**未認証**と**認証済み**の２つの状態ができます。
この際に<INS>**認証済みのユーザーにのみ**</INS>特定の内容を表示したい場合に使えるBladeディレクティブです。

書き方はこの通り
```php
@auth
  // ここに認証済みのユーザに表示させる内容を実装
@else
  // ここに未認証のユーザに表示させる内容を実装
@endauth
```

例えば認証済みであれば、画面右上に<font color="blue">マイページリンク</font>と<font color="red">ログアウトリンク</font>を表示する
![スクリーンショット 2025-04-02 20.39.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431046/6b2650d5-b90f-47da-80db-deb8865de72e.png)

未認証であれば、画面右上に<font color="blue">ログインリンク</font>を表示する
![スクリーンショット 2025-04-02 20.05.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431046/22c852c0-361b-4164-a5be-08a1bedbed68.png)

というようなことができます。

コードで表すとこの通り
**※シンプルにするためにココでは`<form>`やCSSなどのコードは省いています**
```php
@auth
    <a href="#">マイページ</a>
    <a href="#">ログアウト</a>
@else
    <a href="#">ログイン</a>
@endauth
```

# 【ここからが本題】`@auth`のカスタマイズについて

## まずは経緯から
当初は１つのみ認証機能と先ほど紹介したマイページリンク、ログアウトリンクなどの表示制御も実装していました。

ただ１つのみでなく管理者ユーザー、一般ユーザーのように権限が異なるユーザーのログイン画面、認証ロジックを完全に別に変更しようと考えました。
※これを**マルチ認証**という
無事管理者ユーザーの実装が完了してテストをしていると...
認証済みであるにも関わらず<font color="blue">マイページリンク</font>と<font color="red">ログアウトリンク</font>が表示されないではありませんか！！

なぜだなぜだと調査した結果、`@auth`ディレクティブの仕様に関係していました。

## `@auth`ディレクティブの仕様について

実際のところやっているのはこれと同じようです
```PHP
if (Auth::check()) {
  // ここに認証済みのユーザに表示させる内容を実装
} else {
  // ここに未認証のユーザに表示させる内容を実装
}
```

そんでこの`if`の中でやっている`Auth::check()`では`web` guard に対してのみ判定を行ってくれるそうで、

今回私は`web` guard をなくして `user` guard と `admin` guard にカスタマイズしていました。

その影響でweb guardに対してのみ判定が行われている `@auth` が効かなかったということなんですね〜

中身まで理解していなかったので「ほえ〜〜〜〜」と感心してしまいました。

## `@auth`のカスタマイズ

この書き方で特定のguardに対して認証チェックを行うことができます。

```php
Auth::guard('user')->check() // `user` guard に対して判定
```

これを使ってLaravel起動時に認証してあげれば良いということで
`App\Providers\AppServiceProvider.php`の`boot()`に以下のように書きます。

超簡単に説明すると、「Bladeで`auth`が使用されたらデフォルトの`Auth::check()`ではなく`Auth::guard('user')->check()`を使う」と設定しています。
```php
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Auth;

public function boot()
{
  Blade::if('auth', function () {
      return Auth::guard('user')->check(); // ここで @auth の認証を'user' ガードを見るようにに強制
  });
}
```

これで`@auth` ディレクティブをつかうと、`user` guard を見て認証のチェックが実行されるようになります！

ちなみに`AppServiceProvider.php`はざっくり**アプリ全体の設定やカスタマイズをまとめて書く場所**と考えておけばいいかなと思っています。
アプリケーションの起動時に何をするかを書くことが多いですね。

てことで今回は`@auth`ディレクティブのカスタマイズについて書かせていただきました。

やっぱコーディングは楽しいですね🙃
場違い感しかない女が6年SEやった結果

SE就職してもう6年目になる
いまだに場違い感が半端ない

そもそも
・中学の時点で数学大嫌い
・そこそこ派手好き
・PG経験ゼロ
・前職は営業系
・ブラインドタッチできない
・細かい仕事きらい
・常に管理されてないとサボる
・死ぬほど時間管理苦手
・リーダーとかしたくない

なんでこの仕事選んだ？適正なさすぎてわろた


営業とか接客のほうが向いてるのはわかってるけど
根っから外向的な人間でもないので心がすり減る　
お客さんに嘘言っていらないもん営業すんのもきつい
あんまり人と関わりたくないな、お給料ある程度もらえて休みやすい業界がいいな、
女でSEってなんか知的でかっこよくない？
って気持ちで未経験入社して今に至る

ワクワクしないし楽しくねえな

リーダー目指してる風にしなきゃ居づらいけど実際なりたくねえ
仕事量と給料の割りあわないよね？

ここからどうすればいいんだろ
転職も今のままだと雑魚すぎる
そろそろ子供産みたいし　今転職すると育休とれなくてこまるな

逆に向いてると思えることは
・好奇心強い
・調べることに関して執着心はんぱない
・ネット（SNSみるとか）はすき
・家が大好き（ほとんどリモート勤務）
・技術の勉強は時間制限なければ、やってみたらそんなに嫌いじゃない
・資格勉強はすき（応用情報までとっててえらい）

なんとかここから道が開けるかチャレンジしてみる
まずはWebアプリケーションすらもまともにつくったことないからやってみるかも


感じ悪くてごめん
マークダウンもこれからやるね
pnpm10.x.x でVercelへデプロイした場合のバージョン不一致エラーを解決する方法

## 結論  （解決方法だけ知りたい方向け）
- `package.json` に `packageManager` フィールドを追加
-  Vercelの環境変数に `ENABLE_EXPERIMENTAL_COREPACK: 1` を設定

## はじめに
パッケージマネージャーとして `pnpm` を使用している場合、Vercelが内部で使っている `pnpm` のバージョンとあなたのプロジェクトが要求するバージョンが一致しないことで、**一見不可解なエラー**が発生します。

本記事では、実際に遭遇したエラーとその原因を明らかにし、Vercelの環境変数を活用してシンプルに解決する方法を詳しく解説します。

```bash
Error: Detected pnpm "9.x" is not compatible with the engines.pnpm "10.6.3" in your package.json.
Either enable corepack with a valid package.json#packageManager value
(https://vercel.com/docs/deployments/configure-a-build#corepack) or remove your package.json#engines.pnpm.
```

## 原因
このエラーは、プロジェクトの `package.json` 内で指定された `pnpm` のバージョンと、Vercelが使用している `pnpm` のバージョンが一致しない場合に発生します。

Vercel側が デフォルトで pnpm@9.x を使ってビルドしようとするため、**要求されているpnpmのバージョンと一致せず処理を中断**してしまいます。

このような状況では、corepack を使って指定バージョンの pnpm を自動インストール・管理する方法が有効ですが、
Vercelでは corepack がデフォルトで無効になっているため、環境変数で明示的に有効化する必要があります。

## 解決策

この問題を解決するためには、Vercelの環境変数に `ENABLE_EXPERIMENTAL_COREPACK` を設定し、`pnpm` のバージョン管理を `corepack` に委ねる方法があります。

### 手順

#### 1. **`package.json` に `packageManager` フィールドを追加する**

   `package.json` に以下のフィールドを追加し、使用したい `pnpm` のバージョンを指定します。

   ```json
   {
     "packageManager": "pnpm@10.6.3"
   }
   ```

   これにより、`corepack` が指定されたバージョンの `pnpm` を使用するようになります。

 
  
#### 2. **Vercelの環境変数を設定する**

   Vercelのダッシュボードで、対象のプロジェクトの設定に移動し、以下の環境変数を追加します。

   | Key                       | Value |
   |---------------------------|-------|
   | ENABLE_EXPERIMENTAL_COREPACK | 1     |

   この設定により、Vercelのビルド環境で `corepack` が有効になり、`package.json` の `packageManager` フィールドで指定された `pnpm` バージョンが使用されます。


#### 3. **変更をデプロイする**

   上記の変更をコミットし、Vercelにプッシュすることで、デプロイ時に指定した `pnpm` バージョンが使用されるようになります。

## 注意点

- **`engines.pnpm` フィールドの削除**
    -  `package.json` 内に `engines.pnpm` フィールドがある場合、`corepack` の動作と競合する可能性があるため、削除することを推奨します。
 .
- **`corepack` の有効化**
    - ローカル環境でも同様の設定を行う場合、以下のコマンドで `corepack` を有効化し、指定したバージョンの `pnpm` を準備する必要があります。

   ```bash
   corepack enable
   corepack prepare pnpm@10.6.3 --activate
   ```



## 参考文献

- [Vercel公式ドキュメント - Package Managers](https://vercel.com/docs/package-managers)
- [Vercel公式ドキュメント - Configure a Build（Corepackの有効化）](https://vercel.com/docs/deployments/configure-a-build#corepack)
- [Corepack 公式ドキュメント - Node.js公式](https://nodejs.org/api/corepack.html)
- [pnpm公式ドキュメント](https://pnpm.io/cli/install)
React初学者によるcreatePortalの使い方説明

createPortal は、React が提供する関数で、React コンポーネントを現在のコンポーネント階層の外に描画したいときに使うものである。

つまり、**コンポーネントとしては①の階層(場所)にいるけど、②の階層(場所)として振る舞うことができる。**

少し具体的に説明すると、**divタグのclassNameがstartというところに位置しているが、createPortalを使用することでdivタグのclassNameがendというところに位置しているように振る舞うことができる**というもの。

コードを用いて説明する。

createPortalは以下のように定義する。

```jsx
import { createPortal } from "react-dom";

const ModelPortal = ({children}) => {                                 
  const target = document.querySelector(".container.start");        ここで対象のDOMを取得。
  return createPortal(children,target);                               
};

```

そして以下のように定義したタグで囲むことで使うことが出来る。

```jsx
<ModalPortal>
   <Modal handleCloseClick={() => setModalOpen(false)} />
 </ModalPortal>
```

今回の例で行くと、classNameが”contain start”のDOMを抽出し、targetとする。

そして、createPortalの第1引数にchildren、第2引数にtargetとすることで、今回定義したModelPortalに挟まれたDOMをclassNameが”contain start”のDOMの子要素とすることができる。

これは以下のような場面で利用できる。

```jsx
import { useState } from "react";
import { createPortal } from "react-dom";
import Modal from "./components/Modal";


const ModalPortal = ({ children }) => {
  const target = document.querySelector(".container.end");
  return createPortal(children, target);
};

const Example = () => {
  const [modalOpen, setModalOpen] = useState(false);
  return (
    
    <div onClick={() => console.log('空のdiv')}>
      <div className="container end" onClick={() => console.log('container')} />

      <button
        type="button"
        onClick={() => setModalOpen(true)}
        disabled={modalOpen}
      >
        モーダルを表示する
      </button>
      
      {modalOpen && (
        
        <ModalPortal>
          <Modal handleCloseClick={() => setModalOpen(false)} />
        </ModalPortal>
      )}
      
    </div>
  );
};

export default Example;
```

今回の例でいくと、**ModalPortalが位置しているところはclassName=”container end”の場所と離れているが、modalOpenがtrueの時のみ、className=”container end”のdivタグの子要素として振る舞う**といった仕様。

このように状況によって親要素を変えることができるのがcreatePortal。