OmniAICreator/Qiita-1.07M huggingface dataset:
Milk-v Duoで顔認識

## はじめに
　秋葉原ロボット部では、2023年からMilk-v Duoのボートを使った成果物が報告されています。この成果は、Adventカレンダーにまとまっています。

https://milkv.io/ja/duo

https://akbrobot.connpass.com/

https://qiita.com/advent-calendar/2023/akbrobot

　2024年の展示イベントの「NT京都」と「つくろがや！」で、kazuedaが行った成果を展示しています。

https://wiki.nicotech.jp/nico_tech/index.php?NT%E4%BA%AC%E9%83%BD2024

https://tsukurogaya.nagoya/

　行った展示のうち、顔認識は、「Milk-v Duo」と専用のカメラ「CAM-GC2083」を使うことで、認識結果をパソコン上で動作する「VLC Player」表示できます。
　本稿の情報は、2024年03月頃の情報です。新しいファームウェアでは、設定が変わるかもしれません。以降の説明では、USBケーブルでMilk-v Duoにアクセスするパソコンを母艦とよびます。
## 環境構築
　試したファームウェアは、Duo-V.1.0.9です。専用カメラを接続したMilk-v Duoと母艦ととは、USBケーブルで接続し、Milk-v Duoの起動を待ちます。


https://github.com/milkv-duo/duo-buildroot-sdk/releases/tag/Duo-V1.0.9

## 顔認識の実際
　Milk-v Duoが起動したら、既に用意されている「camera-test.sh」を使って画像認識できるようにします。「camera-test.sh」は、以下のディレクトリに存在します。
/mnt/system/usr/bin/camera-test.sh
「camera-test.sh」の内容は、以下の通りです。
```
#!/bin/sh
export LD_LIBRARY_PATH=/mnt/system/lib
sample_vi_fd /mnt/cvimodel/scrfd_480_270_int8.cvimodel
```
　Milk-v Duo側で画像認識ソフトが動作したら、母艦側で「VLCメディアプレーヤー」を起動します。
 
https://www.videolan.org/vlc/index.ja.html

　Milk-V Duoのファームウェア1.0.9のcamera-test.shは、「 VLCメディアプレーヤーの「メディアを開く」から、「ネットワーク」のタブを選び「rtsp://192.168.42.1/h264」と入力して、再生を押します。
　VLCメディアプレイヤーの表示では、ビデオ解像度が1920*1080で、フレームレートが30と表示されています。Milk-v Duoの消費電力は、150 mAです。

https://milkv.io/ja/docs/duo/application-development/tdl-sdk/tdl-sdk-face-detection

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/7632519f-eb8a-0ac6-12e9-a723025619b0.png)

　CCの写真の認識を行いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/bfc5ca07-7bde-dbed-9f21-f4fc4c29e28c.png)

　図の左端のコンソール画面には、検出中の顔の数が表示されます。VLCメディアプレーヤーの画面では、認識されている顔は、水色の枠で囲まれています。左下の、大人の肘が重なっている子供以外は、認識されています。
## おわりに
　本稿では、Milk-v Duoと母艦との間は、USBケーブルで接続しました。Milk-v DuoのEtherのポートはPoEに対応しています。PoEに対応したルーターやハブに有線接続すると、LANケーブルから電源供給されますので、電源の準備が不要となります。
　LANケーブルが1本で、動作が可能となります。個人利用の、留守番しているペットなどのリモートモニタリングに適しているのではないでしょうか。
　また、他のコマンドとして、以下のものがあります。これらのコマンドの動作確認も、楽しいかと思います。
```
sample_cvg           sample_gradfg           sample_overlay        sample_thresh_S16
sample_16bitto8bit   sample_dilate           sample_hist           sample_query               sample_thresh_U16
sample_add           sample_dma              sample_integ          sample_region              sample_vcodec
sample_and           sample_dsi              sample_lbp            sample_resize              sample_vdec
sample_audio         sample_erode            sample_magandang      sample_sad                 sample_vdecvo
sample_bernsen       sample_filter           sample_map            sample_scene_auto          sample_venc
sample_bgmodel       sample_filterandcsc     sample_ncc            sample_sobel               sample_vi_fd
sample_cannyedge     sample_fisheye          sample_normgrad       sample_stcandicorner       sample_vio
sample_cannyhysedge  sample_framediffmotion  sample_or             sample_sub                 sample_xor
sample_cipher        sample_gmm              sample_ordstatfilter  sample_test_tp2863_tp2803  sensor_test
sample_csc           sample_gmm2             sample_osdc           sample_thresh
```
そのテーブル名、大丈夫？MySQL予約語エラーの回避術と識別子の基本

先日、MySQLを5.7から8.0にアップグレードした際にクエリが突然動かなくなり、冷や汗をかく事態に直面しました。
原因を調べたところ、テーブル名に**予約語**を使っていたため、構文エラーが発生していました...
同じようなトラブルを防ぐためにも、識別子と予約語の基本について整理することにしました。


# 識別子って何？
簡単に言うと、識別子はデータベースの中でテーブルやカラムなどに付ける名前のこと。
以下のようなデータベースオブジェクトの名前を指します。

```
・データベース名
・テーブル名
・カラム名
・インデックス名
・ビュー名
・ストアドプロシージャやトリガー名
```

# 予約語って何？
予約語とは、MySQLが「これだけは特別な意味だから使わないでね」と決めているキーワードです。
クエリの動作を制御する重要な言葉なので、普通はテーブル名やカラム名などに使えません。

## 予約語の確認方法
「何が予約語か分からないよ」という方は、公式ドキュメントをチェックするのが一番。
特にバージョンアップで新しい予約語が増えることもあるので、最新情報を見ておきましょう。(今回のエラーもそのパターンだった)


**MySQL 8.0で新たに追加された予約語の例**
・CUBE
→複数の列に対してすべての組み合わせの集計結果を返す。
・ROLLUP
→階層的に集計し、親グループの集計結果も返す。
・WINDOW
→ウィンドウ関数を使って、行ごとの集計結果を他の行と比較する。

公式ドキュメントには常に最新の予約語リストが掲載されているので、バージョンアップ時は要確認です。

[MySQL 8.0 予約語リスト](https://dev.mysql.com/doc/refman/8.0/ja/keywords.html)

## 予約語を使うときの対処法
それでもどうしても予約語を名前に使いたいときや使わざるを得ない時があると思います。
その時はバッククォートで囲みましょう。

例えばこんな感じです。

・エラー例
```sql
CREATE TABLE user (
  id INT
);
```
エラー内容:
`ERROR 1064 (42000): You have an error in your SQL syntax...`


・解決策
```sql
CREATE TABLE `user` (
  id INT
);
```

この例では、予約語のuserをテーブル名として使っています。
バッククォートで囲めばエラーになりません。

### 実務での注意点
・直接SQLを書く場合
予約語は避けるか、バッククォートでしっかりエスケープ。

・ORMを使う場合
ORMの設定で自動エスケープが効いているか確認しておくと安心です。

# 最後に
MySQLで予約語に引っかかると地味にハマるので、事前に気をつけたいところ。
すべての予約語を覚える必要はないものの、「あ、これ予約語かも？」ってピンとくる感覚を持っておくと、余計なトラブルを減らせると思います。
公式ドキュメントをさらっと見て、どんな感じかだけでもつかんでおくといいかもしれません。
Tkinterで謎に詰まってしまう「遅延評価」の対処法

# 環境
Python 3.13
Tkinterインストール済み
# 「遅延評価」によっておきるバグ
Tkinterでフレーム等を使いリストを表示し、その中のボタンにfor文でコマンドを設定したら、for文のカウントと一致せずにコマンドが設定されてしまうことがあります(下は例のコードです)
```py
import tkinter as tk
root = tk.Tk()
root.geometry("500x300")
button = []
for i in range(5):
    button.append(
        tk.Button(
            root,
            text=str(i),
            command=lambda:print(i)
        )
    )
    button[-1].pack(fill="x")
root.mainloop()

# 0,1,2,3,4いずれのボタンを押しても4がprintされてしまう
```

# 解決方法
commandの引数を変えましょう
```diff_python
import tkinter as tk
root = tk.Tk()
root.geometry("500x300")
button = []
for i in range(5):
    button.append(
        tk.Button(
            root,
            text=str(i),
-            command=lambda:print(i)
+            command=lambda count=i:print(count)
        )
    )
    button[-1].pack(fill="x")
root.mainloop()

# きちんと押したボタンの数字がprintされる
```
スプシでもエクセルみたいに半角数字にしてほしい

### スプシの細かい不満：全角数字

Officeスイートのオルタナティブとして、GoogleWorkSpaceを長らく使っていますが、細かいところではスプシがエクセルに劣るところもあります。特に全角数字を入れたあとの挙動が、エクセルであれば「表計算で全角数字なんてありえないっしょ！」と半角に変換してくれますが、スプシではそんな変換してくれません。地味にストレスです。

### 解決策：強制的に変換するGASを組み込む

このGASを組み込みます

```js
function onEdit(e) {
  let range = e.range;
  let value = range.getValue();

  let convertedValue = value.replace(/[０-９，／]/g, function(s) {
    switch(s) {
      case '，': return ',';
      case '／': return '/';
      default: return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
    }
  });
  
  if (value !== convertedValue) {
    range.setValue(convertedValue);
  }
}
```

これで編集が終わると、全角数字が半角に変換されます。

### より機能を追加するには

- 本当であればセルの書式をみて、全角が入らなさそうなところだけやればいい
- だけどその処理が微妙に重い
- そもそもGASのレスポンスが悪い
- これ以上余計な処理を加えたくない

ということで、一旦ここで打ち止め

### 結論

地味にエクセルが手放せない
Robolectricで複数のAndroidSDKをテストした際のOutOfMemoryErrorとその対策

## 事象
Robolectricは、<code>Config</code> アノテーションを用いて複数のAndroidSDKバージョンに対してテスト関数を連続で実行してくれる機能があります。

``` kotlin
    @Test
    @Config(minSdk = 22, maxSdk = 34)
    fun getSdkTest() {
        
    }
```

この機能を用いて、SDK22〜34までをテストした際に <code>OutOfMemoryError</code> が発生しました。

![スクリーンショット 2024-12-01 14.47.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2549554/1d5ac9c2-b7e6-66b7-eb5c-5194230c746f.png)

テスト対象のSDKの数を減らすと正常に完了するため、すべてのSDKバージョンのテスト完了ごとのメモリ解放ではなく、全てのテストが実行されるまで保持しているようです。

## 環境
- Gradle 8.9
- Gradle JDK 21.0.3
- JUnit 4.13.2
- robolectric 4.14.1

## 結論
対象モジュールの <code>build.gradle.kts</code> に、以下のように最大ヒープサイズを指定したところ解消しました。
```
tasks.withType<Test> {
    maxHeapSize = "1024m"
}
```

groovyの場合は、試していませんがおそらくこの記述となります。
```
test {
    maxHeapSize = "1024m"
}
```

デフォルトのテスト時のメモリ上限はおそらく512m程度で設定されているようです。


## 試してダメだったこと

### <code>gradle.properties</code> のjvm引数での最大ヒープサイズの引き上げ
```
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
```

ヒープサイズといえばここの指定と思い引き上げましたが、Unitテストではこちらの指定は使われていないようで、効果無しです。

### テストの分割

``` kotlin
    @Test
    @Config(minSdk = 22, maxSdk = 29)
    fun getSdkTest1() {
        
    }

    @Test
    @Config(minSdk = 30, maxSdk = 34)
    fun getSdkTest2() {
        
    }
```

テスト関数を分けても、テストクラス自体を分けても、メモリを解放する挙動にはならず、一括テストでは効果はありませんでした。分割したテストを個別に実行するのであれば正常になります。

### テスト完了毎にGCを呼ぶ
```
    @After
    fun tearDown() {
        System.gc()
    }
```

SDKバージョンごとにメモリ展開されたオブジェクトはGC対象ではないのでしょう。効果がありませんでした。
プリザンターでBinaries_deletedテーブルに貯まり続けるゴミファイルを削除する方法

:::note info
プリザンターの`BinaryStorage.json`の`Provider`を`Rds`で運用している場合にのみ効果がある方法です。`Local`で運用している場合は、本記事の方法では対応出来ません。
:::

## はじめに
プリザンターで、レコードは削除せずに添付ファイルだけ削除することありませんか？実はこの処理、プリザンター側の設定次第では、見ることも触ることも出来ないゴミデータを作ってしまいデータベースの肥大化の原因となることがあります。

## どうして？
プリザンターでは、添付ファイルは`Binaries`テーブルに1ファイル1レコードの形で格納されています。ファイルの実体は`Bin`フィールドにBASE64エンコードされて格納されています。
添付ファイルの削除を行ったとき、`Binaries`テーブルに格納されているレコードは、`Binaries_deleted`テーブルに移動されます。さて、移動された後のレコードは何に使われるか？と言われると、吊しの状態では何にも使われません。
添付ファイルの詳細設定を変更して「[履歴に存在するファイルは削除しない](https://pleasanter.org/ja/manual/table-management-not-delete-file-with-history)」をONにすれば、履歴から添付ファイルにアクセスが出来きますが、吊しではこの機能はOFFなので、履歴からも見えなくなる=データベースに残っているけど触る手段がないゴミデータとなってしまいます。
レコード削除してゴミ箱から削除すると、ゴミ箱から削除するタイミングで、レコードに紐付くデータは全削除されるため、そのタイミングではデータは消えますが、添付ファイルの削除はするけどレコードは削除しない。ましてや削除してもゴミ箱からは消さないという運用は多いかなと思います。（現状のゴミ箱はサイトの管理権限がないと触れない＆時限削除の機能がないので、一般ユーザは操作する術がないため）

## 解決法
これは簡単に解決できます！
拡張SQLを使ってレコードに更新があったタイミングで、`Binaries_deleted`テーブルに格納されたレコードを削除してしまいます。これらを[マニュアル](https://pleasanter.org/ja/manual/extended-sql)に従ってファイルとして格納します。
```json:DeletedBinariesOnUpdatedDelete.json
{
    "Description": "レコード更新後に削除済み添付ファイルをレコードごと消す",
    "OnUpdated": true,
    "CommandText": "-- Write an arbitrary SQL statement."
}
```
```sql:DeletedBinariesOnUpdatedDelete.json.sql
DELETE FROM
    [Binaries_deleted]
WHERE
    [ReferenceId] = {{Id}}
```
やっていることはとても簡単です。更新後に`Binaries_deleted`テーブルからレコードIDに対応するレコードをサクッと消しています。
このSQLでは全てのサイトで削除が実行されますが、任意でサイトIDの限定や、「履歴に存在するファイルは削除しない」を使用している場合で、それに該当するレコードだけ残しておくというもの可能です。サイトIDの限定については前述のマニュアルを参照してください。「履歴に存在するファイルは削除しない」がONの場合に除外する場合も`Sites`テーブルの`SiteSettings`レコードと、`Results_history`テーブルまたは`Issues_histroy`テーブルを組み合わせて条件を組み上げれば対応可能です[^1]が、本記事ではそこまではタッチしません。

## まとめ
拡張SQLを使用することで、添付ファイルだけを削除した時に残るゴミファイルを削除することが出来るようになりました。データベースサイズは小さくしたいというニーズはあるかと思います。特にSQL ServerのExpress版を使用している場合、10GBのリミットがかけられているので効いてくるかと思います。
ただし、基本的に添付ファイルをいっぱい扱う場合は、どうしてもRdsモードで運用したい場合を除いては、Localモードでの運用することをオススメします。

[^1]:RDBMS側でJSONが触れる必要があります。SQL ServerやPostgreSQLだといろいろと関数がサポートされているので扱いやすいです。詳しく知りたい方はお仕事お待ちしてます！
BGPのトランジットの仕組み

# 他のASに対する経路情報を取得する　トランジット
>トランジットとは、インターネットにネットワークを接続する形態の1つです。企業や個人向けにインターネット接続サービスを提供するISP（Internet Service Provider）などでは、自律したネットワークを構築しています。こうしたネットワークをAS（Autonomous System：自律システム）と呼びます。このASをインターネットに参加させるためには、ほかのASに接続し、さらにパケットを送信するための経路情報を取得する必要があります。そのための方法の1つがトランジットです。
>
>トランジットは`ASが別のASに対して提供するサービス`です。サービス利用者となる`ASは、自身のネットワークをサービス提供元のASに接続し、さらに経路情報の提供を受けます。これにより、広範囲のネットワークの端末と直接通信することが可能`になります。なお、一般的にトランジットは有償で提供されます。

# ASを運用する組織同士が個別に交渉して経路情報を交換　ピアリング
>また`AS間の接続にはピアリングと呼ばれる形態`もあります。こちらは`ASを運用している組織同士が個別に交渉を行い、合意の上でネットワークを接続し、経路情報を交換`します。この接続は無償で行われるのが一般的です。
>
>基本的には、より規模の大きいISPが小規模なISPに対してトランジットでの接続サービスを提供し、大規模ISP同士は無償のピアリングによって接続されています。

https://www.ntt.com/bizon/glossary/j-t/transit.html#:~:text=%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B8%E3%83%83%E3%83%88%E3%81%A8%E3%81%AF%E3%80%81%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88,%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

# トランジットやピアリングのポリシーにはさまざまなバリエーションが考えられる
### ルーティングポリシーに沿ったルートを優先させる
>(1)宛先への複数のルートから優先的に選択する、(2)近隣ネットワークにルートをアドバタイズする方法をフィルタリングする、といったルーティング・ポリシーの組み合わせによって実現される。

>ルーターは、料金を支払う顧客から学習したルートを最初に優先し、次に決済不要のぴあから学習したルート、最後にプロバイダネットワークから学習したルートを優先する。

>決済の内ピアまたはトランジット・プロバイダから学習した経路は他のぴあまたはプロバイダには再アドバタイズしない。

### 顧客AS間のルートでお金を払って経路を作る　有償ピアリング
>ASは、`あるASが他のASの顧客から学んだルートへのアクセスに対して、そのASに経費を支払う`有償ピアリング(paid peering)の取り決めも持っている。有償ピアリングは、金銭の授受があることを除けば、決済不要ピアリングに似ている。

### 特定のルートのためにASに支払う　パーシャル・トランジット
>あるASが、インターネットの宛先のサブセットのルートに対して、別のASに支払いを行うものである。

#### サブセット
>部分集合

https://ejje.weblio.jp/content/subset#goog_rewarded

### 多くのISPを利用して通信する マルチホーミング
>一方のISPを経由した通信が失敗しても、他方のISPを経由した通信を行うことができ、信頼性が向上するこの技術はマルチホーミング(multihoming)と呼ばれている。

# 学習するとは？
経路情報を取得することだと考えている

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
Azure Fundamentals(AZ-900)を取得した時の勉強方法


# はじめに
Microsoft Azure Administrator（AZ-900）に2023年末、一発合格した時の勉強方法を紹介します。

クラウドは受験当時全くの初心者でした。
基本応用情報は取得しています。

AZ-104を受験する方向けの参考になれば嬉しいです。

# 出題範囲

| 分野 | 割合 |
|:--|:--|
|  クラウドの概念について説明する | 25–30%  |
| Azure のアーキテクチャとサービスについて説明する  | 35–40%  |
|  Azure の管理とガバナンスについて説明する | 30–35%  |

出題範囲は変更になる可能性があるため、公式サイトでチェックすることをおすすめします。

https://learn.microsoft.com/ja-jp/credentials/certifications/resources/study-guides/az-900#describe-cloud-concepts-2530

# 勉強方法
#### 講座を見て何となく頭に入れる

まずは一周Udemyの講座を見ました
よくわからずとも、何となく頭に入ればよいかなと
目的は問題集を見たときの単語アレルギー緩和です
問題集で挫折しないための処方箋として、頭に慣らしておきます

#### 問題を解きまくる

あとはひたすら問題を解きまくりました。
分からない問題はすべて調べます。
最初の１回目の問題集が一番時間かかります。
１回目(試験１回、約70問分)は問題を解かず、ひたすら解説を覚えました。

調べる際はUdemyか、MS Lean 、個人ブログなどを参考にしました。
何度も間違えた問題は暗記カードアプリにメモして通勤中に見直していました。

私が使っていたアプリはこちら↓
（Apple storeのページです）

https://apps.apple.com/jp/app/%E8%87%AA%E5%88%86%E3%81%A7%E4%BD%9C%E3%82%8B%E5%8D%98%E8%AA%9E%E5%B8%B3-wordholic-%E4%BE%BF%E5%88%A9%E3%81%AA%E6%9A%97%E8%A8%98%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC/id1434981148

ひたすら問題を解いて暗記をしていきました。

# 実際に活用したUdemy講座

講座はこちらを見ました。
全体的にふんわり頭に入れるには丁度よかったのでおすすめです。
↓

合格への近道！Azure Fundamentals AZ-900 試験対策講座

https://www.udemy.com/course/microsoft-azure-az900-video/?couponCode=CMCPSALE24JP

問題集はこちらを使用。
全て解きましたが、5回分くらいでも合格できたかもしれません。私は不安ですべて解きました。解けば合格間違えなしだと思いますのでおすすめです。
↓

【6万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問）

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/?srsltid=AfmBOoruS6RARat-eFwwEEFYhtfe-Odo_cDF1aVGQRFlS_hRHMXYEzl8&couponCode=CMCPSALE24JP

# 最後に

当時の勉強方法の紹介でした

私が受験した際はなかったのですが、今はMS Lean が試験中に見ることができるようです。時期によって異なる可能性があるので調べておくと勉強時間を短縮できるかもしれません。

仮にLeanを参照できる時期に受講予定であれば
暗記が難しい箇所はLean上で検索してたどり着けるようにしておくのも手かもしれません。

MS Leanのページ

https://learn.microsoft.com/ja-jp/
Cloud MonitoringによるBigQuery スロット割り当て量の監視

::: note info
これは [ZOZO Advent Calendar 2024](https://qiita.com/advent-calendar/2024/zozo) カレンダー Vol.9 の 10日目の記事です。
:::

# はじめに
本記事では、Google CloudのBigQueryのスロットの割り当て量について、[Cloud Monitoring](https://cloud.google.com/monitoring?hl=ja)による監視を導入する方法をご紹介します。
BigQueryのスロットについては、昨日投稿した[BigQuery コンピューティング容量（スロット）ベースの課金体系とスロット予約の特性を理解する](https://qiita.com/okmtz/private/a91bb8b2f0594de5643b)でご紹介しているため、良ければ参照ください。

# Cloud Monitoringによるスロット割り当て量の確認
Cloud MonitoringのMetrics Explorerでは`BigQuery Project > Slots > Slots used by project, reservation, and job type`の指標から、現在割り当てられているスロットの量を確認できます。

次図が確認できるスロット量のグラフの例です。

![スクリーンショット 2024-12-01 15.02.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576866/0e196e0c-f0dc-0661-6029-1ab90c13426d.png)

# スロット割り当て量の監視
スロットベースの課金（BigQuery Editions）を利用する場合、スロットの上限値等はスロットの予約により管理されます。
またスロットのコスト効率はクエリ実行パフォーマンスとのトレードオフになります。
※ 詳細は昨日投稿した[BigQuery コンピューティング容量（スロット）ベースの課金体系とスロット予約の特性を理解する](https://qiita.com/okmtz/private/a91bb8b2f0594de5643b)を参照ください

上述の指標を監視することで、長時間のスロット不足に気が付きやすくなります。

以下が上記の指標に対してアラートを設定する際のTerraform定義になります。
上記の指標を元にアラートポリシーを設定することで対象プロジェクトにおけるSlotの割り当て量を監視することができます。閾値については、プロジェクトでのユースケースに応じてご調整ください。

```tf
resource "google_monitoring_alert_policy" "bq-reservation-assignment-slot" {
  for_each = {
    "project-a" = {
      slots_threshold         = <ALERT_THRESHOLD> # ex: 90
      duration                = "<DURATION>" # ex: "3600s"
      notification_channel_id = "<NOTIFICATION_CHANNEL_ID>"
    }
  }
  project      = each.key
  display_name = "[WARNING] [${each.key}] BigQuery Slots High usage is continuing over ${each.value["duration"]}"
  combiner     = "OR"
  conditions {
    display_name = "[WARNING] [${each.key}] BigQuery Slots High usage is continuing over ${each.value["duration"]}"
    condition_threshold {
      filter          = <<-EOT
                  metric.type="bigquery.googleapis.com/slots/allocated"
                  resource.type="bigquery_project"
                  resource.labels.project_id="${each.key}"
                  EOT
      comparison      = "COMPARISON_GT"
      threshold_value = each.value["slots_threshold"]
      duration        = each.value["duration"]
      aggregations {
        alignment_period     = "60s"
        per_series_aligner   = "ALIGN_MAX"
        cross_series_reducer = "REDUCE_MAX"
      }
      trigger {
        count = 1
      }
    }
  }
}
```
Power BIレポートでGIFアニメーションを表示する

**Microsoft Power BI Advent Calendar 2024** の２日目の記事です。

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

([こちらのリポジトリ](https://github.com/knmaki/Power-BI-samples/tree/main/2411%20PBI%E5%8B%89%E5%BC%B7%E4%BC%9A%20LT%E4%BC%9A%2306%20Party%20Parrot)の転記。サンプルファイルもそこからダウンロードしてね。)


# 1. はじめに
## 1.1. これは何？
Power BI LT 会 6で発表した内容。
Party ParrotをPower BIのレポートで動かす。

https://powerbi.connpass.com/event/336027/

↓をぐりぐり動かしたい。
![img_たくさん.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/251b3006-a6bb-74a8-ff67-daaf6bdda880.png)

## 1.2. Power BI 勉強会とは
楽しいところです。

https://powerbi.connpass.com/

## 1.3. サンプルファイルの開き方
サンプルファイルは `party parrots.pbip` 。

プレビュー段階のPower BI Desktop プロジェクト（ `.pbip` ファイル）を使用しているので、プレビュー機能を有効にする必要あり。

https://learn.microsoft.com/ja-jp/power-bi/developer/projects/projects-overview


# 2. GIFの動かし方
以下を参考。

https://www.ehansalytics.com/blog/2021/10/27/add-an-animated-gif-to-your-power-bi-reports


## 2.1. ダメなケース（動かない）
`挿入`タブ -> `イメージ`ボタン -> ファイル選択

動かない。かなC。

![img_動かない_ハリー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/70f424a2-813a-ff7e-0b03-81a0194e3d77.png)

## 2.2. OKなケース
### キャンバス全体
キャンバスを選択 -> 書式設定 -> `キャンバスの背景` -> `イメージ `の `参照...`からファイル選択 -> `透過性`=0%

![img_GIFアニメ キャンバス全体_吹き出しあり.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/3582237c-a93f-04ac-1659-180f5bf8e21d.gif)


### ボタン

`挿入`タブ -> `ボタン`ボタン -> `空白` -> 書式設定 -> `ボタンのスタイル` -> `フィル`のトグルをオン -> `参照...`からファイル選択 -> `透過性`=0%

![img_GIFアニメ ボタン_吹き出しあり.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/f2a3f07c-ab08-81f5-7789-fcbed09e14b2.gif)


### たくさん動かしてみた
戦いは数だよ兄貴！！

![img_GIFアニメ たくさん.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/3dbcd3ad-ec2a-8de2-42ed-aec2346a9c7b.gif)

リポジトリから.pbixファイルをダウンロードするともっとやばいやつがあるよ💖💖

# 3. たくさん動かすとどうなるか？？
大量にParrot君を入れるといろいろ大変だった。

- ページが無茶苦茶重くなる
  - CPU、メモリー、GPUの使用量が増える
  - 重くなるのはそのページを開いたとき。つまり、ページを開くまでメモリーにロードされない。
  - GIFを入れていないページに戻ると、CPU、GPUの使用量は減るが、メモリーは増えたまま
  - キャッシュとして置いているということ？
- レポートのサイズは大きくならない。pbixファイルに取り込まれる画像自体は一つのみであるため。（pbipファイルで確認）
- 無茶苦茶重いので、整列させるためにはpbip形式内のjsonファイルをPythonで直接編集しなければならなかった
- ビジュアルを大量に含むレポートはサービスに発行できない
- （関係ないけど）Windows Game BarでPower BI Desktop（ストアアプリ版）の画面録画ができない
ラズパイ高速化　なったと思う。

以下で早くなった。
1.bluetooth関連サービスの停止。
```
sudo systemctl stop hciuart.service
sudo systemctl stop bluetooth.service
```
2.bluetooth関連サービスの自動起動を無効にする。
```
sudo systemctl disable hciuart.service
```
3.bluetooth関連サービスの停止。
```
sudo systemctl stop hciuart.service
sudo systemctl stop bluetooth.service
``` 
4.bluetooth関連サービスの自動起動を無効にする。
```
sudo systemctl disable hciuart.service
```
 5. 仮想メモリの SWAP領域を 2GBに広げる
 ```
sudo sed -i -e "s/^CONF_SWAPSIZE=.*/CONF_SWAPSIZE=2048/g" /etc/dphys-swapfile```
```
オーバライド

## オーバーライドとは
親クラスにあるメンバを子クラスで上書きすること

### サンプルプログラム（親クラス）

```java
public class Hero {
    String name = "ミナト";
    int hp = 100;
    //戦う
    public void attack(Matango m) {
        System.out.println(this.name + "の攻撃");
        m.hp -= 5;
        System.out.println("5ポイントのダメージを与えた！");
    }
    //逃げる
    public void run() {
        System.out.println(this.name + "は逃げ出した！");
    }
}
```

## オーバライド

親クラスで定義されているrun()「逃げ出した」を、子クラスで「撤退した」に書き直したい場合、子クラスで再度run()を定義すればよい。
Javaではオーバライドするメソッドには `@Override` アノテーションを付けます。

### サンプルプログラム（子クラス）
```java
public class SuperHero extends Hero {
    @Override
    public void run() {
        System.out.println(this.name + "は撤退した");
    }
}
```
## オーバーライドの説明
上記のプログラムにおいてHeroクラスですでに定義されているメンバrun()をSuperHeroクラスでも定義している。
これにより、形式上run()を上書きできるのである。

## 継承やオーバーライドの禁止
クラス宣言にfinalをつけると継承を禁止でき、メソッド宣言にfinalをつけるとオーバーライドを禁止できる。
## 親インスタンス部へのアクセス
親インスタンス部分のメソッドやフィールドに子インスタンスからアクセスするには

```
super.フィールド名
super.メソッド名
```

のように書く。
gitコマンド備忘録

# ローカルリポジトリの作成
`git init`

# コミットの作成
ステージングエリアに変更を登録する
`git add`

コミットを作成する
`git commit`

git 管理下のファイルやディレクトリを削除する
`git rm`

# 状態の復元
ワークツリーの変更を取り消す
`git checkout`

ステージングエリアに追加した変更をワークツリーに戻す
`git reset`

# 状態の確認
ローカルリポジトリの状態を確認する
`git status`

各エリアの差分を確認する
`git diff`
ワークツリーとステージングエリアの差分を確認するには`--cached`オプションをつける。

コミットの履歴を確認する
`git log`
【Ruby】`freeze`メソッドって以外とややこしい...??

どうもこんにちは。完全なるメモ書きです。

# `freeze`メソッドが実行されたオブジェクトの特徴

1. 破壊的な操作ができません
2. オブジェクトの代入ができます
3. 自作クラスのインスタンス変数をfreezeしない限り、変更できます

# オブジェクトが変更できる例

```rb
CONST_LIST_A = ['001', '002', '003']
begin
  CONST_LIST_A.map{|id| id << 'hoge'}
rescue
end

CONST_LIST_B = ['001', '002', '003'].freeze
begin
  CONST_LIST_B.map{|id| id << 'hoge'}
rescue
end

p CONST_LIST_A   #=> ["001hoge", "002hoge", "003hoge"]
p CONST_LIST_B   #=> ["001hoge", "002hoge", "003hoge"]
```

`map`メソッドは、配列の中身を取り出し、編集し、再代入するという動作を行っている。つまり、**オブジェクトの代入**を行っているため、`freeze`メソッドでオブジェクトを凍結していたとしても変更を行うことが可能。

# オブジェクトが変更できない例

```rb
hoge = "hoge".freeze
hoge.upcase!

CONST_LIST_C = ['001', '002', '003'].freeze
begin
  CONST_LIST_C.map!{|id| id << 'hoge'}
rescue
end

CONST_LIST_D = ['001', '002', '003'].freeze
begin
  CONST_LIST_D.push('add')
rescue
end

p hoge
p CONST_LIST_C   #=> ["001", "002", "003"]
p CONST_LIST_D   #=> ["001", "002", "003"]
```

`hoge`,`CONST_LIST_C`に対しては、破壊的な変更を行おうとしたため、変更されない。
`CONST_LIST_D`に対しては、値を追加しようとしたができない。
Ubuntu 24.04でweztermを動かす

Ubuntuを24.04に上げたらいろいろ動かなくなったのでそのメモ
`wezterm` が動かなくなった。

dlopenで失敗するようですが、その際に以下のURLを参照するようにメッセージがでます。

https://github.com/AppImage/AppImageKit/wiki/FUSE

`libfuse2t64`というのがいるそうです。

```
sudo apt install libfuse2t64
```
で動きました
AI を開発で利用するTips

## ドキュメントの整備
要件定義などをAIに渡して、色々できるのでインプットのベースになるので精度良くつくりたいところです。

ドキュメントの精度とは
- 構造化されているか
- 一貫性
- 量が多くなく簡潔で洗練された言葉をつかう

## テスト環境の整備
- AIが出力するコードの品質を担保する
- AIにフィードバックして自動修正を回したりにも活用できそうです

## コードの構造化 (リファクタリング)
- AIは入力が大事と思っています
- きれいに構造化されていると、AIの出力も良くなる
- 依存関係の整理 (依存先までAIに渡さなくてよくなる)
- タスクを小さく分解できAIのタスクの負荷を下げることができる

コーディングガイドラインの制定と管理
- 少ないルールで自由度があるが構造をきれいにできるもの

## クライアント
AIを活用する度合いによってクライアントとの関わり方がも変えていく必要
- プロトタイプをすぐ作って共有していったりなど

AIを中心とした開発体制の
- メリット
    - 安く早く作れる
- デメリット
    - コードが不安定になる
    - テスト体制を整えていることを伝えたりしてカバーする

## ツールの活用

### エディタ
- Cursor (20$~)
    - Vscodeのクローン(Fork)に機能追加された形
    - AI x エディタのジャンルでは圧倒的な知名度
        - 使いやすく, 発送の新しい機能が追加されている印象

https://www.cursor.com/

- Zed
    - Rust製
    - プロダクトと開発体制がクールな印象ですが、VScodeから移行するコストがネック

https://zed.dev/

### VSCode Extension

- Github Copilot (10$~)
    - 入力補完
    - Chat
        - チャットができるだけ
            - Cursorと同じようにファイルを入力として渡せる
            - Claude, o1, o1-miniに対応
    - edit
        - 追加で編集ができる

https://github.com/features/copilot

- Cline
    - エージェント型のBot
    - 編集, コマンドの実行などもおこなう
    - Acceptを求められる, Acceptを押して行くだけで開発できるのを目標としていそう
    - エージェント型の課題にもなりますが一つのアクションを行おうとするたびに, 会話が増えていってしまうので作業の文脈をわすれてしまいそうと勝手に思っています
    
https://github.com/cline/cline

- Cointinue
    - CursorをVscode Extensionで使えるようにしているような拡張機能
    - Vscodeの最新機能が享受できる代わりにCursorの機能を完全には使用できなくなる

https://docs.continue.dev/getting-started/overview

### リポジトリ全体のマークダウン化

- code2prompt
    - Rust製
    - シンプルで直感的なCLIツール (正規表現でexclude,includeなど指定できた)

https://github.com/mufeedvh/code2prompt


- Source Sage
    - リッチで高機能だが実行速度は遅い印象
    - コミットメッセージの作成や他の機能も付属しています

https://github.com/Sunwood-ai-labs/SourceSage

### ドキュメント管理,作成

- gearindigo
    - ドキュメントの管理作成を行えるツール
    - ドキュメントの作成はAIでおこなうことができる
    - AIわたすためのドキュメントツールとして作られているので使い勝手が良さそう

https://gearindigo.app/
【JavaScript】forって何？JavaScriptのループを解説

# ループ
JavaScriptでは、繰り返し処理を行うための構文がいくつか用意されています。
**`for`文**はループの代表的な構文で、主に**カウンター付きループ**ができます。

また、ほかにも以下の構文があります。

- `while`: 条件を満たしている間ループ、無限ループ
- `forof`: イテレーター（配列）を使ったループ

ここからは各構文の詳細を解説していきます。

# `for`文
`for`文は主に以下のケースで使われます。

- 今何回目のループなのか知りたいとき
- 数値を一定間隔で増やしたり減らしたりしたいとき

構文はこちらです。
```js
for (初期化式; 条件式; 変化式) {
  // 処理
}
```

それぞれの式には役割があります。

- 初期化式: ループ全体が始まる前に一度だけ実行される
- 条件式: 次のループを始めていいのかチェックする
    - `===`などを使って真偽値にするとわかりやすい
- 変化式: 各ループが始まる前に実行される

### 例
例えば、`1`から`10`を足した数=`55`を出力するコードを書いてみます。
公式を使ってもいいのですが、ここでは順番に足す処理を書きます。

このとき、**`1`から`10`を順番に処理する**ために、**`for`文**が使えます。
それぞれの式や処理では以下のことをするようにします。

- 初期化式: 変数`index`を`1`で初期化
- 条件式: `index`が`10`以下（`index <= 10`）ならループを続ける
- 変化式: `index`をインクリメント（1増やす）

```js
let sum = 0
for (let index = 1; index <= 10; index++) {
  sum += index
}

console.log(sum) // 55
```

このコードは以下の手順で実行されます。

1. 初期化式が実行され、変数`index`が`1`で初期化される
1. ループに入り、`sum`に`index`の値=`1`が足される
1. 条件式がチェックされ、`index`は`10`以下なのでループは中断しない
1. `index`をインクリメントする=`1`を足す
1. `index`が`10`を超えるまで2~4を繰り返す
1. `sum`の値がコンソールに出力される

### 条件式の書き方のコツ
条件式の書き方には、ちょっとしたコツがあります。

`for`文は、**条件式を満たしているうちは**ループが継続されます。
そのため、最後のループでは**条件式を満たす値**が`index`に入っています。

条件式`index <= 10`を最後に満たすのは`index == 10`のときなので、最後に処理が実行されるとき`index`は`10`です。
このとき最初は`1`で最後が`10`なので、`1`から`10`の和が計算されます。


# while
`while`を使うと、**条件を満たしているうちはループする**処理ができます。

:::note
前述の`for`文でも条件式を使えば実装できますが、そのような処理の場合`while`のほうが見た目がすっきりしやすいです。
:::

構文はこちらです。

```js
while (条件式) {
  // 処理
}
```

`while`は以下の用途に使えます。

- 条件を使ったループ
- **無限ループ**

## 無限ループ
無限ループを実装するのは非常に簡単です。
`while`文の条件式に`true`を入れ、あとは適当に処理を書くだけです。

以下のコードは無限ループのサンプルです。

:::note alert
ブラウザで次のコードを実行した場合、最悪**ブラウザを強制終了する**ことになります。
実行は自己責任でお願いします。
:::

```js
while(true) {
  console.log('無限ループ')
}
// 無限に「無限ループ」が出力され続ける
```

なお、無限ループといえば悪なイメージがあるかもしれませんが、使うときはたまにあります。

## 条件を使ったループ
もちろん、条件式にちゃんとした条件を入れることもできます。

ここではフィボナッチ数列を生成するコード実装してみます。
フィボナッチ数列は前の2つの数字を足していく数列です。
この数列は無限に続くので、今回は`1000`以上の数字が出た時点でループを終了します。

以下は簡単に実装したものです。
```js
const result = [1, 3] // 初期値
while (result.at(-1) < 1000) {
  result.push(result.at(-1) + result.at(-2))
}

result // [1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322, 521, 843, 1364]
```

<details><summary><code>at</code>メソッドとは</summary>

配列の`at`メソッドは、インデックスを使って配列の要素を取得するものです。
`result[index]`と大体同じですが、`at`は負の数を入れることで**最後から数えた要素**を取り出せます。

</details>

この`while`ループの中では、`result`の最後から`2`番目と`1`番目の要素を足し、配列に追加しています。
そして配列の最後の要素が`1000`を超えた時点でループは終了します。

---

`while(true)`と`break`を使って実装することもできます。

```js
const result = [1, 3] // 初期値
while (true) {
  if(result.at(-1) > 1000) break
  last.push(result.at(-1) + result.at(-2))
}

result // [1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322, 521, 843, 1364]
```

このコードでは、`result.at(-1)`が`1000`を超えていたら`break`でループを終了しています。
それ以外は上と大体同じです。
Ubuntu 24.04 でojを動かす

Ubuntuを24.04に上げたらいろいろ動かなくなったのでそのメモ

`oj` を動かすと失敗するようになった

```
$ oj --version
Traceback (most recent call last):
  File "/home/kousuke/.local/bin/oj", line 5, in <module>
    from onlinejudge_command.main import main
  File "/home/kousuke/.local/share/pipx/venvs/online-judge-tools/lib/python3.12/site-packages/onlinejudge_command/main.py", line 19, in <module>
    import onlinejudge_command.update_checking as update_checking
  File "/home/kousuke/.local/share/pipx/venvs/online-judge-tools/lib/python3.12/site-packages/onlinejudge_command/update_checking.py", line 1, in <module>
    import distutils.version
ModuleNotFoundError: No module named 'distutils'
```

入れ直したりを試していたのだけど、うまく行かず、調べてみるとpython3.13からdistutilsがなくなってsetuptoolsをいれるとよいとのこと

https://qiita.com/pitao/items/1740a62ddee797aed807

ということでやってみる。
最近はpipxというのがあるらしいですね。pip3 install online-judge-tools するとpipxを奨められたのでこちらでやってみる。

```bash
sudo apt install pipx
pipx install online-judge-tools
$HOME/.local/share/pipx/venvs/online-judge-tools/bin/python -m pip install setuptools
```

最初の`pipx install` で `$HOME/.local/bin/oj` ができる。
これで`oj --version`するとやはり失敗します。
ojの中をみるとvenvの環境をつくっているのがわかるので、その環境にsetuptoolsを入れると動きました。
toio用pythonライブラリtoio.pyとtomotoioの違い

BLEで通信してtoio core cubeを動かしたり、ボタンや傾きなどの状態を得ることができるpythonライブラリとしてSIE公式の[toio.py](https://github.com/toio/toio.py)と[tomotoio](https://qiita.com/kenichih/items/f78356107ba6428d73ec)がありますが、それぞれの特徴、違いについてまとめてみました。

# 由来

**tomotio**
tomotoさん作のpython3用toio core cube制御ライブラリです。
Gitリポジトリ https://github.com/tomoto/tomotoio

**toio.py**
SIE謹製 
Gitリポジトリ https://github.com/toio/toio.py

# BLEスタック

**toiotomo**
[bluepy](https://github.com/IanHarvey/bluepy)
RaspberryPi OSやUbuntuなどのLinuxベースのOSでBlueZが動作している環境でないと動かない。

**toio.py**
[Bleak](https://github.com/hbldh/bleak)
Windows10/11、macOS、LinuxベースのOS(BlueZ)で動作

# toio core cubeのスキャン

**toiotomo**
接続するtoio core cubeのBLEアドレスリストをtoio-cubes.txtに書いておく方式。つなぎたいtoio core cubeのBLEアドレスリストが必要。
スキャンのとき(./scan-cubes.shを動かすときなど) root権限(sudo)が必要 
スキャンしてtoio-cubes.txtができてしまえば以降のpythonスクリプトはroot権限は不要
スキャンして割り当てられるcore cubeの順番はtoio-cubes.txtに書いてある順番

**toio.py**
個数指定、名前指定、BLEアドレス指定(Windows/Linuxのみ)、ペアリング済のみ(Windowsのみ)でスキャンできる。
スキャンして割り当てられるcore cubeの順番は"rssi"、"local_name"でソート可能(local_nameでスキャン対象を個別指定することもできる)
cube_list = await BLEScanner.scan_with_id( ["toio-L1L",  "toio-h3e", "toio-i6k", "toio-m1T"], "local_name")

# pythonスクリプトの書き方

**toiotomo**
(asyncioのasync awaitではない)従来型の書き方　シンプル。

**toio.py**
asyncioで書く必要あり　javascriptやC#に慣れた方なら問題ないと思いますが。

# 対応システムソフトウェアバージョン 

**toiotomo**
v02.0005 / BLE protocol v2.3.0

**toio.py**
v02.0006 / BLE protocol v2.4.0

# 比較表
|   | tomotoio |toio.py |
| ---- | ---- | ---- |
| 由来| tomotoさん原作 |SIE|
| BLEスタック | bluepy | Bleak |
| 動作環境 | Linux | Windows/Linux/macOS |
| スキャンと接続| テキストファイルにBLEアドレス | APIで名前/BLEアドレス指定|
|asyncio| - | asyncioで書く必要あり|
|対応システムソフトウェア|v02.0005|v02.0006|

# 共通の制限
複数目標位置指定での移動は目標地点2か所までしか動かない。本来、toio core cubeは29個まで指定可能ですが、OS側の制限というかBLEの標準的な実装だと一回に送れるデータ長に制限があるため、複数目標位置指定では2か所分しか有効にならないようです。Windows/Linuxどちらも同様に２か所までしか有効ではありませんでした。

# あとがき

Bleakはpython-for-androidにも対応している、とのことですが、Android端末にQpython3とか入れるとtoio.pyも動いちゃったりするのだろうか...
iOSについては、toio.py自体が[pythonista3で動く](https://toio.github.io/toio.py/INSTALL_TO_PYTHONISTA3.ja.html)とのことですが未テスト
君は対応したか、Stripeの3Dセキュア必須化問題（for Laravel）

# はじめに

この記事は [G's ACADEMY Advent Calendar 2024](https://qiita.com/advent-calendar/2024/gsacademy) 3日目の記事です（予定）。
書いている人はLAB7卒、現在G's ACADEMY FUKUOKAにお世話になっている棚という者です。

# 記事の要約

- Stripeの決済処理について、2025年1月15日から3Dセキュア認証が段階的に適用されるよ
- **2025年3月末までに3Dセキュア導入が義務付けられている**ので、**何もしないと止まる**よ（参考: [
ECサイトへの導入が義務化！3Dセキュア2.0(本人認証)とは？](https://shop-pro.jp/yomyom-colorme/99995)）
- 嘘、私のアプリ止まっちゃう……？？？この記事はそんなあなたのための記事です（ただしLaravel Cashier利用前提）。

# 経緯

2024年11月中旬ごろ、Stripeから以下のようなメールが届きました。

![Screenshot 2024-12-01 at 13.46.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3949405/fc05d8d8-7b41-43fc-7b00-ed8fac7e8670.png)

へぇ3Dセキュア導入が必須になるんだなぁ……えっアプリ側の改修が必要になるの？1月15日まで？冬季休暇前までには終わらせないとダメなやつでしょこれ！？と慌てて対策したのが現在です。

# 対策方法

Laravel Cashierを導入している場合は対策は容易です。

以下のようにchargeメソッドで決済を行っている部分があるとします。

```
$charge = $user->charge(
    $price,
    $paymentMethodId, [
        "description" => $description,
        "currency" => $currency,
]);
```

これを次のように書き換えてあげればよろしい訳です。

```
try {
    $charge = $user->charge(
        $price,
        $paymentMethodId, [
            "description" => $description,
            "currency" => $currency,
    ]);
} catch (IncompletePayment $exception) {
    return redirect()->route(
        'cashier.payment',
        [$exception->payment->id, 'redirect' => route('home')]
    );
}
```

これは[公式ドキュメント](https://laravel.com/docs/11.x/billing)のHandling Failed Paymentsの項目を読んでいただくと分かるのですが、要は決済中にIncompletePayment例外（＝不完全な支払いの例外）が発生した場合、Cashierが用意した専用の支払い確認ページに飛ばすという処理の追加を行っています。

この専用支払い確認ページでは別途3Dセキュア認証確認のための追加アクションを実行することができ、こちらが完了すると無事決済が通ります。

# 穏やかなテスト

上記を組み込んだ後、Stripeの方で3Dセキュア認証テストのために用意している番号`4000000000003220`を利用し、一連の決済フローを流してみましょう。Stripe管理画面で決済が完了したか確認できれば、ひとまずの対応は済んだと言えるでしょう。

よかった、これで解決ですね……

# よくないわよ

実はこれだけだとダメです。

実装すればわかるのですが、「Cashierが用意した専用の支払い確認ページ」というのが曲者で、全て英語です。

また決済に成功しようが中断しようがトップページに飛ぶという処理なのでUI的には最悪、お客さんから大量の苦情が寄せられることでしょう。

次回はその辺りの解消方法を書きたいと思います。~~このAdvent Calendarの枠が残っていれば……~~
Docker Composeで`restart: always`になっているコンテナを、override.yamlで自動起動しないようにする

Docker Composeで`restart: always`になっているコンテナを、ローカル開発環境だけ自動起動しないようにします。

## 環境
```
$ docker --version
Docker version 27.3.1, build ce12230
$ docker compose version
Docker Compose version v2.29.7
```

## 結論
こんな感じで、`compose.yaml`と同じプロジェクトルートに`compose.override.yaml`を配置しておけばOK

```bash
$ docker run --rm --volume $(pwd):/app --workdir /app ruby:slim ruby -e "require 'yaml';puts YAML.dump(Hash[{ 'services' => Psych.load_file('compose.yaml', aliases: true)['services'].keys.map{|k| [k, {'restart'=> 'no'}]}.to_h }])" > compose.override.yaml
```

読み込むファイル名`compose.yaml`と出力先`compose.override.yaml`の部分は適当に修正してください。

必要に応じて、`compose.override.yaml`は`.gitignore`に含めておくのが良いと思います。

## 説明
Docker Composeの機能として`compose.override.yaml`という名前のファイルを作成しておくと、このファイルで設定を上書きするというものがあります。
参考: [Merge \| Docker Docs](https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/#additional-information)

```yaml:compose.override.yaml（例）
services:
  web:
    restart: 'no'
  app:
    restart: 'no'
  db:
    restart: 'no'
```

このようなyamlファイルを作成すればOKなわけです。

以下のようなRubyプログラムで、サービス一覧を出して`restart: no`を付与するyamlを出力しています。
Rubyを選択したのは[標準ライブラリでYAMLをパースできるから](https://docs.ruby-lang.org/ja/latest/library/yaml.html)です。

```ruby
require 'yaml'

puts YAML.dump(
  Hash[{ 'services' =>
    Psych.load_file('compose.yaml', aliases: true)['services'].keys.map{|k|
      [k, {'restart'=> 'no'}]
    }.to_h }
  ]
)
```

これをワンライナーにして、`docker run`で実行できるようにしたのが冒頭のコマンドです。

[danny\-avila/LibreChat](https://github.com/danny-avila/LibreChat)や[langgenius/dify](https://github.com/langgenius/dify)のような、本番環境でもDocker Composeを使って起動することが想定されているソフトウェアをローカル環境で動かしたい時に、このような設定ファイルを置いておくと自動起動せずに済みます。

## 参考
https://qiita.com/gota_sushi_/items/bdfd6ff3f8538570cca2
TypeScript のモダンな書き方をまとめた！


---

### **1. インターフェースとオブジェクトの型定義**

#### コード
```typescript
interface FormSchema {
  name: string;
  age: number;
}

const FormSchema_jen: FormSchema = {
  name: "example",
  age: 100,
};
```

#### 説明
- **`interface`**:
  - オブジェクトの構造を定義する。
  - 型安全を確保し、プロパティが定義どおりであることを保証する。
- **`const FormSchema_jen: FormSchema`**:
  - `FormSchema` インターフェースを型として指定。
  - オブジェクトがインターフェースで定義されたプロパティをすべて満たす必要がある。

---

### **2. ジェネリクス関数の活用**

#### コード
```typescript
function fom<T>({ a, b, c, d }: { a: number; b: number; c: number; d: T }) {
  return { r: a, h: b, f: c, g: d };
}

const { r, h, f, g } = fom<FormSchema_zzz>({
  a: 1,
  b: 2,
  c: 3,
  d: FormSchema_zzz,
});
```

#### 説明
- **ジェネリクス `<T>`**:
  - 型を動的に指定できる関数。
  - 呼び出し時に明示的に型を指定（例: `<FormSchema_zzz>`）するか、引数の型から推論される。
- **オブジェクトの分割代入**:
  - 戻り値を分解して、それぞれの値を変数に割り当てるモダンな書き方。

---

### **3. 高階関数とコールバック**

#### コード
```typescript
const hensu = (suuji: number): number => {
  console.log(suuji);
  return 100;
};

function handleClick_2(hensu: (suuji: number) => number) {
  hensu(100);

  return {
    a: 1,
    b: 2,
    c: 3,
  };
}

const { a, b, c } = handleClick_2(hensu);
```

#### 説明
- **アロー関数**:
  - `const hensu = (suuji: number): number => { ... }` は短い関数定義のモダンな書き方。
  - 型 (`number`) を指定して引数と戻り値を明確にする。
- **高階関数**:
  - `handleClick_2` は関数を引数として受け取り、その関数を実行する。
  - コールバック関数（`hensu`）の活用例。
- **オブジェクトの分割代入**:
  - 戻り値のプロパティを直接変数 `a`, `b`, `c` に割り当てる。

---

### **4. オブジェクト全体の展開**

#### コード
```typescript
function fomz<T>({ ...atai }: { a: number; b: number; c: number }) {
  return { rr: atai.a, hh: atai.b, ff: atai.c };
}

const { rr, hh, ff } = fomz({
  a: 1,
  b: 2,
  c: 3,
});
```

#### 説明
- **スプレッド構文 (`...atai`)**:
  - 引数のオブジェクト全体を展開して `atai` にまとめる。
  - 必要に応じて個別のプロパティにアクセス。
- **ジェネリクス `<T>`**:
  - 型を動的に受け取る柔軟な関数定義。
  - 今回は型推論で `T` は `{ a: number; b: number; c: number }` と解釈される。

---

### **5. 関数とアロー関数の違い**

#### コード
```typescript
function 関数作る() {
  console.log("関数作る");
}

const 関数いれる = () => {
  console.log("関数いれる");
};

const 関数実行 = 関数いれる;
```

#### 説明
- **通常の関数 (`function`)**:
  - クラシックな関数定義。
  - Hoisting（巻き上げ）により、関数が定義前に呼び出せる。
- **アロー関数 (`=>`)**:
  - モダンな記法。
  - `this` の取り扱いが異なる（親スコープの `this` を継承）。
  - Hoisting は適用されない。
- **関数を変数に代入**:
  - `const 関数実行 = 関数いれる` のように、関数自体を他の変数に代入可能。

---

### モダンな TypeScript の特徴

1. **型安全性**:
   - 型定義（`interface` や `type`）によるエラー防止。
   - ジェネリクスやリテラル型で柔軟性を高めながらも型チェックを維持。

2. **構造の分割代入**:
   - オブジェクトや配列のプロパティを簡潔に取り出す。

3. **アロー関数**:
   - 短く読みやすい構文。
   - `this` の継承など、従来の `function` とは異なる特性。

4. **スプレッド構文 (`...`)**:
   - オブジェクトや配列のコピー、展開が簡単にできる。

---

### 結論
このコードは、TypeScript のモダンな書き方を多用しており、読みやすく型安全なコードを書くための実践例です。特にジェネリクスや分割代入、アロー関数は TypeScript を使う際の基本的かつ便利なテクニックです。
Milk-v Duoで環境モニタ

## はじめに
　Milk-v DuoはCPUとしてRisc-vを搭載したLinuxボードで、秋葉原ロボット部で積極的に活用しているボードです。秋葉原ロボット部の勉強会の成果は、各種展示会での成果物の展示や書籍の販売として公表されています。
　2024年に開催されたNT京都とつくろがや！の秋葉原ロボットのブースで行った展示内容を紹介します。

https://akbrobot.connpass.com/

https://wiki.nicotech.jp/nico_tech/index.php?NT%E4%BA%AC%E9%83%BD2024

https://tsukurogaya.nagoya/

## Milk-v duo上のpython
 Milk-v duo上のpythonでは、pingpongライブラリを使うことで、GPIOに接続されたセンサを制御可能です。
　シリアルコンソールを使って、Milk-v duo上でpythonプログラムを作成してもいいのですが、Mind＋でpythonプログラムを作成します。

https://mindplus.cc/en.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/a8ccfa67-0fdb-70f5-64b1-5b46850e09d8.png)

　「pinpong」ボタンをクリックすると、使用できるデバイスが表示されます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/5b154f2c-b542-9e3a-0d20-e2851103f1e8.png)

dfrobot用の基板に接続されたデバイスが表示されますが、ピン配置がわかれば、汎用のデバイスでも利用可能です。

https://www.dfrobot.com/

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/066b6008-de65-d529-dfb7-29cfff14c161.png)

　「DHT11/22 Temperature a…」と「OLED Display」を選んで、「戻る」ボタンをクリックします。
　「DHT」と「OLED」のブロックが利用可能となります。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/87a56f6d-1f69-37e8-a9bd-cdc21269fe02.png)

プログラムが完成したら、Milk-v duoにpythonプログラムを転送して、動作確認を行います。
　動作中の写真を以下に示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/a220e927-e77c-b552-2b3d-af4785ef629e.png)

 

## 今回のプログラム例
　今回使用したプログラムを以下に示します。
　DHT22の取得した数値を、OLED一定時間ごとに表示します。
```
# -*- coding: utf-8 -*-

import time
from pinpong.board import Board, Pin
from pinpong.libs.dfrobot_ssd1306 import SSD1306_I2C
from pinpong.libs.dfrobot_dht20 import DHT20

Board("MILKV-DUO").begin()

dht20 = DHT20()
oled=SSD1306_I2C(width=128, height=64, bus_num=0)
led = Pin(Pin.A15, Pin.OUT)

# oled.set_font(font="default", width = 15, height = 15)

for index in range(3):
  oled.show()
  led.value(1)
  print("Temperature: {} 'C".format(dht20.temp_c()))
  print("Humidity: {} %".format(dht20.humidity()))
  oled.text("Temperature: ",0,0,8)
  oled.text("{} 'C ".format(dht20.temp_c()),64,16,8)
  oled.text("Humidity: ",0,32,8)
  oled.text("{} %".format(dht20.humidity()),64,48,8)
  led.value(0)
  time.sleep(10)
  oled.show()
```

## おわりに
　Milk-v duoのGPIOに接続したデバイスの制御をpythonで行いました。さらに、pythonのプログラミングは、Mind+のブロックプログラミングで作成しました。他のLinuxボードのGPIOでも、pinpongライブラリを介してpythonプログラムを用いた制御ができるかと思います。
【Ruby】includeとprependとextend...ややこしや〜

どうもこんにちは。

`include`と`prepend`と`extend`。Ruby初学者であれば誰もがつまづくでしょう。
簡単に解説します。（**出力結果を比較しながら眺めてみてください。**）

# 基本的な動作

`include`と`prepend`は大きく変わりません。この二つは、モジュール内のメソッドを**インスタンスメソッド**として使用するためにインクルードするためのメソッドです。

`extend`は、モジュール内のメソッドを**クラスメソッド**として使用するためにインクルードするためのメソッドです。

## `include`

```rb
module Test_a
    def method_1
        puts 'method_1'
    end
end

class Test_b
    include Test_a
end

Test_b.new.method_1   #=> method_1
```

## `prepend`

```rb
module Test_a
    def method_1
        puts 'method_1'
    end
end

class Test_b
    prepend Test_a
end

Test_b.new.method_1   #=> method_1
```

## `extend`

```rb
module Test_a
    def method_1
        puts 'method_1'
    end
end

class Test_b
    extend Test_a
end

Test_b.method_1   #=> method_1
```

# `include`と`prepend`のややこしい探索順

よくRubyGoldの問題で問われるのが、**継承チェーンの探索順**ですが、`include`と`prepend`の違いはここにあります。

## `include`を使用した例

`include`を使用した場合、`Person`クラスの`greet`メソッドが先に見つかります。

```rb
module Greetings
  def greet
    "Hello from Greetings module!"
  end
end

class Person
  include Greetings

  def greet
    "Hello from Person class!"
  end
end

person = Person.new
puts person.greet    #=> Hello from Person class!
```

## `prepend`を使用した例

`include`を使用した場合、`Greetings`モジュールの`greet`メソッドが先に見つかります。

```rb
module Greetings
  def greet
    "Hello from Greetings module!"
  end
end

class Person
  prepend Greetings

  def greet
    "Hello from Person class!"
  end
end

person = Person.new
puts person.greet    #=> Hello from Greetings module!
```

# `extend self`という記述をしている問題が出てきた...

```rb
module Test_a
    def method_1
        puts 'method_1'
    end
end

module Test_m
    include Test_a
    extend self     # classでは`extend self`でエラーになるので注意！
end

Test_m.method_1       #=> method_1
Test_m.new.method_1   #=> undefined method `new' for Test_m:Module (NoMethodError)
```

`extend self`が実行された場合、`Test_m`モジュール自身に対して自身のインスタンスメソッドをクラスメソッド（モジュールメソッド）として追加しています。
Cloudflareで任意のドメインのディレクティブへリダイレクトする

これは[no plan inc.の Advent Calendar 2024](https://qiita.com/advent-calendar/2024/noplan_inc)の6日目の記事です。

どうも〜！no plan株式会社 代表のおかむーです。
最近何かと話題の、Cloudflare、任意のドメインのディレクティブへリダイレクトする方法を紹介します。


# まず結論
- 任意のドメインのディレクティブへリダイレクトすることは可能
- 無料
- ドメインが別のところの管理でもOK

# 昔はどうしていたか
わざわざAWSアカウントを発行して、S3に空のバケットを作りにそこにリダイレクトポリシーを記して、任意のディレクティブにリダイレクトさせていました。とっても面倒w

# 1: ドメインのネームサーバーをCloudflareに向ける
CloudFlareの管理画面から「Add」「Existing domain」を選択しましょう

![Screenshot 2024-12-01 at 1.51.33 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/988a5f3b-1a0d-8f03-b6c7-1d71c06c79cf.png)

Recommendedの「Quick scan for DNS records」 でいきましょう
Continueを押して次へ

![Screenshot 2024-12-01 at 1.52.31 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/64bd4be4-30bf-da74-c2ff-8750df2ec8fd.png)

DNSを変更する案内がでますので、GoogleDomainsとかお名前.comとかの管理画面から、DNSを変更してあげましょう

![Screenshot 2024-12-01 at 1.29.17 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/784ff33b-521c-9853-540a-6539ba8eb5c0.png)


```
$ dig ns {対象ドメイン}
```

とかのコマンドを打つと変更されたか確認できますね

# 2: プランを選択する

FreeプランでOKです

# 3: Ruleでリダイレクトルールを設定する

「Redirect Rules」を選択しましょう
「Create Rule」を押して

![Screenshot 2024-12-01 at 1.32.03 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/ce44df6f-7e19-48ba-21ed-331209858225.png)

「All incoming requests」や「Wildcard pattern」などをつかっていい感じにリダイレクトの設定をしましょう

![Screenshot 2024-12-01 at 1.33.30 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/d71c6663-b27e-61c0-3dda-1db7de47915d.png)


# 4: 動作確認

```
$ curl -I -L {リダイレクト前のドメイン}
```


# まとめ
- 無料で任意のドメインのディレクティブへリダイレクトすることができました

# no plan株式会社について
no plan株式会社は、ブロックチェーン技術、Webサイト開発、ネイティブアプリ開発、チーム育成、などWebサービス全般の開発から運用や教育、支援などを行っています。よくわからない、ふわふわしたノープラン状態でも大丈夫！ご一緒にプランを立てていきましょう！

[no plan株式会社について](https://noplan-inc.com/)
[no plan株式会社 | web3実績](https://noplan-inc.com/web3)
[no plan株式会社 | ブログ一覧](https://noplan-inc.com/blog)
【Linux入門】Minecraftサーバ構築のすゝめ

# はじめに
中高生当時マイクラキッズだった私は、友人とマルチプレイを楽しむために試行錯誤してサーバを構築し、その過程でLinuxと出会い、Linuxに魅了されていった。この記事は、その様子を交えながらLinux初学者にMinecraftサーバ構築を通しての学習を提案する。

# Linuxと出会うまで
中学生の頃、初めて自分用のPCを購入しMinecraftを手に入れ(当時はまだユーロ決済でレートによって値段が変動した！)、同級生たちとマルチプレイをして遊んでいた。batファイルを書きMinecraftをプレイするのと同じWindows上でサーバを動かしていた。
そのやり方だと割り当てるメモリに限界が来て快適なプレイ環境とは言いがたい。プレイするのとは別端末でサーバを動かしたいという欲求が生じた。しかしWindowsをもう一台調達するには金がかかるし、そもそもクライアント用のWindowsでは同時接続数の問題がある。かと言ってサーバ用のものはもっと高価である。いろいろ調べてみると、この世にはLinuxなるものがあるらしいということを知った。

# 実際の運用
どのディストリビューションするとかそういう話は思想や宗教の対立を生むので割愛する。また、インストール作業もここでは言及しない。
サーバを運用していると、定期的に行うバックアップなどの作業を自動化したいという欲求が生じる。シェルスクリプトを書いてcronに実行してもらうという方法で実現可能だ。当時の私がググって調べた上で自分の環境に合うように変更を加えたものが残っている。
[【Minecraftマルチサーバー】自動バックアップがようやく動くようになったメモ](https://qiita.com/zawanume/items/17bcb08cbdf2aa90dc11)

自分で組んだスクリプトが滞りなく動いていることを確認したとき、達成感を得られたことを記憶している。

# 修行
高校生の頃、コンピュータ系の同好会に所属していた。顧問の先生がLinuxに精通していたので、いろいろなことを教えていただいた。多忙な先生に代わって部員用のLinux環境を整備するということもした。その当時のことも残っている。
[LDAPで快適Linux環境 #1 概要](https://qiita.com/zawanume/items/2620ab239de8481e7323)

この修行によりCUIでの操作がかなり手に馴染んだ。また、ドキュメントを読む、英語のフォーラムを当たる、それでも分からないことは実験して挙動から理解するという能力が鍛えられたのもこのときだと思っている。

# 大学入学後
ゲームサークルに入会し、そこではMinecraftも扱っていたのでより広いコミュニティでマルチプレイをするようになった。当時は運営に積極的に関与するつもりは無かったのだが、いろいろあって途中からサーバの管理を引き受けることになった。そこからさらに紆余曲折あり、他大学からもメンバーを受け入れるようになって現在の形に落ち着いた。
中高生時代に遊んでいたときと大きく異なる点は以下の2点である。
- VPSでの運用
- プラグインサーバの採用

VPSで運用するようにしたのは、サークルとしてやっている以上個人に依存するのは良くないと判断したためである。現在は複数人で管理するようにしている。プラグインサーバを用いることで、荒らし対策やブラウザに地図を表示するなどのマルチプレイに便利な機能を持つプラグインを導入できる。

サークルのサーバを管理しているときのことも残してあった。
[ゲームサークルでのMinecraftマルチプレイ環境](https://qiita.com/zawanume/items/f659e4345aa68073c5fb)
[Minecraftマルチプレイをしていたら善良なポーランド人クラフターが遊びに来た件](https://qiita.com/zawanume/items/0b1a8fd05bc2fc191f8d)

外国人が遊びにきた事例については、その後も複数回発生している。最近ではチェンソーマンファンのロシア人クラフターと接触することに成功した。ポートスキャンや小規模な荒らし行為も見られるようになったため、ポートスキャンを検出すると接続拒否する設定やDiscord認証プラグインなどで対策をしている。そのあたりの話も近日中に記事を書きたい。

# おわりに
私はMinecraftがきっかけでLinuxを知り、Linuxを触れるようになった。Minecraftは教育的効果が高いゲームだと言われている。建築や回路など一般に言われているMinecraftの教育的な面だけでなく、Linuxに興味を持ち実際に使えるようになるということもそこに含まれると私は考えている。マイクラキッズの中からLinuxユーザーがたくさん生まれてくることを願ってやまない。
toio core cubeを鉄板に貼り付けて使うための磁石について(令和６年最新版)

# toio core cubeをホワイトボード上で動かすための磁石がほしい

以前、こういうネタの記事を書きました。

https://qiita.com/kenichih/items/acfad593e666b52b75b2

この時は近所の100均ショップで売ってた円盤型ネオジム磁石が直径約13mm、厚み1.7mmでちょうどtoio core cubeの底面、車輪の間に貼り付けて使うにはちょうどよかったのですが...

あらためてこのサイズのネオジム磁石を手に入れようとしても商品入れ替えの激しい100均ショップでは同じものを手に入れることができませんでした。

何件かの100円均一ショップでいくつか適当にそれっぽい大きさの円盤型ネオジム磁石を買ってはみたのですが、直径が大きすぎたり、厚みがありすぎ(2mmだともうダメです。1.5～1.7mm出ないと車輪よりも高くなってしまい、ホワイトボード(の鉄板)には貼りつきますが、走行することができません)たりして使えるものがありませんでした。

というわけで、現時点で入手可能なものを探してみました。

## 要件
直径13mm～14mm程度
厚み1.5～1.7mm程度

![PXL_20241201_042552153.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/db8e38f3-fc5e-dd71-e2b7-3106f0bb6647.jpeg)


## 入手できたもの

### 千石電商

直径13mm 厚み1.5mm

https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4VPZ

東京秋葉原の実店舗だと本店3Fにありました。

![PXL_20241201_042505096.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/2d38f2b6-e949-a848-6b22-8ef3f4638b83.jpeg)


### amazon

直径13mm 厚み1mm

https://www.amazon.co.jp/dp/B01J4Z4QI8

厚み1mmですが、垂直にしたホワイトボードに貼り付けてtoio core cubeを走行させることができました。

![PXL_20241201_042133978.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/04198434-57b7-a090-10d5-f3c62fb545f8.jpeg)


現状、この２点が入手しやすいかなと。値段的にはamazonのE-Valueのものが安いです。磁力的には厚みがある千石電商の1.5mm厚のほうがよさそうです。

## 垂直のホワイトボード上で動かしてみた動作例

<iframe width="1284" height="731" src="https://www.youtube.com/embed/CBQlojBRkAc" title="toio core cubes with neodymium magnet on white board demo" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
BGP

### BGPはAS間のプロトコル
> 単一のAS内では、ルーティング・プロトコルとしてOSPFとISーISが広く用いられている。`自律システム間では、それとは異なるプロトコルBGP(Border Gateway Protocol:ボーダー・ゲートウェイ・プロトコル）`が使われている。

>`BGPなどの一般的なインタードメイン・プロトコル`は、多くの種類のルーティング・ポリシーがAS間のトラフィックに利用できるようにするために設計された。

### インタードメイン・プロトコル
>インタードメインルーティングプロトコル(IDRP)は,OSIやインターネットでの普及が見込まれている`政策的経路制御`プロトコルである.IDRPでは`ネットワークの運営や管理についてのローカルな方針(ポリシー)を反映した緻密な経路制御を行えるが,反映すべきポリシーが多くなると極端に設定が複雑`になる.

https://cir.nii.ac.jp/crid/1573105977036098560#:~:text=%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB(IDRP)%E3%81%AF%2COSI%E3%82%84%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%A7%E3%81%AE%E6%99%AE%E5%8F%8A%E3%81%8C%E8%A6%8B%E8%BE%BC%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E6%94%BF%E7%AD%96%E7%9A%84%E7%B5%8C%E8%B7%AF%E5%88%B6%E5%BE%A1%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E3%81%A7%E3%81%82%E3%82%8B.IDRP%E3%81%A7%E3%81%AF%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E9%81%8B%E5%96%B6%E3%82%84%E7%AE%A1%E7%90%86%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%AA%E6%96%B9%E9%87%9D(%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC)%E3%82%92%E5%8F%8D%E6%98%A0%E3%81%97%E3%81%9F%E7%B7%BB%E5%AF%86%E3%81%AA%E7%B5%8C%E8%B7%AF%E5%88%B6%E5%BE%A1%E3%82%92%E8%A1%8C%E3%81%88%E3%82%8B%E3%81%8C%2C%E5%8F%8D%E6%98%A0%E3%81%99%E3%81%B9%E3%81%8D%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%81%8C%E5%A4%9A%E3%81%8F%E3%81%AA%E3%82%8B%E3%81%A8%E6%A5%B5%E7%AB%AF%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%8C%E8%A4%87%E9%9B%91%E3%81%AB%E3%81%AA%E3%82%8B

# ルーティング・ポリシーの具体例
## インターネットを使うにはお金を払う　トランジットサービス
>一般的なポリシーを一つは、顧客ISPは、インターネット上で、自身以外のネットワーク上の宛先との間でパケットを届けたり受け取ったりするために、別のプロバイダISPに料金を支払うというものである。このとき、顧客ISPはプロバイダISPからトランジット・サービス(transit service)を契約すると言われる。

### インターネットを使用するためにISP間の接続をする
>こうしたISP間の接続は、多くの場合IXPs(Internet eXchange Points:インターネット相互接続点)のリンクで行われる。IXPsとは、他のISPと接続するために、多くのISPのリンクが集まっている設備である。

## 他ASに対する支払いを軽減する
>AS２とAS3が大量のトラフィックを交換しあっていると仮定しよう。これらのネットワークはすでに繋がっている状態にあるので、希望に応じて、異なるポリシーを用いることができる。例えば、お互いに無償で直接トラフィックのやり取りをすることも可能である。こうすれば、AS1がAS2とAS3に代わって運ばなければならなかったトラフィック量が減り、場合によってはAS1への支払いも軽減される。このポリシーは`決済不要ピアリング(settlement-free peering)または決済不要相互接続(settlement-fee interconnection)と呼ばれる。

## アドバタイズがないと許可されていないから転送されない
>2つのASが互いにルーティングアドバイズを送り合い、それぞれのネットワーク内に存在するアドレスを知らせる。そうすることで、AS2とAS3の間でパケットをやり取りできるようになり、AからB、BからAへと直接パケットを送信できる。ただし、決済不要ピアリングは推移的ではないことに注意すべきである。

#### アドバタイズ
>ITの分野では比喩的に、`ネットワーク上で制御情報などを広く告知する機能や挙動`などのことをこのように呼ぶことが多い。
....
ネットワーク制御などの分野で、`ある機器が別に機器に管理情報などを伝達`することをアドバタイズメントということがある。例えば、`ルータが隣接するルータに経路情報を教えることを「ルートアドバタイズメント」（route advertisement）`という。

https://e-words.jp/w/%E3%82%A2%E3%83%89%E3%83%90%E3%82%BF%E3%82%A4%E3%82%BA%E3%83%A1%E3%83%B3%E3%83%88.html#:~:text=IT%E3%81%AE%E5%88%86%E9%87%8E,route%20advertisement%EF%BC%89%E3%81%A8%E3%81%84%E3%81%86%E3%80%82

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/

# 感想
BGPとはISPそれぞれのルーティング・ポリシーの中で通信するためものだった