OmniAICreator/Qiita-1.07M huggingface dataset:
sed でシバンを一度に置換する方法

サーバーの Python に合わせて、ローカルにあるプログラムのシバンを変えたいが手打ちで書き換えるには数が多いときなどに。

```shell
ls ./tmp/*.py | xargs -I{} sed -i '1 {s@#!/usr/bin/python3@#!/usr/bin/python3.11@}' {}
```

- まとめ
    - sed の区切り字は変更できます。"/" を一つ一つエスケープする必要はありません
    - sed ではスクリプトを適用する行を選択できます。サンプルコードは、1 行目だけを置換することでシバンを変更しています。
migrationについて

# migrationファイルについて
業務でmigrationファイルの作成と実行をする機会があったので備忘録


## migrationファイルの作り方
``` php artisan make:migration XXXXX```
XXXの部分を作成したいテーブル名を混ぜて「create_sample_table」のようにして実行

プロジェクトのdatabase/migrationsの下に作成したファイルができる。

## migrationファイルの実行
migrationファイルの実行は
``` sail art migrate```
で行う(コンテナ使用のため「php」ではなく「sail」)

### migrationファイルの処理の書き方
```public function up():void{} ```
の中に書いた処理が上記の実行コマンド時に動く

```public function down():void{} ```
の中に書いた処理が
```sail art migrate:rollback ```
実行時に動く

downにはupで書いたことの逆を書けばいいので、
・テーブル作成した場合はテーブルを削除する処理を書く
・カラムを追加した場合はカラムを削除する処理を書く
・カラムの名前を変更した場合はカラムの名前を元の名前に変更する処理を書く
というイメージ
Microsoft365に登録してあるデバイスを無効化し、再度、有効化する　～　ActiveDirectoryのEntraIDへの名称変更への注意

# 手順と2023年9月時点の注意事項

アクティビティレポートやメールにより、不正なアクセスと思われるものを見つけた際、デバイスの無効化をすることがあると思います。
デバイスの無効化は、MS365の管理画面にあるデバイス画面にて行えます。

でも、実は無効にしたデバイスが、有効なデバイスであり、元に戻したい場合もあります。
そこで、MS365の管理画面からデバイスを再度有効化しようとしますが、MS365の管理画面では、デバイスの再有効化はできません。

Azure内の「Microsoft Entra ID」内にあるデバイス設定から有効化する必要があります。
AzureへはMS365の管理画面からも遷移できますが、リンクを探すのが大変です。
直接、Azure Portalの画面からログインもできますので、こちらの方がわかりやすい気がします。

https://azure.microsoft.com/ja-jp/get-started/azure-portal


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/765392ad-a13e-84ee-c4f6-fbd050ab58f7.png)

以前は、「Active Directory」だったのですが、サービス統合等で名称が変更になるようです。
デバイスの再有効化の記事が古いと、Active Directoryからデバイスを有効化すると記載がありますが、これは2023年8月以降から誤った情報になります。

この点は注意が必要です。


https://learn.microsoft.com/ja-jp/azure/active-directory/fundamentals/new-name
特定商品と同ー期間中に併買される商品ランキング(SPSS Modeler データ加工逆引き11-13)

# 特定商品と同一期間中に併買される商品ランキング

![スクリーンショット 2023-09-20 9.18.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3942dd79-0267-7aea-a20b-34d25d093130.png)

＊同時併買（同じ日）は逆引き11-14を参照ください。

## 1.想定される利用目的

・顧客への施策立案時の商材選定
・予測モデルの特徴量作成


## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/cross_sell_ranking1.str

## 3.サンプルストリームの説明

![スクリーンショット 2023-09-20 9.26.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e680173f-84bb-fa6c-0e0a-7759b112dc3c.png)

a.入力するデータは以下の通りです。
![スクリーンショット 2023-09-20 9.28.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/98feab47-c25f-32fa-20bf-8d8697eaed16.png)

次のプロセスのためにAをハイライトしたままメニューから[条件抽出ノード（AND）]を選択します。結果としてbが自動生成されます。
![スクリーンショット 2023-09-20 9.49.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/cc3bc57d-0064-d7c4-da56-33ca787b4052.png)

b.　[条件抽出]ノードを編集します。Aの購入レコードのみが抽出されます。
![スクリーンショット 2023-09-20 9.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4a850fbd-47a7-df1f-3605-1b4836d85ff5.png)

c.[条件抽出]ノードを編集します。Aを購入したIDの重複を排除します。
![スクリーンショット 2023-09-20 9.30.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/572bd81b-3adb-b989-7911-c86206805283.png)

d.[レコード結合]ノードを編集します。内部結合させることでAの購入経験あるIDのみに取引が絞りこまれます。
![スクリーンショット 2023-09-20 9.31.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5ac3b47f-192e-79a5-52de-e7c4936151a0.png)

e.bを複製して条件の反転[破棄]をすることで集計表にAが含まれないようにします。
![スクリーンショット 2023-09-20 9.31.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/da395953-f0b1-b752-f207-40b22fa349a9.png)

f.[レコード集計]ノードを編集します。
![スクリーンショット 2023-09-20 9.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/d1116d3a-42de-6c2a-ce87-515b0c27bf3f.png)

g.[ソート]ノードを編集します。
![スクリーンショット 2023-09-20 9.33.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/eff16221-7ae6-819b-680e-65d24cd52b8c.png)

[デーブル]ノードを実行します。
![スクリーンショット 2023-09-20 9.34.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9cb028df-6675-8e12-a6d3-2ea4bef0fa08.png)

#### 注意事項

ランキングのための順位フィールドが必要な場合には関数@&#xFFF0;INDEXで作成します。

https://qiita.com/416nishimaki/items/8cd1fc55261fd36a9013

## 4.参考情報

####  AとBの両方または片方を購入した顧客を抽出する

https://qiita.com/416nishimaki/items/7be9d43d01b6f550ea38

####  Webグラフでカテゴリの上位アイテム間の同時購入を確認

https://qiita.com/416nishimaki/items/1546c5e26a22ee67f9c8

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
setlocal内で設定した変数を外部に渡す

## やりたい事
バッチファイルを触ってて、`setlocal`内でセットされてる値を外に渡したくなった。

## setlocalの役割
バッチファイルでは、`setlocal`と`endlocal`に挟まれた範囲で、環境変数のローカル化が行えます。
これは通常、この範囲外には影響を与えません（外からは見えません）

```bat:localvar.bat
@echo off

setlocal
set var=外から見えない
echo 内側：%var%
endlocal

echo 外側：%var%

goto :EOF
```

```text:実行結果
内側：外から見えない
外側：
```

## 外から値を使う
しかし、外側からその値が欲しい場合があります。

そこで、`&&`（論理積）を使います。

```bat:externalvar.bat
@echo off

setlocal
set var=外から見える
echo 内側：%var%
rem endlocalとsetを&&で繋ぐ
endlocal && set var=%var%

echo 外側：%var%

goto :EOF
```

```text:実行結果
内側：外から見える
外側：外から見える
```

これで`endlocal`の後でも、内側で設定した値を使えるようになりました。

## 別バッチから使う
上記のやり方は`setlocal`の外側で`set`しているため、`externalvar.bat`を実行後、別バッチファイルからもこの値を参照することも可能になります（実行中のプロンプトを閉じない場合）

```bat:other.bat
@echo off

echo 別バッチ：%var%

rem 未クリアだと、localvar.bat再実行時にも見える
set var=

goto :EOF
```

```text:実行結果
別バッチ：外から見える
```

## 参考記事
https://windows.command-ref.com/cmd-setlocal.html

https://www.pg-fl.jp/program/dos/doscmd/str_l_and.htm
【Cisco】ミラーポート設定

# ■ポートミラーリング
WireSharkなどをいれたPCで、NW機器のパケットキャプチャをとりたい時にはミラーポートを使います。
Catalystだと"SPANポート"と呼ばれています。
端的に言うと、「送信元」で指定したポートまたはVLANを通過するパケットをコピーして、「宛先」で指定したポートから送信することでPC端末などでパケットの情報を確認できます。

## ■SPAN設定
### ・キャプチャを転送する宛先ポートにswitchport monitorの設定
```console
SwitchA(config)# interface Ethernet1/33   #WireSharkなどを入れたPCをつなぐポートを指定
SwitchA(config-if)# switchport
SwitchA(config-if)# switchport monitor    #モニター用の設定。SPAN専用ポートとなる。
SwitchA(config-if)# no shutdown
```
SPAN専用ポートではSPANセッションのトラフィック以外送受信はできなくなります。
なお、この宛先ポートに接続するPCにIPアドレスを割り振っていてもなくても問題なくパケットキャプチャができます。

### ・monitor sessionの設定
```console
SwitchA(config)# monitor session 1 source interface port-channel1 both #キャプチャしたいポートを指定。双方向取得したい場合はbothを指定。片側のみであればrx/tx
SwitchA(config)# monitor session 1 destination interface Ethernet1/33  #転送先のポートを指定。
SwitchA(config)# end
```
port-channel1で送受信したパケットをコピーし、Eth1/33へ流します。

### ・確認
```console
SwitchA# show monitor session 1
Session 1
———
Type               : Local Session
Source Ports      :
    Both           : Po1
Destination Ports: Eth1/33
 Encapsulation    : Native
          Ingress    : Disabled
```

### ※注意点
・送信元ポートを宛先ポートにできない
・宛先ポートを送信元ポートにできない
・宛先ポートはレイヤ2プロトコル（STP、VTP、CDP、DTP、PAgP）に参加できない
・宛先ポート（モニタリング用のポート）の状態は「up/down(monitoring)」になる
・送信元ポートにport-channelグループを指定できるが、宛先ポートには指定できない
・送信元はセッションごとにVLANまたは物理ポートのいずれかしか指定できない
・イーサチャネルのメンバーポートをSPANの宛先ポートに指定するとバンドルから外れる

あまり使いませんが、以下のようなSPANもあります。

## ■RSPAN
`RSPAN`
・RSPAN用に作成したVLANを使用する
⇒RSPAN用のVLANではMACアドレスの学習は行わないため、RSPAN用のVLANではすべてのパケットがフラッディングされます。

・キャプチャしたパケットはRSPAN用VLANでリモートスイッチに届ける
⇒RSPAN用のVLANはトランクポートを通って離れたスイッチまでキャプチャしたパケットを転送するためのものなので、アクセスポートに割り当てるとそのポートは無効化されます。

設定例：
SwitchAのFa0/6を通過するパケットを、SwitchBのFa0/13に接続したパケットキャプチャ用のPCでも受信可能にする。
```console
SwitchA(config)# vlan 20
SwitchA(config-vlan)# remote-span
SwitchA(config-vlan)# exit
SwitchA(config)# monitor session 1 source interface FastEthernet 0/6
SwitchA(config)# monitor session 1 destination remote vlan 20
```
```console
SwitchB(config)# vlan 20
SwitchB(config-vlan)# remote-span
SwitchB(config-vlan)# exit
SwitchB(config)# monitor session 1 source remote vlan 20
SwitchB(config)# monitor session 1 destination interface FastEthernet 0/13
```

## ■ERSPAN
`ERSPAN`
・ネットワーク（レイヤ3）を越えることが可能
・キャプチャしたパケットはGREでカプセル化してリモートスイッチに届ける
・一部の機種（Catalyst 6500など）で使用可能な機能

設定例：
SwitchAのFa0/6を通過するパケットをコピーして、レイヤ3を越えた先にあるSwitchBのFa0/12に接続したパケットキャプチャ用のPCでも受信可能にする。

```console
SwitchA(config)# monitor session 1 type erspan-source
SwitchA(config-mon-erspan-src)# source interface Ethernet0/6
SwitchA(config-mon-erspan-src)# destination
SwitchA(config-mon-erspan-src-dst)# erspan-id 101
SwitchA(config-mon-erspan-src-dst)# ip address 10.2.2.2
SwitchA(config-mon-erspan-src-dst)# origin ip address 10.1.1.1
```
```console
SwitchB(config)# monitor session 1 type erspan-destination
SwitchB(config-mon-erspan-dst)# destination interface Ethernet0/12
SwitchB(config-mon-erspan-dst)# source
SwitchB(config-mon-erspan-dst-src)# erspan-id 101
SwitchB(config-mon-erspan-dst-src)# ip address 10.2.2.2
```

ただ、基本的には設定もシンプルなローカルSPANを使うことが多いです。
わかりやすく解説！コールバック関数の理解とその使い方

## コールバック関数とは
　コールバック関数は、一つの関数（親関数）に引数として渡され、親関数の中で特定のタイミングで呼び出される関数です。これを利用することで、非同期処理やイベントハンドリングなど、柔軟かつダイナミックなプログラムの構築が可能になります。

## レストランでの例え

コールバック関数を理解するために、レストランでの食事を例に考えてみましょう。

1. __レストランに入る（プログラムを開始）__
2. __ウェイターに注文する（関数を呼び出す）__
この時、食べ終わったらデザートのメニューを見せてほしいと頼む（コールバック関数を登録） 
3. __食事を楽しむ（他の処理を実行）__
4. __食事が終わる（非同期処理が完了）__
5. __ウェイターがデザートのメニューを持ってくる（コールバック関数が実行される）__

　この例で言うと、デザートのメニューを持ってくる行為が「コールバック関数」に相当します。
食事（メインの処理）が終わった後に、ウェイター（プログラム）はデザートのメニューを持ってきます（コールバック関数を実行）。

　このように、コールバック関数はある処理（食事）が終わった後に実行されるべき処理（デザートのメニューを持ってくる）を表しています。
　プログラムにおいて、これは特定のタイミングや、非同期処理の完了後に特定の処理を行うために利用されます。

## 基本的なコールバック関数の使用例
```javascript
// コールバック関数を定義
function greeting(name) {
  alert('Hello ' + name); // ユーザーの名前で挨拶
}

// コールバック関数を引数として受け取り、ユーザーの入力を処理する関数
function processUserInput(callback) {
  let name = prompt('Please enter your name.'); // ユーザーに名前を入力してもらう
  callback(name); // コールバック関数を呼び出し、ユーザーの名前を渡す
}

// processUserInput関数を呼び出し、greeting関数をコールバック関数として渡す
processUserInput(greeting);
```
　この基本的な例では、greeting関数がprocessUserInput関数にコールバックとして渡され、ユーザーの入力後に呼び出されます。

## 非同期処理でのコールバック関数の利用
```javascript
// データを非同期に取得する関数。コールバック関数を引数として受け取る
function fetchData(callback) {
  // ここではデータ取得の代わりにsetTimeoutを使用して、2秒後にコールバック関数を呼び出しています
  setTimeout(() => {
    const data = "何らかのデータ"; // 取得したデータ
    callback(data); // コールバック関数を呼び出し、データを渡す
  }, 2000);
}

// fetchData関数を呼び出し、コールバック関数としてdisplayData関数を渡す
fetchData(function displayData(data) {
  console.log("Displaying data!", data); // 取得したデータを表示
});
```
　この例では、データの取得が非同期に行われるため、データが取得できた時点で特定の処理（この場合はコンソールに出力）を行いたいため、コールバック関数を使用しています。コールバック関数を利用することで、非同期処理の完了を待ってから、次の処理に進むことができます。

## イベントハンドリングでのコールバック関数の利用
```javascript
buttonElement.addEventListener('click', function() {
  console.log('ボタンがクリックされました！');
});
```
　HTML要素にイベントリスナーを追加する際も、コールバック関数が利用されます。この例では、ボタンがクリックされたときに無名のコールバック関数が呼び出されます。

## なぜこのような書き方をするのか？
　コールバック関数を利用することで、特定の処理の完了時点や、特定のイベントが発生した際など、様々なシチュエーションで特定の処理を動的に実行することができます。これにより、コードの再利用性が向上し、制御の流れが明確になります。

## コールバック関数のメリット
- __コードの再利用性の向上__：同じ関数を異なるコールバック関数と組み合わせることで、様々な挙動の処理を実装できます。
- __制御の柔軟性__：非同期処理の完了時や特定のイベント発生時など、特定のタイミングで必要な処理を実行できます。

## 最後に
　関数の実行タイミングを制御したり、特定のイベントに応じて動的に処理を変更したりする際に、コールバック関数は不可欠です。

　この記事を通じて、コールバック関数の理解が深まった人がいると嬉しいです。
raspberry piでMP3ファイル再生

# 概要
今日はRaspbery PIでMP3ファイルを再生しながら何かを作業したかったので、
調べてみたらVLC以外にも再生するアプリケーションがありましたので、紹介致します。

# 事前設定
下記のコマンド順番にパッケージをインストールしましょう。

~~~bash
sudo apt-get update
sudo apt-get upgrade
~~~~

# Audaciousインストール
下記のコマンドでアプリケーションをインストールしましょう。

~~~bash
sudo apt install audacious
~~~~

# 正常にインストールされた場合
下記のメニューで[Sound & Video]-[Audacious]にアプリケーションアイコンが配置されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/cf8485f0-4628-c0e9-300a-c025c35c7e5a.png)

# 実行画面
Repeat,Random機能もありますので、便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/ef372157-a2e2-f733-e5c8-a7d654b2e2bb.png)

# 実行時のリソース状況
下記のようにCPUの使用率も少ないので、軽い感じです。
RPI4で実行しているので、こんな感じですが、RPI3ではどうですかね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/b841cdec-f29c-05ba-1195-2317624a63fe.png)

# 終わりに
これでRPIからも軽くMP3ファイルの再生ができるようになりましたね。
今日はMP3を再生しながら寝ます。＾＾＆
おやすみなさい。
コンパイルエラーが出てないからって油断はしちゃだめだよ

## 経緯

こんなコードがありました。

```kotlin
val hoge: Hoge?
if (savedInstanceState != null) {
    hoge = savedInstanceState.getParcelable("hoge")
} else {
    hoge = arguments?.getParcelable("hoge")
} 

if (hoge == null) {
    throw IllegalArgumentException()
}
```

私は、良かれと思ってこういうコードに書き換えてコミットしました。

```kotlin
val hoge: Hoge = if (savedInstanceState != null) {
    savedInstanceState.getParcelable("hoge")
} else {
    arguments?.getParcelable("hoge")
} ?: throw IllegalArgumentException()
```

冗長な処理を短く書いただけ　という認識でしっかりチェックをしませんでした。

さて、問題はあるでしょうか？
答えはYESです。このコードは実行時にクラッシュします。

```:環境
kotlin 1.7.2
```

## 対策

正確には`arguments?.getParcelable("hoge")`の部分で`java.lang.ClassCastException`の例外でクラッシュします。
`Hoge cannot be cast to java.lang.Void`と続きます。

しかしこのコードはAndroid Studio上ではエラーを吐きません。
過去にも事例があるようです。

https://youtrack.jetbrains.com/issue/KT-39953

例えば以下の様に個別に型キャストをするとクラッシュしなくなります。

```kotlin
val hoge = if (savedInstanceState != null) {
    savedInstanceState.getParcelable("hoge") as Hoge?
} else {
    arguments?.getParcelable("hoge") as Hoge?
} ?: throw IllegalArgumentException()
```

ここで、コンパイルでエラーが出なかったせいだ！というのは簡単ですが、
しかしこのクラッシュを見過ごした原因は明らかにヒューマンエラーです。


### 教訓１

Kotlinは大変優秀な言語で、大体のバグはコンパイルの過程で未然に防いでくれます。
裏を返せば、コンパイルが通ったから重大なバグは発生しない、という油断にも繋がりかねません。

変更を加えた箇所は必ずテストをすること、またはテストコードがあると尚良かったですね。

### 教訓２

実は上述のコードはgetParcelableの部分でdeprecatedのハイライトをされます。
deprecatedになっている処理を放っておくのはそもそもよくありません。今回のようなバグの原因調査のノイズにもなります。

その後PRレビューでご指摘いただきまして、例えばこのように定義されたインライン関数を用いて、

```kotlin:util.kt
inline fun <reified T : Parcelable> Bundle.parcelable(key: String): T? = when {
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getParcelable(key, T::class.java)
    else -> @Suppress("DEPRECATION") getParcelable(key)
}
```

getParcelableを置き換える形に最終的に落ち着きました。

```kotlin
val hoge: Hoge = if (savedInstanceState != null) {
    savedInstanceState.parcelable("hoge")
} else {
    arguments?.parcelable("hoge")
} ?: throw IllegalArgumentException()
```

## 結論

:::note 
**変更した箇所は動作確認(相当のチェック)をする**
:::

あまりにも雑ですが、これに尽きるかもしれない。


## 余談

ちなみにこの変更は色々なチェックを華麗にスルーし、リリース30分後に気づきました(急いでhotfixを出しました)。肝が冷える。
今ではみんな気が引き締まっていますが、本当に油断は大敵ですね。人間は信用なりません。
deliver_later をテストの時だけ即時実行したい


時は、`perform_enqueued_jobs` と書く。

```ruby
  it do
    perform_enqueued_jobs do
      subject
    end

    expect(ActionMailer::Base.deliveries.size).to(eq(1))
  end
```

とりあえず動いてるか？のテストしたい時はこれで良さそう。

ちゃんとどのメソッドが呼ばれてるか？みたいなテストにしたいなら、呼ばれてるMailerをスタブしないとダメそう。

一周回って、結合テスト的に呼び出し〜どんな内容のメールが送信されているか？でテストするなら、このように書くことでメールの内容が検証できる。


```ruby
  mail = ActionMailer::Base.deliveries.last

  expect(mail.subject).to eq('Expected Subject')
  expect(mail.to).to eq(['example@example.com'])
  expect(mail.from).to eq(['from@example.com'])
  expect(mail.body.encoded).to match('Expected Body Content')
```


サービスの開始時なんかはこういうテストだけを書いておくほうが変更時に楽かもしれないなー。

という何番煎じかわからん小ネタでした。
【React】アクセスしている URL の情報を取得できるuseRouteMatchフック

本記事では、React Routerのフックの1つである、**useRouteMatch**についてまとめています。


:::note
useRouteMatchフックを利用するとアクセスしているURLの情報を取得することができます。取得した値を利用して Route コンポーネントの設定に利用することも可能。
:::

### useRouteMatch が返すオブジェクト
useRouteMatchが返すオブジェクトには、マッチングに関する情報が含まれる。
React Routerが提供する **match** オブジェクトを返す。matchオブジェクトは以下の情報を持つ。

|オブジェクト||
|:-|:-|
|path|ルートパス。マッチングに使用されるパターンの文字列。|
|url|実際のURLの一部。リンクの作成やリダイレクトなどに役立つ。|
|isExact|URL がルートパスと一致するか、マッチングが厳密に行われたかどうかを示すブール値。|
|params|ルートのパス内で定義されたパラメーターのキーと値のオブジェクト。|

例：
```javascript
// URLが "/user/123" の場合
let match = useRouteMatch("/user/:id");

// match オブジェクト:
{
  path: "/user/:id",
  url: "/user/123",
  isExact: true,
  params: { id: "123" }
}
```

### パスなしで使用した場合
引数なしで`useRouteMatch()`を呼び出すと、現在のルートのマッチング情報を取得できる。これは、Routeコンポーネントのrenderプロップや子コンポーネント内で現在のマッチング情報を取得したい場合などに役立つ。

例：

```javascript
const MyComponent = () => {
  const match = useRouteMatch();
  // 現在のルートのURLを取得
  return (
    <div>
        <Link to={`${match.url}/components`}>Components</Link>
    </div>
   )
}
```

---

参考リンク
https://reffect.co.jp/react/react-router/
https://qiita.com/h-yoshikawa44/items/aa78b6c7cd1ef43549bf#useroutematch
http://fumiononaka.com/Business/html5/FN2005004.html
WatchConnectivityが有効にならない

# 内容
コードは合っているはずなのに、シミュレーターで動かすと`WatchConnectivity session on paired device is not reachable`など表示されてしまう場合の、一つの解決策の可能性になります。
# 解決法
シミュレーターは、iPhoneとApple Watchでペアになっている機種が定まっています。
### ペアになっている機種の確認方法
シミュレーター一覧の下にある `Manage Run Destinations...`をクリック
![スクリーンショット 2023-09-27 0.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823873/f213c307-0be9-233b-74b0-8ee3e904b335.png)

そうしたら、iPhone側で使っている機種を探します。
そこに書かれているApple Watchが、対応するものになります。
![スクリーンショット 2023-09-27 0.26.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823873/7cbf416b-0681-7a4d-00f3-2aa495f5398d.png)

# 補足
シミュレーターでビルドする際、`WCSession counterpart app not installed`と表示されることがあるのですが、その際はWatch App側をもう一度ビルドし直すとうまくいくかもしれません。
散布図からのエラーバー図の作成方法 


以下の記事の改良版です. 
https://qiita.com/hajkk/items/1580157feecdf7aa562d
https://qiita.com/hajkk/items/da76559c11283b140df4


# もともとの図と完成図

<img width="300", src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228921/567526bb-3524-b606-e0eb-4208c3e12399.png"> <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228921/84a0f488-78a2-6111-3ba6-22e61bcbf708.png">


左がもとの散布図, 右が完成図です. 



# データの出典

e-statから取得してきており, 2016年度における日本の市区町村ごとの事業所数(経済センサス-基礎調査結果, 単位:個)と従業者数(経済センサス-基礎調査結果, 単位:人)が記録されています. 先ほどの図において, 横軸に事業所数, 縦軸に従業者数を図示しています. 

# 作り方
データはあらかじめ次の形で与えられているとします. 

|       x |       y |
|    :--: |   :--:  |
|  118718 | 1477012 |
|   36655 | 532655  |
|   14312 | 174152  |
|   14224 | 172162  |
|   13145 | 159039  |

作成コードは次. おまけとして, 右図で横軸と縦軸の中央値の両対数fittingのプロセスも書いています. 傾きは1.080(28), $R^2$は0.972でした. 以上です. 

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm

def plot_scatter(df: pd.DataFrame):
  fig, ax = plt.subplots(figsize=(4, 4))
  ax.set_xscale('log')
  ax.set_yscale('log')
  ax.set_xlim([10**0, 10**6])
  ax.set_ylim([10**0, 10**7])
  ax.scatter(df['x'], df['y'], fc='none', ec='b', s=12)
  fig.savefig('left.png')

def plot_errorbar(df: pd.DataFrame):
  xbw = 0.1
  df['xbin'] = 10**(np.round(np.log10(df['x']) / xbw) * xbw)
  summary = df.groupby('xbin').quantile([0.25, 0.50, 0.75])\
              .reset_index().pivot(index='xbin', columns='level_1', values='y')
  fig, ax = plt.subplots(figsize=(4, 4))
  ax.set_xscale('log')
  ax.set_yscale('log')
  ax.set_xlim([10**0, 10**6])
  ax.set_ylim([10**0, 10**7])
  ax.errorbar(summary.index, summary[0.50], yerr=[summary[0.50]-summary[0.25], summary[0.75]-summary[0.50]],\
              fmt='o', c='b', mfc='none', lw=1, capsize=4, label='Errorbar: 25, 50, 75%')
  ax.legend(loc=2, fontsize=12)
  fig.savefig('right.png')

 def fit():
    fitdata = np.log(summary.reset_index())
    fitdata[~np.isfinite(fitdata)] = np.nan
    fitdata.dropna(inplace=True)
    X = sm.add_constant(fitdata['xbin'])
    y = fitdata[0.50]
    res = sm.OLS(y, X).fit()
    print(res.summary())

  fit()
  

if __name__ == '__main__':
  df = pd.read_csv('data.csv')
  df.columns = ['x', 'y']
  plot_scatter(df)
  plot_errorbar(df)
```
【React】文字数を正確にカウントする

`ev.currentTarget.value.length`のように文字数をカウントすると絵文字や「𩸽」などの文字を正確にカウントできません。

以下のように記述するとtextareaに入力された文字数を正確にカウントできます。

```tsx

export default function TextArea() {
  return (
    <textarea
      onChange={(ev) => {
        const segmenterJa = new Intl.Segmenter('ja-JP', { granularity: 'grapheme' })
        const segments = segmenterJa.segment(ev.currentTarget.value)
        console.log(Array.from(segments).length)
      }}
    />
  )
}


```

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter
OAuth2.0でPKCEを使う際に，検証コードからチャレンジコードを生成する(Python)

# これは何？
OAuth2.0では，PKCE（Proof Key for Code Exchange by OAuth Public Clients）を使って認可コード横取り攻撃を防止できます。このときクライアント（例：スマホ）と認可サーバでは，それぞれで検証コード（code_verifier）からチャレンジコード(code_challenge)を算出します（詳しい話は参考リンクをご参照ください）。この算出方法をPythonで試してみました。

# 確認したこと
[RFC7636](https://datatracker.ietf.org/doc/html/rfc7636#appendix-B)にサンプル記載があるように，
code_verifier:dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
から
code_challenge:E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
を算出できることを確認します。
ロジックは[RFC7636 4.2. Client Creates the Code Challenge ](https://tex2e.github.io/rfc-translater/html/rfc7636.html#4-2--Client-Creates-the-Code-Challenge)に示されています。検証コードをSHA-256でハッシュした値を，base64urlでエンコードします。
```
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
```
この方式をs256と呼びます。

# テスト用のコードと実行結果

```Python:pkce.py
import base64, hashlib
code = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
print('code_verifier:{}'.format(code))
sha256hash = hashlib.sha256(code.encode()).digest()
print('sha256 hash:{}'.format(sha256hash))
challenge = base64.urlsafe_b64encode(sha256hash).rstrip(b'=').decode()
print('base64url encode:{}'.format(challenge))
```

実行結果はこちら
```
$ python3 pkce.py
code_verifier:dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
sha256 hash:b'\x13\xd3\x1e\x96\x1a\x1a\xd8\xec/\x16\xb1\x0cL\x98.\x08v\xa8x\xadm\xf1DVn\xe1\x89J\xcbp\xf9\xc3'
base64url encode:E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
```
[RFC7636 Appendix B](https://datatracker.ietf.org/doc/html/rfc7636#appendix-B)の結果と一致しました。

# 参考リンク
[RFC7636](https://datatracker.ietf.org/doc/html/rfc7636#appendix-B)
https://www.authlete.com/ja/developers/pkce/
https://dev.classmethod.jp/articles/oauth-2-0-pkce-by-auth0/
https://developers.line.biz/ja/docs/line-login/integrate-pkce/#how-to-integrate-pkce
jbuilderことはじめ

# Railsのjbuilderを詳しく解説

Ruby on RailsでAPIを開発するとき、効率的なJSONレスポンスの生成が欠かせません。その際の強力なヘルパーとして、`jbuilder`を導入することが多いでしょう。この記事では、jbuilderの基本から応用テクニックまでを詳細に解説します。

## 1. jbuilderとは？

`jbuilder`はRuby on RailsでのJSONテンプレートを生成するためのgemです。簡単なDSLを使い、ビューのようにJSON構造を記述することができます。

## 2. インストールと初期設定

### インストール

Gemfileに以下を追加して、`bundle install`を実行します。
```text
gem 'jbuilder', '~> 2.0'
```
arduino
Copy code

### 設定

通常、特別な設定は必要ありませんが、`config/application.rb`において、jbuilderのジェネレータをカスタマイズすることもできます。

```ruby
config.generators do |g|
  g.jbuilder false # jbuilder用のファイルを生成しない場合
end
```
3. 基本的な使い方
3.1 Controllerの設定
PostsControllerで投稿情報をJSONとして返す場合の例を考えます。

```ruby
class PostsController < ApplicationController
  def index
    @posts = Post.all
    render json: @posts
  end
end
```
3.2 jbuilderのテンプレート
app/views/posts/index.json.jbuilderというファイルを作成します。

```ruby
json.array! @posts do |post|
  json.id post.id
  json.title post.title
  json.content post.content
  json.created_at post.created_at.strftime('%Y-%m-%d %H:%M:%S')
end
```
このコードでは、投稿をJSON配列としてレンダリングし、日付を特定のフォーマットで表示します。

4. 高度な使い方
4.1 パーシャルを使う
パーシャルを使うと、jbuilderのテンプレートを再利用できます。_post.json.jbuilderという名前のパーシャルを作成し、投稿のJSON形式を定義します。

```ruby
# app/views/posts/_post.json.jbuilder

json.id post.id
json.title post.title
json.author post.author.full_name
```
このパーシャルをindex.json.jbuilderで利用するときは、以下のように書きます。

```ruby
json.array! @posts do |post|
  json.partial! 'posts/post', post: post
end
```
4.2 カスタムヘルパーメソッドの利用
jbuilder内でヘルパーメソッドを利用することができます。例えば、現在のユーザーに基づいて内容を変更したい場合などに役立ちます。

```ruby
json.array! @posts do |post|
  json.id post.id
  json.title post.title
  json.can_edit current_user&.can_edit?(post)
end
```
# デメリット
1. パフォーマンスの懸念:
jbuilderを使って複雑なJSONを組み立てる場合、特に大量のデータを扱う場合、パフォーマンスのボトルネックになることがある。シンプルなto_jsonメソッドや高速なシリアライザライブラリ（例：Oj）に比べると、jbuilderは遅いと感じることがある。

2. オブジェクトの中身の非表示:
jbuilderを使うと、特定の属性を簡単に非表示にすることができますが、これが過度に行われると、どの属性がレスポンスに含まれているのかが一見して分かりづらくなる場合がある。

3. 冗長性:
同じ構造のJSONを異なるエンドポイントで使用する場合、似たようなjbuilderのテンプレートが複数箇所で作成される可能性がある。このような冗長性は、将来のメンテナンスや変更を困難にする可能性がある。

4. フロントエンドとの結合度:
jbuilderを使うと、バックエンド（Rails）がフロントエンドが必要とするJSONの構造を詳細に知る必要があります。これにより、フロントエンドとバックエンドの間の結合度が高くなる可能性があります。
CERN ROOT install (for windows)

## CERN ROOTについて
欧州原子核研究機構(CERN)によってデータ解析ソフトROOTが開発、提供されています.
CERNというのはヒッグス粒子を生成したLHCという加速器を所有する機関ですね.
原子核実験、素粒子実験の人間はよくお世話になると思います.最近は宇宙系の人もデータ解析で使うようですね.
データ解析とは無縁と言った人でも、ROOTはC++のコードを対話的に実行できるのでちょっとしたC++のプログラムのテストや計算機がわりとしても便利です.

これは私の愚痴ですが、単純に使っている人が少なくて情報があまりないのと検索しても管理者権限の方のrootばっかりヒットしちゃうのが難点です

## ROOTのインストール方法

ROOTの説明はここまでにしておいて、ROOTのインストール方法について書いておきたいと思います.
インストールに関しては、
https://root.cern/install/dependencies/
を読んでもらえばよいです.ここには各OSごとの依存関係が列挙されていて、ここに書いてあるものをインストールしたのちに
https://root.cern/install/all_releases/
から使用しているPCに対応した最新のインストーラをもってきて実行すればよいです.

## ROOTのインストール方法 (windows)
windowsの場合について詳しく書いておきます.

### 依存プログラムのインストール
windows の場合は、
・CMake
・Visual Studio の Desktop Development With C++ workload
・python (>2.7)

が必要です.CMakeは
https://cmake.org/download/
のBinary Distribution のWindows x64 Installer:という欄の右にあるファイルをダウンロード、実行すればよいです.

Visual Studioは公式サイト(https://visualstudio.microsoft.com/ja/ )からインストールし、開いて適当にポチポチしたら、次のものを選択してインストールします.PATHが分からないという人は(自分もですが)インストール時の設定でPATHを通すことを選択できるので必ずやっておきましょう.
pythonの開発環境みたいなのは、選択してもしなくてもよいです.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729740/4bef8c13-8ddd-5703-2a9a-b26e79cfcd9a.png)


pythonも公式(https://www.python.org/downloads/ )からインストールすればそれでよいです.
python 2.7以降ならOKみたいなので、よほど昔から使っているパソコンでもなければ既にpythonが入っているのならアップデートしなくても問題はないでしょう.


### ROOT本体のインストール

さてROOT本体のインストールです.
https://root.cern/install/all_releases/
から最新のリリースに行って、
Windows Visual Studio 2022 64-bit x64 とか書いてあるものを選びましょう.exeファイルのほうです.
この記事を書いてから時間が経っていると、2022のところは2025とかだったりするかもしれません.

インストール時にPATHを通すところにチェックを入れるのを忘れないようにしましょうね.

### インストールの確認
コマンドプロンプトに行って、$ root とすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729740/f2c314be-cd48-9ca5-05d3-ac59b044a117.png)
rootが起動すれば成功です.


## 参考文献
各依存プログラムのインストールについてちょっと雑に書いているので、一応詳しくインストールを解説してくれた記事を貼っておきます.

・CMake
https://www.kkaneko.jp/tools/win/cmake.html
・Visual Studio
https://4engineer.net/tips/vs2022-install/
・python
https://www.python.jp/install/windows/install.html
ハッカソンに初めて参加しました【技育CAMP マンスリーハッカソンvol.10】

# はじめに
こんにちは。hitomiです。
今回はマンスリーハッカソンvol.10に参加したので、その経緯や感想、ハッカソンの雰囲気などをお伝えできればなと思います。

# 技育CAMP マンスリーハッカソンとは？
サポーターズさんが主催する初心者の方向けのハッカソンで、月に1、2度ほどオンラインで開催されます。実際ハッカソン初参加の方が多く、かくいう私もその一人です。初めての方への配慮やサポートも充実しているため、参加していてとても安心感がありました。

# 自己紹介
所属：立命館大学の学部2年生です。
プログラミング歴：競技プログラミングをしていました。開発に関しては今年の夏ごろから本格的に始めたので、まだまだ初心者です。

# なぜ参加したのか？
* 成果物が欲しい
ハンズオン教材で物を作ったりはしていたのですが、オリジナルな成果物が欲しいなと思いました。その際、期限や成果発表が設けられているほうが途中でなあなあになったりすることなく、高いモチベを維持してやり遂げられると考えました。
* チーム開発がしてみたい
チームでの開発の経験もほとんどなかったので、してみたいと思いました。チームを組んだあゆくん[(@aya172957)](https://x.com/aya172957?s=20)とは今まではあまり交流がなかったのですが、このハッカソンを通して仲良くなることができました！

# 何を作ったのか？

knowFillという作品を作りました。穴埋め問題を自動で作成できるアプリで、画像をアップロードすると、その画像内のテキストを読み取り、穴埋め問題にして返してくれるというものです。詳しくは発表スライドを見ていただければと思います。
<br>
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vRKkR0NEKw2ln_Tv4VfQ-Imx-SmD8k3EFWWDfx0lc63AQkYW5mqkjGme0BjtXVcJLS888xIJpiQIoBR/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【2023マンスリーハッカソンvol.10発表中❗️】<br>/／<br>📣実況中継〜〜🍠🍁<br>\＼<br>チーム名：【torits】<br>作品名：【knowFill】<a href="https://twitter.com/hashtag/%E6%8A%80%E8%82%B2CAMP?src=hash&amp;ref_src=twsrc%5Etfw">#技育CAMP</a> <a href="https://twitter.com/hashtag/%E3%83%8F%E3%83%83%E3%82%AB%E3%82%BD%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#ハッカソン</a> <a href="https://t.co/4g6AJ7ERBR">pic.twitter.com/4g6AJ7ERBR</a></p>&mdash; 【公式】技育プロジェクト (@geek_pjt) <a href="https://twitter.com/geek_pjt/status/1713464660534632629?ref_src=twsrc%5Etfw">October 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 開発を通しての感想
バックエンドを勉強している2人でチームを組んだので、フロントエンドの開発が大変でした。機械学習を必要とするアプリなので、その部分を友人が担当する必要があり、私がフロントエンドを担当することになりました。今後バックエンドの勉強をしていくにあたっても、フロントエンドの基本的な理解は大切だと感じているので、大変良い勉強になりました。最大の難所であるUIに関しては最大限頑張ったのですが、やはりフロントエンドを本業とする方のいる他のチームのUIは比較にならないほどすごくて、とても悔しかったです。

初めて共同開発をしたのですが、主にコミュニケーションについて大変良い経験になりました。意見や提案をする際の伝え方や、それらについての議論の方法について深く考えるきっかけになりました。相手の意見を尊重しつつ、自分の意見や提案を齟齬が生じないようにしっかりまとめて、どのようなメリットデメリットがあるのか明確にすることが重要だと思いました。このあたりは一人で開発や勉強をしているだけでは身につかないので、今回のハッカソンにおいて一番の収穫でした。また、あゆくんのAPIドキュメントの書き方やnotionでのタスクの切り方がとても参考になり、こういうのはバックエンドの人が複数人いないと経験できないことだなと感じました。

# ハッカソンを通しての感想
技術的に自信のない方が嫌な思いをしないような配慮が徹底されていて、感動しました。実際、授業でしかプログラミングをやったことがない友達が、即席チームでとても楽しそうに参加していました。参加者においても、発表に対するコメントがとても暖かくて、心地よかったです。今回は懇親会に参加することができなかったので、次回は参加したいです；；
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574379/67a24285-57f1-aeb3-7bd8-8cdc403918f7.png)

# 最後に
いかがだったでしょうか。ハッカソン初参加を迷っている方は、ぜひマンスリーハッカソンでその一歩を踏み出してみてください！！
terraform/.tool-versions などを git で無視する

# 【terraform/.tool-versions などを git で無視する】

## .git/info/exclude に追記する

`.gitignore` に書く必要がなく、自分の環境だけで特定のファイルを無視することができる

```
$ vim .git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

terraform/.tool-versions # 追加

```

`git status` をすると無視してくれていたので完了
DeepStream について調査中

DeepStream SDK はNVIDIAのGPU環境で、 は AI ベースのマルチセンサー処理やビデオ、音声、画像の理解のためのストリーミング分析ツールキットです。

以下の内容は、DeepStream の実例を調査することで、DeepStream についての理解を得ようとする、初心者のメモです。

## NVIDIAの公式のgithub にあるdeepstream のサンプル
https://github.com/NVIDIA-AI-IOT/deepstream_python_apps

## qiita
[360度カメラでDeepStreamSDKのnvdewarperの最新版を試してみる](
https://qiita.com/akira-sasaki/items/c37c671a364136574346)

データの表示

```
gst-launch-1.0 v4l2src device="/dev/video0" ! \
'image/jpeg, width=1472, height=736, framerate=30/1' ! \
nvv4l2decoder mjpeg=1 ! \
nvvideoconvert ! \
nvegltransform ! \
nveglglessink sync=0
```

nvdewarperで歪み補正

```
gst-launch-1.0 v4l2src device="/dev/video0" ! 'image/jpeg, width=1472, height=736, framerate=30/1' ! nvv4l2decoder mjpeg=1 ! nvvideoconvert ! nvdewarper config-file=dewarp_config.txt  ! m.sink_0 nvstreammux name=m width=600 height=480 batch-size=2 num-surfaces-per-frame=2 ! nvmultistreamtiler width=600 height=480 ! nvegltransform ! nveglglessink sync=0
```


[Jetson NanoにDeepStream SDK Python Bindingを入れて物体検出をしてみる](https://qiita.com/FXsimone/items/49cc69df5deaeef8e6b7)

[Jetson TX2でDeepStream SDKを動かしてみた](https://qiita.com/tsota/items/8aefccfb149a3c8b40b7)

[Jetson Nano(4GB), Xavier NX Developer Kitを使って4カメラでDeepStreamで遊ぶ](https://qiita.com/akira-sasaki/items/e3942569dd45dbe0e743)

python スクリプトでの実行例

```
python3 deepstream_test_3.py /dev/video2 /dev/video3 /dev/video0 /dev/video1 
```

# gst-launch 関連記事 
[gst-launchとの長き戦い](https://qiita.com/yamamo-to/items/89a28959cb786e9c80fc)

[gstreamer備忘録](https://qiita.com/maueki/items/b54cbe5207bb16869756)

[DeepStream SDKでリアルタイム動画認識からのLINE通知](https://qiita.com/dcm_sakai/items/3bb253e4f4a4360010db)
optparseの使い方

# optparseとは
optparseとはコマンドラインのオプションを取り扱うためのライブラリであり、Rubyプログラムでコマンドラインユーザーインターフェースを簡単に実装するために使用されます。

# optparseの使い方
- 下記のように記述することでoptparseライブラリをインポートすることができます。
``` Ruby
require 'optparse'
```

- デフォルトのオプションや変数を設定します。
``` Ruby
options = {}
```

- OptionParserを使用してコマンドラインオプションと引数を定義します。
  - opts.bannerは、OptionParser オブジェクト内でコマンドラインヘルプメッセージを定義するための属性です。ここで定義したメッセージはユーザーがヘルプオプションを使用してヘルプ情報を表示したときに表示されます。
  - opts.on は、コマンドラインオプションを定義するためのメソッドです。このメソッドは、オプションのショートフォーム（-f）およびロングフォーム（--fruit）を指定し、そのオプションが受け取る値の説明を定義できます。ブロック内のコードは、オプションが指定されたときに実行されます。
``` Ruby
OptionParser.new do |opts|
  opts.banner = "Usage: fruit_info.rb [options]"

  opts.on("-f", "--fruit FRUIT", "Specify a fruit") do |fruit|
    options[:fruit] = fruit
  end

  opts.on("-t", "--taste TASTE", "Specify the taste of the fruit") do |taste|
    options[:taste] = taste
  end
end.parse!
```

- オプションで実際に行う処理の中身を記述します。
``` Ruby
if options[:fruit]
  puts "Fruit: #{options[:fruit]}"
  # ここで、指定されたフルーツに関する情報を取得できるロジックを追加
else
  puts "Please specify a fruit using -f or --fruit option."
end

if options[:taste]
  puts "Taste: #{options[:taste]}"
end
```

上記のように記述することで、コマンドラインで実行する際に引数を指定して、コードを実行することが可能となります。
今回の例だとコマンドライン引数として -f または --fruit オプションを使用してフルーツ名を指定し、-t または --taste オプションを使用してそのフルーツの味を指定できます。

- コマンドラインでのコードの実行することができます。
``` bash
ruby fruit_info.rb -f Apple -t Sweet
```
このコマンドは、"Apple" というフルーツの情報を表示し、その味を "Sweet" と設定します。


# まとめ
「optparseの使い方」で説明したように、optparseを使用することで、コマンドライン引数に対応したRubyプログラムの実行が可能となります。


# 参考文献
- [library optparse (Ruby 3.2 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/library/optparse.html)
Google devtool 縦の線について

dev toolの「パフォーマンス」タブ。
フロントで行っている計測の状況を細かく記載してくれていて便利感がバリバリです。


## 計測時のここのライン（赤色、緑色、青色）はなんなのか？


![Yahoo__JAPAN_と_DevTools_-_www_yahoo_co_jp__と__アマングアス___スーパーヤマトワールド_-_Discord.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/7439491b-d212-59b1-9930-7735f3d4e9a4.png)
Yahoo japanで計測!

調べてみると、左から順に以下のようです。

緑色・・・最初にpaintを始めたタイミング（画面上に表示が始まったタイミング）
青色・・・DOMContentLoadedが終わったタイミング（DOMツリーの読み込み完了タイミング）
赤色・・・Loadが終わったタイミング（画像やCSSなど、外部ファイルを読み込み完了タイミング）

緑色の線の箇所はスクリーンショットを確認するとわかりやすいです。
たとえばYahoo japanサイトのように画像やCSSがバリバリ多そうなサイトだと、
「青色から赤色までが長くなる」、ということなのでしょう。

## 試しにテストサイトでも試してみました。

画像　と
テスト　という文字だけのサイト。

![スクリーンショット 2023-10-16 23.15.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/f03e2b31-4abb-6d35-791b-98571ea63e8c.png)

### 画像がない時
ほぼ青と赤の幅がありません。そらそうです、外部ファイル呼んでないので。
![DevTools_-_127_0_0_1_5500_index_html_と_index_html_—_test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/f16d028a-383e-e912-074d-82e2b75ab997.png)



### 画像がある時
ぎゃー！めちゃめちゃ青から赤が広い！
10MBの画像ですので。そりゃ重い。
![DevTools_-_127_0_0_1_5500_index_html_と_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/146ec29d-bc64-ca52-bc62-7c824097fa16.png)


## 参考
https://groups.google.com/g/google-chrome-developer-tools/c/3wS7qVQ6YY8
https://amzn.asia/d/cpcXCKN
【1分で分かる】Github Pagesを使おう！

## Github Pagesとは
Githubが提供してくれる無料のWebサイト公開サービスです！

*特徴*
- 無料
- サーバー契約不要
- 静的サイトのみ
- URLは https://"username".github.io/"repository"でほぼ固定
- 商用利用などは負荷

とりあえず無料で超簡単に簡易公開できることだけ理解して詳しいことは
[公式を参照](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages)しましょう。

作ったリポジトリのsettingからpagesを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525019/097806f8-913c-631f-51fe-dbc757cccce1.png)

任意のブランチを選択してsave
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525019/a8d98365-ef97-540a-2a61-e46ecac882b9.png)

これだけで先程のURLにアクセスすれば大丈夫！
超簡単ですね！！


参考までに私めのサンプルページを公開しておきます。
https://ktsm-yt.github.io/resume/
Railsの`attribute`メソッドの活用方法

# はじめに
Ruby on Railsの`attribute`メソッドは、モデル内で仮想的な属性（カラムを持たない属性）を定義するのに役立ちます。この記事では、`attribute`の基本的な使用方法やそのメリットについて解説します。

##  `attribute`とは？

`attribute`メソッドは、Active Recordモデルに仮想的な属性を追加するためのメソッドです。これを使用することで、データベースのカラムとは独立した属性をモデルに追加することができます。

```ruby
class User < ApplicationRecord
  attribute :nickname, :string
end
```
上記の例では、Userモデルにnicknameという仮想的な属性を追加しています。

2. なぜattributeを使うのか？
柔軟性: データベースに変更を加えずにモデルに新しい属性を追加できます。
変換: カスタムの型変換を指定できます。
一時的な属性: フォームオブジェクトやサービスオブジェクトに仮想的な属性を追加する場面で有用です。
3. 実用的な例
例として、ユーザーが生年月日から年齢を計算する機能を考えます。

```ruby
class User < ApplicationRecord
  attribute :birthdate, :date

  def age
    return unless birthdate

    today = Date.today
    age = today.year - birthdate.year
    age -= 1 if today < birthdate + age.years
    age
  end
end
```
この例では、birthdateという仮想属性を使用して、ユーザーの年齢を計算するメソッドageを提供しています。

その他の使用例

仮想属性の追加:

データベースのカラムとは関係なく、モデルに属性を追加したい場合があります。このような属性を仮想属性といいます。以下は、Book モデルに rating という仮想属性を追加する例です。

```ruby
class Book < ApplicationRecord
  attribute :rating, :integer
end
```
属性の型変換:

属性の型をカスタムして、特定の振る舞いを持たせることができます。例えば、Boolean型を持つ属性をカスタムして、文字列 "true" または "false" としてDBに保存する場合の例を以下に示します。

```ruby
class User < ApplicationRecord
  attribute :admin, :string, default: "false", cast: :boolean
end
```
ここでは :cast オプションを使用して、Booleanの値を文字列として保存するようにカスタマイズしています。

デフォルト値の設定:

attribute メソッドを使用すると、属性のデフォルト値も設定できます。以下の例では、新しい User オブジェクトが作成されたときに、role 属性のデフォルト値として "guest" が設定されます。

```ruby
class User < ApplicationRecord
  attribute :role, :string, default: "guest"
end
```
カスタム型の定義:

RailsのAttributes APIを使用すると、カスタムの型も定義することができます。例えば、JSON形式の文字列をハッシュとして読み書きするカスタム型を定義する場合の例を以下に示します。

```ruby
class JsonType < ActiveRecord::Type::String
  def deserialize(json_string)
    JSON.parse(json_string || "{}")
  end

  def serialize(hash)
    hash.to_json
  end
end

class UserProfile < ApplicationRecord
  attribute :preferences, JsonType.new
end
```


##  `attribute`とインスタンス変数の使い分け

Ruby on Railsのモデル内でデータを保持するための方法として、`attribute`とインスタンス変数がよく用いられます。それぞれの特性と適切な使用場面を理解することで、コードの可読性や保守性を向上させることができます。

### インスタンス変数

- **定義**: クラス内のメソッドで使用される変数。`@`を接頭辞として持ちます。
- **特性**: メソッド間でのデータの共有や、オブジェクトの内部状態の保持に利用されます。
- **使用場面**: コントローラ内でビューにデータを渡す際や、クラスの内部でのみ使用する一時的なデータの保持に適しています。

```ruby
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end
end
```
### attributeメソッド
- **定義**: Active Recordモデルの仮想的な属性を定義するメソッド。
- **特性**: データベースのカラムとは独立した属性をモデルに追加できる。型変換やデフォルト値の指定が可能。
- **使用場面**: データベースに保存されないが、モデル内での状態管理やビジネスロジックに必要な属性を定義する場合に適しています。
```ruby
class User < ApplicationRecord
  attribute :birthdate, :date
end
```
UbuntuでDNSを建てるとき

## 目的
ubuntuでDNSを建てる時、ubuntu自体がDNSportを使ってしまっている。この時の対象法を備忘録として残しておく

## 手順
/etc/systemd/resolved.confに以下を追加する

```/etc/systemd/resolved.conf
[Resolve]
DNSStubListener=no
```

systemd-resolvedを再起動
```bash
$ sudo systemctl restart systemd-resolved
```

OK
【TypeScript / JavaScript】this = "これ" ← どれ？ 【備忘録】

# この記事で分かること
- TypeScript（JavaScript）における関数の宣言方法
- 各宣言方法におけるthisの扱い

# 初めに
初めまして。新人エンジニアをしているものです。
先日TypeScriptにおける関数宣言について学習する一環で、`this`の取り扱いについて学んだので備忘録として書き上げます。

# （前提）TypeScriptの関数の宣言方法
まずは複数ある関数の宣言方法を簡単にまとめます。

### ①function構文による宣言
```ts
function sum (a : number, b : number) : number {
    return a + b ;
}
```
- JavaScriptでよくみられる記法
- TypeScriptでは引数と戻り値に型注釈を付けられる
    - 変数の型注釈を書かない → any型判定
    - 戻り値の型注釈を書かない → 型推論
- 巻き上げ（宣言した行の前の行で呼び出すこと）が可能

### ②function式による宣言
```ts
const sum = function funcName (a : number, b : number) : number {
    return a + b ;
}
```
- 関数宣言は文であるのに対し、**関数式は式**
    → 変数に直接代入可能
- 関数名は省略可
- function式で宣言された関数名は関数内でのみ利用可能
- 巻き上げ不可

### ③アロー関数による宣言
```ts
const sum = (a : number, b : number) : number => {
    return a + b ;
}

// 省略形の例
const plusOne = n => n + 1;

```
- ほかの二つと比べて比較的新しく実装された機能
- 関数式同様、**アロー関数は式**
- 短く書くことができる
- 引数が一つ、処理が一行（return）だけのときは省略形で書くことができる
- ※引数の丸かっこも省略可だが、その場合は引数・戻り値の型注釈が書けなくなるので、可読性の観点からも書いたほうがベター。
```ts
// 引数の丸かっこを省略した場合、型注釈を使うことはできない
const plusOne = n :number :number => n + 1;  // ← このような記法はエラーになる
```

# thisのふるまいの違い

#### アロー関数以外におけるthis
-> **実行時に`this`のふるまいが決まる**
関数における`this`の基本的な参照先はベースオブジェクト（メソッドを呼ぶ際に.の前に置かれているオブジェクトのこと）を指します。
下の例では、`this.name`を出力する関数funcを二通りの方法で呼び出しています。


```ts
function func () {
    console.log(this.name)
}

const obj = {
    name : "Baki",
    func : func,
}

// 1.単純に関数として呼び出す
func();  // "undefined"

// 2.obj のメソッドとして呼び出す
obj.func();   // "Baki"
```
1の方法で呼び出す場合には、ベースオブジェクトが存在していない場合、`undefined`が出力されます。
対して、2の方法で呼び出す場合には`obj`がベースオブジェクトとなるため、`obj`に含まれる`name`プロパティの値が出力されます。

※お使いの環境がstrict modeを利用している（コードに`"use strict"`と明記されている）場合、"undefined"ではない結果が出力されているかもしれません。これはthisがundefinedの場合はグローバルオブジェクトをベースオブジェクトとするというJavaScriptの仕様によるものです。

このように、呼び出し方でふるまいが変わるのがアロー関数以外における`this`です。


#### アロー関数におけるthis
->**宣言時に決まる静的な値**
アロー関数はにおけるthisはレキシカルなスコープを持っています。端的に言えば静的な値のことで、宣言時の値を格納し、ベースオブジェクトには左右されません。
下の例では上と同様、`this.name`を出力する関数funcを二通りの方法で呼び出しています。


```ts
const func = () => {
    console.log(this.name)
};

const obj = {
    name:"Yujiro",
    func:func
};

// 1.単純に関数として呼び出す
func();    // "{}"

// 2.objのメソッドとして呼び出す
obj.func();    //{}
```
実際に適当な環境で実行していただければわかるかと思いますが、いずれの呼び出し方法でも空のオブジェクト`{}`が出力されていることがわかるかと思います。
上述の通り、アロー関数は宣言時のthisを参照するため、1行目で使っているthis(未定義なので空のオブジェクト)が出力されています。

# まとめ
今回は関数の宣言方法とそれらの差、アロー関数とそれ以外の宣言方法におけるthisの違いについてまとめました。
一見、thisが動的に変化するfunction構文・式による宣言方法は便利に思えますが、strict modeを使用していないと予想外の値を参照してしまい、想定とは異なる挙動につながりかねません。
同じような用途でも細かい仕様が異なる機能はほかにもあるので、逐次調べつつ、日々精進したいと思います。
ありがとうございました。

# 参考サイト
- https://jsprimer.net/basic/function-this/#substitute-this
dockerを一般ユーザーで実行できる様にする

## 目的
本番環境でやたらrootで操作するのは良くない。
dockerを一般ユーザーから操作出来る様になろう

## 手順
docker グループの確認

dockerをインストールすれば出来ているはず
```bash
$ cat /etc/group | grep docker
docker:x:112:
```

dockerグループにユーザーを追加する
```bash
$ sudo usermod -aG docker ユーザー名
```

確認
```bash
$ groups ユーザー名
```

ログインしなおす
```bash
$ exit
```

dockerを実行してみる
```bash
$ docker

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
```
【C++】じゃんけんゲーム2

# 【C++】じゃんけんゲームpart2

以前じゃんけんゲームを作ったのですが、それをもとにさらに改良してみたので、新しい記事にしました。

https://qiita.com/ayamo/items/05d910730a3e784dd2df

以前の記事に沢山のコメントありがとうございます！とても為になり勉強になります:blush:
なかなかレベルが低い私なので、技量が追い付かず、今回も自分の作ったコードを元に改良する形となってしまったの申し訳ございません。
これからコメントを参考に勉強していきたいと思います！

### 違う数値や文字を入れると、再度入力できるように改良。
前回は、breakでプログラムから抜けてしまっていたので、再入力できるように出来たらな～と思い作り直しました。
ランダムのところを、数値ではなく文字にするのにどうしたらいいか、解決するのに苦労しました。。。

```c++
#include <cstdlib>
#include <ctime>
#include <iostream>

using namespace std;           // stdという記述を省略可能とする

enum {
    ROCK = '1',
    SCISSORS = '2',
    PAPER = '3'
};                           // マジックナンバー避ける為数字に名前付ける。

enum { YES = '1', NO = '2' };

class Aite {                  // 相手のクラス
   public:
    char aitenote(char aihand);  
};

char Aite::aitenote(char aihand) {
    cout << "相手が出した手は・・・";
    if (aihand == ROCK)
        cout << "グー" << endl;
    else if (aihand == SCISSORS)
        cout << "チョキ" << endl;
    else if (aihand == PAPER)
        cout << "パー" << endl;
    return aihand;                    // 呼び出し元へ返す。
}

int main() {
    char tugi;
    do {                        // 1だったら、再度じゃんけん開始
        srand((unsigned)time(NULL));           // 現在の時刻で初期化
        char myhand;

        do {
            cout << "あなたは何を出す？ 1:グー、 2:チョキ、 3:パー >> ";
            cin >> myhand;
            cout << "あなたが出した手は・・・";

            if (myhand == ROCK) {                  // 1だったらグーと表示
                cout << "グー" << endl;
            } else if (myhand == SCISSORS) {        // 2だったらチョキと表示
                cout << "チョキ" << endl;
            } else if (myhand == PAPER) {             // 3だったパーと表示
                cout << "パー" << endl;
            } else {
                cout << "出してる手が範囲外です。1～3を入力して下さい。"
                     << endl;
            }
        } while (myhand != ROCK && myhand != SCISSORS && myhand != PAPER);

        char aihand;
        Aite note;
        aihand = note.aitenote(rand() % 3 + 1 + '0');   // 1～3(数値ではなく文字を)ランダムに出す

        if (myhand == aihand)                            // あいこの条件
            cout << "あいこ" << endl;
        else if (myhand == ROCK && aihand == SCISSORS ||    // 自分の勝ちの条件
                 myhand == SCISSORS && aihand == PAPER ||
                 myhand == PAPER && aihand == ROCK)
            cout << "あなたの勝ち" << endl;
        else                                              // 他の条件は自分は負け
            cout << "あなたの負け" << endl;

        do {
            cout << "まだじゃんけんしますか？1:yes, 2:no >> ";
            cin >> tugi;
            if (tugi == NO) {                     // もし、2だったらじゃんけん終了
                cout << "終わります";
            } else if (tugi != YES && tugi != NO) {       // 1・2じゃなかったら
                cout << "1か2を入力して下さい。" << endl;
            }

        } while (
            tugi != NO && tugi != YES);  // 1・2じゃなかったら、まだじゃんけんしますか？に戻る。

    } while (tugi == YES);  // 1だったら再度じゃんけん開始
}
```
macOSでPythonからMeCabを使おうとすると /usr/local/etc/mecabrc が見つからないと出るとき

記事の内容はこちらを参照してください。
https://mishimay.github.io/892d4ce149bc05b43494/
<!--



## 前提

Homebrewで`mecab`と`mecab-ipadic`を、pipで`mecab-python3`をインストールしている。

```
% brew install mecab
% brew install mecab-ipadic
% pip install mecab-python3
```
Pythonのプログラムで`MeCab`を使用している。

```py:xxx.py
import MeCab
tagger = MeCab.Tagger()
...
```

## エラー内容

Pythonプログラムを実行すると以下のような例外が投げられる。

```
----------------------------------------------------------

Failed initializing MeCab. Please see the README for possible solutions:

    https://github.com/SamuraiT/mecab-python3#common-issues

If you are still having trouble, please file an issue here, and include the
ERROR DETAILS below:

    https://github.com/SamuraiT/mecab-python3/issues

issueを英語で書く必要はありません。

------------------- ERROR DETAILS ------------------------
arguments: 
default dictionary path: None
[ifs] no such file or directory: /usr/local/etc/mecabrc
----------------------------------------------------------
```

## 原因

MeCabの辞書へのパスがHomebrewでインストールされた場所を指していない。

## 解決方法

環境変数に `MECABRC=/opt/homebrew/etc/mecabrc` を設定する。

```
% MECABRC=/opt/homebrew/etc/mecabrc python xxx.py
```

## 環境
macOS Sonoma Version 14.0

`% brew list --versions`
mecab 0.996
mecab-ipadic 2.7.0-20070801

`% python --version`
Python 3.11.4





-->
pythonのmain関数をモジュールとしてインポートして戻り値を使う方法

# はじめに

python の main 関数を使うのは、下記のようなご利益があるが、、

- 再利用性: モジュールとして他のスクリプトやモジュールからインポートしたとき、main関数の中にコードを隔離することで、そのコードが自動的に実行されるの防げる。この構造により、モジュールの関数やクラスを再利用しながら、主要な実行部分をスキップできる。
- 整理と構造: main関数を使うことで、グローバルスコープをクリーンに保ち、コードの構造を整理することができます。これにより、コードの読みやすさと保守性が向上する。
- 引数の処理: argparseなどのライブラリを使って、コマンドラインからの引数を処理する際に、それらの引数をmain関数に直接渡すことができます。
- エラーハンドリング: main関数内で発生するエラーや例外を、関数の外部でキャッチして処理することが容易
- テストの容易性: main関数を使うと、プログラムの主要な部分を独立してテストすることが容易。

実際にコーディングしていると、main関数で使っている変数の中身を ipython や jupyter などで直接アクセスして debug したくなる時がある。その時の方法について紹介します。

--- 
2023.10.17 追記
Googleが開発した[`Fireライブラリ`](https://github.com/google/python-fire)の利用の選択について、@asobinin_kinsan(kinsan asobinin) 様からのご指摘を頂戴しました。[`Fireライブラリ`](https://github.com/google/python-fire)を用いた方が、シンプルかつ利便性の良いコードになります。使い方については他の良い記事がありますので、そちらを参考にしてください。

https://qiita.com/SaitoTsutomu/items/a5eb827737c9d59af2af

この記事は、argparse が使い慣れている人向け、と解釈ください。

## 簡単な例

``` python:mymodule.py 
import numpy as np

fname = "test.txt"
pixel = 1
type = 0

def main(fname, pixel, type):
    
    if type > 0:
        x = np.arange(pixel)
    else:
        x = -1 * np.arange(pixel)

    return x
    
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Process data')
    parser.add_argument('--fname', type=str, required=True, help='file name')
    parser.add_argument('--pixel', type=int, required=True, help='pixel value')
    parser.add_argument('--type',  type=int, required=True, help='type value')
    args = parser.parse_args()
    main(args.fname, args.pixel, args.itype)
```

このようなプログラムを書いているときに、main 関数の中身の x をみたい時がある。
そういう場合は、モジュールとして main 関数を読んで、return される変数を取得すればよいです。

``` python:
In [1]: from mymodule import main

In [2]: main("a.txt",10,-4)
Out[2]: array([ 0, -1, -2, -3, -4, -5, -6, -7, -8, -9])

In [3]: main("a.txt",10,1)
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

```

このように、return x の x が戻ってくるので、これで中身を確認できます。

## デバッグ時の使い方

return 文はそこで関数が終了、という意味なので、main文が長くて、いろんな変数を使っている場合で、なんか変な変数があり、その中身を見たければ、その変数の近くに return 文を挿入し、他は何も変更せずに実行すると、中身が見ることができて便利です。
Windows PowerShell での Connect 操作例

# はじめに
* Windows PowerShell です
* Connect 操作する必要があり、その備忘です

# 手順

## IAM 操作権限

* このポリシーを AWS CLI 実行する IAM ユーザ/グループにアタッチ
    * 以下のドキュメント参考にポリシー作成
        * https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/security_iam_id-based-policy-examples.html#connect-access-control-resources-example1
    * その他参照ドキュメント
        * https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/user-management.html
        * https://docs.aws.amazon.com/cli/latest/reference/connect/#cli-aws-connect
    * ユーザの更新は試していません

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ds:DescribeDirectories",
                "connect:ListInstances",
                "connect:ListRoutingProfiles",
                "connect:ListSecurityProfiles",
                "connect:ListUsers",
                "connect:CreateUser",
                "connect:DescribeUser",
                "connect:UpdateUser*",
                "connect:DeleteUser"
            ],
            "Resource": "*"
        }
    ]
}
```

## プロファイル設定と確認

```
${profile} = {プロファイルを指定}

aws sts get-caller-identity `
    --query "Account" `
    --output text `
    --profile ${profile} `
```

## インスタンスの一覧取得と設定

```
aws connect list-instances `
    --profile ${profile}

${instance-id} = {任意のIdを指定}
```

## セキュリティプロファイルの一覧取得と設定

```
aws connect list-security-profiles `
    --profile ${profile} `
    --instance-id ${instance-id}

${security-profile-id} = {任意のIdを指定}
```

## ルーティングプロファイルの一覧取得と設定

```
aws connect list-routing-profiles `
    --profile ${profile} `
    --instance-id ${instance-id}

${routing-profile-id} = {任意のIdを指定}
```

## Amazon Connect ユーザ作成

```
${username} = "Mary"
${password} = "Pass@Word1"
${identity-info} = "FirstName=Mary,LastName=Major"
${phone-config} = "PhoneType=SOFT_PHONE,AutoAccept=false,AfterContactWorkTimeLimit=0"

aws connect create-user `
    --profile ${profile} `
    --username ${username} `
    --password ${password} `
    --identity-info ${identity-info} `
    --phone-config ${phone-config} `
    --security-profile-id ${security-profile-id} `
    --routing-profile-id ${routing-profile-id} `
    --instance-id ${instance-id}
```

## Amazon Connect ユーザの一覧取得と設定

```
aws connect list-users `
    --profile ${profile} `
    --instance-id ${instance-id}

${user-id} = {任意のIdを指定}
```

## Amazon Connect ユーザの削除

```
aws connect delete-user `
    --profile ${profile} `
    --instance-id ${instance-id} `
    --user-id ${user-id}
```