OmniAICreator/Qiita-1.07M huggingface dataset:
solana 開発勉強日誌7　jitobundleの理解を深める

https://adventar.org/calendars/10211

###### 今回の記事はSolana Advent Calendar 2024　12/2　記事です。





理解度がまだ浅いですが、jitobundleへの理解はsolanaを触る上で必要な知識だと思います。一緒に学んで行きましょう。







https://speakerdeck.com/andooown/jitowoshi-tutamev-botru-men-super-tokyo-tech-night

andooownさんの説明がとても分かりやすいです。








solanaでTxを通そうとすると、
⓵優先手数料（Prioritization Fees）を増やす
⓶jitobundleを使用する
⓷検知を早くする
の上記3つに分かれてると思います。

⓷は初級中級には難しい為現状できるとすれば、⓵⓶に取り組むのが良いのかなという印象。


# Miner Extractable Value
Jito は MEV（Miner Extractable Value　=　意訳するとバリデーターが得られる最大利益）において優先事項として、バリデーターとステーカーが MEV 報酬の取り分を最大化できるようにしながら、負の要因を最小化すること。と書かれています。

負の要因というのはネットワークの公平性の損失が考えられます。具体的に例をあげると



##### ⓵フロントランニング


ユーザーのトランザクションをバリデーターやブロックプロデューサーが先読みして利益を得る行為（例: 他人の取引を先回りして有利な価格で売買する）

###### ⓶サンドイッチ攻撃


ネットワークの信頼性低下
特定のトランザクションの前後に取引を挿入して利益を得る行為
被害者となるユーザーが損失を被る






# jitobundle


jitobundleを使う事でSolana ブロックチェーン上で複数のトランザクションを順次かつアトミックに実行できます。その重要性を理解するために、まずいくつかの重要な特性を確認しましょう。


| 特性 | 説明 |
|:-----------------------:|:------------:|
| 順次実行    |bundle内のTxは、並んだ順序で実行されることが保証     |
| アトミック実行	      |bundle内のすべてのTxは同じスロット内で実行     |
| 全か無かの結果	     | bundle内のいずれかのTxが失敗した場合、全てのTxが失敗     |
|bundleサイズ	  | bundleあたり最大 5 つのTxを内包(今後増えるらしい)         |

基本的な流れの図

![スクリーンショット 2024-11-29 020810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/53a55cf9-7d97-274a-52e3-e4ecb6bda6f4.png)





Solanaで送信する１つのTx内の計算制限は 140 万 CU（ 最大1232 バイト
１つのTxに最大1232 バイトしか詰めれないので裁量取引（アービトラージ）以外においても
不具合が起こる可能性があります。


###### 計算リソース制限（140万CU）によるリスク
複数の処理を1つのトランザクション内で実行する必要がある場合、計算リソースの制限を超えるとトランザクションが失敗します。この結果、一部の操作が完了せず、データの整合性が崩れる可能性があります。

###### 複雑な取引の制限

高度なロジックや複数の契約を絡めた複雑なトランザクション（例: アービトラージ取引や複数のプロトコル間のスワップ）が実行できない可能性があります。


<BR>
<BR>


jitobundleがある事で単純計算700万CUの処理が行える事になります。
今後のsolana上でゲームやRWA、DEPIN等の更に複雑なプロジェクトが出てきても処理が行えるjitobundle。とても重要な事が分かると思います。

<BR>
<BR>


例えばSOL-USDCのLPプールがあり、現在SOLしか持っていない場合だと
⓵SOL-USDCのスワップ
⓶LPへデポジット
⓷デポジット証明のNFT発行
<BR>

３つの手順が必要ですが、jitobundleを使う事による単純計算700万CUの処理が行える事により、⓵⓶⓷３つのTxをアトミックに処理する事も可能になります


<BR>

<BR>

# jitobundleを使ってみる


現在jitobundleを使ってそのまま動かせるプログラムです。
raydiumのSOL-USDCプールを指定してSWAPする内容です
<BR>


テスト稼働用のウォレットで動かしましょう


<BR>


https://github.com/coolcode/solana-jito-swap.git

<BR>
<BR>



```rb
git clone https://github.com/coolcode/solana-jito-swap.git
```

```rb
cd solana-jito-swap
```
```rb
mkdir markets
curl https://api.raydium.io/v2/sdk/liquidity/mainnet.json -o ./markets/raydium.json
```
```rb
npm install
```



```rb
npm start
```



![スクリーンショット 2024-11-29 130328.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/a252ab6e-073b-c2dc-2b7e-e2b2c10f17af.png)




Txが通ったらJito Explorerで確認してみましょう！！
<BR>
<BR>
<BR>
<BR>
<BR>
<BR>

参考資料など↓



https://explorer.jito.wtf/



https://www.quicknode.com/guides/solana-development/transactions/jito-bundles



https://docs.jito.wtf/
AtCoder ABC381 復習(緑コーダーがPythonでA〜Cを解答)

## ABC381 感想まとめ

今回は珍しく、金曜日の21時から開催。私は平日のため仕事に疲れ果てて降り、寝てしまっていました。そのため、土日に復習で問いたものを掲載します。

## [A - 11/22 String](https://atcoder.jp/contests/abc381/tasks/abc381_a)

問題文中の 11/22 文字列 をあらかじめ作っておいて、それと入力 S を比較しました。

``` python
N = int(input())
S = input()

half = (N + 1) // 2 - 1 # 半分の長さ
str = "1" * (half) + "/" + "2" * (half) # 11/22の文字列を作る

if S == str:
    print("Yes")
else:
    print("No")
```

## [B - 1122 String](https://atcoder.jp/contests/abc381/tasks/abc381_b)

問題文に数式が入っていてが若干わかりにくかった（麻雀を知っている人向けには、「数列がチートイツ かどうかを判定する問題」と言い換えられる）。

回答は、与えられた条件を順にチェックして、最後まで残ったら Yes という流れにしました。


``` python
S = input()

# 偶数チェック
if len(S) % 2 != 0:
    print("No")
    exit()

# ペアチェック
for i in range(1, len(S), 2):
    if S[i-1] != S[i]:
        print("No")
        exit()

# 個数==2 かチェック
counter = defaultdict(int)
for s in S:
    counter[s] += 1

for k, v in counter.items():
    if v != 2 :
        print("No")
        exit()
``` 

## [C - 11/22 Substring](https://atcoder.jp/contests/abc381/tasks/abc381_c)

下記のような流れで処理しました。

1. "1"の数をカウント(この段階では、"1" 以外の文字はスルー)
1. "1"の連続の後に "/" が来るか判定
1. "/" の後に "2" の連続があるか判定
    1. ここで、条件を満たす文字列が出来るなら、その長さを更新する

文字をカウントする one_counter, two_counter, slash_counter を用意し、パターンに応じて増やしたり初期化したりします。

``` python
N = int(input())
S = input()

one_counter = 0 # 1 のカウンター
two_counter = 0 # 2 のカウンター
slash_counter = 0
answer = 0 # 答えを格納

for i in range(N):
    # "1"の数をカウント
    if S[i] == '1':
        if slash_counter > 0 or two_counter > 0:
            one_counter = 0
        one_counter += 1
        two_counter = 0
        slash_counter = 0
        continue

    if S[i] == '/':
        slash_counter += 1
        # slashがあれば、最低1にはなる
        answer = max(answer, 1)

        two_counter = 0
        continue   

    if S[i] == '2':
        # "1"の連続の後に "/" が来るか判定
        if slash_counter != 1 or one_counter == 0:
            slash_counter = 0
            one_counter = 0
            two_counter = 0
            continue

        # "/" の後に "2" の連続があるか判定
        two_counter += 1
        if slash_counter == 1:
            if one_counter > 0:
                # 条件を満たす文字列が出来るなら、その長さを更新する
                same_count = min(one_counter, two_counter)
                answer = max(answer, same_count * 2 + 1)
        else:
            # slash がない or 多い場合はリセット
            slash_counter = 0
            one_counter = 0

print(answer)

```
gradle install

# gradle set up
gradle setupのtipsです。

## brewでエラーが出る方へ

macOSでのgradleのinstallにはbrewを使用しますが、macOSが古かったりすると失敗します。


```bash
brew install gradle
```

このエラーが出る方。
<details><summary>Error</summary>

```bash
Error: You are using macOS 12.
We (and Apple) do not provide support for this old version.
It is expected behaviour that some formulae will fail to build in this old version.
It is expected behaviour that Homebrew will be buggy and slow.
Do not create any issues about this on Homebrew's GitHub repositories.
Do not create any issues even if you think this message is unrelated.
Any opened issues will be immediately closed without response.
Do not ask for help from Homebrew or its maintainers on social media.
You may ask for help in Homebrew's discussions but are unlikely to receive a response.
Try to figure out the problem yourself and submit a fix as a pull request.
We will review it but may or may not accept it.
```

</details>

## 公式サイトに従ってインストール

そんな時は本家gradle公式サイトの手順でインストールします。
Download by the following url:
https://gradle.org/install/#helpful-information



```bash
% sudo unzip -d /opt/gradle gradle-8.11.1-bin.zip
```

配置する。
```bash
% ls /opt/gradle/gradle-8.11.1
LICENSE	NOTICE	README	bin	init.d	lib
```

パスを通す。`.zshrc`とかに書き込み。
```bash
% export PATH=$PATH:/opt/gradle/gradle-8.11.1/bin
```

成功。
```bash
% gradle -v     

Welcome to Gradle 8.11.1!

Here are the highlights of this release:
 - Parallel load and store for Configuration Cache
 - Java compilation errors at the end of the build output
 - Consolidated report for warnings and deprecations

For more details see https://docs.gradle.org/8.11.1/release-notes.html


------------------------------------------------------------
Gradle 8.11.1
------------------------------------------------------------

Build time:    2024-11-20 16:56:46 UTC
Revision:      481cb05a490e0ef9f8620f7873b83bd8a72e7c39

Kotlin:        2.0.20
Groovy:        3.0.22
Ant:           Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM:  20.0.1 (Oracle Corporation 20.0.1+9-29)
Daemon JVM:    /Users/mariko.shozawa/Library/Java/JavaVirtualMachines/openjdk-20.0.1/Contents/Home (no JDK specified, using current Java home)
OS:            Mac OS X 12.6.3 aarch64


```
【React】useHistoryでURLは変わるのに画面が変わらない時

# 環境
+ React 18.3.1
+ Typescript 4.9.5
+ Chakra UI 2.8.0
+ react-router-dom 5.2.0

# 事象
ログイン画面のボタンを押してトップ画面へ遷移する機能を作成
ログイン画面のボタンを押すとブラウザのURL欄はトップ画面のURLに変わっているが、画面はログイン画面のまま

![スクリーンショット 2024-11-29 12.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/3deeecac-cf31-f168-b512-bc9be862fa10.png)


# 原因
index.tsxで```React.StrictMode```を使っているため

## ソースコード（一部省略）
```typescript:index.tsx
import React from 'react';

const root = ReactDOM.createRoot(
    document.getElementById('root') as HTMLElement
);
root.render(
    <React.StrictMode> /* これが原因 */
        <ChakraProvider theme={theme}>
            <BrowserRouter>
                <Router />
            </BrowserRouter>
        </ChakraProvider>
    </React.StrictMode>
);
```

https://react.dev/reference/react/StrictMode


>Strict Mode enables the following development-only behaviors:
>
>Your components will re-render an extra time to find bugs caused by impure rendering.
>Your components will re-run Effects an extra time to find bugs caused by missing Effect cleanup.
?Your components will be checked for usage of deprecated APIs.

要約するとバグを検知するために再レンダリングする・・・①
エフェクトを再実行する・・・②
非推奨のAPIがないかチェックする

おそらく上記の①または②に該当したため事象が起こったと推測されます。

# 対応
```React.StrictMode```を削除

## ソースコード（一部省略）
```typescript:index.tsx
import React from 'react';

const root = ReactDOM.createRoot(
    document.getElementById('root') as HTMLElement
);
root.render(
    <ChakraProvider theme={theme}>
        <BrowserRouter>
            <Router />
        </BrowserRouter>
    </ChakraProvider>
);
```


# 参考

https://qiita.com/RyotaAmano/items/c730eec3386a99aade73

→同様の事象であったため原因は異なった


https://zenn.dev/yousaku/articles/44ac6fecc05ae9

→```React.StrictMode```はcreate-react-appで環境構築した際にデフォルトで使用されている
これの役割やどういう挙動をするコンポーネントなのか理解することに役立った
未経験でも爆速でスマホアプリを作る方法

# はじめに

この記事は、株式会社スピードリンクジャパン Advent Calendar 2024 の3日目の記事です。

https://qiita.com/advent-calendar/2024/slj

## 未経験でも爆速でスマホアプリを作る

スマホアプリを開発するなら、**Flutter**を使うのがオススメ！  
この記事では、初心者にもわかりやすく、Flutterでアプリを作る方法とその魅力を解説します。

---

## まず知ってほしい！Flutterって何？

Flutterは、**Googleが開発したアプリ開発のフレームワーク**です。  
1つのプログラムで**iPhone**と**Android**両方のアプリを同時に作れるのが特徴です。

---

## どうしてFlutterで早く作れるの？

アプリ開発では通常、**iPhone用**と**Android用**に別々のプログラムを書く必要があります。  
でもFlutterなら、**1つのコードで両方に対応できる**ため、作業量が大幅に減ります！

---

## Flutterのここがすごい！

### 1️⃣ **すぐに結果が見られる**  
Flutterには「**ホットリロード**」という機能があります。  
プログラムを変更すると、**画面が即座に更新**されます！

- **デザイン変更をすぐ確認**
- **修正が簡単で開発スピードUP**

---

### 2️⃣ **キレイなデザインを簡単に作れる**  
Flutterには「**ウィジェット**」という便利なパーツが豊富に用意されています。  
これを組み合わせるだけで、**プロ並みのデザイン**が作れます。

---

### 3️⃣ **どんなスマホでも速く動く**  
Flutterで作られたアプリは、iPhoneでもAndroidでも**サクサク動作**！  
使う人に快適な体験を提供できます。

---

## Flutterでアプリを作る流れ

### 1️⃣ **環境構築**  
難しくないので、頑張れば1時間で環境が作れます！
（ちなみに、私は最初ちょっと苦労しましたが…笑）

そんな私が環境構築したときの記事を置いておきます👇
  - [2週間で4回のFlutter環境構築を行なった駆け出しエンジニアが書く　Flutter環境構築Windows編](https://qiita.com/kominato_slj/items/62d766778e9812a96014)

https://qiita.com/kominato_slj/items/62d766778e9812a96014


今なら1時間でできます！👌



### 2️⃣ **画面を作成**  
Flutterでは、画面を「ウィジェット」で構成します。  
以下のコードでシンプルなボタンが作れます👇
```dart
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text("My First App")),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            print("Button Pressed!");
          },
          child: Text("Click Me"),
        ),
      ),
    ),
  ));
}
```
![スクリーンショット 2024-11-29 12.25.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/8bd18e0b-8aa7-dc33-ef20-8ec07c1a928f.png)

今はシンプルなものですが、Flutterのパッケージを使えばプロ級の画面が作れます
パッケージのサイト：[pub.dev](https://pub.dev/)

パッケージをインストールして公式のコードコピペするだけでカレンダーとか、予約フォームでよく見る日付選択のダイアログとかできちゃいます！
私が過去に試したものです！👇
- カレンダー
  - [【Flutter】カレンダーを作る](https://qiita.com/kominato_slj/items/1508d2e394b61ba47b56)

https://qiita.com/kominato_slj/items/1508d2e394b61ba47b56

![スクリーンショット 2024-11-29 11.54.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/04bcf3b8-0721-91d4-c526-08ed586d6140.png)

- 日付選択
  - [【Flutter】iOS風のDatePickerを表示するには？
](https://qiita.com/kominato_slj/items/2be71354343f1fb20ad6)

https://qiita.com/kominato_slj/items/2be71354343f1fb20ad6

![dialog_gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/c3e30aa9-6d2a-94b0-ffee-f1b31afef54c.gif)


### 3️⃣ **機能を追加**  
API連携やデータ保存などの機能を追加していきます。  
Flutterには多くのプラグインがあり、すぐに拡張可能です。
Firebaseは、バックエンドの処理を簡単に実装できるので時短でおすすめです

### 4️⃣ **テストして修正**  
「ホットリロード」で変更後の結果を即確認しながら、問題を修正。

### 5️⃣ **リリース**  
完成したらGoogle PlayやApp Storeに公開！  
Flutterなら、**両プラットフォームへのリリースが簡単**です。

---

## まとめ

Flutterは、**早く・簡単に・キレイなアプリ**を作れる魔法のツールです。  
もし「アプリ開発に挑戦してみたい！」と思っているなら、まずFlutterを試してみてください！

これからのアプリ開発は、**Flutter**で決まり！🚀
`pandas.read_csv`で、欠損値を含むbool列またはint列を読み込んだときの挙動

# 環境
* Python 3.12.4
* pandas 2.2.3


# はじめに
`pandas.read_csv`で欠損値を含むbool列を読み込んだときの挙動が、自分の期待と異なる部分があったので、その挙動をまとめました。



# bool列の場合

## 欠損値なし AND `dtypes`引数を指定しない

```
In [262]: data1="""
     ...: count,flag
     ...: 1,true
     ...: 2,false
     ...: """

In [265]: df1 = pd.read_csv(io.StringIO(data1))

In [266]: df1
Out[266]:
   count   flag
0      1   True
1      2  False

In [267]: df1.dtypes
Out[267]:
count    int64
flag      bool
dtype: object
```

dtypeは`bool`になりました。

## 欠損値あり AND `dtypes`引数を指定しない


```
In [269]: data2="""
     ...: count,flag
     ...: 1,true
     ...: 2,
     ...: """

In [270]:  df2 = pd.read_csv(io.StringIO(data2))

In [271]: df2
Out[271]:
   count  flag
0      1  True
1      2   NaN

In [272]: df2.dtypes
Out[272]:
count     int64
flag     object
dtype: object
```

dtypeは`object`になり、欠損値は`NaN`でした。


## 欠損値あり AND `dtypes`引数を指定する

### dtypeに`bool`を指定する

```
In [290]: df2_2 = pd.read_csv(io.StringIO(data2), dtype={"flag":"bool"})
---------------------------------------------------------------------------
ValueError: Bool column has NA values in column 1
```

dtypeが`bool`は欠損値を含むことができないので、`ValueError`が発生しました。

以下の`pandas.Series()`を実行したときのように、欠損値は`False`に変換されると期待していたのですが、そうではありませんでした。

```
In [350]: pd.Series([None, True], dtype="bool")
Out[350]:
0    False
1     True
dtype: bool
```

https://qiita.com/yuji38kwmt/items/ee97729018bdcf72cfd7#none%E3%81%A8true%E3%82%92%E6%A0%BC%E7%B4%8D%E3%81%99%E3%82%8Bdtype%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B


### dtypeに`boolean`を指定する

```
In [291]: df2_3 = pd.read_csv(io.StringIO(data2), dtype={"flag":"boolean"})

In [292]: df2_3
Out[292]:
   count  flag
0      1  True
1      2  <NA>

In [294]: df2_3.dtypes
Out[294]:
count      int64
flag     boolean
dtype: object
```

dtypeが`boolean`ならば欠損値を含むことができるので、エラーは発生しませんでした。


# int列の場合
bool列と同じような結果ですが、一応記載します。

## 欠損値あり AND `dtypes`引数を指定しない

```
In [304]: data3="""
     ...: count,count2
     ...: 1,10
     ...: 2,
     ...: """

In [305]: df3_1 = pd.read_csv(io.StringIO(data3))

In [306]: df3_1
Out[306]:
   count  count2
0      1    10.0
1      2     NaN

In [308]: df3_1.dtypes
Out[308]:
count       int64
count2    float64
dtype: object
```

## 欠損値あり AND `dtypes`引数を指定する

### dtypeに`int64`を指定する

```
    In [309]: df3_2 = pd.read_csv(io.StringIO(data3), dtype={"count2":"int64"})
---------------------------------------------------------------------------
...
File parsers.pyx:1226, in pandas._libs.parsers.TextReader._convert_with_dtype()

ValueError: Integer column has NA values in column 1
```


### dtypeに`Int64`を指定する
```
In [310]: df3_3 = pd.read_csv(io.StringIO(data3), dtype={"count2":"Int64"})

In [311]: df3_3
Out[311]:
   count  count2
0      1      10
1      2    <NA>

In [312]: df3_3.dtypes
Out[312]:
count     int64
count2    Int64
dtype: object
```

# まとめ


* 欠損値を含むbool列には、dtypeに`boolean`を指定しましょう
* 欠損値を含むint列には、dtypeに`Int64`を指定しましょう
【ChatGPT】生成AIのウソは、創作のヒントに使えるのでは（By 博報堂）という考えをもとに、Promptを作成してみました。


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

　今回は、生成AIのウソは、創作のヒントに使えるのでは（By 博報堂）という考えをもとに、Promptを作成してみました。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)

***
　まずは、ニュース。

　YouTubeチャンネルのPIVOTに
　　松尾豊教授が登場。

　松尾豊教授と言えば、
　　AIの第一人者。

　[【松尾豊教授に聞く、生成AIの「次の10年」】](https://youtu.be/ker41VCT3j4?si=0Zw__rk5LE1ujasW)

　LLMの今後の発展
　LLMのソブリン化
　ロボティクスへの応用
　生成AIのリスク
　まず絶望から始めよ
　技術を舐めろ
　AIを崇めるな
　ラーメン屋に学べること
　　に言及。
***
　次に、

　自然な抑揚のある多言語対応の
　　音声を生成できる生成AIを
　　　開発しているElevenLabsから。

　ElevenReaderのiOSアプリで、
　　PDF、記事、電子ブック、
　　　リンク、テキストから
　　　　個人用ポッドキャストを
　　　　　32ヶ国語で作成できる
　　　　　　ようになりました。

　[ElevenLabs公式ポスト](https://x.com/elevenlabsio/status/1861833756027297965?t=npdol2SmDuA-DYDGrTLiEQ&s=19)
***
　さて、【本題】です。

　今回は、
　　生成AIのウソは、
　　　創作のヒントに使えるのでは
　　　　ないか（By 博報堂）という
　　　　　考えをもとに、
　　　　　　Promptを
　　　　　　　作成してみました。

　“ウソつきは泥棒のはじまり”と
　　言われます。
　　　それだけ“悪いこと”という
　　　　認識ですよね。

　でも
　　“嘘から出たまこと”という
　　　言葉もあります。

　ウソがいけないとはいえ、
　　そのウソが、人を刺激するのも
　　　また事実。

　ちょっとしたウソで
　　イマジネーションが
　　　刺激されたりします。
***
　博報堂さんが、
　　生成AIの“ウソ”を、
　　　創作のヒントに、と
　　　　生成AIを使っています。
[“AIのうそ”すら創作のヒントに──生成AIは創作活動を支援するか？　博報堂の生成AIに対する考え方](https://www.itmedia.co.jp/aiplus/spv/2411/28/news026.html)

　博報堂と言えば、
　　日本を代表する広告代理店。
　　　さまざまなアイディアを
　　　　形にしてきました。

　CMに限らず
　　アニメにも。
　　　『コードギアス』も
　　　　そのひとつだとか。

　同社は2月、
　　AIによって人間の能力を
　　　向上させていくことを
　　　　目的とする研究機関
　　　　「Human-Centered AI Institute」
　　　　　　を設立しました。
***
　それはともかく、
　　博報堂に限らず、
　　　企画会議などでは、
　　　　“アイディア100本ノック”と
　　　　　呼ばれる手法で
　　　　　　会議参加者に100本ずつ
　　　　　　　アイディアを出させる
　　　　　　　　ことがありました。

　　さすがに
　　　もう廃れていることでしょう😅
　　　　正直、時間のムダですからね。

　これを
　　生成AIにやらせてみても
　　　たいしたアイディアは
　　　　出てきません。
　　　　　前提条件を絞っても。

　理由は簡単で、
　　生成AIは、突飛な文章を
　　　出さないように、
　　　　作られています。

　だから、
　　いくらアイディアを
　　　出力させても
　　　　こちらが望むような
　　　　　アイディアは出てきません。
***
　さて、
　　今回の博報堂さんの記事を見て
　　　（本当はタイトルなんですが😅）
　　　ふと思い付いたアイディアを
　　　　Promptにしてみました。

　こちらが、そのPromptです。
```Text:イマジネーション刺激するウソPrompt
ユーザーのイマジネーションを刺激するために、ウソを付いてください。
[＊＊＊]について。
```

　＊＊＊に
　　欲しいネタ元のキーワードを
　　　入れて送信してください。

　やってみると
　　“ウソ”とは言わずに
　　　“フィクション”と言いますね。
　　　　こっちの方が
　　　　　抵抗感は小さいか。

　“クルマ”についてやると、
　　“夢見るクルマ”を創作してきました。
　　　なかなかの設定です。

　　エンジンを切ると
　　　スリープモードに移行して
　　　　翌日のルートを夢見ます。

　　翌日、ドライバーに
　　　そのことを報告するとか。

　　しかも
　　　走行中に吸い込んだCO2を
　　　　夢の中で利用して
　　　　　排気を極限まで減らすとか。

　“ファンタジー異世界”についてやると、
　　ここでも思いもよらぬ
　　　設定を出して、
　　　　物語を形作りました。

　とんだアイディア発生Promptですが、
　　その出力は楽しめました。

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

　今回は、ここまで。
コンタクトコントロールパネル (CCP) のビジュアルアップデートをSalesforceで試してみた

## はじめに

Amazon Connectコンタクトコントロールパネル（CCP）のビジュアル一新のアップデートが2025年3月1日以降に予定されています。

用意されているドキュメントでは新ビジュアル確認方法として、以下2つの方法が記載されています。
- スタンドアロン CCP-v2を使用する場合
- Amazon Connect Streams APIを使用する場合（カスタムCCPを使用）

https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/amazon-connect-upcoming-changes.html

Salesforce CTI Adapterを使用して、標準のCCPで新ビジュアルがどのようになるかスクリーンショットが用意されていますが、確認方法の記載がありません。

この記事では、標準のCCPを使用してSalesforce画面での新ビジュアル確認方法を記載します。

## 前提

新ビジュアルを確認するには、CCPのURLへ `visual-refresh=true` を追加します。

- Before : https://instancename.my.connect.aws/ccp-v2/
- After  : https://instancename.my.connect.aws/ccp-v2?visual-refresh=true

また、この方法はAmazon ConnectインスタンスのID管理方法が `Amazon Connectにユーザーを保存` としている場合に適用されます。
ID管理方法が `SAML2.0ベースの認証` の場合は、他の方法を使用して新ビジュアルの確認をできる可能性があります。

## 新ビジュアル確認方法

カスタムCCPとは違い、Salesforceで標準のCCPを使用している場合、埋め込まれているCCPのURLへパラメータを付与することは恐らくできません。

今回は、Chromeの検証ツールを使用して新ビジュアルを確認します。

### 1.ユーティリティバーにソフトフォンが設定されているアプリケーションを開く

![スクリーンショット 2024-11-29 11.46.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/00e40c8d-b129-cb00-e259-211877bd0178.png)

### 2.CCPでログインした状態で検証ツールを開き、`https://instancename.my.connect.aws/ccp-v2` を検索

![スクリーンショット 2024-11-29 11.57.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/1f9d1e1d-4fa9-1940-76e8-611f51823827.png)

### 3.iframeに設定されているCCP-v2のURLへ `?visual-refresh=true` を追加

**※CCPでログインした状態でパラメータ追加を行わないとビジュアルが切り替わりません。**

![スクリーンショット 2024-11-29 11.59.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/85b535ea-83cf-8ab9-fcc2-9a2da8f15a6e.png)

### 4.新ビジュアルへ切り替わります

![スクリーンショット 2024-11-29 12.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/6d3e2632-1bff-6a51-083e-4c73bd32f0b5.png)
Microsoft Fabric アイコンへの導線

## はじめに

アドベントカレンダー一つ目の投稿は軽いもの、ということでアイコンセットについての導線として記事投稿💡

## まとめ

結論としてのリンク集をまとめておきます。

- [MS Learn - Microsoft Fabric 製品、エクスペリエンス、および項目のアイコン](https://learn.microsoft.com/ja-jp/fabric/get-started/icons)
- [Github - Icons.zip](https://github.com/microsoft/fabric-samples/blob/main/docs-samples/Icons.zip)
- [Github - Fabric Icons](https://github.com/FabricTools/fabric-icons/tree/main) ※おすすめ

## MS Learn

[Microsoft Fabric 製品、エクスペリエンス、および項目のアイコン](https://learn.microsoft.com/ja-jp/fabric/get-started/icons)

公式コレクションとしての情報が記載されています。
実際に見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/557677b7-6c1e-655c-8ab0-6b6dca429d1a.png)

ダウンロードすると、規約などのpdfが入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/4cfdefbc-0df0-e56f-1e90-8ea523ee51a5.png)

svgフォルダには直下にすべてのファイルが並んでおり、Fabric のワークロードだけでなく、UI上のアイコンもすべて入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/9b46ee0b-543a-17fa-bd79-7fb2982be5d6.png)

適当なサイズで検索して整理しておくといい感じになると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/73f6b34a-4e4d-95fb-ef4a-86f33e4047a1.png)

また、同Repoには icon をpng に変換した際に使用されたであろう notebookが同梱されているので、OneLake 上に置きたい場合には使えるかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/1434d054-7f04-8b84-8c48-7cbd9ab284b6.png)


実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/90a04c68-f236-6885-8855-c22df5e19428.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d495e1e0-49c9-265e-c037-af72b5aa4aef.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/408f5833-2791-6929-b2b1-14d1c799e04c.png)

## Fabric Icons 

おすすめはこちらです。

[Fabric Icons](https://github.com/FabricTools/fabric-icons/tree/main)

READMEにアイコンが整理されています。
海外の MVP の方が作成したもので、ソースとなる公式コレクションのREPO上にあるパッケージが更新されるとこちらも更新されるようになっているそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8e3e721b-6f45-885e-3b00-0cfac9087710.png)

## 関連

アイコンといえば akihiro_suto さんの記事なのでこちらもリンクしておきます。（いつもありがとうございます！

https://qiita.com/akihiro_suto/items/6987b9b3d0f82dca8ef9
command not found: docker(195) error(154) 

Docker 入門者のアウトプット Calendar 2024
https://qiita.com/advent-calendar/2024/docker-beginner
Day 3 の投稿予定記事です。

pythonで作業しようと思い、dockerコマンドを実行しようとした。

```bash
$ docker run -v Users/ogawakiyoshi/llm:/tmp/llm  -it kaizenjapan/anaconda /bin/bash
bash: docker: command not found
$ docker
bash: docker: command not found
$ exit
exit
```
>bash: docker: command not found

あれ、dockerの中にはdocker導入してないけど。

ちょっと画面を戻したら、docker run少し前にしていた。

いつもはプロンプト#になるはずなのに、
なぜかなってない。

プロンプトの先を見たら、docker runした名前がついてた。そっちでも見分けられたのに。

exitして抜けた。
NetSuiteのイメチェン(Redwoodエクスペリエンス)

NetSuiteご利用者の方へ朗報！:santa::santa_tone1:
まではいきませんが、以下でNetSuiteのイメチェンが可能です。各個人でも可能ですので、ご利用者はお試しください。:airplane:

１．プリファレンスの設定へ
　ホーム > プリファレンスの設定をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114483/c1ba10b7-aea8-af2a-d7f7-e282bc8a866e.png)

2.外観の変更
　外観サブタブ > Redwoodエクスペリエンス > 有効化をクリック > 保存ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114483/a40dc13e-aa39-4f73-bf5b-13574e13fca2.png)

3.完成:point_left_tone2:長きにお使いで画面に飽きられた方、是非お試しください！
嫌だった場合は、逆の手順でお戻し下さい。:writing_hand:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114483/a6f99463-ba4d-d2b6-0acc-70a78b3f17db.png)
【ASTERIA Warp】メール受信（Office365アダプター利用）テンプレート エラー修正備忘録

## はじめに
**未読メールを取得し、本文と添付ファイルを保存する**テンプレートをダウンロードして使ってみたのですが、エラーが発生してしまったので備忘録として残します。

ちなみにテンプレートの詳細はリンク先の「詳細・ダウンロードはこちら」から確認することができます◎

https://www.asteria.com/jp/warp/feature/template/office365mail_receive

## 原因
「添付ファイルをダウンロード」とコメントが書かれたコンポーネントでエラーが発生していました。
調査すると、Office365アダプターのストアドプロシージャ「DownloadAttachments」の呼び出し方がバージョンアップによって変わってしまったことが原因みたいでした。

テンプレートのバージョンは**ASTERIA Warp2112**なので、
それ以上のバージョンのものを使用していると本事象が発生するかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/55924233-4f0e-4934-ba1b-2b67573b7b58.png)

## 解決策
テンプレートのフローで使用している3つのパラメータに、**UserId**パラメータを追加し、
直前のコンポーネントで値を引き渡すように設定したら、正常に動作するようになりました。

修正前
```
{call DownloadAttachments(?MessageId?,?AttachmentId?,?DownloadTo?)}
```

修正後
```
{call DownloadAttachments(?MessageId?,?UserId?,?AttachmentId?,?DownloadTo?)}
```

## 最後に
ナレッジ記事の方に「テンプレートはサポート対象外」と記載があったのでQiitaに残させていただきました。（ぼくは解決策を見つけるまで結構苦しみました…）
S3バケットのデータを一括ダウンロードしたい

## **▽概要**
・S3バケット内のデータを一括ダウンロードしたい
・とりあえず簡単にサクッとダウンロードしたい

ってことでAWS CLIを使って、S3バケットの中身を一括ダウンロードしてみる

AWS CLIからWebサイトのコンテンツを一括でローカルにダウンロードや他のS3への転送ができるので、
S3静的ウェブサイトホスティングで、Webサイトを公開している時とかに、
テスト用に同じサイトを構成したい時とかに、コンテンツをサクッと取得できるので結構便利かも…

## **▽内容**

**①AWSコマンドラインインターフェース をダウンロードして、PCにインストールする**
https://aws.amazon.com/jp/cli/
自分のPCはWindowsなので「64 ビットの Windows インストーラをダウンロードし、実行します。」のリンクからインストーラーをダウンロードしました。

インストーラーをダブルクリックで実行するとウィザードは開くので「Next」と「Install」をクリックしてインストールを実施する

**②対象のIAMアカウントに対して、AWS CLIが実行できるようアクセスキーを発行する**
IAMユーザーを一から作成する場合
IAM>ユーザー＞ユーザーの追加
・ユーザ名：○○○○
・AWSアクセスの種類を選択：アクセスキー
・アクセス許可の設定：グループの作成＞任意のグループ名(Adminとか)で作成し、ポリシーに「AdministratorAccess」を追加する



既存のIAMアカウントにアクセスキーを付与する場合
許可されているポリシーに「AdministratorAccess」が含まれているか確認し、
不足しているようであれば、「AdministratorAccess」を付与(「AdministratorAccess」のけん
「セキュリティ認証情報」のタブから「アクセスキーを作成」をクリックする

ユースケースに「コマンドラインインターフェース(CLI)」を指定して、
「上記のレコメンデーションを理解し、アクセスキーを作成します。」にチェックを入れ、「次へ」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659351/be39c561-c6c6-5280-f278-df500d1bd510.png)

タグ入力画面が表示されるので、何か必要だったら入力し「アクセスキーを作成」をクリックする

アクセスキーIDとシークレットアクセスキーが表示されるのでメモ
もしくはCSVをダウンロードする

**③AWS CLIに、アクセスキーを使ってログインしてみる**
自分のPCはWindowsなので、スタートから「コマンドプロンプト」を起動して下記のコマンドを入力する
```
C:\Users\○○>aws configure

AWS Access Key ID: ②で取得したIDを入力
AWS Secret Access Key: ②で取得したシークレットアクセスキーを入力
Default region name： 指定があればリージョンコードを指定するが空白でもOK
Default output format：結果の出力形式 指定が無ければそのままEnterを押す

```
リージョンコード参考：
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html


**④対象のS3バケットからコンテンツを一括ダウンロードする**
hoge.com というS3バケットから、自分のPCのC:\temp\hogeに一括ダウンロードする
```
例：aws s3 cp s3://S3バケット名 ダウンロード先のパス --recursive
aws s3 cp s3://hoge.com  C:\temp\hoge --recursive
```


:::note info
参考
kopi-moto というS3バケットからkopi-sakiというS3バケットにコンテンツををコピーしたい場合

aws s3 cp s3://kopi-moto s3://kopi-saki

cpの部分をsyncに変えると、宛先バケットにまだ無いコンテンツのみをコピーできます
:::


## **▽最後に…**
今回サクッとコンテンツのダウンロードを実施したくAWS CLIを初めて使ってみました。
IAMアカウントへの権限付与などできれば、サクッとCLI使えて便利と思いました。
AMIからのEC2インスタンス作成とか、AMI作成とかCLIでやってみたいです。
今回この対応でIAMについても勉強できました。よかったです。(小学生並みの感想)
プリザンターのダッシュボードのタイムラインでフィルターをサイトごとに設定する方法

## はじめに
プリザンターのダッシュボード機能、いろいろと便利なのですが、標準機能でカバーできないところがちらほらと・・・。
例えば、タイムライン。1つのパーツに複数のサイトを設定する場合は、ダッシュボードの管理画面からの設定は全てのサイトに一律適用されます。また、各サイトにサーバースクリプトで`view.Filters`を設定していたとしても基準サイトに設定してあるものが他のサイトにも適用されてしまいます（他のサイトに設定してあるフィルターは無視される）。これだと、サイトごとにフィルターを設定したいときに困る・・・。

## 解決法
管理画面からでは小技は使えないので、サーバースクリプトを使います。基準サイトの`view.Filters`が全てのサイトに適用されるので、基準サイトの`view.Filters`に全部書いてしまいます。

### サーバースクリプト例
2つのサイト、サイトIDが100と200のものをタイムラインに設定するとして、100を基準サイトに設定する場合の例です。基準サイトにフィルターを制御するためのサーバースクリプトを設定します。
フィルター条件は、サイトID:100では状況が100（吊しだと未着手）、サイトID:200では状況が900（吊しだと完了）を表示させるとします。論理式としてまとめると`(SiteId:100 & Status:[100]) · (SiteId:200 & Status:[900])`ですね。

```javascript
if (context.Action === 'dashboardpart') {
	let data = {};
	data.and_Filter1 = JSON.stringify({
		SiteId: 100,
		Status: '[100]'
	});
	data.and_Filter2 = JSON.stringify({
		SiteId: 200,
		Status: '[900]'
	});
	view.Filters.or_Filter = JSON.stringify(data);
}
```
例としてはこのようなコードになります。フィルターのOR/AND機能を使います。
タイムラインで全てのサイトに基準サイトのフィルターが適用されることを逆手にとって、サイトIDを条件に加えることで、サイトごとに条件を与えることを可能にしています。また、`context.Action`が`dashboardpart`の場合のみ実行されるようにすることで、一覧表示などのダッシュボード表示以外の場合に、フィルターが実行されることを防いでいます。

## まとめ
ダッシュボードのタイムライン、サイトを複数設定するときは管理画面からの設定だと、基準サイトの設定が全てに適用されるためサイトごとの個別制御が出来ないという弱点があります。サーバースクリプトを使用することで、この弱点はカバーできるので、是非活用してみてください！
エスケープが必要な文字とその方法

JSON では、文字列中に特殊文字が含まれる場合、適切にエスケープする必要があります。以下に、エスケープが必要な全ての文字を示します。

---

### **エスケープが必要な文字とその方法**

| 文字  | エスケープ方法   | 説明                                                                 |
|-------|------------------|----------------------------------------------------------------------|
| `"`   | `\"`            | ダブルクォート: 文字列の開始/終了を意味するため、エスケープが必要。     |
| `\`   | `\\`            | バックスラッシュ: 自身をエスケープする必要がある。                     |
| `/`   | `\/`            | スラッシュ: 古いブラウザでは問題回避のためエスケープされることがある。 |
| `\b`  | バックスペース  | バックスペース文字 (ASCII: 8)                                        |
| `\f`  | フォームフィード | フォームフィード文字 (ASCII: 12)                                     |
| `\n`  | 改行            | 改行文字 (ASCII: 10)                                                |
| `\r`  | 復帰            | キャリッジリターン (ASCII: 13)                                       |
| `\t`  | タブ            | 水平タブ文字 (ASCII: 9)                                             |
| `\uXXXX` | Unicode       | 特殊文字 (例: `\u2028` = 行区切り, `\u2029` = 段落区切り)            |

---

### **エスケープが必要な例**

```json
{
  "text": "He said, \"Hello, World!\" and left.",
  "path": "C:\\Program Files\\App",
  "unicode": "\u2028\u2029",
  "newline": "First line.\nSecond line.",
  "tab": "Key\tValue"
}
```

---

### **エスケープ前後の例**

#### エスケープ前:
```json
{"quote":"She said "Yes!""}
```

#### エスケープ後:
```json
{"quote":"She said \"Yes!\""}
```

---

### 注意点
- `JSON.stringify` を利用する場合、JavaScriptではエスケープが自動的に処理されます。
- 生データを直接操作する場合、上記のルールを守る必要があります。
【参加レポート】AWS Jam Eventに参加してきました！

ちょっと前にはなってしまいますが、11/6（水）にAWS Partner 向けに大阪オフィスにて実施されたAWS Jam Event に参加してきました。
これまでにもHands-On Eventには参加したことがあったのですが、Jam Eventには初めての参加だったので、体験した感想などお伝えできればと思います。

※チャレンジ内容に関しては、ネタバレになってしまうので、触れません。予めご容赦ください。

## AWS Jamとは？

自分がそうであったように、そもそもまず「AWS Jam」とは何ぞや？という方もおられるかもしれませんので、軽く紹介から。

公式よりAWS Summit Japan 2024で実施されたAWS Jam のレポートが出されています。

https://aws.amazon.com/jp/blogs/news/aws-jam-report-aws-summit-japan-2024/

その中で紹介されているので、少し引用させていただきます。

> AWS Jamは、AWS のユースケースに沿って用意された様々なテーマの課題を解決しながら「AWS を楽しく学ぶ」実践型のイベントです。参加者はAWS やシステム開発の知識や経験を活用し、必要に応じてその場で情報を調べながら、与えられた複数の課題を AWS マネジメントコンソールなどを利用してクリアしていきます。AWS Jam では、課題ごとに獲得得点やヒントが設定されており、時間内にクリアした課題と使用したヒントを総合してチームの得点を競い合います。

今回参加したAWS Jamも参加人数が30人、4人チーム・3人チームが合計8チームあり、課題クリアの得点を競う、という形式でした。

自分は3人チームに配属され、その日初めてお会いした他社のエンジニア2名と課題に挑戦することとなりました。


## 当日の流れ

当日のタイムテーブルとしてざっくり以下の内容でした。
| 時間 | 内容 |
|:-:|:-:|
| 50分 | オープニング&KickOff |
| 170分 | Jam！ |
| 40分 | クロージング |

KickOffはチーム内での自己紹介やチーム名決めなど。
自分たちのチームはそれぞれ苗字の頭文字を取って「TKO SEs(SystemEngineers)」としました。

## いざ課題に挑戦

全部で13問の課題にはEasy・Medium・Hardのレベル分けがされており、それぞれクリアした時の得点が異なっています。

挑戦時のルールの一つとして、モブプログラミング（複数人で一つの画面・課題に挑戦する）で実施することがありました。
1人が画面を操作するドライバーとなり、他のメンバーは課題解決の方法を探してドライバーに提案をするという形でしたが、新鮮な体験で面白かったです。

挑戦の合間に休憩も挟みつつでしたが、あっという間の170分だったように思います。

Easyレベルの課題であればヒント（各課題に2,3個あり、開示した数によって得点が下がる）も開示せずにクリアできるものも多かったのですが、Mediumからは結構悩んだりヒントを開示しないと難しいというレベル感でした。

## 結果発表

自分たちのチームは13問中８問解決完了で、8チーム中4位という結果でした！

一つ一つの課題を完了できないことよりも、ガンガンヒントを見るようにしてクリア数を稼ぐことを目指していましたが、その分で他チームと差が開いた印象です。

![スクリーンショット 2024-11-06 173839.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755487/0f9be274-700c-9aa9-322c-436d8fc240ab.png)

## まとめ

初めて参加しましたが、他社のエンジニアさんと交流しながら課題に挑戦するという経験はとても楽しかったです。

AWS Jamの課題自体も、全く分からないという感じも全部ヒント無しで楽勝という感じでもなく、良い塩梅の難易度だったように思います。

AWSマネジメントコンソールでリソースを触りながら仕組みを理解する・AWSを勉強する手段としてはかなり良いなと感じたので、今後は社内でも挑戦できないか模索してみたいと思います！
Unityでロマンシングサガ風ゲーム制作！閃きと連携システムの実装方法

# Unityでサガ風ゲームを作ろう！閃きと連携システムの実装方法

ロマンシングサガシリーズの特徴的な「閃きシステム」や「連携システム」を、自分のゲームに取り入れたいと考えたことはありませんか？この記事では、Unityを使用してこれらのシステムを再現する方法を解説します。初心者の方でも理解しやすいよう、具体的なコード例を交えて説明します。

[Unity入門の森はこちら](https://feynman.co.jp/unityforest/)

## Unityの基本設定

### Unityとは？

Unityは、2Dおよび3Dゲームの開発に広く利用されているゲームエンジンです。無料で利用可能で、初心者からプロフェッショナルまで幅広く使用されています。

### インストール手順

1. [Unity公式サイト](https://unity.com/)からUnity Hubをダウンロードします。
2. Unity Hubをインストールし、アカウントを作成します。
3. Unity Hub内で新しいプロジェクトを作成します。

これで、開発を開始する準備が整いました。

## 閃きシステムの実装

### 閃きシステムとは？

閃きシステムは、キャラクターが戦闘中に新しい技を習得する仕組みです。これにより、プレイヤーは戦闘を通じてキャラクターを成長させることができます。

### 実装方法

戦闘中に特定の条件を満たすと、新しいスキルを習得するロジックを組み込みます。以下はその一例です。

```csharp
void TryToLearnNewSkill()
{
    float learnProbability = 0.1f; // 10%の確率
    if (Random.value < learnProbability)
    {
        string newSkill = "新しい技";
        playerSkills.Add(newSkill);
        Debug.Log($"閃き！{newSkill}を習得しました！");
    }
}

```
## 連携システムの実装

### 連携システムとは？

連携システムは、複数のキャラクターが特定の条件下で協力して強力な技を発動する仕組みです。これにより、戦略的な戦闘が可能になります。

### 実装方法

キャラクターの行動を監視し、特定の組み合わせが揃ったときに連携技を発動させます。以下はその一例です。

```
void CheckForCombo()
{
    if (actions.Contains("技A") && actions.Contains("技B"))
    {
        Debug.Log("連携技発動！");
        ExecuteCombo("連携技");
    }
}

```
## マップ作成とイベント設定

### タイルマップでフィールドを作成

UnityのTilemap機能を使用すると、2Dのフィールドマップを効率的に作成できます。タイルを配置して地形をデザインし、キャラクターが移動できるエリアを設定します。

### NPCとの会話イベント

NPCとの会話やアイテムの取得などのイベントは、トリガーを使用して実装します。以下はその一例です。

```
void OnTriggerEnter2D(Collider2D other)
{
    if (other.CompareTag("Player"))
    {
        Debug.Log("NPCとの会話を開始します");
        // 会話イベントの処理をここに追加
    }
}
```

## 便利なリソース

### Unity Asset Store

[Unity Asset Store](https://assetstore.unity.com/)では、無料および有料のアセットが多数提供されています。キャラクターのスプライトや背景画像など、ゲーム制作に必要な素材を手軽に入手できます。特に、以下の無料アセットは初心者におすすめです。

- **Starter Assets - Third Person Character Controller**: キャラクターの移動操作とカメラワークのシステムが含まれています。 
- **Skybox Series Free**: 16種類のスカイボックスが収録されており、ゲームの雰囲気を簡単に変えることができます。
- **DOTween (HOTween v2)**: 簡単にアニメーションを追加できるツールで、移動や回転などのアニメーションを手軽に実装できます。

これらのアセットを活用することで、開発効率を大幅に向上させることができます。

### Unity入門の森

[Unity入門の森](https://feynman.co.jp/unityforest/)は、初心者向けの学習サイトで、Unityの基本から応用までを体系的に学べます。特に、以下の講座が人気です。

- **タワーディフェンスゲームの作り方**: 2Dのタワーディフェンスゲームをゼロから作成する講座です。 
- **放置インフレ系クリッカーゲームの作り方**: スマホアプリで人気の放置ゲームやクリッカー系ゲームの作り方を学べます。
- **3Dアクションゲームの作り方**: ゼルダの伝説や原神のような本格的な3Dアクションゲームの制作方法を解説しています。

これらの講座を通じて、実践的なスキルを身につけることができます。

## まとめ

- Unityを使用すれば、サガシリーズのようなゲームを初心者でも制作可能です。
- 閃きシステムや連携システムは、シンプルなロジックで実装できます。
- 豊富なリソースを活用して、効率的にゲーム開発を進めましょう。

ゲーム制作は挑戦と学びの連続ですが、その過程で得られる達成感は格別です。ぜひUnityを活用して、あなたの理想のゲームを形にしてください！

[Unity入門の森はこちら](https://feynman.co.jp/unityforest/)
AWSの支払い通貨を気にしてみた

## クレジットカードでの支払い
クレジットカードの変更をしたときに気になったので、支払い通貨をJPYにしたらなにか影響があるのか少し調べてみた。

### 11/29 10:37の提示レート

月末でどう変動するかはおいといて、現時点でどの程度なのか大雑把に把握しておく。
※ネットの情報では基本的に円建てでデメリットは無いとのことなので、そのバイアスあり。

AWSは153（小数点なし）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/afe5d1d7-6fac-475b-5a15-461aad37db9e.png)

MasterCardは152.03。銀行手数料（Bank Fee）はAWSに対するハンデ？としてゼロにした。
日付は昨日（11/28）。※AWSは明確な日付提示がないが、まあ同じ日付でしょう。

https://www.mastercard.us/en-us/personal/get-support/convert-currency.html

で、ドルで請求の場合、私のカードはOricoなのでその手数料がかかるな、と調べたら、来月あたり（2024/12）から手数料が上がるらしい。

https://www.orico.co.jp/information/service/20241024_01.html

>改定内容（税込）
>|| 改定前	| 改定後 |
>|:-:|:-:|:-:|
>| Mastercard	|2.20%	|3.85%
>| Visa	|2.20%	|3.85%
>| JCB	|1.60%	|1.60%

### 結局

支払い通貨は円にしておいた。
Bank Feeがゼロでも改定後の手数料ならAWSが有利と読み取れたので。
ゼロから学ぶDeepLearning5は少しわかりにくいかも：ミソは目的関数の形をバッチ処理できるものにすること

### ゼロから作るDeep-Learning 生成モデル編、

第一にはなぜEMアルゴリズムというのを強調するのか？

p.94が出発点で肝心なんだけど問題あり。
解析的云々とか書いているが全く関係ない。
log-sum云々もわかりずらい。記号の使い方も問題がある。
その先は数式とコードを適当にまぜてごまかしてあるようにも見える。読む気しないな。
査読者が多い、というのは誰も読んでないということかもしれない
EとMの二段階最適化を強調するのはおかしいな。一発で勾配を取るんです。

### ミソは、独立な複数のランダム変数を用いた項の総和として最適化関数を表すこと。
全ての\sumが一番外側に来てればよい。
目的関数が$\sum_a \sum_b \sum_c F(a,b,c,t,\theta)$の形になってればよい。これを$\theta$を動かして最小化する。
この最小化はとてもやりやすい。まず$a,b,c$を独立にランダム発生させてサンプリングで和が取れる。バッチ和がとれる。総和の形になっているのでバッチ最適化を繰り返してグローバル最適化することが期待できる（SGD)。自動微分はそもそもどんな関数形でもpytorchにある関数形の組み合わせなら可能。バッチ和の自動微分ができればGPUに乗り、pytorchのoptimizerで最適化できる。
ゆめみの執筆を支える環境

ゆめみの執筆委員会（ゆめみ大技林製作委員会）は今年、技術書典16および17、技術書同人誌博覧会10（年明けの11でも頒布予定）、そしてコミケ104（年末の105でも頒布予定）で、ゆめみ大技林を頒布しました。

https://techbookfest.org/product/ajJSVxhQcQ0YDRnq0b4fx7

https://techbookfest.org/product/kdUdfz8a1KZQJZvJxRVu8V

また、今年11月に開催された FlutterKaigi で配布したノベルティ技術書の製作も行いました。電子版は BOOTH にて無料配布しています。 

https://yumemi-inc.booth.pm/items/6322258

## 執筆環境

[Vivliostyle](https://vivliostyle.org/ja/) という CSS で組版できる OSS を利用しています。このライブラリは次の特徴を持っています。

- 記事はマークダウンで執筆する
- Web や CSS 知識を使って組版する

他にも組版ライブラリはありますが、業務でも使っている知識が使えるので、おすすめの組版システムです。この記事以外でも、執筆環境について書いています。それらもぜひ見てください。

https://qiita.com/usamik26/items/131e22d355cda4563e3e

https://zenn.dev/macneko/articles/06aec138a357b9

ゆめみの執筆委員会では、社内の GitHub のリポジトリに、それを組み込んだ執筆用のテンプレートを作成して、執筆しています。今回は、そのテンプレートリポジトリの日々の改善を紹介します。

## PRのレビューコストの削減

我々は商業誌ではなく同人活動の一貫でもあるので、個人の書き味を尊重しています。厳密な原稿チェックはしていませんが、次のような最低限のレビューを行っています。

- 誤字脱字
- 文章の意図や意味が伝わりづらいところはないか
- 電子版と紙版で情報落ちがないか
- 社外秘の情報が含まれていないか

そのような目的で、記事追加の PR が作られています。また、depandabot による依存ライブラリを更新するメンテナンス用の PR も作れています。

これまでは変更内容を確認して、手元でビルドして PDF を確認していました。しかし、執筆の佳境に入ると、同時期に多くの PR が作られ、レビューコストもあがります。また執筆期間でもなくても、メンテナンス目的の PR は日々作られます。通常業務の忙しさから放置することもありました。

通常の開発業務では PR が作れると CI が動き、テストやビルドの確認が自動で行なわれてるのが一般的です。執筆という特殊な対象だったので、CI はいる？と躊躇してましたが、やっぱり必要と判断して作成しました。

現在、PR を作成すると、GitHub Actions で PDF が生成され、それがコメントで添付されます。これまで、ローカルでビルドしていた作業は不要になりました。レビューは執筆内容の確認、PDF の組版に問題はないかの目視だけになり、作業量は下がりました。以前は執筆者に PDF の手動添付をお願いしてましたが、それは不要になりました。

メンテナンス PR は変更内容と PDF が生成できたかを確認してマージしています。厳密には、PDF 作成を構成するライブラリのアップデートなので、PDF のスナップショットテストを仕込みたいところですが、いまは対応していません。

## フォントを共通化するテーマ

複数人で開発するので、それぞれの執筆環境は異なります。執筆プロジェクトでは、ローカルに Node.js を用意してビルドする方法、Docker イメージを使ってビルドする（Docker Desktop は不要で、Docker イメージを colima で実行する）方法を提供しています。

ここで問題になるのは（Vivliostyle で設定したテーマにもよりますが）、PDF のフォントはローカルにあるフォントが利用されます。執筆メンバーは macOS 上で書くことが多いので、大抵は macOS のシステムフォントが使われます。ただし、印刷所へ入稿する PDF は Vivliostyle の推奨でもある Docker イメージを利用します。入稿用のフォントはその Docker イメージが持つフォントになります。同じ内容の執筆プロジェクトでもビルド環境によってフォントが異なります。

最近までは、この問題は認識していましたが、影響は少ないだろうと思い、そのままにしていました。ただ、上記の GitHub Actions で PDF を生成したときに、Actions の実行環境に日本語フォントがなく、文字がいわゆる豆腐になってしまった。また、電子版と紙版でフォントの違いによる組版の違いに遭遇してしまったため、対応することにしました。

この解決として、フォントだけを設定するテーマを作成しました。当初はフォントデータの取り扱いにうまくいかずでしたが、Vivliostyle の開発者の方々に教えてもらいました。改めて、ありがとうございました。

https://github.com/mitsuharu/vivliostyle-theme-noto-sans-jp

このフォント設定のテーマは次のように設定します。どの環境でもフォントは Noto Sans に固定されます。

```javascript:vivliostyle.config.js
module.exports = {
  theme: [
    '@vivliostyle/theme-techbook',
    '@mitsuharu/vivliostyle-theme-noto-sans-jp',
  ],
};
```

このフォントを設定するテーマは一般にも公開しています。同様にフォントの問題に悩まされている方は、ご利用ください。

## 自動化は他にも対応中

他にもリリース用のタグを打つと、電子版と印刷所入稿用の PDF を作成してリリースのアセットに添付するなど、便利な自動化を進めています。記事を書く、表紙画像を描く、以外は自動化できるようにテンプレートを改良しています。

## まとめ

Qiita など、記事を書かれる方は多いと思いますが、それを本として出版したとなると限られてくると思います。同じ執筆でも、本製作は別の楽しさがあるので、興味ある方はぜひ挑戦してみてください。

ゆめみ大技林は、主にゆめみメンバーが書いていますが、執筆に興味ある社外の方も大歓迎です。本を作りたいけど、やり方がわからない方、書いてみませんか？

## 編集後記

この記事は勉強会参加のために乗車した新幹線の中で書いています。山陽新幹線はトンネルが多いので、ネットワーク不調で Qiita の記事保存が飛ばないか心配してます。
3年前の自分が持っておいた方がよかった学習のマインドセット

**「市場なんてクソくらえ！」**

自分が学習することにおいて、どこがホットな領域か、何がトレンドか、という市場を考え、そこに対してマーケティングすることは無意味である。

自分が学習することにおいて、一番マーケティングすべき対象は自分である。

そして、日々の学習の上で、持っておくべきマインドセットは4つある。

## 4つのマインドセット

- collector's fallacyに陥らない
- syntopical readingをする
- この世のカオスに対して寛容であれ
- 歴史の風雪に任せる

### collector's fallacyに陥らない

Elaborationなしに集めようとするな。

ただ収集してもゴミの山にしかならない。

動きが激しい領域だから、ベストプラクティスを、金言を、最先端を、データを、単語を、数式を…と求めて、とにかくたくさん集めようとすることはあろう。

もちろん知っていることは悪くはないが、骨を折らずに得たようなデータは情報にはなっても知識にはならないだろう。

学習者は、知識を獲得しなければならず、さらに知恵を身につけなければならない。そのためには、Elaborationを必ず伴う。

### syntopical readingをする

「この本が話題だから、この本が一番有名だから、これを読む」、ということをやりがちである。そして、その本に関する他の書籍を読まない。

勿体無い！

一冊読んだら、それに関する知識がたまり、理解が進む。別の同じ領域の本を読んだら、もっと素早く、もっと深く、もっと鋭く、読むことができる。

そして、それぞれの著者の意見の違いを見つけ、自分の意見や考えを作ることができる。

### この世のカオスに対して寛容であれ

この世はシンプルではない。

単一の基準や、非合理性の入る余地のないフレームワーク、これらを採用すると、この世はシンプルに映る。

しかし、それは世界を曲解しているのであって、事実ではないし、真理には至らず、価値を創出することからも遠ざかる。

カオスをカオスとして、寛容に受け入れるべきである。

シンプルなフレームワークやアイデアが出てきた時には眉唾物である。syntopical readingをすることで、相反する事実を見つけることをこころがけるべきである。

### 歴史の風雪に任せる

自分をマーケティングの対象とすることは、圧倒的なブルーオーシャンである。ブルーオーシャンであるが、しかし、誰も生息できないような深海であるかもしれない。

自分の興味と自分のやりたい仕事のために、syntopical readingをやり、elaborationをかかさずやり、カオスに向き合っていくこと、これのコスパは見合うのだろうか？

それは歴史の風雪に任せるべきである。

他人になんと言われようとも、その時限りである。歴史の風雪の方が圧倒的に強く、信頼できる。

そして、存在するかどうかわからない集団のマーケティングの結果よりも、自分という確固たる存在をマーケティングした結果の方が、歴史の風雪に耐え、リターンが来る確率は高いだろう。

## まとめ

**「市場なんてクソくらえ！」**

自分をマーケティングして、自分の興味をつきつめろ。ゴミの山を作るな。

最後は歴史の風雪がなんとかしてくれる。
Gspread の使い方 (フォルダーの一覧）

フォルダーに次のようなファイルがある時の一覧を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/77a03839-f57c-df34-d096-d7d62189f6e6.png)

## 共有設定
フォルダーの共有設定をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/83dd018a-df09-f5b9-947c-f820e805b86d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f2dd07a3-219c-38e0-9e28-890075952399.png)

次のようにして得られる Eメールアドレスを加えます。

```text
$ jq . service_account.json | grep client_email
  "client_email": "sss-aaa@project-nov15-2024.iam.gserviceaccount.com",
```

## Google Drive API を使えるようにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/03a5148f-dfed-19e5-1e2f-ed0e72a1ee1c.png)

## プログラム

```py:list_spread.py
#! /usr/bin/python
#
#	list_spread.py
#
#					Nov/29/2024
# ------------------------------------------------------------------
import sys
import os

# pipx でインストールされたパッケージのパスを取得

package_path = os.path.expanduser('~/.local/share/pipx/venvs/gspread/lib/python3.12/site-packages')

sys.path.append(package_path)

package_path = os.path.expanduser('~/.local/share/pipx/venvs/gspread-dataframe/lib/python3.12/site-packages')

sys.path.append(package_path)

import gspread
from oauth2client.service_account import ServiceAccountCredentials
import pandas as pd
from gspread_dataframe import get_as_dataframe, set_with_dataframe

# ------------------------------------------------------------------
credentials = ServiceAccountCredentials.from_json_keyfile_name('./service_account.json')
#
client = gspread.authorize(credentials)

spreadsheets = client.openall()
for spreadsheet in spreadsheets:
	print(f"タイトル: {spreadsheet.title}, ID: {spreadsheet.id}")
#
# ------------------------------------------------------------------
```

## 実行結果
アクセス権のあるものが、すべて表示されます。

```text
$ ./list_spread.py 
タイトル: 豊田小_2024-10-08, ID: 1TKKGXSYzpWj3ekaQMfYtMiQtPDc1ebQ
タイトル: 羽川小_20241106, ID: 1eK0hZ_kI6FO2J2RZ94hizP7VZ1lkYObX5N
タイトル: 都市の人口, ID: 1D1hk5LH6O3BlFehaBgnzfGtbcra35BX0r9niclA
タイトル: nov26_aa, ID: 14MdjJ3Hvna9ynheAphHozcW_k1JNQjjtkOtvu
タイトル: 絹義務小_2024-06-05, ID: 1hygAKaT2Jpmi7fa1yiRa0mYClOxRr99
タイトル: 絹義務小_2024-11-12, ID: 1rW5RphB5UGAXxN9SJMy3HqgT5T9hO
タイトル: 絹義務小_2024-09-25, ID: 1cGr-uoEa-kjHGLi5u9OfKcdYWrM
タイトル: 豊田小_2024-06-18, ID: 1DBwZHtrPQ28wjCu5Mp5DtlVbcvSo9pkN
タイトル: 間々田小_2024-10-23, ID: 1JWd7zaxidv5uGEKuMndgwGjVk3U3U07
タイトル: 間々田小_2024-06-19, ID: 1kGVQR1db7UnFc-fWygdKleB5tKwIPi
タイトル: 乙女中_2024-10-02, ID: 1ut0lZdayQ9R3Dc28-JLLNvAQvZTf8
タイトル: 乙女中_2024-07-02, ID: 1Ak2rJG-_nnusmr_br2gGOw-w36pcx
タイトル: 大谷中_2024-10-31, ID: 1Rd3F5mcC7AEs6dPDXn3GlyG1R0n
```
Proj #001 キャンバスアプリで支払申請のフォームを作成するゾ～第6回 Dataverse使わなくて済んだので秘伝のタレをコッソリ教えるスレ～

https://qiita.com/Novskiiiiiiiiii/items/6048795780fe515346fd

前回、「リストのアイテムが数万あってフォーム上でChoicesしようとするとダメぽだったのでDataverseに逃げた」という話をしましたが、試行錯誤して数万のリストでもマスタとして使えるようになったので残しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/4cb8f5d5-4267-3102-461e-d939e07ff181.png)

こんな感じで、「テキスト入力」項目と「ドロップダウン」項目を設置しておきます。
説明のためにドロップダウンの項目のVisibleをTrueにしてスクショしてますが、
実際にはこの項目は非表示にしています。

で、テキスト入力に関しては特にプロパティの設定はありません。
強いて言うなら数値だけ入力できるように正規表現で制限かけるくらいかと思いますが、
今回の件とは関係ないので割愛します。

さてドロップダウンの方のプロパティを設定しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/030214dc-e078-b499-0e09-c8ba9f7106d4.png)

Itemsにこのように入れます。

    Filter('相手先コード一覧', タイトル=txt_client_code.Text)

Valには、表示させたい項目名を選択します。
今回は「相手先コード一覧」というリストのタイトルを相手先コードとして使用しているので、
タイトルを持ってきています。

txt_client_code　というのはテキスト入力項目の名称です。

なので、

「テキスト入力フィールドに入力した相手先コードの値と、相手先コード一覧リストのタイトルを照合して、相手先コード一覧リストからタイトル列を持ってくる」というFilter関数の設定になります。

これで数万アイテムのリストをマスタとして参照させる事が可能になりました。

内容としては実にシンプルですが、めちゃくちゃ実用的な情報だと思うので、心の中で投げ銭をお願いします。
みなさまの業務が少しでもラクになれば幸いです。

それではまた。

https://qiita.com/Novskiiiiiiiiii/items/f8c66d18e741998468c2
拡張子を除いたファイル名の先頭と末尾のみを String#gsub のみでマスキングする

# メモ

```rb
RUBY_VERSION
#=> "3.3.6"

require 'minitest/autorun'

class TestMaskFilename < Minitest::Test
  def mask_filename(filename)
    # 肯定後読みでファイル名の先頭 1 文字を指定する。
    # 肯定先読みでファイル名の末尾 1 文字と拡張子を指定する。
    # String#gsub のブロック引数には正規表現にマッチした部分文字列が渡されるので、
    # '*' を同じ長さだけ並べた文字列に置換することでマスキングする。  
    filename.gsub(/(?<=\A.).+(?=.\.\w+\z)/) { |matched| '*' * matched.length }
  end

  def test_mask_filename
    assert_equal('佐*****密.xlxs', mask_filename('佐倉杏子の秘密.xlxs'))
    assert_equal('佐**********s.zip', mask_filename('佐倉杏子の秘密.xlxs.zip'))
    assert_equal('M*************密.docx', mask_filename('Mr.Children の秘密.docx'))
  end
end
```
テレワーク向けの背景画像作ってみた

### **はじめに**
こんにちは。7月にUXデザイナーとしてジョインした水原です。
現在はJR西日本のアプリWESTERの開発や新規サービスの企画・改善を行い、
より良い体験設計に邁進しています。

今回は、入社後に社内メンバーと話していて、「ほしい」、「必要だ」と意見の多かったテレビ会議中に使う背景壁紙の制作について、お話をさせていただきます。

---
### **目次**
- 目的とデザインコンセプト
- ツール選び
- 画面構成
- まとめ

---
### **目的とデザインコンセプト**
TRAILBLAZERでは、1on1をする文化が根付いていて、
部内はもちろんあらゆる人と1on1をします。
その会話の中から、デザイナーとしてすぐやってみたいことを見つけました。
それがテレビ会議中の壁紙です。
そして、会話の中から必要性を読み取り、
目的を以下のように整理しました。

- 他社との会議時にTRAILBLAZERメンバーであることがわかる
- TRAILBLAZERのミッションである「GO WILD WEST!」の浸透

以上の目的を達成するために、今回はシンプルに文字とロゴを目立たせ、
TRAILBLAZERの勢いを表現することをデザインコンセプトとしました。

---
### **ツール選び**
ツールは何でも良いのですが、今回は繊細なグラデーションを使いたかったので、
Adobe Illustratorを選択しました。
TRAILBLAZERでは、AdobeツールやFigmaを目的に合わせて自由に選んでグラフィック等を制作しています。

---
### **画面構成**
一般的に壁紙のサイズは1920×1080の横長の長方形。
そこに以下のように人がメインで入ってくるので、
読ませたい文字や見せたいロゴを避けて構成していく必要があります。

![img_human.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932355/5c031ff9-70bb-4ae8-4ce8-749158e367e6.png)

今回は浸透させたいミッションを左側に配置し、目立たせました。
右上にTRAILBLAZERのロゴを配置し、勢いを出すために背景を山にしました。
この山にうっすらグラデーションをさせて勢いを増すようにしました。
そんな検討でできたのが以下の画像。
![壁紙_トレブレ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932355/59ffce3b-e118-f1ad-cc0c-d12ffaf718bc.png)

---
### **まとめ**
今回は、TRAILBLAZERで使っているテレビ会議向けの背景壁紙作成について、書いてみました。
ポイントとしては、ロゴや文言を人が入るスペースを考慮して配置することです。
是非、皆さんも会社を盛り上げる背景壁紙を作ってみてください。


https://hrmos.co/pages/trail-blazer
Docker Buildx でマルチプラットフォームビルドを実現

## 背景
Windows環境（Intel/AMD）で開発を進めている中で、Lambda（Linux/ARM64）にデプロイするための Docker イメージをビルドしようとしたところエラーが発生しました。
**結論、ホストマシンとビルドターゲット間のプラットフォームの違いが原因でした。**
この記事では、このような異なるプラットフォーム間のビルド課題を解消するために、Docker Buildxを活用する方法を解説します。

## Docker Buildx とは
Docker Buildx は、Docker の拡張ツールで、特にマルチプラットフォーム対応のコンテナイメージをビルドするために使われます。
通常の Docker ビルドではホストと同じプラットフォーム向けのイメージしか作成できませんが、Buildx を使えば、異なるプラットフォーム向けのイメージを簡単にビルドできます。


## なぜ異なるプラットフォームでのビルドができない？
そもそも、なぜ異なるプラットフォーム間でビルドができないのかというと、**ホストマシンとターゲットプラットフォーム間のアーキテクチャや命令セットの違い**が原因です。

### 1. CPUアーキテクチャの違い
ホストマシン（ビルドを実行するマシン）とターゲットプラットフォームのCPUアーキテクチャが異なる場合、互換性がないバイナリが生成される可能性があります。
例えば、ホストが x86_64（Intel/AMD） で、ターゲットが arm64（ARM） の場合、生成されるコードが異なるCPUの命令セットを理解できません。
そのままではターゲットの環境で実行できないコンテナイメージが作成されます。

### 2. ネイティブ依存関係
Dockerイメージの中には、ネイティブのライブラリやバイナリ（CやC++で書かれたコード）を含む場合があります。
これらのネイティブコンポーネントは、ビルド時のプラットフォーム（ホスト）でコンパイルされるため、異なるプラットフォームで動作しない可能性があります。
例えば、x86_64 でビルドされたライブラリ（例：glibc）は、arm64 では動作しません。
特に、Dockerfileで RUN コマンドを使用してソフトウェアをインストールする際に問題が発生します。

### 3. Dockerの設計方針
Dockerは、シンプルで高速なビルドを提供するため、基本的にはホストプラットフォームと同じアーキテクチャをターゲットにしています。
ホストとターゲットのアーキテクチャが一致する場合、ネイティブな速度でビルドと実行が可能です。
一致しない場合、標準的なDockerではこれをサポートしていないため、エラーになります。

## マルチプラットフォームビルドの流れ

### 1.Buildx インスタンスの作成
```bash
docker buildx create --use --name mybuilder
```
mybuilderの部分は任意の名前で大丈夫です。

### 2.QEMUの有効化
```bash
docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64
```
QEMU をインストールすることで異なるプラットフォームへのビルドがエミュレート可能になります。

### 3.Buildx インスタンスを初期化
```bash
docker buildx inspect --bootstrap
```
docker buildx createはインスタンスを作成するだけなので初期化が必要

### 4. プラットフォームの確認
```bash
docker buildx ls
```

下記のように出力されれば大丈夫です。`PLATFORMS`にlinux/amd64やlinux/arm64があるので、マルチプラットフォームが有効になっています。

```bash
NAME/NODE        DRIVER/ENDPOINT                   STATUS    BUILDKIT   PLATFORMS
mybuilder*       docker-container
 \_ mybuilder0    \_ unix:///var/run/docker.sock   running   v0.17.2    linux/amd64, linux/arm64, linux/arm/v7, linux/386
```
### 5.マルチプラットフォームビルドの実行
```bash
docker buildx build --platform linux/arm64 --tag my-image:latest .
```

## QEMU とは
QEMUは、オープンソースのエミュレーターで、異なるプラットフォーム間（例：x86_64 と arm64）の互換性を提供します。具体的には、ホストマシンがサポートしていないCPUアーキテクチャの命令セットをエミュレーションし、その環境でアプリケーションやOSを実行可能にします。Dockerと組み合わせることで、異なるプラットフォーム向けのコンテナイメージをビルドできるようになります。

### Buildx だけではダメな理由
Buildx はマルチプラットフォームビルドをサポートしますが、ホストプラットフォーム以外のアーキテクチャ向けのビルドには QEMU が必要です。
Buildx はあくまで Docker のビルド機能を拡張するツールであり、異なるCPUアーキテクチャ（例：x86_64 → arm64）の命令セットそのものをエミュレーションする機能は持っていません。


## Buildx 関連の便利コマンド
### 1. Buildx バージョン確認
```bash
docker buildx version
```

### 2. ターゲットプラットフォームの確認
現在のホストマシンのプラットフォームを確認します。
```bash
uname -m
```

### 3.  Buildx インスタンスの削除
不要になった Buildx インスタンスを削除します。
```bash
docker buildx rm mybuilder
```



**・追記**

:::note warn
Docker デーモンが再起動すると、 QEMU 設定がリセットされるので、定期的に有効化が必要になる。
:::