OmniAICreator/Qiita-1.07M huggingface dataset:
SAP移行時間への影響 – CPUモデル変更による性能変化

## はじめに
SAPの移行で、複数回同じ環境をリストアして移行の時間計測をすることがありますが、移行の処理にはさまざまな要因が関わるため、回によっては処理が遅くなることがあります。ある案件の移行で「CPUモデル変更による性能変化」が原因でSUMの処理時間が遅くなったことがあり、今回はそちらをテーマに絞って紹介していきます。

## インスタンス(OS)再起動やVMotionの後にCPUモデルが変わる
クラウド環境では、仮想マシンのインスタンス（OS）再起動やVMotionなどで異なる物理筐体に再配置されることがあり、その影響で仮想マシンのCPUモデル（型番）が変わることがあります。
※あらかじめCPUモデルが固定されている仮想マシンや専用ホストのCPUモデルはそのままです。
※仮想マシンで設定されているCPUのコア数もそのままです。

下記画像は、例としてAWSのインスタンスタイプt3.mediumの環境でOS再起動して確認したものです。OS再起動後にCPUモデルが変更されていることが確認できます。
(左:再起動前 右:再起動後)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552891/70bd0059-9b35-4d53-ad22-e780ab7e1e26.png)

ある案件のクラウド環境ではインスタンス(OS)再起動やVMotion後にシングルスレッド性能が20~45%程度低いCPUモデルに変わっていたことがありました。知らないうちに性能が低いCPUに変わっている可能性があるので注意が必要です。

## CPUのシングルスレッド性能の影響を受けやすい処理
では、CPUのシングルスレッド性能が変わると例えばどういう処理が影響を受けやすいのかというと、並列で実行されずに逐次的に実行される処理です。

例えば、SUMのフェーズの中で、ACT_UPGというDDICオブジェクトを1つずつ順番に有効化していくような長時間かかる処理があります。このような並行で実行されない処理はCPUの1つのスレッドが持つ性能に頼る必要があり、つまりシングルスレッド性能に大きく影響をうけやすいと考えられます。
※下記Noteにも記載されている通り、ACT_UPGのフェーズでは、1つのワークプロセスが依存関係の計算に使用されると記載されており、逐次的に実行される処理であることが確認できます。

>1918279 - Performance analysis for ACT_UPG phase
During Calculation of Dependencies, firstly the list of DDIC objects and switch / enhancement (SFW) objects are read from table E071 for all packages which are bound to upgrade. these packages include support packages, enhancement packages, addon packages and transport requests. After that, a complete dependency graph is built up in memory. Accordingly, memory play very important role in the calculation as well CPU. <b>Only one work process is used for dependency calculation. There are many database access on dictionary tables(i.e. DD02L).</b>SAP Note  1897538 was a known issue for the dependency calculation. At last, all objects are assigned to individual levels.  After Calculation of Dependencies phase is finished, the line below can be found in activation log file.

Note内で、ACT_UPGでは対象テーブルに多数のDBアクセスがあると記載があります。これは要するにAPからDBに向けてのリクエストが多く発生するということであり、ネットワークレイテンシ(AP から DB へリクエストが届くまでの時間)も処理時間に影響を与える重要な要素であることがわかると思います。こちらはまた別の回で紹介します。

## CPUのベンチマーク比較ツール
CPUのシングルスレッド性能を比較したい場合は、下記PassMarkというサイトが便利です。
https://www.passmark.com/

比較表のSingle Thread Ratingの項目で、各CPUのシングルスレッド性能を確認することが可能です。
今回はAWSのインスタンスタイプt3.mediumの環境でインスタンス再起動して検証して、そこまでCPUの性能差はありませんでしたが、クラウド環境によっては性能差が出てきます。
性能の劣化が気になる場合などにCPUモデルを確認しておくと良いと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552891/c9db6dbc-be4b-4a48-880d-574302c39cf8.png)

## おわりに
誰かの参考になれば幸いです。
[Docker] プライベートレジストリを構築して社内開発者にマスタイメージを配布できるようにする

## 概要

社内サーバーにプライベートDockerレジストリを構築する機会があったのでメモ

## 手順

### 1. Dockerの導入

#### 必要パッケージのインストール

以下のコマンドで、`dnf-plugins-core`をインストールします。

```sh
dnf install -y dnf-plugins-core
```

#### 公式Docker-CEリポジトリの登録

Docker公式のリポジトリを追加します。

```sh
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
```

#### Dockerのインストール

次に、Dockerエンジンと関連パッケージをインストールします。

```sh
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

#### Dockerの起動と有効化

Dockerサービスを起動し、システム起動時に自動起動するよう設定します。

```sh
systemctl start docker
systemctl enable docker
```

---

### 2. Dockerレジストリの導入

Dockerの公式レジストリイメージを利用して、プライベートレジストリをセットアップします。

https://www.docker.com/ja-jp/blog/how-to-use-your-own-registry-2/

#### レジストリコンテナの起動

以下のコマンドで、ポート5000番でレジストリを起動します。

```sh
docker run -d -p 5000:5000 --name registry registry:2.7
```

#### レジストリの動作確認

レジストリコンテナが正常に起動しているか確認します。

```sh
docker ps
```

また、ブラウザや`curl`を使用して、以下のURLにアクセスし、応答を確認します。

```sh
curl http://[サーバーのIPアドレス]:5000/v2/_catalog
```

エラーがなければ、空のJSONレスポンスが返ってきます。
※ { } とだけ返ってくるはず

---

### 3. Dockerイメージのプライベートレジストリへの登録

#### 1. タグの設定

リポジトリにプッシュする前に、イメージにタグを付ける必要があります。

**書式:**
```sh
docker tag <元のイメージ名>:<元のタグ> <レジストリ>:<ポート>/<イメージ名>:<タグ>
```

例えば、以下のようにタグを付けます。

```sh
docker tag my-image:latest <server-ip>:5000/my-image:latest
```

#### 2. リポジトリへプッシュ

タグ付けしたイメージをレジストリに登録します。

```sh
docker push <server-ip>:5000/my-image:latest
```

#### 3. 登録確認

プライベートレジストリに登録されたイメージを確認するには、以下のコマンドを実行します。

```sh
curl http://<server-ip>:5000/v2/_catalog
```

登録済みのイメージリストが表示されます。

---

### 4. Dockerクライアントからの利用

#### 1. `docker-compose.yml`の作成

Dockerクライアントからプライベートレジストリのイメージを利用するために、`docker-compose.yml`を作成します。

```yaml
services:
  my_server:
    image: <server-ip>:5000/my-image:latest
    container_name: <container-name>
    restart: unless-stopped
    environment:
      - TZ=Asia/Tokyo
    privileged: true
    command: /sbin/init
```

#### 2. コンテナのビルドと起動

以下のコマンドを実行し、コンテナをビルド・起動します。

```sh
docker-compose up -d --build
```

ビルドが成功し、コンテナが起動すれば完了 🚀
【SAP】SE16N　デバッグモードでのテーブルデータ登録手順

１．T-code：SE16N を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/93de43ba-c7a8-423e-9397-399488bd9a8d.png)

２．T-code：/h を実行（デバッグモード起動）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/a5eff215-9088-4d1a-add8-6ed195c54f03.png)

按一下enter键，进入debug画面，然后右下侧红框里面入力对应的信息。如下一步。
変数 「GD_EDIT」＝ X、「GD_SAPEDIT」＝ X　を設定
変数 「GD_EDIT」、「GD_SAPEDIT」を入力し、変更ボタンをクリック

※两个X一定要是大写，写完之后点enter。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/80380621-a6c3-4ac5-95f4-c4ba6c7b0a07.png)

3．F8 を押すと、SE16Nの画面に戻ります。
※F8或者左上角的图标。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/2580f2ef-11c3-4300-82fc-dee7c374eb31.png)

4．新規登録ボタン・挿入ボタン・削除ボタンが表示されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/03393a29-1ea3-47ad-be3f-7b193763af23.png)
vite typescript vuejsで@/でsrc配下が補完されない

# vite typescript vuejsで@/でsrc配下が補完されない

## 確認すべき点のまとめ
* tsの場合```include[]```の文言を```tsconfig.json```へ追加
* jsの場合プロジェクト直下に```jsconfig.json```を追加

以上で私の場合は@/が補完されるようになりました。


## vscodeの拡張機能をinstall
* Vue Language Features (Volar)
* TypeScript Vue Plugin (Volar)

### ts使わないパターン
#### vscodeの設定ファイルに追記（必要かよくわかってないが手順としてやったので一応メモ）
```jsonc:.vscode/settings.json
{
    // ...
    //@補完が聞くように
    "typescript.tsdk": "node_modules/typescript/lib",
    "editor.quickSuggestions": {
      "strings": true
    },
    "javascript.suggest.paths": true,
    "typescript.suggest.paths": true,
    
    "typescript.preferences.importModuleSpecifier": "shortest",
    "javascript.preferences.importModuleSpecifier": "shortest",
    "eslint.validate": ["javascript", "javascriptreact", "vue"],
    "editor.formatOnSave": true,

    "recommendations": ["Vue.volar"]
    // ...
}
```

#### プロジェクト直下にjsconfig.jsonの作成
* 私のプロジェクトの場合下記構成になっています。
* Djangoとvueを一つのプロジェクトフォルダにまとめています。
* 各環境に読み解いてください。

```
project
 L frontend
    L src
    L jsconfig.json //本来vueプロジェクトを作るとここに作られる
 L backend
 L jsconfig.json //※プロジェクト直下のここに追加
``` 

#### jsconfig.json(tsを使わない場合）
``` jsonc:project/jsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".", // .をベースパスに設定
    "paths": {
      "@/*": [
        "frontend2/src/*"
      ] // @/はvuejs/frontend2/src/を指す
    }
  },
  "include": [
    "frontend2/src/**/*"
  ] // srcフォルダ内の全ファイルを含める
}
```

## typescriptの場合はこうでした・・・

``` jsonc:.vscode/settings.json
{
  // ...
  "typescript.tsdk": "frontend/node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "editor.quickSuggestions": {
    "strings": true
  },
  "typescript.suggest.paths": true,
  "javascript.suggest.paths": true,
  "volar.tsPlugin": true,
  "volar.tsPluginStatus": true
  // ...
}
```


```
project
 L .vscode
    L settings.json
 L frontend
    L src
    L tsconfig.json //本来vueプロジェクトを作るとここに作られる
 L backend
 L tsconfig.json //こいつが別になくても動いた・・・なぜ・・・
``` 

### ということでフロントエンド直下のtsconfig.jsonをせってい
``` jsonc:frontend/tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "types": ["vuetify"]
    // 他の設定...
  },
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "include": [ //こいつがキー設定だった！！！
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ]
}

```

なんとかこれで動くはずです！！！！
オブザイヤー表彰式を開催したらチーム全体のモチベーションが上がりました

## はじめに
皆様の会社の決算時期はいつでしょうか？
3月決算の会社が多いと思いますが、私たちポーラ・オルビスグループは12月決算です。
そこで、昨年度末に1年の締めくくりとしてチーム内でオブザイヤー表彰式を行ってみました！
初めて行った取り組みだったのですが、メンバー全員が良い気分で期末を迎え、来年も頑張るぞ！という気持ちになれたのでご紹介します！
3月決算の皆様もそうでない方も、是非期末に試してみてください！


## オブザイヤー表彰の目的
各々頑張っていた領域を認められてうれしい気持ちで年を越し、来年に向けてさらに意欲を高めることを目的としています:arrow_upper_right:
また、他の方がオブザイヤーとして評価された領域についても学び、すごかったねーだけでなく『自分も来年は真似して挑戦してみよう！』と思えるようになることも目指して企画しました。

企画にあたって、一部メンバーに対してベストプレイヤーみたいなのを決めると『自分も頑張ったのに…』という気持ちになる恐れがあるなと思いました。
そのため、その人が一番輝いていた(頑張っていた)点を○○オブザイヤーとして表彰し、チームメンバー全員が受賞者となる形式にしました:trophy:
賞に対して人を選出するのでなく、人に対して賞を設定して表彰するイメージです！


## 進め方
対象者は私たちITプロダクト開発チーム社員6名全員です。
普段、人から褒められる機会が少なくて悲しいので、メンバーだけでなくチームリーダーである私も対象に入れてもらいました:joy:

手順は以下のステップです！
:one:オブザイヤーノミネート
　一年を振り返って、自分以外のチームメンバー全員に対して○○オブザイヤーの名前を付けて提出します。
　ノミネートに関しては他のメンバーの意見に引っ張られず各自で考えてほしかったので、ノミネート案とその理由をDMで提出してもらいました。
:two:投票
　各メンバーからノミネートされた○○オブザイヤー案を共有して投票を行いました。
　投票はSlackのオープンなチャンネルで実施しました。
　各メンバーのノミネートに対して一人一票投票し、多数決で受賞オブザイヤーを決定しました。
 　投票の基準は特に設けず、各々良いと思ったものを投票してもらいました。
:three:トロフィー作成
　物理的なトロフィーを作るにはお金がかかるので、Copilotにお願いして各賞にふさわしいモチーフのトロフィーの絵を描いてもらいました。
:four:オブザイヤー表彰式
　チームMTGで受賞オブザイヤーを発表し、各メンバーから受賞コメントをもらいました。

## オブザイヤーノミネートの注意点
各メンバー自由に考えてほしいなと思う一方、個性を出してほしかったので下記のようなルールにしました。
あまり明確なルールではないのでニュアンスを感じていただければと思います:cloud:

:x:　NG例　:x:
・スクラムマスターオブザイヤー(ポジションそのままだとあまり面白みがない)
・がんばったオブザイヤー(具体的にどんな行いを表彰されているか分からない)

:o:　OK例　:o:
・コード書いたオブザイヤー
・わくわくオブザイヤー
具体的な行動をそのまま表現、もしくは少し概念的なキーワード設定を推奨して個性的な名前になるようにしました！

## トロフィーの作成方法
https://qiita.com/mizuki_jessie_POHD/items/f788e8651bdc45498ebc

こちらの記事でCopilotの画像生成のお世話になりましたが、今回も画像生成をお願いしました。
各賞にふさわしいモチーフを事前に考え、「○○オブザイヤー受賞トロフィーの絵を描いてほしい」「○○のモチーフにしてほしい」等をお願いして自分のイメージに近い画像を生成してもらいました。
「背景キラキラの華やかなデザインにしてほしい」というお願いを追加することで背景を含めてゴージャスな絵になり、気分が上がるのでおススメです。
実際に作成した際のプロンプトとトロフィーはこんな感じです:trophy:
こちらはのびのびオブザイヤーのトロフィーです:bird:

```
のびのびオブザイヤー受賞トロフィーの絵を描いてください。「NOBINOBI OF THE YEAR」の文字を入れてください。翼のモチーフ。おしゃれで華やかなデザイン。背景はキラキラ。
```
![画像1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739961/c629883b-9296-4dac-8bca-01f328e59f64.jpeg)



## 良かったこと
自分が頑張ったことを他メンバーから称賛されたことでモチベーションアップに繋がり、非常に効果のある取り組みだったと思います:clap:
お互いの良い点を称賛し合う風土を形成できたこともチームビルディングの点で効果があったと感じます:sparkles:

私自身も自分の良い行いを5点もあげてもらえてとても気分が良かったです:blush:
匿名性なのでノミネート案が被り5点にならないこともありましたが、複数のメンバーに特定の取組を認めてもらえたことで自分の強みとして自信に繋がるという点では効果があると思いました！

個人的には、ただオブザイヤーを発表するだけでなくトロフィー(絵ですが)をお渡しできたのは受賞した気分を味わえて更に効果があったかなと思います:musical_note:
運営する側としても楽しく進められました！

## 課題等
今回は6人で行いましたが、人数が多いと全員分考えるのも大変なので大きな組織での実施は難しそうだなと思いました:sweat_drops:
また、自分が頑張っていたと思っている点が表彰されなかった場合に少しがっかりしてしまうことも懸念されます。
ですが、それ以上に褒められて嬉しい気持ちの方が大きいと思うのであまりマイナス効果にはならないかなと思います！


## おわりに
今回はITプロダクト開発チーム内のオブザイヤー表彰の目的や方法をご紹介しました。
さらに具体的にイメージしていただくために、私たちのチームで実際にノミネートされたオブザイヤー案や表彰した結果等をこちらでご紹介します！
是非こちらもご覧ください:eyes:

https://qiita.com/hayakawa_POHD/items/445f874c3e39ee5fac09
譲渡アプリ受取後の署名エラー

## エラー
iCloud KVS使用の譲渡アプリを受取後に、以下のようなエラーが出たときの解決方法です。
>Provisioning profile "iOS Team Provisioning Profile: [BUNDLE ID]" doesn't match the entitlements file's value for the com.apple.developer.ubiquity-kvstore-identifier entitlement.

## 解決方法
`entitlements`の`iCloud Key-Value Store`の値を`<譲渡した側のチームID>.<Bundle ID>`にすればよい。

![Screenshot 2025-03-03 at 15.37.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328477/f59617bf-66d5-4423-aa2e-897d8a37232f.png)

### 譲渡した側のチームIDがわからなければ
1. `~/Library/Developer/Xcode/userdata/provisioning profiles`にある当該プロジェクトのプロビジョニングプロファイルを探す
2. 見つけたプロビジョニングプロファイルをQuick Lookで開く（ファイル選択してスペースキー）
3. その中の`com.apple.developer.ubiquity-kvstore-identifier`キーの値を`entitlements`にコピペ
[PostgreSQL][PHP][Vue]お手頃アプリ作成

# 認証無しのAPIでデータ取ってきて画面に表示するだけの簡単なシステム
の、ためだけにわざわざローカル環境にApache・PHP・Node・DB入れるとかめんどくせ～（ものぐさ

そんな時は。。。

# そう、DevContainerだね
環境としてはこちら
- PHP：8.3
- PostgreSQL：16

設定ファイルはこちら
```jsonc:devcontainer.json
{
	"name": "passport-inquiry",
	"image": "mcr.microsoft.com/devcontainers/php:1-8.3-bullseye",

	"forwardPorts": [
		8080, // Apache
		5173 // vite
	],
	"features": {
		"ghcr.io/itsmechlark/features/postgresql:1": {
			"version": "16"
		},
		"ghcr.io/devcontainers-extra/features/vue-cli:2": {
			"version": "latest"
		}
	}
}
```

ベースはPHPで、ポスグレとVueCliを一緒に入れてる感じです。
※正直VueCliはプロジェクトを作るために入れた感じですが既にローカルとかでプロジェクト作成されている場合はなくてもいいと思ってる。
→PHPかポスグレ入れたタイミングでNodeが付属されているため

この構成で入れるとApacheがPHPに付属してきて、localhost:8080からアクセスできるようになります。

# じゃあ作ってくか。。。
色々と設定を変えれば簡単にできると思うけど、その設定を調べるのも面倒くさいので、ビルド後の配置はコマンドゴリゴリでやるための構成です。
自分で使う時はvite.configやPHPソースの場所、マウントするフォルダなどを色々と切り替えて考えて行ってね！

フォルダ構成はこんな感じ
![スクリーンショット 2025-03-03 152549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/996378/087e94c9-e855-43b4-886d-bccb66a850ef.png)

phpフォルダには名前の通り、PHPのバッチとか共通的なクラスとかFunctionを格納する。
vueフォルダはVueプロジェクトのルートフォルダとなります。

# 公開（ローカルブラウザ）で見るためには？
内包されているApacheのDocrootがデフォルトだと「/var/www/html」になるので、vue資源をビルドして出来るdistフォルダの中身を　/var/www/html　にコピーすればよろし。

PHP製のAPIを追加するとかであれば、
phpフォルダ内にapiフォルダを作ってそこで実装し　/var/www/html　にコピーする。
またはvueプロジェクトしたのpublicフォルダ下にapiフォルダを作ってそこで作ってビルドすればdistにそのままコピーされるため、vueの資源と一緒に　/var/www/html　にコピーすればいいだけになるね。

ちなみにviteだけでの起動も出来るため、いちいちビルドがめんどくせぇって時はviteで立ち上げておいて、localhost:5173をブラウザで開くのもよろし。
→そのためにDevContainerの設定JSONのforwardPortsにポート指定してある


こんな感じで「ちょっとこんな感じの案件が有るんだけど。。。」みたいな時のプロトを作る際の手間をちょっとでも減らせればということで記事化してみた。

ね、簡単でしょ？
AHK✕クリップボード｜コピペを利用して文字列整理の実施について｜小さな業務改善に向けて

```
F1::
Send {Ctrl down}c{Ctrl up}  ; Ctrl+Cでコピー
Sleep 100                   ; 少し待機（クリップボードが更新されるのを待つ）
Send {Ctrl down}v{Ctrl up}  ; Ctrl+Vで貼り付け
return
```
```
F2::
Clipboard := ""             ; クリップボードをクリア
Send {Ctrl down}c{Ctrl up}  ; コピー
ClipWait 1                  ; クリップボードにデータが入るのを待つ
Clipboard := "[" Clipboard "]"  ; 前後に「[」「]」を追加
Send {Ctrl down}v{Ctrl up}  ; 貼り付け
return
```

```
; ホットキー Ctrl+Shift+V で実行
^+v::
ClipboardOld := ClipboardAll  ; 現在のクリップボード内容を保存
Clipboard := ""               ; クリップボードをクリア
Send ^c                       ; コピー操作（選択中のテキストをコピー）
ClipWait, 1                   ; クリップボードにデータが入るのを待つ
if (ErrorLevel = 0)           ; クリップボードにデータがあれば
{
    Num := Clipboard          ; クリップボードの内容を取得
    if Num is number          ; 数値かどうかを判定
    {
        Result := Num * 0.0174533        ; 10を足す処理
        Clipboard := Result   ; 結果をクリップボードにセット
        MsgBox, % "元の値: " Num "`n新しい値: " Result  ; 確認メッセージ（任意）
    }
    else
    {
        MsgBox, クリップボードの内容は数値ではありません。
        Clipboard := ClipboardOld  ; 元のクリップボード内容を復元
    }
}
else
{
    MsgBox, クリップボードにデータがありません。
    Clipboard := ClipboardOld  ; 元のクリップボード内容を復元
}
return
```

```
; ユーザー入力待ち（Ctrl+J）
^j::
; コマンドを格納する連想配列（毎回初期化）
commandMap := {}

; CSV を読み込む（毎回実行）
Loop, Read, commands.csv
{
    line := A_LoopReadLine
    StringSplit, fields, line, `,
    commandMap[fields1] := fields2
}

; 入力に応じたコマンドを取得
InputBox, userInput, 入力待ち, キーワードを入力してください, , , , , , , , 
if ErrorLevel
    return

command := commandMap[userInput]
if (command = "")
{
    MsgBox, 対応するコマンドが見つかりません: %userInput%
    return
}

; 即時実行
RunCommand(command)
return

; コマンドを実行する関数
RunCommand(cmd) {
    StringSplit, commands, cmd, `;  ; `;` で区切る
    Loop, %commands0%  ; 分割されたコマンド数だけ繰り返す
    {
        currentCmd := Trim(commands%A_Index%)  ; 現在のコマンド（余分な空白を削除）
        if (SubStr(currentCmd, 1, 5) = "Send ")
        {
            action := Trim(SubStr(currentCmd, 6))
            if (RegExMatch(action, "^{.*}$"))  ; {文字列} の形式
            {
                StringReplace, action, action, {, , All
                StringReplace, action, action, }, , All
                ; 特殊キーの場合は Send を使い、それ以外は SendRaw
                if (action = "Home" || action = "End" || action = "Enter" || action = "Tab" || action = "Up" || action = "Down")
                {
                    Send {%action%}  ; 特殊キーとして送信
                }
                else
                {
                    SendRaw %action%  ; それ以外は生の文字列として送信
                }
            }
            else
            {
                Send %action%  ; キーコマンドとして実行
            }
        }
        else if (SubStr(currentCmd, 1, 4) = "Run ")
        {
            action := SubStr(currentCmd, 5)
            Run %action%
        }
        else
        {
            SendRaw %currentCmd%
        }
        Sleep, 200  ; コマンド間に少し待機（安定性のため）
    }
}
```
XserverでどうやってもSSH接続できない… → PC再起動したら治った

## 現象
XserverにSSH接続しても "Connection refused" エラーになってしまう。

- ホスト名指定もあっている
- ポートも10022を指定している
- パーミッションも .ssh を700、 秘密鍵も600に設定済み
- 秘密鍵にパスフレーズを設定しているが、そもそもパスフレーズ入力画面が出てこない

``` ~/.ssh/config
Host xserver
    HostName svXXXXX.xserver.jp
    User ユーザー名
    Port 10022
    IdentityFile ~/.ssh/XXXXXX.key
    ServerAliveInterval 60
```

## 解決法
再起動して再度SSH接続を試みると、パスフレーズが求められて解決。
AmplifyのNext.js SSR環境でIAM ロールを設定する方法


## **概要**
- Amplify の SSR 環境で Amazon SDK をセキュアに設定する方法
- Amplify のコンピューティングに対して IAM ロールを設定する方法

## **今回の障害**
- Amazon Bedrock SDK を Amplify の SSR 環境から接続したいが、アクセスキーやシークレットキーは設定したくない
- ローカル環境では SSO により認証情報が取得され、問題なく実行できる
- ステージング環境などのデプロイ環境では `CredentialsProviderError: Could not load credentials from any providers` というエラーが発生する

## **解決方法**

### **1. IAM ロールを作成する**
1. IAM > ロール > 新しいロールを作成
2. 信頼されたエンティティの種類 → **AWS サービス**
4. カスタム信頼ポリシーを追加

    ```json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": [
                        "amplify.amazonaws.com"
                    ]
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    ```

5. 必要な権限を追加（使用するリソースは適宜調整）

    ```json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "bedrock:InvokeModel"
                ],
                "Resource": "*"
            }
        ]
    }
    ```

---

### **2. Amplify のコンピューティングに作成した IAM ロールを追加**
1. Amplify の管理画面を開く
2. [すべてのアプリ] > 該当のアプリ > [アプリケーションの設定] > [IAM ロール] に移動
3. コンピューティングロールを編集
4. デフォルトのロールに先ほど作成した IAM ロールを選択し、保存
   - ブランチごとに IAM ロールを選択可能
   - デフォルトではすべてのブランチがこのロールを使用するため、他の SDK を使いたい場合は IAM ロールを分けると便利

---

## **Issue**
[GitHub Issue - AWS Amplify Hosting](https://github.com/aws-amplify/amplify-hosting/issues/3205)

## **リリース情報**
- **2025年2月18日** にリリースされた模様
- [チュートリアル](https://aws.amazon.com/jp/blogs/mobile/iam-compute-roles-for-server-side-rendering-with-aws-amplify-hosting/)

---

これで、Amplify の SSR 環境から Amazon Bedrock SDK をセキュアに利用できるようになります！ 🎉
Chartjsマウスポインタをあわせたときの縦軸に線を引く設定

# how to

## 必要な設定

```graph.vue
import { crosshairPlugin } from '../common/crosshairPlugin'

// Chart.js の設定を初期化
ChartJS.register(
  Title,
  Tooltip,
  Legend,
  LineElement,
  PointElement,
  CategoryScale,
  LinearScale,
  Filler,
  crosshairPlugin,　　　　//今回必要なのはこいつ
)
```


## common配下にpluginを作成（正直場所はどこでもいい）
```common/crosshairPulugins.ts
import { type Plugin } from "chart.js";

/**
 * クロスヘアプラグイン
 * マウスオーバー時に、X軸とY軸に沿った線を描画するプラグイン
 * @param {Object} options - オプション
 * @param {Object} options.line - 線の設定
 * @param {string} options.line.color - 線の色
 * @param {number} options.line.width - 線の太さ
 * @param {Array} options.line.dashPattern - 破線のパターン
 * @param {Object} options.sync - 同期設定
 * @param {boolean} options.sync.enabled - 複数のチャート間で同期する場合に使用
 * @param {Object} options.xLine - X軸に沿った線の設定
 * @param {boolean} options.xLine.enabled - X軸に沿った線を描画するかどうか
 * @param {Object} options.yLine - Y軸に沿った線の設定
 * @param {boolean} options.yLine.enabled - Y軸に沿った線を描画するかどうか
 * @returns {Object} プラグイン
 * 
 */
export const crosshairPlugin: Plugin = {
  id: "crosshair",
  defaults: {
    line: {
      color: "rgba(0, 0, 0, 1)",
      width: 1,
      dashPattern: [5, 5],
    },
    sync: {
      enabled: true, // 複数のチャート間で同期する場合に使用
    },
    xLine: {
      enabled: false,
    },
    yLine: {
      enabled: true,
    },
  },
  afterDraw: (chart, _, options) => {
    // getActiveElements() メソッドを使用して、アクティブな要素を取得
    const activeElements = chart.getActiveElements();
    if (!activeElements.length) return;
    const activePoint = activeElements[0];
    const { ctx } = chart;
    const { top, bottom } = chart.chartArea;
    const x = activePoint.element.x;

    // Y軸の線を描画
    if (options.yLine.enabled) {
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x, top);
        ctx.lineTo(x, bottom);
        ctx.lineWidth = options.line.width;
        ctx.strokeStyle = options.line.color;
        ctx.setLineDash(options.line.dashPattern);
        ctx.stroke();
        ctx.restore();
      }
  },
};


```
Terraform 入門："Failed to load plugin schemas"でTerraformのプラグインスキーマ読み込みエラーと解決方法

## はじめに
Terraformを使用中に「Failed to load plugin schemas」のエラーが発生しました。

:::note alert
***このエラーは、TerraformがAWSプロバイダのスキーマをロードできず、プラグインの起動に失敗していることを示しています。***
:::

さまざまな対処法を試しましたが、最終的に端末の再起動で解決しました。本記事では、エラーの発生状況と解決策について解説します。

## エラーの発生状況
このエラーは、TerraformでAWSプロバイダを使用しようとした際に発生しました。

```実際のエラー.log
│ Error: Failed to load plugin schemas │ │ Error while loading schemas for plugin components: Failed to obtain provider schema: Could not │ load the schema for provider registry.terraform.io/hashicorp/aws: failed to instantiate provider │ "registry.terraform.io/hashicorp/aws" to obtain schema: timeout while waiting for plugin to │ start..
```

Terraformがプラグインのスキーマをロードできず、プロバイダのインスタンス化に失敗していることが示されています。

## 試した対処方法
1. **terraform initの再実行**
   ```sh
   terraform init -reconfigure
   ```
   → 解決せず

2. **terraform providers schema -json の実行**
   ```sh
   terraform providers schema -json
   ```
   → 同じエラーが発生

3. **terraform plugin cacheのクリア**
   ```sh
   rm -rf .terraform/plugins
   terraform init
   ```
   → 解決せず

4. **端末の再起動**
   ```sh
   sudo reboot
   ```
   → **解決！**

## 原因の考察（あくまで個人推測レベル）
このエラーは、Terraformのプラグインプロセスの起動がタイムアウトしていることが原因と考えられます。

プラグインの起動に失敗する原因として、以下のような要因が考えられます。
- システムのリソース不足（メモリ、CPU使用率が高い）
- 一時的な環境の不整合（プロセスが正常に終了していないなど）
- Terraformのプラグインが適切にキャッシュされていない

再起動によって、これらの問題が解消され、Terraformのプラグインが正常に動作するようになったと考えられます。

## まとめ
Terraformを使用していて「Failed to load plugin schemas」のエラーが発生した場合、まずは以下の手順を試してみてください。
1. `terraform init -reconfigure` の実行
2. `.terraform/plugins` の削除と再 `init`
3. 端末の再起動（最も効果的）

特に、環境によってはTerraformのプラグインが正しく動作しないことがあるため、最終的にシステムの再起動が有効な解決策となる場合があります。
スクリーンショットの縦横比がおかしい（マルチウィンドウ）

# 出来事
Widnows11にアップグレードしたら、スクリーンショットの縦横比がおかしくなった。

# 事象
ノートPC + ディスプレイ1台で作業している。
ノートPC側でスクショを撮ると、画面すべてをスクショできず、縦横比もおかしい。
ディスプレイ側でスクショを撮ると、正常にスクショできる。

# 調査したこと
ネットを調べると、ディスプレイの倍率を100%で統一するすれば直ると書いてあった。
試したところ確かに直ったが、ディスプレイの倍率を100%にすると、文字が小さくなったりして大変だった。
正直これなら、ディスプレイ側でスクショを撮るようにした方がマシである。

# 解決法
ディスプレイの設定より、２つのディスプレイの下のラインを揃えることで直った。

↓つまりこれを

![{24D38F01-55FF-4263-8D4C-CDB0EE639F79}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612369/c298469c-69fd-4302-9b66-a34d249e8dea.png)

↓これにしたら直った。

![{736CEAAB-18D3-411B-B577-153040119BC8}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612369/b1da6203-0987-400f-91af-ddc4f61bbd50.png)

# 感想
理由は分からない。
ただし、ディスプレイの配置で下のラインを揃えることで修正された。

まあ、正直これはこれで使い勝手が悪いんだけど、ディスプレイの倍率いじるよりはマシなので、良かったら参考にしてほしい。
Nginx②静的コンテンツの配信方法

## はじめに
Nginxを使用した静的コンテンツの配信をローカル環境で手軽に体感することを目的としておりますので、Nginxに初めて触れる方向けの内容となっております。

## 環境
* nginx-1.26.3
* Ubuntu 24.04

## 静的コンテンツの配信方法
1. `index.html`の作成
2. 設定ファイルの作成
3. 設定を有効化
4. `/etc/nginx/nginx.conf`の修正
5. `/etc/nginx/conf.d/default.conf`を`/etc/nginx/sites-available`に移動
6. 設定テスト
7. 設定の反映&Nginxの再起動

## index.htmlの作成
すでに作成されている場合は飛ばしていただいて結構です。
`index.html`の中身は何でも大丈夫です。
```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Nginx Site</title>
</head>
<body>
    <h1>Welcome to my Nginx site!</h1>
    <p>This is a sample page served by Nginx.</p>
</body>
</html>
```

## 設定ファイルの作成
```
sudo mkdir -p /etc/nginx/sites-available
sudo vim /etc/nginx/sites-available/default
```
設定ファイル内に記述すること
```
server {
    listen 80;
    server_name localhost;

    # リクエストされた際にドキュメントがある場所
    root /path/to/static/files;
    # リクエストを受けた際に提供するファイル名
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
```
### 注意点
rootのディレクトリ名にスペースや特殊文字などを含む場合、パス全体をダブルクォート`" "`で囲みます。

## 設定を有効化
```
sudo mkdir -p /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
```
`sites-available/`にある設定を`sites-enabled/`にシンボリックリンクで適用

## /etc/nginx/nginx.confの修正
```conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
```
最後の行に`include /etc/nginx/sites-enabled/*;`を追加します。
`/etc/nginx/sites-enabled/`内にあるすべての設定ファイルをNginxの設定に組み込むことができるようになります。

## `/etc/nginx/conf.d/default.conf`を`/etc/nginx/sites-available`に移動
```
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/sites-available/
```
### `/etc/nginx/sites-available`に移動する理由
`/etc/nginx/conf.d/default.conf`に`server_name localhost;`が含まれており、それが原因で他の設定が適用されなくなることがあるからです。

## 設定テスト
```
sudo nginx -t
```
`syntax is ok`と表示されれば問題ないです。

## 設定の反映&Nginxの再起動
```
sudo systemctl reload nginx
sudo systemctl restart nginx
```
## 補足:`sites-available`と`sites-enabled`で分ける理由
`/etc/nginx/sites-available`はすべての設定ファイルを保存し、`/etc/nginx/sites-enabled`は実際に有効化された設定のリンクを保存することで、サイトの有効化・無効化を簡単に管理するためです。

## まとめ
以上で、静的コンテンツを表示できました。
Next.js エラー事象 Hydration failed because the server rendered HTML didn't match the client.

# Hydration failedの解決について
備忘録で残すシリーズ

**そもそも原因**
Hydration エラーは「SSR で出力された HTML と CSR での HTML が違う場合」に発生する
→サーバー側とクライアント側で描画される情報に不一致が生じるのでエラーになる


# エラーが起きたコード
クライアントが利用しているブラウザによって変化させたい項目があった。
``` javascript
import { useEffect, useState } from "react";

export default function Home() {
  const [preLink, setPreLink] = useState("");

  useEffect(() => {
    // ユーザーエージェントでブラウザ判定
    const userAgent = navigator.userAgent;

    if (userAgent.includes("Chrome") && !userAgent.includes("Edg")) {
      // Chrome なら Edge で開くスキームを使用
      setPreLink(microsoft-edge:);
    } else {
      // Edge またはその他のブラウザでは通常の URL
      setPreLink("");
    }
  }, []);

  return (preLink)
}

```

発生したエラー
```
Hydration failed because the server rendered HTML didn't match the client. 
As a result this tree will be regenerated on the client. 
This can happen if a SSR-ed Client Component used
```
# エラー解消コード
解決方法
useStateの初期状態をnullに

``` javascript
import { useEffect, useState } from "react";

export default function Home() {
  //ここを更新、初期状態を null に
  const [preLink, setPreLink] = useState<string | null>(null); 

  //SSR ではuseEffectが無視される
  useEffect(() => {
    // ユーザーエージェントでブラウザ判定
    const userAgent = navigator.userAgent;

    if (userAgent.includes("Chrome") && !userAgent.includes("Edg")) {
      // Chrome なら Edge で開くスキームを使用
      setPreLink(microsoft-edge:);
    } else {
      // Edge またはその他のブラウザでは通常の URL
      setPreLink("");
    }
  }, []);

  return preLink;
}
```

# 原因と解決方法（ざっくり）
### 原因
Hydration エラーは「SSR で出力された HTML と CSR での HTML が違う場合」に発生する
→サーバー側とクライアント側で描画される情報に不一致が生じるのでエラーになる

### なぜ解決できるか
**SSR では null を返して何も描画しないという特徴を活かす。**

**SSRではnull、CSRで任意の文字列となった場合、対象の要素は新規の要素として判定されるためこれらは矛盾と判定されない。**


SSR で null だった場合、そもそも HTML がないので、存在しない要素となる。
これにより、setStateで更新された要素は、「**クライアント側で新しく追加された要素**」として処理される。
→Next.js の Hydration（SSR と CSR の照合） で競合しない

つまり
**SSRではnull、CSRで任意の要素となった場合、新規の要素として判定されるためこれらは矛盾と判定されない。**

### 今回の解決方法
SSR では null を返し、SSR時点で HTML を生成しないことで、Hydration エラーを防ぐ。
zipファイルの解凍

Sub ExtractAndUnzipAttachment()
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim doc As NotesDocument
    Dim rtitem As NotesRichTextItem
    Dim embeddedObjects As Variant
    Dim obj As NotesEmbeddedObject
    Dim filePath As String
    Dim outputFolder As String
    Dim command As String
    Dim zipFound As Boolean

    ' データベースと文書を取得（適宜変更）
    Set db = session.CurrentDatabase
    Set doc = db.GetDocumentByUNID("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") ' 文書AのUNIDを指定

    ' 添付ファイルの取得
    If doc.HasItem("Body") Then
        Set rtitem = doc.GetFirstItem("Body")
        embeddedObjects = rtitem.EmbeddedObjects
        zipFound = False

        ForAll obj In embeddedObjects
            If (obj.Type = EMBED_ATTACHMENT) Then
                If (Right$(LCase(obj.Name), 4) = ".zip") Then
                    filePath = "C:\temp\" & obj.Name
                    Call obj.ExtractFile(filePath) ' ZIP を保存
                    zipFound = True
                    Exit ForAll
                End If
            End If
        End ForAll

        ' ZIP ファイルが見つかったら解凍
        If zipFound Then
            outputFolder = "C:\temp\Test"
            
            ' tar コマンドを実行して解凍
            command = |cmd.exe /C tar -xf "| & filePath & |" -C "| & outputFolder & |"|
            Call session.SendConsoleCommand("", command)

            MsgBox "ZIPファイルの解凍が完了しました: " & outputFolder
        Else
            MsgBox "ZIPファイルが見つかりませんでした。"
        End If
    Else
        MsgBox "本文に添付ファイルがありません。"
    End If
End Sub
Volta+Reactの環境構築

## 環境
* Ubuntu 24.04

## Reactの環境構築方法
1. Voltaのインストール
2. node.jsのインストール
3. Reactのプロジェクトの作成
4. Reactのプロジェクトの起動

## Voltaのインストール
```bash
sudo curl https://get.volta.sh | bash
exec $SHELL -l #シェルの再起動
```
Voltaのインストールが成功しているか確認します
```bash
volta -v
```
何かバージョンが表示されていましたら、成功です

## node.jsのインストール
```
volta install node
```

### node.jsのインストールに関する他のコマンド
```bash
# NodeのLTS版のインストール
volta install node

# 最新バージョンのインストール
volta install node@latest

# 特定バージョンのインストール
volta install node@14.15.4

# 14系の安定版のインストール
volta install node@14

# Volta管理下の各種バージョンの確認
volta list

# Voltaで管理しているツールの一覧確認
volta list all
```

## Reactのプロジェクトの作成
```bash
npx create-next-app my-app(任意の名前)
```

## Reactのプロジェクトの起動
```bash
# 先ほど作ったディレクトリに移動
cd my-app
# ローカル環境でプロジェクトをスタート
npm start
```
`http://localhost:3000/`にアクセスし、開発用のページが表示されます。

## まとめ
以上で、Reactの環境構築ができました。
LIFF(LINE)はiOS 16でのみ仕様に沿った動作をする、という話

サークル運営している友人の手伝いで、LIFFアプリと作っています。

例ですが、サイトはで表示され
https://example.jp/

LIFFのエンドポイントURL
https://example.jp/login
としていました。

この状態でも私のスマホで動かすと問題なく動いていました。
ただ主催も初めて開いたときはうまく動くけれど一度閉じるとしばらくaccess.line.meでBad Requestで開けなくなるようでした。

私のスマホやほか多くの人では問題なかったので、要因調査にかなり日数を要したのですが

https://developers.line.biz/ja/docs/liff/developing-liff-apps/#initializing-liff-app-notes

を読むと上記って動作保証外なのですね。

作り始めた当時には読んで違和感を持ってたような気もするのですが、事象との繋がりはみえず思い至りませんでした。

結果としては
LIFFのエンドポイントURL
https://example.jp/
として、それで動くようにサイト側も修正すると問題なく動作するようになったようでした。

AndroidやiOS 18の人たちでは同様の問題は発生しておらず、主催のスマホ(iOS 16)と他一人iOS 16でのアクセスログが同様の事象が発生していたのでiOS 16でのバグ※1かなぁ、、、と調査していたのですが結果としてはiOS 16でのみ仕様通り（？）動作しなくて、他では問題なく動作していた、という感じですね。

※1 iOS 16より低いものからのアクセスが確認できなかったので、より古いのだと同様に動作しない可能性はありそう
PL-900 (Microsoft Power Platform Fundamentals) 合格体験記

## はじめに
日々の業務で Power Apps や Power Automate に触れている初心者エンジニアが
PL-900 に合格するまでの勉強資料とスケジュールについて投稿します。

## 受験者経歴
29歳でIT分野に転職。転職してから2年経過。転職時にプログラミング知識はほぼ無し。
業務は Power Apps でのノーコードアプリ作成や Power Automate でのデータ処理など。
2年前にAZ-900とLPICについては取得済。
Power BI や Power Pages などについては現在もほぼ触れてこず。

## 勉強法
いろんな方の合格体験記や勉強法を読んできましたが私が行ったことは
**ひたすらUdemyの過去問を解く！！！！！**
これオンリーでやり過ごしました:zap:

## 試験出題範囲や試験時間
主な出題範囲は公式のドキュメントに記載があります。

https://learn.microsoft.com/ja-jp/credentials/certifications/resources/study-guides/pl-900#skills-measured-as-of-june-21-2024

> ・Microsoft Power Platform のビジネス価値を説明する
・Microsoft Power Platform の基本コンポーネントを特定する
・Power BI の機能を実証する
・Power Apps の機能を実証する
・Power Automate の機能を実証する
・Power Pages の機能を実証する
・Microsoft Power Platform の AI 作成エクスペリエンスについて説明する

私が受験した時は試験時間は45分間で出題数は40問弱ありました。
恐らく700点以上取れれば合格です。

テストセンターでの受験もしくはオンラインでの受験が可能です。

## 勉強時間と参考資料
受験日は 2025年1月29日でした。
Udemyの過去問は12月半ばに購入し、1月に入ってから本格的に追い込みをかけました。
過去問をひたすら解いて間違ったところは復習する、選択方式なので自信が無かった問題にはマークをつけておき、正解していたとしても解説を読み込む。
それの繰り返しです。
合計時間としては **`10時間`** くらいです。

ただ、私は業務上、`常日頃 Power Apps と Power Automate に触れていた`ためそこの分野については追い込むことなくいけました。
まったく Power Platform に触れたことない状態から勉強するとなると **`30時間`** くらいは見積もっていたほうが良いかなというのが体感です。

ちなみに私がUdemyで購入した過去問は以下になります。
Udemy全般で不定期にセールが行われているので時間に少し余裕があるのであれば安くなっている時が狙い目です！

https://www.udemy.com/course/2023pl-900-power-platform-fundamentals/?couponCode=KEEPLEARNING

模擬問題集が4つあるのですが、私はそれを4周して安定して合格点が取れるようにしてから試験に臨みました。
※Udemy内の合格基準は70%です。


## Microsoft Power Platform Virtual Training Dayを受講してバウチャーを発行する

https://www.microsoft.com/ja-jp/events/top/training-days/powerplatform#power-platform%E3%81%AE%E5%9F%BA%E7%A4%8E

不定期開催ではありますが、マイクロソフトのバーチャルトレーニングを受講すると受験料が半額になるバウチャーが発行されますので、試験勉強に加えて受験コスト削減に役立ててみてください。
以前は無料になってたのですが、今は50%になってしまいました...。

## 実際に受験してみて
率直な感想としてはUdemyの過去問だけではカバーしきれていないかなと思いました。

もちろん実際に Power Apps や Power Automate 、 Power BI に触れているとかなり有利になると思います。
Power BI に関して実際に触れていなかったので、問題集だけでは問題文の全体像のイメージが掴みづらかったです。

解答方法としては選択方式になります。
解答が複数ある場合もありますし、この構想を実現したい場合に適切なアプリは？などドラッグアンドドロップでケースを当てはめていく問題などもあります。
全部分からなくても部分点はもらえます。

最近では `Copilot（コパイロット）` に関する問題も出題されているのでそのあたりも押さえておくと安心だと思います。

## まとめ
Udemyの過去問題集は安定して80%以上をとれていると安心して臨めると思います！
基礎編をまんべんなく学べるのでPower Platformを勉強し始める方にはちょうどいい内容かなと感じました。
他の方も合格体験記など掲載されてますので、いろいろと参考にしてみるのもありだと思います！！
実際に私も他の方の体験記を色々読んでみました。
ぜひ、少しでも参考になればと思います！！
RPGツクールMZユーザー向けGitHubのススメ

RPGツクールでゲーム制作を行っていると、やはり不安になるのはPCストレージ故障による制作中のデータの喪失かと思われます。そこで、本稿では効率的で確実なバックアップ手段としてGitHubを用いたバックアップ&バージョン管理についてツクラー向けに解説していきます。
なお、**本稿は主にツクラーが自身の作品をGitHubで管理するための最低限の内容**となることをご了承ください。

# 1.GitHubとは
正確な説明はQiita内外にいくらでもあるし、ここではツクラーとして認識すべき内容のみを記載します。
- ソースコードの管理ができるサービス
- 内容を公開することも非公開で管理することも可能

さしあたり、上記２点を押さえておけばツクラーとして理解は十分です。

# 2.GitHubでツクール作品を管理するメリット
自分がGitHubを用いてツクール作品を管理するようになって感じたメリットは以下の通りです。
- 信頼性の高いバックアップ
- 変更履歴の確認
- 複数端末での開発の円滑化

## 2.1.信頼性の高いバックアップ
GitHubは超大手のサービスですので、早々無くなることは無いと考えられます。そのため、バックアップとして信頼性があります。

## 2.2.変更履歴の確認
RPGツクールMZがバージョン1.9.0になったことで、dataフォルダ内のjsonファイルの整形が可能になりました。これにより、GitHub内の変更履歴を確認することで、「あ、この時にあのスキルの火力を下げたんだった」とか「あのプラグインを入れてからこの事象が起きるようになったのか」といったことを見返すことができます。

## 2.3.複数端末での開発の円滑化
オンライン上のプロジェクトファイル（リモートリポジトリ）が常に最新状態に保たれ、これを容易にローカルに複製できるため、デスクトップPCとノートPCの2台を使い分けて開発する人などには大変おすすめです。

# 3.GitHubの使い方

1. GitHubにアクセスする（ツクラー向け）
https://github.com/
1. Sign Upを選択し、画面の指示に従ってアカウントを作成する
1. GitHubデスクトップをインストールする
https://docs.github.com/ja/desktop/installing-and-authenticating-to-github-desktop/installing-github-desktop
1. インストールし、起動したら先ほど作成したアカウントでログイン
1. Create New Repositoryを選択
1. 保存場所や名前を設定してCreate Repository
1. 保存場所に設定したフォルダにツクールのプロジェクトフォルダをコピー
1. 画面左下のSummaryに更新内容を書き、Commit to mainをクリック
1. Publish Repositoryをクリック
1. Keep this code privateのチェックマークを入れたままPublish Repositoryをクリック

以上でGitHubへ自作ゲームのバックアップが完了します。

ゲームに変更を行った場合はCommit to mainとPush Origin（先ほどの手順のPublish Repositoryの位置に出るボタン）で更新したものを反映してください。

※参考
https://www.kagoya.jp/howto/it-glossary/develop/githubdesktop/

## 3.1.commitとpush

### commitとは
commitとは変更の一区切りです。データベースを設定した。マップをひとつ作ったといった区切りのたびにcommitするといいでしょう。

### push
pushはcommitした変更内容をオンライン上にあるデータへ反映することです。その日の作業を終えた時などに行うといいでしょう。

## 3.2.端末買い換え時など
新しい端末を購入し、RPGツクールとGitHub Desktopをインストールした際の作業についてです。

1. GitHub Desktopを起動する
1. Clona a repository from the Internetを選択する
1. 以前作成したリポジトリを選択する

以上で新しい端末にも最新のプロジェクトファイルを複製することができます。便利ですね。

# 4.まとめ
GitHub Desktopでツクールのプロジェクトを管理し、皆様もよいツクラーライフを！
【ChatGPT＋DALL-E3】簡単なPromptから画像生成AI用のPromptを生成するPromptGeneratorを作りました。


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

　今回は、簡単なPromptから画像生成AI用のPromptを生成するPromptGeneratorを作りました。

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

　今回は、
　　簡単なPromptから
　　　DALL-E3用のPromptを生成する
　　　　PromptGeneratorを作りました。

　こちらの“かいちのAI大学”さんの
　　YouTube動画を参照しました。
　　　[【知らないと損】生成AI×画像生成すごい使い方5選【ChatGPT、チャットGPT】](https://youtu.be/gnypjdGbU58?si=1PHzPBnagdytU1HG)

　この動画では、下記２点がポイント。

　・Promptの基本的な構造
　　　スタイル指定
　　　対象物
　　　対象物の特徴
　　　対象物の動き
　　　背景要素

　・Promptは、
　　　ヤムル（YAML）形式で書く

　ヤムル（YAML）形式とは
　　こんな形のものです。
```Text:ヤムル（YAML）形式のサンプル
スタイル: "リアルな写真"
対象物: "黒猫"
特徴: "青い目、ふわふわの毛"
動き: "座っている"
背景: "月明かりの下の森"
```

　今回、作成した
　　PromptGeneratorは、
　　　簡単なPrompt
　　　　（上で言うと“黒猫”）を
　　　　　上のサンプルのような
　　　　　　Promptにします。

　そのPromptを使って
　　描画すれば、
　　　いいだけです。

　もちろん、
　　出力されたPromptを修正する
　　　ということもできます。
***
　PromptGeneratorの使い方は、
　　下記Promptを入力送信して、
　　　次の入力で、簡単なPromptを
　　　　入力して送信するだけです。

　PromptGeneratorは
　　継続して働いていますので、
　　　出力されたPromptをコピーして
　　　　別セッションでの描画をすれば
　　　　　毎回PromptGeneratorを
　　　　　　入力する必要が
　　　　　　　ありません。

　では、PromptGeneratorのPromptです｡
```Text:
あなたは優れたヤムル（YAML）フォーマットのプロンプトジェネレーターです。ユーザーが指定する簡単なプロンプト（例: "黒猫" や "未来都市"）を受け取り、それを詳細なヤムル形式に変換してください。

出力するヤムルは以下の5つの要素を含む必要があります：
- **スタイル**: 画像のスタイル（例: "リアルな写真", "水彩画", "サイバーパンク風"）
- **対象物**: 生成したい主な対象（例: "黒猫", "サムライ", "宇宙船"）
- **特徴**: 対象物の詳細な特徴（例: "青い目", "鎧を着た", "未来的なデザイン"）
- **動き**: 対象物の動きやポーズ（例: "座っている", "走っている", "飛んでいる"）
- **背景**: 画像の背景（例: "夜の森", "ネオン輝く都市", "宇宙空間"）

### 出力例:
もしユーザーが「黒猫」と入力した場合、以下のようなヤムルを出力してください。

　```yaml
スタイル: "リアルな写真"
対象物: "黒猫"
特徴: "青い目、ふわふわの毛"
動き: "座っている"
背景: "月明かりの下の森"
　```
```

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

　今回は、ここまで。
SSH接続時でハマりかけた（Load key  : error in libcrypto）

イヤな汗をかいた事象だったので、自戒の意味も込めて作成しました。

## 環境
以下の環境で動作させています。

```
% winver

Windows11
バージョン:24H2
OSBuild:26100.2605
```

## ハマりかけた事象
```
$ ssh -i ~/.ssh/id_ed25519 dev@192.0.2.100
Load key "/home/user/.ssh/id_ed25519": error in libcrypto
dev@192.0.2.100: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

### SSH接続時にエラーが発生
「提供データに不備はないはずなのになぜだ…？」と焦ってしまった自分は、エラーの１行目ではなく２行目の`Permission denied`がエラーの根幹だと、解消のため権限変更などに躍起になってしまいましたが当然解消せず。

落ち着きを取り戻して同様のエラーを解消した記事がないかを探したところ、参考元の記事にたどり着きました。



「・・・え？末尾に改行がない？」

```
-----BEGIN OPENSSH PRIVATE KEY-----
a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110
略
a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110
-----END OPENSSH PRIVATE KEY-----
```

```
-----BEGIN OPENSSH PRIVATE KEY-----
a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110
略
a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110a1b2c3d4e5f6g7h8j9k110
-----END OPENSSH PRIVATE KEY-----
(改行アリ)
```

あっという間に解決するのでした。５分くらいずっと見当違いの箇所を触ってしまっていた…。

## 参考にした記事
https://qiita.com/katzueno/items/5a97ef7a97df10cdf533
超絶オススメPodcat リファラジのご紹介

とてもとてもお勧めのテック系Podcastを見つけたので紹介します。
https://refactoradio.com/

一年少し前に始まり、毎週一回、現在#63まで配信されています。
昨日見つけ、昨日と今日で面白さのあまり#55まで聞いてしまいました。

お勧めはしたいのですが、めんどくさがりで人に勧める記事は書きたくないので、Claude 3.7 sonnetさんに記事を書いてもらいました。

### リファクタリングとともに生きるラジオ（リファラジ）の概要

「リファクタリングとともに生きるラジオ」（通称：リファラジ）は、リファクタリングを愛する2人のエンジニア、lacolacoさんと奥野さんがパーソナリティを務めるテクノロジー系ポッドキャストです。2024年から配信が始まり、現在も毎週火曜日に更新されています。

### 番組の特徴

1. **コンセプト**：「三度の飯よりリファクタリングが好きな2人がゆるく楽しく雑談するラジオ」というキャッチフレーズの通り、リファクタリングという技術的なテーマを中心に、エンジニアリングの実践的な議論を展開しています。

2. **配信形式**：Spotify、Apple Podcast、YouTube、Voicyなど複数のプラットフォームで配信されており、どこでも聴くことができます。

3. **内容**：リファクタリングの技術的な話題だけでなく、コードの設計、命名規則、APIの設計、プログラミング言語の特徴など、幅広いエンジニアリングトピックを取り上げています。

4. **スタイル**：堅苦しい技術解説ではなく、「居酒屋で技術の話をしているような」ラフな雰談形式で、聴きやすく親しみやすい内容になっています。

### 人気エピソードと話題

- 『ルールズ・オブ・プログラミング』を取り上げた回が特に人気
- クラスの使い方、SOLIDの原則、API設計など実務に直結するトピック
- 最新の言語機能（例：「令和のJavaがすごい!」など）についての議論

### リスナーからの評価

エンジニアコミュニティからは高い評価を受けており、「エンジニア必聴の最高の技術ラジオ」と紹介されることもあります。特に以下の点が評価されています：

- リファクタリングという普段あまり議論されない泥臭いテーマを深掘りしている点
- 正解を提示するのではなく、議論を通じて新しい視点を提供している点
- 実務に役立つ内容が多く、「他人のコードレビューを聞いているような感覚」が得られる点

### 聴き方

「ながら聴き」に最適なコンテンツとして、ウォーキングや家事をしながら聴くリスナーが多いようです。エンジニアのキャリアや最新トレンドといった重いテーマではなく、日常的な技術の話題を気軽に楽しめるのが特徴です。

### まとめ

「リファラジ」は、リファクタリングという特定のテーマに焦点を当てながらも、幅広いエンジニアリングの知見を提供する貴重なポッドキャストです。実務経験のあるエンジニアにとって共感できる内容が多く、技術的な視野を広げるのに役立つでしょう。特に、コードの品質向上や保守性を高めることに関心のあるエンジニアには必聴のコンテンツと言えます。
統計検定3級に合格しました

# はじめに
統計検定3級を受験し、合格しました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/768789/e6e686a9-1838-4ac9-85ae-14374e43badc.png)

そこでせっかくなので勉強内容等を備忘録として残しておきます。

# 試験について
詳細は以下をご確認ください。

https://cbt.odyssey-com.co.jp/toukei-kentei/kgrade3.html


# 教材
以下テキスト/サイトを使用しました。

 - 教科書

https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E7%89%88-%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A%E5%85%AC%E5%BC%8F%E8%AA%8D%E5%AE%9A-%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A3%E7%B4%9A%E5%AF%BE%E5%BF%9C-%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%88%86%E6%9E%90-%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A/dp/4489023324/ref=sr_1_2?crid=2HA5P8ZA1J3ZS&dib=eyJ2IjoiMSJ9.C_ZOBkX6q0otb-L3xAAyjxB8R093pV-PAgl14SrXfgE8jNyogTgd6hFFcKICoZA-x2PTdVjH1fD23-W_-uar9qxVc0AqhkiBxtEh29rYKppUBVJ1eR23GnPdGsvdo1hYFvdfSxYBiRo7c9dJOjv0cGjedb02fPYhpO2dZRn_DXPZCZc36YY6aHBTc-t8i9384SO9x_F_yYPUFNzzBZQFrHDBlYIICZiALwnsEt89k_zWdR0O80sGIgQ2GF4Fyz_LW26-5rVn-NFgCcgfDjaN9UhzEUhvIMd5qZ9VVpYeywM.yY5DYC5ZyV0KzAqkIqV2yrtg-p5gq4cuGM4JMKLcpAo&dib_tag=se&keywords=%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A3%E7%B4%9A%E5%AF%BE%E5%BF%9C&qid=1722226896&sprefix=%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A3%E7%B4%9A%E5%AF%BE%E5%BF%9C%2Caps%2C178&sr=8-2

 - 問題集

https://www.amazon.co.jp/dp/4788920484?SubscriptionId=AKIAIBX3OSRN6HXD25SQ&tag=jitsumuksbook-22&linkCode=xm2&camp=2025&creative=165953&creativeASIN=4788920484

 - 統計学の時間

https://bellcurve.jp/statistics/course/

「統計学の時間」については、以下理由から利用しました。
 - 基礎を押さえるために、まず読むと良さそうと思った
 - スマホでいつでも手軽に読める

ただ教科書/問題集で内容は網羅されていたため、本試験においては不要だったと感じました。


# 勉強内容
以下流れで進めました。

1. 「統計学の時間」の3級範囲にあたる箇所(基礎編16あたりまで？)を読む
1. 教科書の練習問題を解く(分からない問題は教科書の該当箇所を読みつつ解く)
1. 「2」の復習&教科書の練習問題を改めて自力で解く
1. 「3」の復習&間違えた問題や見直したい部分が無くなるまで繰り返し解く
1. 問題集の問題(3級のみ)を解く
1. 「5」の復習&間違えた問題や見直したい部分が無くなるまで繰り返し解く
1. 問題集の模擬試験(3級のみ)を解く(30分時間計測)
1. 「7」の復習&間違えた問題や見直したい部分が無くなるまで繰り返し解く
1. 公式や不安な部分を見直す


# 勉強期間
3ヶ月程度だったと思います(勉強時間は分かりません)。
「統計学の時間」を1ヶ月以上かけてだらだら読んでしまったため、教科書/問題集のみ進めていれば1～2ヶ月程度で済んだかもしれません。


# おわりに
統計学の基礎を学ぶのに良い試験でした。
ちなみに実際の試験の問題は、問題集の問題に近い感じでした。

少しでも参考になりましたら幸いです。
v-ifで値をセットして画面表示できないようにしているのに、一瞬画面表示されてしまう

default値を指定することで解消。
```
<template>
  <div>
    <router-link to="/reservations" v-if="isAdmin">
      予約フォーム
    </router-link>
    <router-view/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isAdmin : false, #falseをセットする
    };
  },
  created() {
    this.judgmentMethod()
  },
  methods: {
    judgmentMethod()
  }
}
</script>
```
インターネットショートカット のアイコンをメモ帳から変更する

# はじめに
インターネットショートカット(.url)のアイコンは、実はメモ帳をいじるだけで変更できるという話
# .urlファイルの内容
これが最低限の構成ですが…
```twitter.url
[InternetShortcut]
URL=https://twitter.com/home
```
ちょっと付け足せば、簡単にアイコンを変えられます。
```twitter.url
[InternetShortcut]
URL=https://twitter.com/home
IconFile=C:\User\icon\my_icon.ico
IconIndex=0
HotKey=0
IDList=

```
```IconFile=```のパスを書き換えれば自分の好きなアイコンを指定できます。
なお、プロパティからの変更ではアイコンがすぐに変わりますが、この方法で書き換えただけでは、アイコンがすぐには変わりません。

# エクスプローラーの再起動
即座にアイコンの変更を反映させたい場合、エクスプローラーの再起動が必要です。
2つ方法があります。

1.タスクマネージャーを開いて、エクスプローラーを右クリックして再起動をクリック。

2.コマンドでエクスプローラーを再起動する。以下はPowerShellのコマンドです。
```PowerShell
Stop-Process -Name explorer
Start-Process explorer
```
ESP32がものすごい勢いで謎文字列を大量にシリアルに吐くので困った

いつものようにArduino IDEでESP32のコードを書いて実行して、いざシリアルモニタでログを見ようとしたら…
### なんかものすごい勢いで文字が流れてる！ ###
何これ？
```
16:13:21.583 -> rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
16:13:21.583 -> configsip: 0, SPIWP:0xee
16:13:21.583 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
16:13:21.615 -> mode:DIO, clock div:1
16:13:21.615 -> load:0x3fff0030,len:4916
16:13:21.615 -> load:0x40078000,len:16436
16:13:21.615 -> load:0x40080400,len:4
16:13:21.615 -> ho 8 tail 4 room 4
16:13:21.615 -> load:0x40080404,len:3524
16:13:21.615 -> entry 0x400805b8
16:13:21.615 -> E (60) flash_parts: partition 0 invalid magic number 0x77f6
16:13:21.615 -> E (60) boot: Failed to verify partition table
16:13:21.615 -> E (60) boot: load partition table error!
16:13:21.615 -> ets Jun  8 2016 00:22:57
16:13:21.647 -> 
16:13:21.647 -> rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
16:13:21.647 -> configsip: 0, SPIWP:0xee
16:13:21.647 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
16:13:21.647 -> mode:DIO, clock div:1
16:13:21.647 -> load:0x3fff0030,len:4916
16:13:21.647 -> load:0x40078000,len:16436
```
さっぱりわからないのでChatGPTに聞いてみたら、

「このログを見る限り、ESP32が 「パーティションテーブルの読み込みに失敗」 してリブートを繰り返しているようです。」

と。対処方法をいろいろ提示されたのだがどれも的を得ていないのでggrksしてみたら、同じことで困ってて解決した方がいらっしゃいました。
https://gijin77.blog.jp/archives/33372499.html

ツール > Flash Mode:"QIO" となっているのを "DIO" にしたらなおったと。やってみたら直りましたありがとう！
Vite + ReactでもNextjsのようなファイルルーティングをしたい人へ贈るTips

## 私はNext.jsが好きだ
めっちゃ好きです。あのファイルルーティングがめっちゃ開発が楽になるので好きなんです。
その前提で、Next.jsは使わないけどこのファイルルーティングの機能を使いたい人に贈るTipsです。

## 前提
Vite + React + React Routerを利用する前提です。
（React Routerがメジャーバージョンアップで結構大幅な修正があったので使う人も怖いと思うかもですが、、、）

## 結論
https://github.com/oedotme/generouted

これを使おう！これを読んでる人はREADME.mdを見ればわかるはず！！公式ドキュメントが全てだ！！！

実装サンプルはこれ(公式ドキュメント)

https://stackblitz.com/github/oedotme/generouted/tree/main/explorer

## ...は暴論かと思うので少しだけ解説

### インストール
```zsh
npm i @generouted/react-router react-router
```

```vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import dynamicImport from "vite-plugin-dynamic-import";
import generouted from "@generouted/react-router/plugin";

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    dynamicImport(),
    generouted(), // ←これが今回のプラグインです。他のは無視でもいいかもですが。。。
  ],
});

```
肝になるのが、`generouted()`です。これが特定のディレクトリを監視してルーティングを自動で生成してくれるプラグインです。

### generoutedのConfig
もちろんConfigがあります。
```typescript
type Options = {
    source: {
        routes: string | string[]; // ルーティングを置いてあるディレクトリのパスです。
        modals: string | string[]; // このプラグインではModalも定義できます。
    };
    output: string; // 型定義付きのrouterHooksを自動生成してくれます。後述...
    format: boolean; // フォーマットするかどうか
};
```
デフォルトでは

```typescript
generouted({
    source: {
        routes: "src/pages",
        modals: "src/pages"
    },
    output: "src/router.ts",
    format: false,
})
```
っぽいっす。これだけはドキュメント漁ってもなかった。。。

### outputって何をoutputするの？
devで起動してると、自動で生成してくれます。
```src/router.ts
// Generouted, changes to this file will be overridden
/* eslint-disable */

import { components, hooks, utils } from "@generouted/react-router/client";

export type Path = `/` | `/fuga` | `/hihi` | `/hoge`;

export type Params = {};

export type ModalPath = never;

export const { Link, Navigate } = components<Path, Params>();
export const { useModals, useNavigate, useParams } = hooks<
  Path,
  Params,
  ModalPath
>();
export const { redirect } = utils<Path, Params>();

```

React RouterをWrapしたHooksとかLinkとかNavigateとかを生成してくれる。
これがめっちゃ便利！！！

### 読み取ってくれるファイル
とりあえずルーティングだけ紹介します。
そのほかは公式のGithubを見よ！

#### index.tsx
`src/pages/index.tsx` → /
`src/pages/posts/index.tsx` → /posts
#### ネストされたルーティング
`src/pages/posts/2022/index.tsx` → /posts/2022
`src/pages/posts/2022/resolutions.tsx` → /posts/2022/resolutions
#### ダイナミックルーティング
`src/pages/posts/[slug].tsx` → /posts/:slug
`src/pages/posts/[slug]/tags.tsx` → /posts/:slug/tags
`src/pages/posts/[...all].tsx` → /posts/*

#### レイアウトファイル
`_layout.tsx`これがレイアウトファイルです。これだけNextjsとは違います。
実際にページの内容を表示するのはreact-routerの`<Outlet />`です。

#### _app.tsx
Next.jsのPageルーティングの_app.tsxの作用とほぼ同じです。
レイアウトファイルと同じく、実際にページの内容を表示するのはreact-routerの`<Outlet />`です。

## 最後に
何度でも言いますが、筆者はNextjsのエコシステムが大好きなのですが、開発案件によってはVercelを採用してなかったり、そもそもNextjsは使わずにViteを使ってるところもあると思います。

その上で、あのファイルルーティングを利用したい人はいるとおもうので、その人に届けばと思います。
以上！
SVMとは？簡単に詳しく解説＆実例付き


### 1. SVM（サポートベクターマシン）とは？

SVM（Support Vector Machine：サポートベクターマシン）は、**分類問題や回帰問題を解くための強力な機械学習アルゴリズム** です。特に、高次元データや非線形なデータにも適用できる点が特徴です。

SVMの主な目的は、**データを2つ以上のクラスに分類する最適な境界（超平面）を見つけること** です。この境界を「決定境界」と呼び、データのクラスが最もよく分離されるようにマージンを最大化します。

---

### 2. SVMの仕組み

SVMは、次の2つの概念を基に動作します。

#### (1) マージン最大化
SVMは、データを分類するための「最適な超平面（決定境界）」を見つけます。このとき、**各クラスのデータ点と超平面との距離（マージン）を最大化** することを目指します。

例えば、以下のようなデータセットを考えてみましょう。

| X1 | X2 | クラス |
|----|----|------|
| 1.2 | 3.4 | A |
| 2.3 | 1.5 | B |
| 3.1 | 4.2 | A |
| 4.5 | 2.3 | B |

SVMは、このデータを最もよく分離する直線（2Dの場合）や平面（3Dの場合）、または超平面（高次元の場合）を求めます。

#### (2) サポートベクター
データの中には、分類を決定するのに特に重要な点がいくつかあります。これらの点を「サポートベクター」と呼びます。

サポートベクターは、決定境界のすぐ近くにあり、その位置が分類の結果を大きく左右します。SVMは、このサポートベクターを使って決定境界を調整します。

---

### 3. SVMの実例：メールのスパムフィルタリング

SVMの実用例として、**スパムメールの分類** を考えてみましょう。

#### (1) データ準備
メールの内容を数値データに変換し、特徴量を作成します。例えば：

| メールの単語 | 迷惑メール（1）/ 普通のメール（0） |
|------------|------------------|
| "無料" の出現回数 | 1 |
| "今すぐ" の出現回数 | 2 |
| "限定" の出現回数 | 0 |
| "こんにちは" の出現回数 | 0 |

#### (2) SVMの適用
このデータをSVMに入力すると、SVMは「迷惑メール」と「普通のメール」を最もよく分離する決定境界を求めます。新しいメールが届いたとき、そのメールが決定境界のどちら側にあるかを見て、スパムかどうかを分類します。

#### (3) 結果
SVMは、**新しいメールを正確に分類する決定境界を学習し、スパムメールを高精度でフィルタリングできるようになります**。

---

### 4. SVMのメリットとデメリット

#### ✅ メリット
- **高次元データに強い**：多くの特徴量を持つデータ（例えば、画像やテキスト）でもうまく機能します。
- **非線形データの分類が可能**：カーネル関数を使うことで、複雑なデータのパターンを見つけられます。
- **過学習しにくい**：マージンを最大化することで、一般化性能が高まります。

#### ❌ デメリット
- **計算コストが高い**：大規模データセット（数百万以上のデータ）では、計算時間がかかることがあります。
- **ハイパーパラメータの調整が難しい**：カーネルの選択や正則化パラメータ（C）の調整が必要です。

---

### 5. まとめ

- **SVM（サポートベクターマシン）は、分類問題を解決する強力なアルゴリズム** で、特に高次元データや非線形データに適しています。
- **決定境界を最適化し、マージンを最大化することで分類精度を向上** させます。
- **スパムフィルタや画像認識など、実世界の様々な問題に適用可能** です。

SVMを適切に活用すれば、より高精度な機械学習モデルを構築できるでしょう！