OmniAICreator/Qiita-1.07M huggingface dataset:
shaka-packagerを使って、パッケージング&配信まで


## shaka-packagerとは？
Googleが公開している、HLSのパッケージャです。
https://github.com/google/shaka-packager
mp4ファイルをHLSで配信できる形にフォーマットするパッケージになります。

## shaka-packager導入
cmakeをhomebrewでインストールする

```
$ brew install cmake
```
$ shaka-packagerをクローンする
```
$ git clone https://github.com/google/shaka-packager.git
```
ビルド用のフォルダを準備します
```
$ cd /path/to/shaka-packager
$ mkdir build
$ cd build
```
cmakeビルドとmakeビルドします
```
$ cmake ..
$ make
```
ビルドしたpackagerのバージョンを確認します
```
$ cd path/to/shaka-packager/build/packager
$ ./packager --version
```
これで導入は完了です。

## HLSのWidevineパッケージ化
今回は無料のライセンスサーバーとして、ライセンスサーバー,key,ivを使います。
| 1 | 2 |
|:--|:--|
|ライセンスサーバURL   | https://license.uat.widevine.com/cenc/getcontentkey/widevine_test  |
| key  | 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9  |
| iv  | d58ce954203b7c9a9a9d467f59839249  |
| hls_base_url  | s3のバケットURL  |




```
$ cd path/to/shaka-packager/build/packager
$ ./packager \
  in=sample.p4,stream=audio,output=audio.mp4 \
  in=sample.mp4,stream=video,output=video.mp4 \
  --enable_widevine_encryption \
  --key_server_url https://license.uat.widevine.com/cenc/getcontentkey/widevine_test \
  --content_id 7465737420636f6e74656e74206964 \
  --signer widevine_test \
  --aes_signing_key 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 \
  --aes_signing_iv d58ce954203b7c9a9a9d467f59839249 \
  --hls_master_playlist_output master.m3u8 \
  --hls_base_url https://my-backet.s3.ap-southeast-2.amazonaws.com/test/ \
  --hls_key_uri https://license.uat.widevine.com/cenc/getcontentkey/widevine_test
```
実行すると以下のファイルが生成されます。
master.m3u8
stream_0.m3u8
stream_1.m3u8
audio.mp4
video.mp4

生成されたファイルをS3にアップロードしてください。今回はtestフォルダにまとめます。
```
$ aws s3 ls s3://test/

```

## 再生できるか確認
再生にはGoogleのShaka Playerを使用します。

https://shaka-player-demo.appspot.com/demo/

Custom Contentの＋ボタンを選択し、MAINタブでManifest URLを入力してNameには任意の名前を設定します。
Manifest URL https://s3-ap-northeast-1.amazonaws.com/my-backet/test/master.m3u8

![スクリーンショット 2024-12-11 14.39.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169685/be23a886-0469-0474-742a-ce115dd330d9.png)

DRMタブでCusotom License Server URLを入力し、SAVEします。
Cusotom License Server URL https://license.uat.widevine.com/cenc/getcontentkey/widevine_test

![スクリーンショット 2024-12-11 14.44.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169685/657fe1e5-78e2-7ef0-d2ba-0b86d99a6307.png)

動画が再生されました。
![スクリーンショット 2024-12-11 14.30.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169685/baa39824-69e5-e741-b05c-fee8e7af6b4f.png)
(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org



## 終わりに
実際に商用で利用する場合はDRM サービスプロバイダーのPOCサーバーを建てて検証することがあるかと思いますが、無料でのライセンスサーバーがあれば、無料で簡単に検証が可能です。
Shaka Playerを使用しましたが、DRM対応のPlayerであればアプリで検証することも可能です。
Laravelで$request->all()を使ってはいけない理由

:::note info
[Laravel Advent Calendar 2024](https://qiita.com/advent-calendar/2024/laravel) の8日目です :muscle:
:::

こんにちは :smiley: tatata-keshiです :exclamation: 

LaravelのControllerでは、リクエストデータを操作する際に`$request->all()`を使用することがあります。しかし、実務での利用にはいくつかの問題点があり、推奨されないケースが多いです。本記事では、その理由と安全な代替方法について解説します。

## $request->all()について
`$request->all()は、HTTPリクエストで送信された全てのデータ（クエリパラメータやフォームデータなど）を連想配列として取得するためのLaravelのメソッドです。このメソッドは、簡単にリクエストデータを取り扱える便利なツールですが、以下の理由から使用を避けるべきです。

## $request->all()を使うべきでない理由

### 不必要なデータの混入
`$request->all()`を使うと、ユーザーが送信した全てのデータが取得されます。これには、意図していないフィールドや不正なデータも含まれる可能性があります。例えば、悪意のあるユーザーが不正なデータを送信させることが可能です。

```PHP
// 悪い例
$data = $request->all();
User::create($data); // 不要なフィールドがデータベースに挿入されるリスク
```

### セキュリティリスクの増大
特にデータベース操作時、予期しないデータがエスケープされずに挿入されることで、セキュリティホールとなる可能性があります。例えば、悪意のあるデータが直接挿入されてSQLインジェクションが発生するリスクが高まります。特に`DB::raw()`や`whereRaw()`句といった直接SQL文を記述している箇所がある場合は要注意です！

### バリデーションの不足
`$request->all()`では、取得したデータに対して明示的なバリデーションをかけるのが難しくなります。特定のフィールドに対して適切なバリデーションが実施されない場合、アプリケーションの動作が不安定になる可能性があります。

### 可読性と保守性の低下
コードを読んだ他の開発者にとって、`$request->all()`の内容を即座に把握することは困難です。必要なデータだけを明示的に指定する方法に比べ、コードの可読性や保守性が劣ります。

## 推奨される代替方法

### $request->only()を使う
必要なデータのみを取得する方法として、`$request->only()`があります。このメソッドは、指定したキーのデータのみを取得できるため、安全性が向上します。

```PHP
$data = $request->only(['name', 'email', 'password']);
User::create($data);
```

### $request->validated()を使う
フォームリクエスト（Form Request）を活用して、バリデーションを事前に実施し、バリデーション済みのデータを取得する方法です。

```PHP
public function store(UserRequest $request)
{
    $data = $request->validated();
    User::create($data);
}
```

### バリデーションロジックを明確化
簡単な場合は`$request->validate()`メソッドを用いることで、必要なフィールドとそのバリデーションルールを明確に定義できます。

```PHP
$data = $request->validate([
    'name' => 'required|string|max:255',
    'email' => 'required|email|unique:users,email',
    'password' => 'required|min:8|confirmed',
]);
User::create($data);
```

## まとめ
Laravelにおける`$request->all()`の使用は、便利ではあるものの、セキュリティや保守性の観点から避けるべきです。代わりに、`$request->only()`や`$request->validated()`を活用し、必要なデータを明示的に指定することで、安全で信頼性の高いアプリケーションを構築できます。
【Azure】Github Actions経由でReactアプリをAzure App Serviceにデプロイすると失敗する

## はじめに

ReactプロジェクトをGithub ActionsでAzure App Serviceに自動デプロイをしようとした際にエラーが出力されてうまくいかなかったため、解決策を共有します。

## 問題

Github Actionsからデプロイした際に、ビルドで以下のエラーが出力される。

```
> reactapp6.client@0.0.0 build
> vite build

There was an error exporting the HTTPS developer certificate to a file. Please create the target directory before exporting. Choose permissions carefully when creating it.
failed to load config from D:\a\AutoDeployTest\AutoDeployTest\reactapp6.client\vite.config.js
error during build:
Error: Could not create certificate.
    at file:///D:/a/AutoDeployTest/AutoDeployTest/reactapp6.client/node_modules/.vite-temp/vite.config.js.timestamp-1733635020217-ec2ccb5262f8b.mjs:24:11
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadConfigFromBundledFile (file:///D:/a/AutoDeployTest/AutoDeployTest/reactapp6.client/node_modules/vite/dist/node/chunks/dep-yUJfKD1i.js:53604:15)
    at async loadConfigFromFile (file:///D:/a/AutoDeployTest/AutoDeployTest/reactapp6.client/node_modules/vite/dist/node/chunks/dep-yUJfKD1i.js:53433:24)
    at async resolveConfig (file:///D:/a/AutoDeployTest/AutoDeployTest/reactapp6.client/node_modules/vite/dist/node/chunks/dep-yUJfKD1i.js:52956:24)
    at async createBuilder (file:///D:/a/AutoDeployTest/AutoDeployTest/reactapp6.client/node_modules/vite/dist/node/chunks/dep-yUJfKD1i.js:51044:18)
    at async CAC.<anonymous> (file:///D:/a/AutoDeployTest/AutoDeployTest/reactapp6.client/node_modules/vite/dist/node/cli.js:851:23)
Error: Process completed with exit code 1.
```

## 解決策

以下の記事で発生しているエラーと全く同じため同じように対応する。

https://qiita.com/KM_20005/items/275f27994697451246a3


## おわりに

同じエラーをローカルのビルド時にも見ていたはずなのに思い出すのに３時間ぐらいかかりました。ただ思い出したら記事にした通りの手順で解決できたので、自分の記事に助けられました。

こういうことがあると記事を書いててよかったなーって思います。
ElixirからResoniteを操作するライブラリ作ってみた

# 環境
Resoniteが動く環境としてUbuntu 22.04を使っています

# やりたいこと
ElixirからResoniteのオブジェクトを動かす
動画の例は正方形のオブジェクトを動かしています

# 完成動画
<iframe width="200" height="400" src="https://www.youtube.com/embed/MfnUzYgfaao" title="elixir_to_resonite v0.001" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 仕組み
Elixir→WebSocket→Resonite

# ソースはこちら
https://github.com/ymn-t-yamanashi/elixir_to_resonite/releases/tag/V0.001

# Resonite側作成
下記のように組み立てます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/4128deff-44a5-1074-d05f-0e721b550a8e.png)

Slot InputをRootに設定しいください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/49cc9a4f-d574-d7c1-8ce4-5ef66d4e51e7.png)



「Cylinder」と「Box」を作成してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/0696e754-82c3-6212-c9fe-9091fd411cee.png)


# 実行
WebSocketサーバー
```sh
$ cd elixir_to_resonite_server
$ mix deps.get
$ mix phx.server
```
Resonite側
「Call」と「Async Call」を押してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/6db07afa-07bf-278c-6929-3b82878c7378.png)

Elixir操作クライアント

```
$ cd elixir_to_resonite_client
$ mix deps.get
$ mix run -e "ElixirToResoniteClient.hello()"
```
# ProtoFluxが組むのがめんどくさ人むけ
elixir_to_resonite-0.001/ProtoFlux/V0.001/
elixir_to_resonite.resonitepackageをResoniteでインポートできます
Firebase Authenticationのブロッキング関数はタイムアウトに気をつけよう

## ブロッキング関数とは？

Firebase Authenticationでは、Cloud Run Functionsの関数を認証時に実行するブロッキング関数という機能が提供されています。

ブロッキング関数は、ユーザーアカウントの作成やログインなどの認証処理のフローを一時的に停止させ、関数の処理が完了するまで待機させます。

以下のような認証関連のイベントごとにブロッキング関数を設定できるので、サインアップ時のFirestoreデータ作成やカスタムクレームの設定、認証中のチェック処理等を行うのに非常に便利です。

- ユーザーが作成される前
- ユーザーがログインする前
- メールの送信前
- SMSメッセージの送信前

なお、ブロッキング関数の利用にはFirebase Authentication with Identity Platformへのアップグレードが必要になります。

## 7秒のタイムアウト制限

ブロッキング関数は便利な機能ですが、認証処理のフローをブロックするため、タイムアウトが7秒と短めに設定されています。

関数内の処理を7秒以内に収めることはそれほど難しくありませんが、この時間にはCloud Run Functionsのインスタンス起動時間も含まれているため注意が必要です。

Cloud Run Functionsは通常コールドスタンバイ状態にあるため、起動時間が長くなると、タイムアウトのリスクが高まります。

## タイムアウトの防止策

認証処理はアプリケーションの重要な部分であるため、タイムアウトを避けるために、ブロッキング関数にはミニマムインスタンスを設定することをお勧めします。

```typescript
import { beforeUserCreated } from 'firebase-functions/v2/identity';

export const beforecreated = beforeUserCreated(
  {
    // ミニマムインスタンス数を1に設定
    minInstances: 1,
  },
  (event) => {
    // TODO
    return;
  }
);
```

この設定により、指定された数のインスタンスが常時稼働状態となり、起動時間がかかってタイムアウトが発生するリスクを軽減できます。

ただし、ミニマムインスタンスを設定した状態でも、ミニマムインスタンスで処理可能な総リクエスト数を超えるようなアクセス負荷が集中した場合は、新しいインスタンスが起動されるため、起動時間によるタイムアウトを100%防止できるわけではありません。

プロジェクトによってはミニマムインスタンス数をより多めに設定したほうが良い場合もありますので、要件に応じて適切なミニマムインスタンス数を設定しましょう。

## コスト管理のための環境別設定

タイムアウト対策としてミニマムインスタンスを設定するのは有効ですが、インスタンスが常時稼働状態となるため、その分の費用も発生します。開発環境と本番環境でFirebaseプロジェクトを別々に管理している場合は、環境変数を利用し、本番環境のみにミニマムインスタンスを設定することも可能です。

```.env.production
ENVIRONMENT='production'
```

```.env.staging
ENVIRONMENT='staging'
```

```typescript
import { defineString } from 'firebase-functions/params';
import { beforeUserCreated } from 'firebase-functions/v2/identity';

export const beforecreated = beforeUserCreated(
  {
    // 環境変数ENVIRONMENTがproductionの場合のみミニマムインスタンス数に1を設定
    minInstances: defineString('ENVIRONMENT').equals('production').thenElse(1, 0),
  },
  (event) => {
    // TODO
    return;
  }
);
```

コストを抑えつつ本番環境でのトラブルを軽減できるので、開発環境でたまに発生する認証エラーが許容できる場合は、こちらの設定もお勧めです。
isucon14に参加してきました(5400点くらい)

## isucon14に参加してきました
友達に「isucon出ない？」と誘われたので初参加してきました。
仕事が繁忙期だったりプライベートが諸々いそがしかったのも有り、素振りが5時間くらいしかなかったのでisuconとはの概要をさら～っと把握したくらいで、あまりセオリー的なのはわからない状態で突撃しました。

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

ライドチェアというライドシェアサービスがお題でした（動画のクオリティがすごい）
この世界では椅子が目的地まで自分を運んでくれるそうです。

## やったこと
### 1. MySQLを別サーバーに移行
競技開始時点では3台のサーバーにそれぞれアプリもDBも乗っている状態だったので、サーバーの役割を分割させることにしました。
いらないサービスを全部止めてから（APPのservice、cronとか）作業したので、特にハマることなくスムーズに行ったのですが、他チームでDB分けるのハマった、みたいな投稿があったので、いらないものは止めてから作業するのはよかったかもしれません。
とにかくDBの負荷が高かったので、DBサーバーを作ることでリソースをいい感じに使えるようになりました。

### 2. インデックスをはる
 1. をやっている最中チームメンバーがインデックスを張ってくれました。
点数めちゃ伸びた、すごい、インデックス大事

### 3. スロークエリ出してみる
MySQLのスロークエリを出しました。
pt-query-digestも使ってみて、チームメンバーにクエリ修正をお願いしました。（修正は間に合わなかった）

### 4. 椅子のマッチロジックを変えてみる
椅子のマッチロジックが「配車を受け付けている椅子をランダムで1台ピックする」というロジックだったので、せめてもの思いで一番近い椅子をマッチするようにしました。
ただ、チームで言語はnodejsを採用することになっていたのですが、私のほうが1mmもnodejsを触ったことがなくコードを読むのが精一杯だったので、コードはChatGPT(GPT-4o)に書いてもらいました。
提案されたコードはバグなく動くレベルでAIの進化に感動しました。
（プロンプトを上手に使う能力が求められますね...）
ちなみにこれも結構点数が上がりました。

...とこんな感じで初isuconは5400点くらいで終了しました。

## やりたかったこと
- 決済周りの処理を別サーバーに切り出し&ロジックを読み込みたかった
- マッチ速度改善したものの、ユーザー様の不満度が依然として高めだったので、もっと他のロジックを考えたかった（が、具体的にどうしたら良かったかまではわからず）

## 感想
- 楽しい！！！！（サーバー飛ばしても決済できなくなっても誰からも怒られないので、試したいこと試したい放題）
- コード読む時間が全然足りなかった
- 意外とアプリケーションのロジック触ることになった（もっとサーバーやミドルウェア周りのチューニングをするイメージだった）
- AIすごい

運営の皆さん&一緒に出てくれた友達の方ありがとうございました！
Linuxの仕組みと基本的な動作原理

Linuxは、オープンソースで開発されたUnix系のオペレーティングシステム(OS)です。このシステムは、単純でしかも高い柔軟性を持つ設計が大きな特徴です。この記事では、Linuxの基本的な構成や動作原理を解説します。

# 1. Linuxの基本構成

Linuxは、主に下記の要素で構成されています。

カーネル (Kernel)LinuxカーネルはOSの核心部分で、ハードウェアとソフトウェアの桩を掛ける件となる部分です。主な機能は以下の通りです。

**プロセス管理**: 実行中のプログラムを管理します。

**メモリ管理**: メモリの割定や解放を管理します。

**デバイス管理**: 入出力デバイスとの通信を管理します。

**ファイルシステム管理**: データの読み書きを支援します。

シェル (Shell)シェルは、ユーザーがコマンドを入力し、OSと互動するためのインターフェースです。代表的なものに、bash、zsh、fishなどがあります。

ユーザー空間 (User Space)アプリケーションやユーティリティプログラムが実行される空間です。例えば、vimやgccなどのツールがこれに含まれます。

# 2. Linuxカーネルの動作原理

Linuxカーネルは、システムリソースを最適に管理するよう設計されています。主な仕組みは以下の通りです。

マルチタスクLinuxカーネルは、複数のプロセスを同時に実行することが可能です。CPUの時間を小さな単位で分割し、各プロセスに順番に割り当てます。

仮想メモリ実際の物理メモリを超えるメモリ空間を提供します。スワップ領域を利用して、メモリが不足した場合でも突然のシステム不穏を防ぎます。

ファイルシステムLinuxは、階層的なディレクトリ構造を持つファイルシステムを採用しています。代表的なものにext4やXFSなどがあります。

デバイスドライバ各種ハードウェアを制御するためのプログラムで、カーネルのモジュールとして実装されています。これにより、Linuxはさまざまなデバイスで動作可能です。

# 3. Linuxの特徴的な仕組み

プロセス間通信 (IPC)プロセス間でデータをやり取りするための仕組みです。代表的な方法に、パイプ、ソケット、メッセージキューがあります。

パーミッションとセキュリティファイルやプロセスに対するアクセス権を設定します。ユーザー、グループ、その他の3つのカテゴリで制御します。

パッケージ管理システムソフトウェアを最適にインストール・アップデートするための仕組みです。apt (Debian系)、yum (RedHat系)などが代表例です。

# 4. Linuxが動作する流れ
起動プロセス (Booting)

BIOS/UEFIがブートローダー(\u4f8b: GRUB)を起動します。
↓
ブートローダーがLinuxカーネルをロードします。
↓
カーネルが初期化プロセス(initまたはsystemd)を開始します。
↓
ランレベルの設定システムの動作モードを決定します(例：通常モード、シングルユーザーモード)。
↓
デーモンプロセスの起動サービス(例：ネットワーク、データベース)がバックグラウンドで動作を開始します。
↓
ユーザー環境のセットアップログイン後、シェルが起動し、ユーザーはコマンドを実行可能になります。

# 5. Linuxの主な用途

サーバー: Webサーバー(Nginx, Apache)、データベースサーバー(MySQL, PostgreSQL)

組み込みシステム: スマート家電、IoTデバイス

開発環境: Docker、Kubernetesを活用したソフトウェア開発

デスクトップ環境: Ubuntu、FedoraなどのデスクトップLinuxディストリビューション

# まとめ

Linuxは、突出した突出した安定性・柔軟性・セキュリティを持つOSです。その基盤となるのは、システムリソースを最適に管理するカーネルの仕組みです。Linuxの設計は、初心者からプロフェッショナルまで、課題に合わせて学びやすく使いやすい設計がされています。
MDM SaaSのライセンスの考え方を簡単に理解してみる

# Q. MDM SaaSのライセンスの考え方って複雑!?
# A. いいえ、非常にシンプルです。
### 「IDMCプラットフォームで使えるMDM SaaSはライセンスがIPUライセンスとは異なると聞きましたが、MDM SaaSのライセンスの考え方について教えて欲しい。」というお客様からの声が非常に多いため、ここに分かりやすく記事を書いておきます。

# MDM SaaSのライセンスの考え方は次の３つのライセンスの組み合わせで決定します。
**①ユーザ数に基づくライセンス**
**②データ量に基づくライセンス**
**③その他オプションライセンス**

つまり、以下のような考え方ですね。
![スクリーンショット 2024-12-09 17.47.11（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947834/c089e4b2-4678-1687-90df-c2353304ecd5.png)

そして、例えば、③その他オプションライセンスが不要な場合は、①＋②の合計がMDM SaaSのライセンスとなります。シンプルな構成の場合、ユーザ数とレコード数が分かればOKという感じで非常にシンプルです。


もう少し詳細を説明するために、上記のA〜Gに関する情報も交えてご説明します。

# ①ユーザ数を算出するために
では、もう少し詳しく。
ユーザ数を正確に算出するためには以下のA.とB.の2つのタイプのユーザ数をカウントします。
### A. MDMを使用する業務ユーザー数
- MDMのデータモデルや品質ルールの作成を行うユーザ
- MDMシステムへログインし登録・更新を行うユーザ
- 業務アプリケーションからAPI経由でMDMシステムを参照するユーザ
### B. MDM管理者
- InformaticaのIDMC全体の管理者
- ユーザ管理やロール管理業務を行うユーザ

# ②データ量を算出するために
つづいて、データ量についても、もう少し詳しく。
MDMのデータ量とはデータボリューム(サイズ)ではなく、マスターのレコード件数を指します。マスターのレコード件数は次の方法で算出します。
### マスターの種類　X　レコード件数

## インフォマティカが事前に定義するマスターの種類とは?
ん!? マスターの種類!?
インフォマティカではマスターの種類を大きく５種類に分類していて、それぞれのマスターの種類が何レコードあるかを計算します。MDMで管理したいマスタがどれに該当するかを予め決定したうえで、それぞれのマスターの種類で何レコードぐらい管理したいのかを計算します。

では、まず、マスターの種類から。
### C.マスターの種類
1. 顧客マスタ (B2B/B2C)
2. サプライヤー
3. 製品/商品
4. 参照データ
5. その他

MDMで管理したいマスターの種類を上記５つの中から該当するものを決定します。１〜４になければ５.その他に振り分ける感じですね。

## レコード件数のカウント方法とは?
つづいて、レコード件数についてです。
### D.レコード件数
レコードのカウント方法は、名寄せされる前の"非集約レコード"の件数をカウントします。シンプルに言い換えると、MDM SaaSの"相互参照表"に登録されている(登録されるであろう)レコードの件数となります。

例えば、取引先マスタに「インフォマティカ・ジャパン株式会社」のレコードを管理したい場合、複数のソースシステムから該当のレコードを集めて・名寄せを行い、その結果以下のような相互参照表となる場合は、合計３レコードがレコードのカウント対象となります。
![スクリーンショット 2024-12-09 19.17.58（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947834/0eb25d90-249a-8f49-8396-d34a3a7c9dad.png)

相互参照表にマスターレコードが取り込まれるケースは、ハブ型やコンソリデーション型のMDMのスタイルの場合ですね。一方、集中管理型のスタイルの場合は相互参照表は１件の場合が多いのでその場合は1となります。

このように、マスターデータの種類 x レコード件数の合計が、ライセンス対象となります。

# ③その他オプションライセンス
その他オプションライセンスは３つあります。
## E. 追加ユーザ
標準で付随するユーザ数以外に、更にユーザ数を増やしたい場合にこのオプションを追加することが可能です。
## F. フルサンドボックス
一つ作成したOrg(組織)とは別に新たなOrg(組織)を作成したい場合にこのオプションを追加することが可能です。フルサンドボックスの利用用途は開発・テスト・QA用途に限定する必要があります。
## G. 追加Org(組織)、追加Sub-Org(サブ組織)
新たなOrg(組織)や、新たなSub-Org(サブ組織)を作成したい場合にこのオプションを追加することが可能です。F.フルサンドボックスとの違いは、こちらは本番環境としても利用可能です。

# 実はお得なMDM SaaSライセンス!!
### MDM SaaSのライセンスには、データ統合(Data Integration)やデータ品質(Data Quality)の他、アプリケーション統合(Application Integration)などの機能が無償で使える??
MDM SaaSのライセンスに付帯するライセンスとして、MDM SaaSを中心としてマスターデータのインバウンド・アウトバウンドの範疇に限って、６つのIDMCソリューションが利用可能です。付帯する６つのIDMCソリューションは下記の通りです。
1. Cloud Data Integration
2. Cloud Data Quality
3. Cloud Application Integration
4. Cloud API Gateway Service
4. MDM SaaS Reference 360 Basic

### 本記事では上記の機能の詳細は割愛しますが、MDM SaaSのライセンスの考え方が少しでもご理解頂けたら幸いです。
Stream DeckのPlugin開発をはじめる

Stream Deckを持っているので、Pluginを作成してみます。

公式から出ている開発ドキュメントは以下にあります。

https://docs.elgato.com/

Stream DeckのPlugin開発のGetting startedは以下です。


https://docs.elgato.com/streamdeck/sdk/introduction/getting-started

Node.js環境で開発できるらしいです。

すでにNode.js環境はあるので、ガイドにしたがって、お手軽にコマンドを実行してCLIをインストール、テストプラグインを作成します。

:::note
Stream Deckには、**Stream Deck Mobile**というAndroid/iOSアプリがあり、それを利用すると、Windows PCで起動したStream Deckアプリと連携させて、実機のStream Deckデバイス代わりになります。

今回、プラグイン開発のCLIでコマンドを実行すると、モバイルアプリでもテストプラグインが動作しました。

詳細には対応できないことがあるかもしれませんが、そこは確認しつつとなります。
:::

# ディレクトリ構成

```
.
├── *.sdPlugin/
│   ├── bin/
│   ├── imgs/
│   ├── logs/
│   ├── ui/
│   │   └── increment-counter.html
│   └── manifest.json
├── src/
│   ├── actions/
│   │   └── increment-counter.ts
│   └── plugin.ts
├── package.json
├── rollup.config.mjs
└── tsconfig.json
```
上記は[https://docs.elgato.com/streamdeck/sdk/introduction/getting-started](https://docs.elgato.com/streamdeck/sdk/introduction/getting-started)から引用です。

`imgs`には、プラグインで使うアイコンなどの画像を入れます。

プラグイン導入時のデフォルトアイコン（背景画像）、Stream Deckアプリのプラグイン一覧で表示されるプラグインのアイコンなどをここに入れるようです。

`ui`には、プラグインを配置した際の設定エリアをHTMLファイルで設定します。

https://sdpi-components.dev/

`sdpi-components`というStream Deckプラグイン開発用のWebコンポーネントが準備されているようです。

`src`がプラグイン開発の本体であるソースコードです。

ドキュメントでは「`index.ts`がプラグインのエントリーポイントです」となっていますが、現時点（2024/12）では`plugin.ts`でした。
`rollup.config.mjs`に、`input: "src/plugin.ts",`という記載がありましたので、ここで指定するようです。

`actions/increment-counter.ts`がプラグインの機能の本体です。
`plugin.ts`に以下の記載があり、プラグインの機能をクラス形式で実装し、導入するようです。

```js
import { IncrementCounter } from "./actions/increment-counter";
```

# 実行方法

プラグインを実行するスクリプトは通常のNode.js環境での開発と同様に、`package.json`に記載されています。

```json
"scripts": {
    "build": "rollup -c",
    "watch": "rollup -c -w --watch.onEnd=\"streamdeck restart com.****.****\""
},
```

`npm run watch`でスクリプトを実行すると、以下のように実行されます。

```
rollup v4.28.1
bundles src/plugin.ts → com.****.****.sdPlugin/bin/plugin.js...
created com.****.****.sdPlugin/bin/plugin.js in 2.9s
watch.onEnd $ streamdeck restart com.****.****
✔ Restarted com.****.****

[2024-12-09 18:46:43] waiting for changes...
```

これを実行中に、PC上のStream Deckアプリの表示がリロードされ、アプリウィンドウ右側のプラグイン一覧に`test`カテゴリの`counter`プラグインが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/1bd50ab1-8a4d-977e-35f5-c0869bc6ac5c.png)

これで、通常のプラグインと同様にStream Deck上に配置することできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/aef18373-730b-5fe2-12fc-26ce719eac83.png)

watchスクリプトはホットリロードになっているようで、`actions/increment-counter.ts`などのソースコードを変更すると、少し時間はかかりますが、アプリおよびデバイスへ反映されました。

これは便利ですね。

公式ドキュメントでは、以降の工程で、テストプラグインのカウンター機能をバイナリカウンタにしたり、256からゼロへリセットされる機能を設けたりしています。

https://docs.elgato.com/streamdeck/sdk/introduction/your-first-changes

バイナリカウンタについては、現時点（2024/12）ではすでに、テストプラグインは増加値を1～5までに変更できる機能が設けられていました。

VSCodeと接続したデバッグ方法も、上記のページで紹介されていました。

これにより、ステップ実行をはじめとするデバッグが可能となります。

以降でも、ドキュメントではさまざまな解説がされています。

# 終わりに

Node.js環境で開発できるということで、HTML/CSS/JSに関して多少知識はある程度のわたしでも、とっつきやすさを感じました。

開発方法についても、公式ドキュメントの説明でそれほどつっかからなかったので、はじめやすいです。

今のところ、つくりたいものは思いついていないのですが、題材となるものを考えて、何かつくってみたいと思います。

もし、共有できそうな情報ができましたら、また記事にするかも知れません。

ここまで読んでくださり、ありがとうございました。
UnityでもGithub Copilotをおすすめします

Github Copilotを布教する記事です。

# 結論
UnityにおいてもGithub Copilotは有効活用できます！

VSCodeだけではなくVisual Studioでも利用可能です。
C#のときはIDE派の方もいますか？
私はそうです。

## 導入方法
ドキュメントに丸投げ

https://learn.microsoft.com/ja-jp/visualstudio/ide/visual-studio-github-copilot-install-and-states?view=vs-2022

## おすすめの利用シーン
- とりあえず導入しておく
    - クラス名やコメントから、常に予測して提案してくれます
    - 時々、心を読まれたのかと思うぐらい適切な提案がもらえます
- 一般的な処理（ドキュメントに載ってそうなこと）を実装するとき
    - そのまま動作するような高精度の提案がもらえます

## あまりお勧めできない場面
- 基礎がわからない場合
    - 的外れな提案もよくあるので、自分の中にある程度「正解」がないと有効活用はできないかも
    - とはいえ、まったくの初心者でも簡単なゲームを作れるぐらいの力もありそうです
- そのゲーム固有の知識が求められるロジック
    - 学習量が少なくなるためどうしても精度は落ちます
    - 開いているファイルを参照しているようなので、関連するファイルを開いておけば精度を上げられるかも
        - が、ほかのファイルから適当にコピペしてきました！という提案が多いのであんまりあてにならない
- リファクタリング
    - スピード重視で動作するコードを書いて直してもらうやり方を試したがうまくいかなかったのでもうやってません
        - 一切コードを変更してくれなかったり
        - 日本語のコメントを全削除されたり
        - ifをelseifに勝手に変更されたり
        etc.

ただまあ、AIは恐るべきスピードで進歩しているのでそのうち上手にこなせるようになるでしょう。

# おわりに
一般公開からもう２年もたっているんですね。
本業で開発から離れていたせいで、今年に入ってからGithub Copilotを知りました。
キャッチアップできてなくて恥ずかしい！

周知の技術だと思いますが、私みたいな人のきっかけになればと思い記事作成しました。
簡単な記事ですみません。
ユーザーストーリーを恋愛ゲームで活用してみた

## はじめに
これからの品質はユーザーストーリーということで、QAチームのメンバーと勉強した結果を業務以外…プライベートで恋愛ゲームを攻略する際に活用してみました。
そのことについて、ノリと勢いで書いていこうと思います。

## ユーザーストーリーおさらい
ユーザー目線でシステムを使ったとき、どう役に立つかを表したものです。
こんな形でまとめることが多いと思います。
- `ユーザー` として`目的`をしたい、なぜなら`価値`があるからだ
- `ユーザー`として`ニーズ`のために`目的`を達成したい

作成したストーリーを行動順や優先度に沿ってマッピングして管理します。（ユーザーストーリーマッピング）
こうすることで視覚的に捉えやすくなるほか、抜け漏れがないかなどの確認がしやすくなります。

## 恋愛ゲーム攻略とは
### 恋愛ゲームの概要
ゲーム内のキャラクターと疑似恋愛をするというジャンルのゲームです。
男性向け、女性向けなど、恋愛ゲームの中にもさまざま種類がありますが、
今回は女性向け、学園でときめく思い出を作る作品という前提で話を進めます。

### ゲームの目的
いろんな楽しみ方があるので、この記事では一番王道なものをゴールとします。

:::note info
特定の攻略キャラとハッピーエンディングを迎えること
:::

ハッピーエンドのためには、攻略キャラの好感度を上げる必要があります。
好感度は、相手が喜ぶことをする…好みを理解した振る舞いをすると向上する仕組みです。

### 面白さ
挙げたらきりがないので、今回の話に関わるところだけ。
- 複数人いる攻略キャラがとにかく濃い
- 現実の恋愛さながら思い通りにならないこそばゆさ
- 結ばれるまでの絶妙な期間の駆け引き

### 難しさ
裏を返すと、一人ひとりキャラが立っているので、全員に同じような対応をしているとハッピーエンドにたどり着けません。
ユーザーごとに求める価値が違うというわけです。

好感度を上げて、ハッピーエンドに到達したい…！
だけど、自分の思うがままに振舞ってしまうとうまくいかない。
私ならこうする、ではなく、この人は何に喜ぶのか？を考えて行動したい！
相手の価値観ってどうすれば理解できるのか…！
価値を整理するって仕事でやったな…

ということで、ユーザーストーリーの出番です。

## 情報を整理する
### 目的
- 攻略キャラの言動や背景を整理して、相手が求める行動をとれるようになりたい
- 自分の頭の中で情報まとめようとすると、思い込みで判断を誤る可能性が高いので、フォーマットに落とし込む形で整理したい
- ユーザーストーリーに慣れたい

### やったこと
以下の2点を軸に情報を整理して、確実にハッピーエンドを迎えられるように備えてみました。
- 時系列にまとめる
- 人物像をまとめる

### 時系列でまとめてみる
好みのキャラと出会えるかどうかはゲーム上確率による部分も大きいので、キャラごとの行動はまとめられません。
そこで今回は発生するイベントでまとめることにしました。

体育祭→期末試験→文化祭→クリスマスパーティ→元旦→バレンタイン→期末テスト…etc

これらのイベントの発生時期を把握しておくことで、
体育祭の前に体力を養っておこうとか、試験前に知力を身に着けようといった、自分磨きの段取りが組めます。
より素敵な状態でアピールができるというわけですね。
また、季節イベントに向けておしゃれしたりプレゼントを買ったりしやすくなるので、イベントを制しやすくなります。

戦略を練りやすくなるといった点で有効な手段でしたが、並べ替えといったマッピング要素はなかったため、整理できれば形式は何でもよさそうです。

## 相手の情報をまとめる
ユーザーストーリーに必要な情報がほぼないところからスタートなので、最初は会話を中心に情報収集します。
性格、部活、バイト先、得意と苦手、将来の夢、境遇…
直接的には得られない情報もあるので、頭の中で補完・想像することも重要です。
少しずつ情報が見えてきたら、ユーザーストーリーの形で書き出してみます。

例
- 後輩
- バイト先が同じ
    - 頼りにされると喜ぶ
- 誰かを守れる人になるという夢がある

:::note info
`頼りになる人`として`自分の成長を実感する`ために`主人公から頼りにされ`たい
:::

### 活用方法
属性や行動理由が見えてきたら、「だからどうする」に活用します。
相手がどうしてほしいのかを踏まえて、自分がどう振舞うかを決めていきます。
例として挙げたものであれば、
困りことがあったときに後輩を頼ってみる、頼もしいと伝えてみる、など。
逆に普段は人から頼られることが多くて疲れているといったキャラであれば、何かあれば支えになると伝えたり、実際にサポートするといった行動をとったりします。

完璧に理解しきることは難しいので、実際行動した後に相手のリアクションを見て適切な行動ができたかを判断します。
良ければ継続、良くなかったら次回以降のアクションを改善し、より好感度の高い状態を目指していきます。
恋愛ゲームでもPDCAサイクルを回すことがハッピーエンドの近道になるんですね。

## 書き出しての感想
恋愛ゲームでは攻略キャラの言動から最適解を考察をする必要があるので、
人物、行動、理由が整理できるユーザーストーリーの形は個人的に使いやすかったです。
なんとなくプレイするよりも理解が深まり、より世界観にどっぷり浸かれる分楽しさもマシマシでした。

マッピングについては、時系列で並べるほかに攻略キャラの心情について追記すると、よりユーザーストーリーマッピングのように活用できる気がします。
その場合、事前に推測して相手のことを理解する使い方ではなく、
相手の態度の変化を受けて記録していくことになるので、どちらかというと「だからこの時、相手の態度が変わったのか！」という答え合わせでの活用になりそうです。

今回は「価値や目的」に当たる部分が不明瞭で、人物像や行動から価値/目的を逆算するというやり方でやってみましたが、
優先されるべき価値を誤認する可能性が高くなる＝適切なアクションをとれないことが増える、といったリスクがあるため、
実際の業務では、提供したい価値はなんぞやが明らかな状態からまとめていく方がよさそうです。
恋愛ゲームをやりこめばユーザーストーリーをマスターできる、という結果にならず残念ですが、
背景から理由を推察する練習になったこと、
ユーザーストーリーは整理する手段であって作成を目的にしないこと（その後のアクションが大事）
という学びを得られたので、初心を忘れないためにも今後のプレイ時も続けていこうと思います。
STM32マイコンの選択

STM32マイコンはとてもたくさんの製品があり、どれを選べばいいのか分からないという人もいると思います。
そこで、STM32マイコンの選択の際に役立ちそうな情報をまとめてみました。

# STM32マイコンの製品名の意味
STM32マイコンには、STM32F446RET6というように「STM32」の後ろにアルファベット・数字が続いていますが、これにはそれぞれ意味があります。

STM32F446RET6を例に見てみます。
「STM32」はSTM32マイコンという意味です。
続く「F」はSTM32マイコンのカテゴリを意味しています。
Fは汎用的マイコンという意味で、困ったらこれを選ぶといいかもしれません。
|記号|意味|
|---|---|
|F|汎用|
|L|低消費電力|
|H|超高性能|
|P|Flash書き込み出荷品|

その後ろの「446」という3桁の数字は製品シリーズ名を表しています。
|記号|意味|
|---|---|
|0xx|エントリー・レベル|
|1xx,3xx|ミッドレンジ|
|2xx,4xx,7xx|ハイエンド|

ここまでがマイコンの性能に直接関係ある情報です。
F446は汎用マイコンのハイエンドモデルということですね。
高性能なものだとH723などがあります。

ここから後ろはパッケージの情報などがあります。
3桁の数字の後ろの「R」という数字はピン数を示しています。
|記号|ピン数|
|---|---|
|D|14|
|F|20|
|E|25|
|G|28|
|K|32|
|T|36|
|C|48/49|
|U|63|
|R|64/66|
|J|72|
|M|81|
|O|90|
|V|100/144|
|Q|132|
|Z|143/144|
|A|168/169|
|I|176|
|B|208|
|N|216|
|X|240|

ピン数が多いとADCが使えるピンが多かったりします。使用するピンに要件がある場合は注目してみるといいかもしれません。

続く「E」はFlashサイズが512KBであることを示しています。を示しています。
Flashとは簡単に言えばプログラムを書き込むところです。
ちなみにArduino Megaが256KB、Raspberry Pi Picoが2MBです。
|記号|サイズ(KB)|
|----|------|
| 3  | 8    |
| 4  | 16   |
| 6  | 32   |
| 8  | 64   |
| B  | 128  |
| Z  | 192  |
| C  | 256  |
| D  | 384  |
| E  | 512  |
| F  | 768  |
| G  | 1024 |
| H  | 1536 |
| I  | 2048 |

その後ろの「T」はパッケージ外形がLQFPであるという意味です。
手はんだするのであればLQFPがいいと思います。頑張ればTSSOPやUFQFPNでもできるのかもしれませんが。
それぞれがどういうパッケージなのかはネットで調べてください。

|記号|パッケージ|
|------|------------------|
| H,K  | UFBGA/TFBGA      |
| P    | TSSOP            |
| T    | LQFP             |
| U    | UFQFPN           |
| Y    | WLCSP            |

最後の数字は動作保証温度です。過酷な環境で使わないのであればあまり気にしなくて大丈夫だと思います。

|記号|動作保証温度|
|------|--------------------|
| 6    | -40 ～ +85℃       |
| 7    | -40 ～ +105℃      |
| 3    | -40 ～ +125℃      |


こちらのサイトにまとまっているのでまとめて見たい人はこちらをご覧ください。

https://www.stmcu.jp/naming/

# Nucleoボードが売られているもの
NucleoボードとはSTM32マイコンの評価ボードのことです。

動作確認をしたりブレッドボード上で軽く作ってみたいときに便利なので、Nucleoバージョンも売られているマイコンにしておくと実験がしやすいです。

下のリンクからNucleoボードの一覧が見られます。

https://www.stmcu.jp/design/hwdevelop/nucleo/


# 入手性
[秋月電子](https://akizukidenshi.com/catalog/default.aspx)など国内で売られているものだと入手性がいいのと、それだけメジャーなものだということでネットに情報も多くてはずれを引きづらいです。
Get Collection

[Previous << Get Events](https://qiita.com/flowcadence/items/da3adfa951ab7641c2c2)
[Next >> Network Status](https://qiita.com/flowcadence/items/bf5ff242f33c9f0630ff)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#flow-cli-と-fcl

Flow CLIは、Flowネットワークから任意のコレクションを取得するコマンドを提供しています。
```ruby
flow collections get <collection_id>
```

<h1>Example Usage</h1>

```ruby
flow collections get 3e694588e789a72489667a36dd73104dea4579bcd400959d47aedccd7f930eeb \
--host access.mainnet.nodes.onflow.org:9000
```

<h3>Example response</h3>

```ruby
Collection ID 3e694588e789a72489667a36dd73104dea4579bcd400959d47aedccd7f930eeb:
acc2ae1ff6deb2f4d7663d24af6ab1baf797ec264fd76a745a30792f6882093b
ae8bfbc85ce994899a3f942072bfd3455823b1f7652106ac102d161c17fcb55c
70c4d39d34e654173c5c2746e7bb3a6cdf1f5e6963538d62bad2156fc02ea1b2
2466237b5eafb469c01e2e5f929a05866de459df3bd768cde748e068c81c57bf
```
<h1>Arguments</h1>

<h3>Collection ID</h3>

* Name: `collection_id`
* Valid Input: SHA3-256 hash of the collection contents

<h1>Flags</h1>

<h3>Host</h3>

* Flag: `--host`
* Valid inputs: an IP address or hostname.
* Default: `127.0.0.1:3569` (Flow Emulator)

コマンドの実行に使用する Access API のホスト名を指定します。このフラグは、`--network` フラグで定義されたホストをすべて上書きします。

<h3>Network Key</h3>

* Flag: `--network-key`
* Valid inputs: ホストの有効なネットワーク公開鍵の 16 進数文字列

コマンドを実行する時にセキュアなGRPCクライアントを作成するために使用するAccess APIのネットワーク公開鍵を指定します。

<h3>Network</h3>

* Flag: `--network`
* Short Flag: `-n`
* Valid inputs: the name of a network defined in the configuration (`flow.json`)
* Default: `emulator`

どのネットワークに対してコマンドを実行するのかを指定します。

<h3>Filter</h3>

* Flag: `--filter`
* Short Flag: `-x`
* Valid inputs: a case-sensitive name of the result property.

結果から、唯一の値として取得したいプロパティの名前を指定します。

<h3>Output</h3>

* Flag: `--output`
* Short Flag: `-o`
* Valid inputs: `json`, `inline`

コマンド結果のフォーマットを指定します。

<h3>Save</h3>

* Flag: `--save`
* Short Flag: `-s`
* Valid inputs: a path in the current filesystem.

結果を保存したいファイル名を指定してください。

<h3>Log</h3>

* Flag: `--log`
* Short Flag: `-l`
* Valid inputs: `none`, `error`, `debug`
* Default: `info`

ログレベルを指定します。コマンド実行中に表示する出力を制御します。

<h3>Configuration</h3>

* Flag: `--config-path`
* Short Flag: `-f`
* Valid inputs: a path in the current filesystem.
* Default: `flow.json`

`flow.json` コンフィギュレーションファイルへのパスを指定します。`-f` フラグを複数回使用して複数のコンフィグレーションファイルをマージすることもできます。

<h3>Version Check</h3>

* Flag: `--skip-version-check`
* Default: `false`

低速な接続を避けて処理を高速化するために、起動時のバージョンチェックをスキップします。

*Last updated on **Nov 26, 2024** by **Giovanni Sanchez***

翻訳元

https://developers.flow.com/tools/flow-cli/get-flow-data/get-collections

***
<b>[Previous << Get Events](https://qiita.com/flowcadence/items/da3adfa951ab7641c2c2)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Get Collection)

<b>[Next >> Network Status](https://qiita.com/flowcadence/items/bf5ff242f33c9f0630ff)</b>
Gradle bulidでPlugin [id: 'org.springframework.boot', version: '3.3.2'] was not found in any of the following sources:

久々にハマったのでメモ

昨日まで普通にビルドできていたのに、gradleのキャッシュクリアしてからgradle buildするとビルドできなくなった。結論からいうとMcafeeのファイアーウォールのせいだった。。


やっていたこと

```
$ ./gradlew clean build --refresh-dependencies

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/yukiyoshimura/dev/otegalu/backend/build.gradle.kts' line: 1

* What went wrong:
Plugin [id: 'org.springframework.boot', version: '3.3.2'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'org.springframework.boot:org.springframework.boot.gradle.plugin:3.3.2')
  Searched in the following repositories:
    Gradle Central Plugin Repository
```

このようにbuildeでエラーになるが、以下は存在するのになぜnot foundかわからなかった。

```
Plugin [id: 'org.springframework.boot', version: '3.3.2'] was not found in any of the following sources:
```


```
# debugオプションをつけてみる
./gradlew clean build --refresh-dependencies --debug

# 問題の箇所を抜粋
[INFO] [org.apache.http.impl.execchain.RetryExec] I/O exception (java.net.SocketException) caught when processing request to {s}->https://plugins.gradle.org:443: Broken pipe
```

通信ができていないようだ。

調べた結果、Mcafeeのファイアーウォール設定が原因だった。ファイアーウォールを一旦無効にするとうまくいった。
https://youtrack.jetbrains.com/issue/IDEA-345272/Connection-failed-Broken-pipe.-Please-check-network-connection-and-try-again.

都度ファイアーウォールを無効にするのは手間がかかるのでいい解決方法がわかったら更新する。。
【2024年度版】アクセシビリティ・デジタル・Web・AI・UX・IT 資格まとめ

## 資格を受ける意義
本記事に掲載した資格は、所持せずとも働けるような分野の資格が多いと思います。
しかし、その分野の**学びのモチベ**にしたり・見聞を広げる・将来への投資という意味では、資格はとても有用だと思うので、ぜひ興味がある方は役立てていただければと思います。

個人的にはUX・アクセシビリティら辺に興味があるので、勉強中です。

:::note warn
私自身が受験したことないものも多数あるので、詳しい詳細は各資格の公式サイトを見ていただければと思います。
:::

## 資格一覧
:::note
内容は随時更新していきます。
また今回は、クラウド関連の資格は掲載していません。すでにまとめ記事等が多く出回っている気がするためです。
:::

### **I. アクセシビリティ関連資格**

**デジタルアクセシビリティアドバイザー認定試験** 

https://daa.ne.jp/

- 受験時期：オンラインで通年受験可能
- 受験料：
    - Basicレベル：5,500円（税込）
    - Standardレベル：7,700円（税込）
    - Professional 　 準備中

### **II. デザイン関連資格**

**アドビ認定プロフェッショナル**

https://adobe.odyssey-com.co.jp/

- 受験時期：通年（オンライン受験可能）
- 受験料：10,780円（税込）（学割だと 8,580円（税込））

**Photoshopクリエイター能力認定試験**

https://www.sikaku.gr.jp/ns/ps/

- 受験時期：通年（CBT方式）
- 受験料：
  - スタンダード：7,800円
  - エキスパート：8,800円

**Illustratorクリエイター能力認定試験**

https://www.sikaku.gr.jp/ns/il/

- 受験時期：通年（CBT方式）
- 受験料：
  - スタンダード：7,800円
  - エキスパート：8,800円

**CGクリエイター検定**

https://www.cgarts.or.jp/

- 受験時期：年2回（7月・11月）
- 受験料：
  - ベーシック：5,600円
  - エキスパート：6,700円

**色彩検定**

https://www.aft.or.jp/

- 受験時期：年2回（6月・11月）（1級は11月のみ）
- 受験料：
  - 1級：15,000円
  - 2級：10,000円
  - 3級：7,000円
  - UC級：6,000円

**JIDAデザイン検定**

https://jida-design-kentei.studio.site/#about

- 受験時期：通年？
- 受験料：
  - アカデミック（学生会員、準会員、一般学生）：8,800円
  - 一般（正会員、賛助会員、一般社会人）：11,000円  
<sub>※資格登録料が受験料とは別途かかります</sub>

### **III. Web関連資格**

**ウェブデザイン技能検定**

https://www.webdesign.gr.jp/

- 受験時期：年4回（5月・8月・12月・2月　※1級は年1回）
- 受験料：
  - 1級：33,000円
  - 2級：23,000円
  - 3級：14,000円（※23歳未満の在職者は4000円、※23歳未満の在職者以外は6000円）

**HTML5プロフェッショナル認定資格**

https://html5exam.jp/

- 受験時期：通年（CBT方式）
- 受験料：
  - レベル1：16,500円
  - レベル2：16,500円

**PHP技術者認定試験**

https://www.phpexam.jp/

- 受験時期：通年（CBT方式）
- 受験料：
  - 初級：12,000円
  - 上級：15,000円

**Webクリエイター能力認定試験**

https://www.sikaku.gr.jp/web/wc/

- 受験時期：通年（CBT方式）
- 受験料：
  - スタンダード：6,100円
  - エキスパート：7,700円

**ウェブ解析士**

https://www.waca.associates/

- 受験時期：通年（月2回 CBT方式）
- 受験料：
  - スタンダード：17,600円


### **IV. AI関連資格**

**Pythonエンジニア認定試験**

http://cbt.odyssey-com.co.jp/

- 受験時期：通年（CBT方式）
- 受験料：
  - 基礎：11,000円
  - 実践：13,200円

**G検定**

https://www.jdla.org/certificate/general/

- 受験時期：年3回（11月・1月・3月）
- 受験料：13,200円（税込）

**E資格**

https://www.jdla.org/certificate/engineer/

- 受験時期：年2回（8月・2月）
- 受験料：33,000円（税込）

### **V. UX関連資格**

**人間中心設計専門家（HCD-Net認定）**

https://www.hcdnet.org/certified/about/

- 受験時期：年1回（11月）
- 受験料：12,000円

**UX検定**

https://www.uxia.or.jp/certification/

- 受験時期：通年（オンライン受験可能）
- 受験料：
  - 基礎：9,900円

**Google UXデザイン プロフェッショナル認定**

https://www.coursera.org/professional-certificates/google-ux-design

- 受験時期：通年（オンライン受験可能）
- 受験料：49ドルから

### **VI. IT関連資格（基本情報系）**

**基本情報技術者試験**

https://www.ipa.go.jp/shiken/kubun/fe.html

- 受験時期：通年（CBT方式）
- 受験料：7,500円（税込）

**応用情報技術者試験**

https://www.ipa.go.jp/shiken/kubun/ap.html

- 受験時期：年2回（春期・秋期）
- 受験料：7,500円（税込）

**情報セキュリティマネジメント試験**

https://www.ipa.go.jp/shiken/kubun/sg.html

- 受験時期：通年（CBT方式）
- 受験料：7,500円（税込）

**ITストラテジスト**

https://www.ipa.go.jp/shiken/kubun/st.html

- 受験時期：年1回（春期）
- 受験料：7,500円（税込）

:::note alert
注意事項：
- 受験料は2024年12月現在の金額です。変更される可能性があります
- 一部の資格は、受験地域や受験方法によって料金が異なる場合があります
- 各資格の詳細な試験日程は、各試験実施団体の公式サイトで確認することをお勧めします
:::
材料力学「一端固定、他端移動支持の突き出しはりの自由端Bに集中荷重P」(2/3)問題文だけで、図がない場合,AI先生に聞きました。

(再)以下おすすめです。
https://qiita.com/mrrclb48z/items/369b66044a32fdc3c8ee#sympy%E3%81%A7bettis-theorem%E3%81%A7
　

 **できませんでした。**
・問題文だけでで、**図がない場合**で,AI先生に聞きました。
・タイトル変更予定。(2024-12-09)

:::note info
前　 [(1/3) sympyでやってみたい。
](https://qiita.com/mrrclb48z/items/369b66044a32fdc3c8ee)次　 [(3/3) マクスウェルの相反定理をAI先生に聞きました。
](https://qiita.com/mrrclb48z/items/e228d48bc3d66195f9aa)

:::


 # オリジナル
(以下は、私が2箇所修正済みです。集中加重→集中荷重。Iy→I)
```
材料力学の問題なのですが・・・
問題：一端固定、他端移動支持の突き出しはりの自由端Bに集中荷重Pが作用している。
このとき、反力RA、RCおよび反モーメントMAを求めよ。また、自由端におけるたわみを求めよ。ただし、
はりの縦弾性係数をE、断面二次モーメントをIとする。
```
回答省略

# Gemini先生へ
```
上記をsympyでお願いします。
```
```
コードを一つにして下さい。
```
??? Gemini先生は、一気に数値入力、matplotlib作図です。
??? 私は聞き方、修正方法がわからないので、あきらめました。


# Chat先生へ
```
反力の位置はaで、自由端の位置はa+ｂで。sympyのコードをお願いします。
```
コード省略

私の実行結果。
KeyError: MA

私の力不足で、あきらめました。


# copilot先生へ
Python 辞書のマージ方法まとめ

2つの辞書をマージする方法についてまとめ

## アンパック
python 3.5以降
アンパックにより、辞書のすべてのキー、バリューが展開される。

```python
dict1 = {"name": "Grace", "age": 33}
dict2 = {"city": "Kobe", "country": "Japan"}
dict_merge = dict(**dict1, **dict2)
```

## update
updateメソッドは破壊的に更新

元の辞書にキーと値を追加する。

```
# dict1を更新
dict1.update(dict2)

print(dict1)
```

#### キーの競合
キーが競合する場合は、追加した値で更新する。

```python
dict1 = {"name": "Alice"}
dict2 = {"city": "Tokyo"}
dict1.update(dict2)
print(dict1)  # {'name': 'Alice', 'city': 'Tokyo'}
```

## 元の辞書を変更せずにマージ
`copy()` を使用する
```python
dict1 = {"name": "Alice", "age": 25}
dict2 = {"city": "Tokyo", "age": 30}

# dict1を変更せずにマージ
merged_dict = dict1.copy()
merged_dict.update(dict2)

print("dict1:", dict1)          # {'name': 'Alice', 'age': 25}
print("merged_dict:", merged_dict)  # {'name': 'Alice', 'age': 30, 'city': 'Tokyo'}
```


## `|` 演算子
`|` 演算子は新しい辞書を返す。元の辞書は変更しない。
イミュータブルな操作ともいう。
python 3.9以降

```python
dict1 = {"name": "Grace", "age": 33}
dict2 = {"city": "Kobe", "country": "Japan"}
dict_merge = dict1 | dict2
print(dict_merge)
```

#### キーの競合

同じキーが両方の辞書に存在する場合、右側の辞書 (dict2) の値が優先されます。

```python
dict1 = {"key": "value1"}
dict2 = {"key": "value2"}
dict_merge = dict1 | dict2
print(dict_merge)  # {'key': 'value2'}
```

## まとめ


| 方法                       | サポートバージョン     | 特徴                                                          | 破壊的操作                              | 重複キー時の挙動       | メモリ効率性         | サンプルコード                                                 |
| ------------------------ | ------------- | ----------------------------------------------------------- | ---------------------------------- | -------------- | -------------- | ------------------------------------------------------- |
| `update()`               | 2.x 以降 | 元の辞書を直接更新する方法。                                              | はい                                 | 右側の辞書の値で上書きされる | 高い             | `dict1.update(dict2)`                                   |
| `{**dict1, **dict2}`     | 3.5 以降 | 新しい辞書を作成するため、元の辞書は変更されない。                                   | いいえ                                | 右側の辞書の値で上書きされる | 中程度            | `merged_dict = {**dict1, **dict2}`                      |
| `dict(**dict1, **dict2)` | 3.5 以降 | `{**dict1, **dict2}` の代替。`dict()` コンストラクタを使って明示的に辞書を作成する方法。 | いいえ                                | 右側の辞書の値で上書きされる | 中程度            | `merged_dict = dict(**dict1, **dict2)`                  |
| `\|` 演算子        | 3.9 以降                                               | シンプルで直感的な方法。新しい辞書を作成し、元の辞書は変更されない。 | いいえ            | 右側の辞書の値で上書きされる | 高い                                                      |
| `\|=` 演算子       | 3.9 以降                                               | 元の辞書を直接更新する破壊的操作。                  | はい             | 右側の辞書の値で上書きされる | 高い                                                      |
| `copy() + update()`      | 2.x 以降 | 元の辞書を変更せず、新しい辞書を作成する方法。                                     | いいえ                                | 右側の辞書の値で上書きされる | 低い             | `merged_dict = dict1.copy(); merged_dict.update(dict2)` |
エンジニアじゃないけど、PAY.JPを使って雰囲気を感じてみた

## はじめに
初めまして、BASE株式会社の神宮司です。普段の仕事は、ネットショップ作成サービス「BASE」のプロダクトの責任者と、Pay IDというショッピングサービスの事業責任者をしてます。だいぶ前ですがエンジニア職も通っておりまして、PAY.JPロンチ時には、MVCの概念も分からぬままに、Reactをヒーヒー言いながら書いていました。

## 今回は何をしてみたのか
PAY.JPロンチ時のコードを書いていたのに、そもそもPAY.JPを利用した経験がない！ということを、このアドベントカレンダーを通して思い出したのでPAY.JPを使った簡易サイトを作って雰囲気を感じた。という記事です。

年の瀬の時期なのでそれに合わせて簡単におみくじサイトを作りました。テストモードでのPAY.JP利用のため実際には課金は行われませんし、[テストカード](https://pay.jp/docs/testcard)しか利用できません。テストカード情報を入力して安心しておみくじを引いてください。

念のため本番利用ができるクレジットカード情報は絶対に入れないでください。

## 作ったサイト
作成したおみくじのサイトは[こちら](https://gleeful-lily-fd1ec9.netlify.app/)です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10731/770bc0e2-6ed4-375f-5d12-07de913ef970.png)
https://gleeful-lily-fd1ec9.netlify.app/

イースターエッグ的なものも仕込んであるので興味があれば、遊んでみてください。

## PAY.JPの雰囲気を感じてみて
決済処理の複雑なところを簡単に理解しやすくAPIを提供してくれているのでサクサク進みました。困った時には都度ChatGPTに聞きながら進めていくという感じで特段つまづくこともなくサイトを作ることができました。個人的には雰囲気を感じることができただけでも満足です。

個人開発している方も是非触ってみていただけると良さそうです。
記号だけ！Brainfuckってどんな言語？

# Brainfuck
世の中にはたくさん言語がありますが、
**Brainfuck**という言語を知っていますか？
名前からしてヤバそうですが、ちょっと調べてみました

# 文法
なんとこの言語は、**8つの記号だけ**を使用してプログラムします。
そのため、Hello worldを書くと...
```brainfuck:Hello world in brainfuck
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
```
みたいに意味不明なコードになります。
この言語を習得出来たらすごいですね。
~~Qiitaのコードブロックに対応してることに衝撃を受けた~~

# 名前の由来
頭がおかしくなるような文法だからだそうです。
そりゃ、そうか。
rp2040のpio その2

# 概要
ラズパイpicoのpioは、小さいcpuです。
verilogが手に入ったのでやってみた。
Lチカ、やってみた。

# テストベンチを書いた。

```
`timescale 1ns/100ps
module test();
	localparam NONE = 0;
	localparam INSTR = 1;
	localparam PEND = 2;
	localparam PULL = 3;
	localparam PUSH = 4;
	localparam GRPS = 5;
	localparam EN = 6;
	localparam DIV = 7;
	localparam SIDES = 8;
	localparam IMM = 9;
	localparam SHIFT = 10;
	reg clk;
	reg reset;
	reg [31:0] din;
	reg [4:0] index;
	reg [3:0] action;
	reg [1:0] mindex;
	reg [31:0] gpio_in = 0;
	reg [15:0] program[0:31];
	wire [31:0] gpio_out;
	wire [31:0] gpio_dir;
	wire [31:0] dout;
	wire [3:0] tx_full;
	wire [3:0] rx_empty;
	wire [5:0] plen = 2;
	wire [23:0] div = 24'h0280;
	wire [31:0] pin_grps = 32'h04000000;
	wire [31:0] exec_ctrl = 32'h00001000;
	wire out;
	assign out = gpio_out[0];
	task act(input [3:0] a, input [31:0] d);
		begin
			@(negedge clk);
			action = a;
			din = d;
			@(posedge clk);
		end
	endtask
	pio u(.clk(clk), .reset(reset), .action(action), .index(index), .mindex(mindex), .din(din), .dout(dout), .gpio_in(gpio_in), .gpio_out(gpio_out), .gpio_dir(gpio_dir), .tx_full(tx_full), .rx_empty(rx_empty));
	integer i;
	initial
	begin
		clk = 1'b0;
	end
	initial
	begin
		program[0] <= 16'he1_01;
		program[1] <= 16'he1_00;
	end
	initial
	begin
		reset = 1'b1;
		repeat(2) @(posedge clk);
		reset = 1'b0;
		for (i = 0; i < plen; i++)
		begin
			index = i;
			act(INSTR, program[i]);
		end
		mindex = 0;
		act(PEND, exec_ctrl);
		act(DIV, div);
		act(GRPS, pin_grps);
		act(EN, 1);
		act(NONE, 0);
		repeat(100) @(posedge clk);
		$finish;
	end
	always
	begin
	#20
		clk = !clk;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$display("                time action din out ");
		$monitor("%t %h %h %h ", $time, action, din, out);
	end
endmodule





```

# 実行結果

```
>vvp a.out
VCD info: dumpfile test.vcd opened for output.
                time action din out
                   0 x xxxxxxxx x
                 200 x xxxxxxxx 0
                 800 1 0000e101 0
                1200 1 0000e100 0
                1600 2 00001000 0
                2000 7 00000280 0
                2400 5 04000000 0
                2800 6 00000001 0
                3200 0 00000000 0
                4600 0 00000000 1
                6600 0 00000000 0
                8600 0 00000000 1
               10600 0 00000000 0
               12600 0 00000000 1
               14600 0 00000000 0
               16600 0 00000000 1
               18600 0 00000000 0
               20600 0 00000000 1
               22600 0 00000000 0
               24600 0 00000000 1
               26600 0 00000000 0
               28600 0 00000000 1
               30600 0 00000000 0
               32600 0 00000000 1
               34600 0 00000000 0
               36600 0 00000000 1
               38600 0 00000000 0
               40600 0 00000000 1
               42600 0 00000000 0
pio4.v:916: $finish called at 43400 (100ps)
```

# uart_rxは、こちら

https://qiita.com/ohisama@github/items/cf60b6f27f5229cc047c


# uart_txは、こちら

https://qiita.com/ohisama@github/items/bfc50d745eeae86b5420

# spiは、こちら

https://qiita.com/ohisama@github/items/baf18a2b600492832389

以上
【VSCode拡張】Foamを使ってZettelkasten方式でメモを取る方法


はじめまして、I-kunと申します。
A-kun ひとり Advent Calender 9日目です。

## はじめに

Foamは、個人の知識管理を効率化するためのVSCode向けオープンソースツールです。本記事ではFoamの特徴、導入方法、活用方法を解説します。

## この記事を読んで欲しい人

- Zettelkasten方式に興味がある人
- ローカルでの知見管理に興味がある人
- 急に餃子が食べたくなってきてしまった人

## サービスの特徴

Foamの特徴は、まずなんといってもZettelkasten方式のメモを残せることです。

Zettelkasten方式とは、ドイツ語で「メモ箱」という意味です。メモを箱に入れて整理するイメージです。メモ同士をリンクさせることで、メモ同士の関連性を可視化することができます。

詳しくは、佐藤かえでさんのこの動画がわかりやすいです。

<iframe width="1553" height="400" src="https://www.youtube.com/embed/5IaaGi4Z4Tg" title="メモのタイトルに文章を書いたほうがいい理由 #ツェッテルカステン" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<iframe width="320" height="400" src="https://www.youtube.com/embed/6M-H02MAIhk" title="ツェッテルカステンを２年間続けた結果と変化" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

こんな感じに記事同士を関連づけて、グラフ表示することができます。

[![Image from Gyazo](https://i.gyazo.com/fb33fcebfd74ca1c7d385ac81fd67d14.jpg)](https://gyazo.com/fb33fcebfd74ca1c7d385ac81fd67d14)

その他、Foamの設計思想については公式がまとめています。

https://foambubble.github.io/foam/principles

## サービスの導入方法

FoamはVSCodeの拡張機能としてインストールすることで利用できます。

[![Image from Gyazo](https://i.gyazo.com/f429a49798380cd5621226abf3c7539d.png)](https://gyazo.com/f429a49798380cd5621226abf3c7539d)

正常に動作しない場合は、下記のリンクから推奨される拡張機能をインストールしてみて下さい。

https://foambubble.github.io/foam/user/getting-started/recommended-extensions

下記テンプレートから簡単にリポジトリを生成することができます。

https://github.com/foambubble/foam-template

## 使い方

自分がよく使うものは下記です。

### Graphを表示

cmmand + shift + p でコマンドパレットを開き、Foam: Show Graphを選択することで、メモの関連性をグラフで表示することができます。また、Controlsの欄から、表示するノードをフィルタリングできます。

[![Image from Gyazo](https://i.gyazo.com/d1d168b1e4c237c975fc1458ac04707f.png)](https://gyazo.com/d1d168b1e4c237c975fc1458ac04707f)

### 記事から記事へのリンク

1. Markdownでメモを取る
2. メモA.mdからメモB.mdへリンクを作りたいときは、メモAの記事内で[["メモB"]]と入力する

これで記事間のリンクが作成されます。

### タグを使ったリンク

#hogehoge と入力することで、タグが作成されます。

複数の記事で同じタグを使うことで、関連記事を見つけやすくなります。

### Githubを使った共有・バージョン管理・公開

Githubを使うことで、メモを他の人と共有したりすることができます。PRなどでバージョン管理もできるので、チームでの利用も可能です。

また、Github Pagesを使うことで、外部に公開することもできます。

詳しくは公式ドキュメントを参照して下さい。

こちらの記事に詳細な機能はまとまっています。

https://foambubble.github.io/foam/user/recipes/recipes

## まとめ

Foamは、個人の知識管理に特化したツールとして優れています。特に、ローカル環境での安全性やZettelkasten方式によるリンクの可視化が魅力です。Markdown形式を利用した拡張性も高く、Githubを用いたチームの知識管理にもおすすめです。
ソファ問題の受話器型の元祖を調べた。

# 解決？
2024年11月29日にJineon Baekさんが、ソファ問題を解決したとする論文を発表したらしい[^1]。それによると、最大は1992年にジョセフ・ガーバーさんが見つけた図形で、値は2.2195...となる。
論文は119pにわたり、もちろん英語で書かれているので、理解するのは骨が折れそう。
そこで、ガーバーさんの前に、1968年ジョン・ハマーズレイさんが発見した、いわゆる**受話器型の元祖**の図形をみていく。
![受話器型](https://upload.wikimedia.org/wikipedia/commons/c/c1/Hammersley_sofa_animated.gif)

# 受話器型の図形
$1 \times \frac{4}{\pi}$の長方形の両脇に半径1の四分円を接合させた図形から、直径$\frac{4}{\pi}$ の半円をくりぬいた図形。面積は、 $\frac{\pi}{2} + \frac{2}{\pi} \approx 2.207416$となる。
ふと、数学的証明があるのかなと思った。wikipedia[^2]によると、[ココ](https://archive.org/details/hammersley1968/page/83/mode/2up)を参照のよう。p.84のAppendix IV Problems の Problem 8に以下の通り書いてある。

> Problem 8. A long passage of unit width has a right-angled bend in it. A flat rigid plate of area A (always kept flat on the floor) can be manoeuvred from one end of the passage to the other. Prove that $A<2\sqrt{2}$. Show also that, if the plate has a suitable shape (to be determined), we may have
$$ A = \frac{\pi}{2} + \frac{2}{\pi}. $$
Is this the largest possible value for A?

翻訳すると（by DeepL）
単位幅の長い通路が直角に曲がっている。 面積Aの平らな剛体板（常に床に平らに置いておく）を通路の端から端まで動かすことができる。 このとき、$A<2\sqrt{2}$であることを証明せよ。 また、板が適当な形をしていれば（これから決める）、Aの式が成り立つことを示せ。
これはAの取りうる最大の値か。

どうやら、数学的証明が乗っているわけではなかった。
もうひとつのwikiリンク[^3]では、Hammersley's Sofaとして、

> Hammersley showed the the largest area is at least p/2 + 2/p via the following:
![Hammersley's Sofa](https://web.archive.org/web/20080107101427im_/http://mathcad.com/library/constants/sofa_images/IMG1248.PNG)
![2.20](https://web.archive.org/web/20080107101427im_/http://mathcad.com/library/constants/sofa_images/IMG1249.PNG)
The region consists of two quarter-circles on either side of a 1 by 4p rectangle from which a semicircle of radius 2/p has been removed.

コンピュータで描画された図があった。Gerver's Sofaでは、Givenのあとに数式がズラーっとあったが、ハマーズレイのソファーは数学的証明というより、発見されたということなのだろうか。
その後も、ハマーズレイのソファーが通路に引っかからないという証明は検索しても見つからなかった。まあ、GIFでみれば一目瞭然なのだろうけど、もしかしたら内側の角が干渉してるんじゃないか？とか心配になるのは私だけだろうか？

[^1]:[[2411.19826] Optimality of Gerver's Sofa](https://arxiv.org/abs/2411.19826)
[^2]:[ソファ問題 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%82%A1%E5%95%8F%E9%A1%8C)
[^3]:[Moving Sofa Constant(アーカイブ版)](https://web.archive.org/web/20080107101427/http://mathcad.com/library/constants/sofa.htm)
【Unity】ML-Agentsで機械学習をしよう！① 導入編

# 先に言っておきます！
この記事の内容を終わらせたら、
Unityで強化学習をすることができるようになります！
そのために、ML-Agentsというライブラリを使いますが、
ダウンロード手順も解説するので簡単にできると思います！

:::note info
導入について分からないことがあったらコメントなどで
教えてください！可能な範囲で答えます:cheese::cake:
:::

# 0.事前準備
- ソフトのインストール
Unity (筆者は6000.0.26f1を使います)
- Unityで「3D (Built-In Render Pipeline)」のプロジェクトを作成
:::note warn
必ず、**3D (Built-In Render Pipeline)で作成してください。**
Universal 3Dにすると、物体がすべて紫色になります。
:::

# 1.ML-Agentsをダウンロードする
https://github.com/Unity-Technologies/ml-agents/tree/release_22

上のリンクを開いたら、ページ下部の[download]を押してください
![ML-Agents-download-page](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930283/50cdaf69-5e2d-0ab6-a5f1-06e2cbbc4c3e.png)
ダウンロードはこれで完了です。

# 2.ディレクトリを移動
ダウンロードされたZIPファイルの中の「ml-agents-release_22」というフォルダを
どこでもいいのでコピーしてください。
```text
ml-agents-release_22
└ Project
    └ Assets
        └ ML-Agents
```
コピーされたフォルダの「Project/Assets/ML-Agents」を
自分のプロジェクトの「Assets」にコピーしてください。

# 3.パッケージをインストール
パッケージマネージャーを開いてください。
(Window -> Package Manager)
![Unity_Package_Manager_1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930283/8ba280dc-3afb-7e55-0fd1-53d8a4714f15.png)
「Git URLからパッケージをインストール...」を押して、
そこに、2つの文字列を一回ずつ入れてください。
```text:文字列
com.unity.ml-agents
com.unity.nuget.newtonsoft-json
```
終わったら今度は「ディスクからパッケージをインストール...」をします
Jsonファイルを選択するよう言われるので、
「ml-agents-release_22/com.unity.ml-agents.extensions/package.json」
を選択してください。

:::note
途中で「Some of this projects source files refer to API that has changed. These can be automatically updated. It is recommended to have a backup of the project before updating. Do you want these files to be updated?」と聞かれたら、左のYesを押して下さい。
:::

:::note
2025/3/17 追記
Unity RegistryのRecorderというパッケージもインストールしないと
エラーが発生するようです。
:::

# 4.サンプルを動かそう！
これでサンプルを動かす準備ができました。
とりあえず最初は、
「Assets -> ML-Agents -> Examples -> PushBlock -> Scenes」の
「PushBlock.unity」を開いて実行してください。
![PushBlock](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930283/fc340083-42a6-ef66-6a72-61fc7e89fbc1.gif)
青い四角が白い物体を運ぶはずです！
他のサンプルも面白いのでよかったら見てください！

# おわりに
どうでしたか？Unityでここまで出来るんです！
これは学習済みのAIなので、次回は自分で学習させてみましょう！