OmniAICreator/Qiita-1.07M huggingface dataset:
How to access an ECS container for debugging?

この記事は、[エアークローゼットアドベントカレンダー2024の日18目](https://qiita.com/advent-calendar/2024/air-closet)の記事です。

https://qiita.com/advent-calendar/2024/air-closet

今日は、ECSコンテナへのアクセス方法を紹介したいので、ぜひ参考にしてください！
# この記事のまとめ
・ECSとは？
・ECS Exec
・事前条件
・Execコマンド

# ECSとは？
Amazon Elastic Container Service (ECS) は、Dockerコンテナを管理・実行するための高度なコンテナオーケストレーションサービスです。ECSを使用すると、アプリケーションを複数のDockerコンテナに分割し、それらを効率的かつスケーラブルに実行できます。また、タスクスケジューリングや自動スケーリングなどの機能も備えています。
# ECS Exec
ECS ExecはAWS Systems Manager（SSM）を活用しています。
具体的にはSSMセッションマネージャーを利用して、「exec」コマンドを開始するデバイスとターゲットコンテナの間に安全なチャネルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957202/3384c17c-f856-5049-a41a-aa1e14430238.png)

この機能はClientでもServerでもSSMの機能が必要なため、事前に設定する必要があります。これにより次のセクションに行きましょう。
# 事前条件
#### 1. Client-Side
AWS CLIを使用してexecコマンドを開始する場合、インストールする必要があるパッケージはAWS CLI用のSSMセッションマネージャプラグインだけです。使用しているプラットフォーム（Linux、Mac、Windows）に応じて、指示に従って適切なバイナリを設定する必要があります。

https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

#### 2. Server-side(AWS Fargate)
Fargateソフトウェアスタックは、「プラットフォームバージョン」と呼ばれるものを介して管理されているため、最新バージョンである 1.4（ECS Execの前提条件が含まれているバージョン）を使用していることを確認するだけです。

サービスをデプロイする際には、「exec」の実行コマンドを有効にすることが必要です。
```bash
aws ecs update-service --service <SERVICE_NAME> --cluster <CLUSTER_NAME> \
  --enable-execute-command \
  --force-new-deployment

```

AnsibleまたはEcspressoを使用している場合は、この構成があることを確認してください。
```json
 "enableExecuteCommand": true
```

#### 3. IAM
次のアクセス権限をタスクIAMロールに追加し、タスクIAMロールをタスク定義に含める必要があります。
```json
{
   "Version": "2012-10-17",
   "Statement": [
       {
       "Effect": "Allow",
       "Action": [
            "ssmmessages:CreateControlChannel",
            "ssmmessages:CreateDataChannel",
            "ssmmessages:OpenControlChannel",
            "ssmmessages:OpenDataChannel"
       ],
      "Resource": "*"
      }
   ]
}
```
ECSタスクロールレベル(role level)でIAM権限を設定する必要です（ECSタスク実行ロールレベルではなく）。これは、SSMと同じコンテナ内で実行されるためです。他のAWSサービスに対してそれらのアクションを実行するためには、コンテナ自体にIAM権限を付与するべきです。

# Execコマンド
もし上記のすべての手順を完了したなら、ECS Fargateに接続する準備ができていると思います。以下のコマンドを参考してください。
```bash
aws ecs execute-command --cluster <CLUSTER_NAME> --task <TASK_ID> --container <CONTAINER_NAME> --interactive --command "sh"
```
アクセスできました。:thumbsup: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957202/1ba22b71-c1b2-a583-e043-dc59bc37f4cb.png)

#
最後までご覧いただきありがとうございました！

[エアークローゼット Advent Calendar 2024](https://qiita.com/advent-calendar/2024/air-closet)はまだまだ続きますので、ぜひ他のエンジニア, デザイナー, PMの記事もご覧いただければと思います
【VBA】日付処理サンプル

# はじめに
日付処理のサンプルを作ってみたので、Qiitaの記事として公開します。

## 処理の中身
先月の年月を年は西暦4桁、月は2桁で表示します。

## サンプルソースコード
サンプルソースコードは以下の通りです。

```
'日付処理サンプル
'新規作成 2024/12/20

Sub Get_date()
    '現在の日付変数
    Dim currentDate As Date
    '西暦変数
    Dim year1 As Integer
    '月変数
    Dim month1 As Integer
    '文字列型月変数
    Dim str_month1 As String
    Dim result_str As String
    
    '現在の時刻を取得
    currentDate = Date
    '年と月を取得
    year1 = year(currentDate)
    month1 = month(currentDate) - 1
    
    '前月が0ならば西暦を１引いて、月を１２にする
    If month1 = 0 Then
        year1 = year1 - 1
        month1 = 12
    End If
    '月を文字列にする
    str_month1 = CStr(month1)
    
    '月が１文字の時、0をつけて２文字にする
    If Len(str_month1) = 1 Then
        str_month1 = "0" & str_month1
        
    End If
    
    '西暦4桁、月2桁を結合する
    result_str = CStr(year1) & str_month1
    'ポップアップする
    MsgBox result_str
    
   
End Sub

```

# 最後に
しょーもないVBAコードですね
初心者向け！とりあえず見た目がかっこいいCUI環境を作る

初めてターミナルに触れたときって、なんか怖いですよね。
画面ポチポチでやってたGUIではなく、全てをコマンドで指示するCUI、、、
まずは見た目をかっこよくして形から入りませんか？
見た目がかっこよくなればきっともう怖くない！はず？

![スクリーンショット 2024-12-19 10.19.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/d00b5ef6-1855-bcbb-8699-48dd6350e39c.png)

一応、Macだけではなく、Windowsの人でも同じ様な雰囲気に持っていけるように書いていく(つもりです)ので、参考にしてみてください！

## ターミナル画面を半透明化
これだけでなんかかっこいい、ウィンドウを半透明化にする方法です。

### Mac
Mac環境のひとはiTerm2をインストールしてください。
Macで標準装備されている`ターミナル`アプリでは透過設定ができません。
以下のリンクから最新版をDLしてきましょう。

https://iterm2.com/downloads.html

インストールができたらアプリを起動して上部メニューから「Settings」へ

![スクリーンショット 2024-12-20 11.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/ccaeec12-7626-fb40-9a74-0c0fc57d956f.png)

まずは外タブ「Profile」から、内タブ「Window」に入り、画像を参考に`Transparency`と`Blur`を設定していきましょう。
`Transparency`が透過度合い、`Blur`がぼかし具合の設定になります。
透過度が高すぎると背景と文字が混ざって見にくくなるので、適度に設定を調整しましょう。
`Blur`を入れてぼかすのもおすすめです。

![スクリーンショット 2024-12-20 11.52.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/51dddc41-c5e1-fc33-dcdc-caf25e4fe8c6.png)

### Windows
Windows環境の人は`PowerShell`をインストールしてください。
WindowsでCLIを使う人はWSL環境を構築していると思うので、インストール済みの人も多いと思います。

https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4

インストールできたらタブ横の「∨」からメニューを表示して「設定」へ

![スクリーンショット 2024-12-20 120353.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/55204d67-2202-0c29-e791-ba09515b5188.png)

左部から対象となるプロファイル(例だと`Windows PowerShell`)を開き、右枠の下部にある「外観」を開いて、画像を参考に透明度の設定を行ってください。

![スクリーンショット 2024-12-20 132005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/15ecd553-d696-b2bd-9dd7-dadb5bd02f65.png)

こちらも透明度は程々に(0で透明度100%)して、おすすめはアクリル素材を有効化することです。
アクリル素材を有効化すると背景にぼかし効果がはいります。

## zsh
Macであればデフォルトで`zsh`になっていますので下記を参考に`.zshrc`を設定しましょう。

https://qiita.com/Shankou/items/668912939e21e2fcabe9

Windows(WSL環境)の人は`zsh`をインストールするところからになるので、下記コマンドから進めていきます。

```
sudo apt install zsh
```

インストールコマンドはLinuxのディストリビューションにもよりますが、Red Hat系だと`apt`ではなく`yum`になります。

インストールが終わったら以下のコマンドでzshの配置場所を確認します。
多分`/usr/bin/zsh`と表示されると思いますが、各自確認してください。

```
which zsh
```

確認が取れたら、デフォルトのログインシェルを変更していきます。
ログインシェルの変更は`chsh`(チェンジシェル)コマンドになります。

```
chsh
```

変更したいShellのPATHを聞かれますので、先程確認した`which zsh`の結果を入力します。
ここまでできたら今のタブはそのままに、新しいタブを追加して表示を確認してみましょう。
以下の様な画面が出てきたら成功です。

![スクリーンショット 2024-12-20 135544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/c75e145d-22b3-cdf9-a02b-7d6771e95013.png)

`0`を入力すると空の`.zshrc`を作成してくれます。
※既に`.zshrc`が存在していた場合はこの画面がでてきません。

あとは`.zshrc`を設定していくだけになります。

## 次回は Neovim
お疲れ様です、これでターミナルの画面がもう怖くありませんね！？(圧

次回はNeovimのインストールと設定を行っていきます。
その名の通り新しくてすごいVimです。
エディタを開くたびに真っ黒背景の白文字だと気が滅入るので、こちらもとりあえず見た目から入りましょう。

![スクリーンショット 2024-12-20 14.19.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639915/8f22575f-a525-1484-c2c3-3dbf4466c75c.png)
MySQLテーブルサイズを簡単チェック


information_schema.tablesを利用して、テーブルごとのサイズ情報を取得します。


```mysql
SELECT 
    TABLE_SCHEMA AS `データベース名`,
    TABLE_NAME AS `テーブル名`,
    ROUND(DATA_LENGTH / 1024 / 1024, 2) AS `データサイズ(MB)`,
    ROUND(INDEX_LENGTH / 1024 / 1024, 2) AS `インデックスサイズ(MB)`,
    ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS `合計サイズ(MB)`
FROM 
    information_schema.tables
WHERE 
    TABLE_SCHEMA = 'database_name'
ORDER BY 
    (DATA_LENGTH + INDEX_LENGTH) DESC;

```

##### 各列の意味:
- TABLE_SCHEMA: データベース名
- TABLE_NAME: テーブル名
- DATA_LENGTH: テーブルのデータ部分のサイズ
- INDEX_LENGTH: テーブルのインデックス部分のサイズ
- DATA_LENGTH + INDEX_LENGTH: 合計サイズ

##### 使い方:
クエリのyour_database_nameを調べたいデータベース名に置き換えて実行してください。
結果は各テーブルのサイズをMB単位で表示します。

##### output

| データベース名          | テーブル名        | データサイズ(MB) | インデックスサイズ(MB) | 合計サイズ(MB) |
|-------------------------|-------------------|------------------|------------------------|----------------|
| database_name      | table_1          | 25837.00         | 45177.00              | 71014.00       |
| database_name      | table_2          | 28123.00         | 2448.86               | 30571.86       |
| database_name      | table_3          | 12457.00         | 9748.97               | 22205.97       |
| database_name      | table_4          | 5903.00          | 2766.16               | 8669.16        |
| database_name      | table_5          | 2429.00          | 2332.47               | 4761.47        |
| database_name      | table_6          | 1688.00          | 2369.00               | 4057.00        |
| database_name      | table_7          | 994.00           | 1285.20               | 2279.20        |
TypeScript: ピタゴラス数

## プログラム

```ts:pythagoras.ts
console.log("** 開始 ***")
let set_aa = new Set<number>()
const nmax: number = 100
let icount: number = 0
for (let it=1; it<nmax; it+=1)
	{
	const it2 :number = it * it
	for (let jt=it+1; jt<nmax; jt+=1)
		{
		const jt2 :number = jt * jt
		const itjt2 :number = it2 + jt2
		const tt :number  = Math.sqrt(itjt2)
		const kt :number = Math.floor(tt)
		const kt2 :number = kt * kt
		if (itjt2 == kt2)
			{
			const ratio :number = it / jt
			if (!set_aa.has(ratio))
				{
				set_aa.add(ratio)
				console.log(it,jt,kt,ratio)
				icount += 1
				}
			}
		}
	}

console.log("icount = ",icount)
console.log("*** 修了 ***")
```

## 実行結果

```text
$ bun run pythagoras.ts 
** 開始 ***
3 4 5 0.75
5 12 13 0.4166666666666667
7 24 25 0.2916666666666667
8 15 17 0.5333333333333333
9 40 41 0.225
11 60 61 0.18333333333333332
12 35 37 0.34285714285714286
13 84 85 0.15476190476190477
16 63 65 0.25396825396825395
20 21 29 0.9523809523809523
20 99 101 0.20202020202020202
28 45 53 0.6222222222222222
33 56 65 0.5892857142857143
36 77 85 0.4675324675324675
39 80 89 0.4875
48 55 73 0.8727272727272727
60 91 109 0.6593406593406593
65 72 97 0.9027777777777778
icount =  18
*** 修了 ***
```

## 確認したバージョン

```text
$ node --version
v22.3.0

$ bun --version
1.1.40
```

## tsc でコンパイル

```bash
tsc pythagoras.ts --lib es2020,dom
```

実行

```bash
node pythagoras.js
```
[Elixir] Task.async_streamで手軽に処理を並列化する

この記事は Elixir Advent Calendar 2024 シリーズ10の25日目です。昨日は @t-yamanashi さんでした！

https://qiita.com/t-yamanashi/items/5eeb35ac2e62b2567a96

---

先日書いた記事で、Stripeでの従量課金について解説しました。

https://qiita.com/items/3f0d6a92fd3e262ee9c5

[imagepix](https://imagepix.app) では当然ながら顧客ごとに請求を行うため、顧客ごとのサービス使用量を定期的に記録するバッチ処理が必要です。ここで逐次処理をしていると、顧客が増えた際に全顧客分の使用量の記録が終わらないまま次のバッチ処理が始まってしまったり、過少請求が発生してしまったりする可能性があります :money_with_wings: 

それぞれが独立していてある程度時間がかかってしまう処理を高速化するには、並列に処理するのが手っ取り早いです。Elixirには並行処理[^concurrently]を実現する機能が充実していますが、今回は `Task.async_stream/3` で手軽に処理を並列化してみます。

[^concurrently]: 記事内の記述が並列だったり並行だったりしますが、`Task.async_stream/3` のドキュメントでは「concurrently」という言葉が使われているのでここでは「並行処理」と記述しています。今どきCPUのコア数が1つということはあまりないと思うので、実際は並列に処理されていることでしょう。

https://hexdocs.pm/elixir/Task.html#async_stream/3

`Task.async_stream/3` はStream[^stream]を作成するだけで、処理は実行されません。今回は各処理の戻り値を使わないので、[Stream.run/1](https://hexdocs.pm/elixir/Stream.html#run/1) で処理を実行します。

[^stream]: https://hexdocs.pm/elixir/enumerable-and-streams.html#streams

なお、実際にリクエストを送信すると迷惑なので、今回は [Process.sleep/1](https://hexdocs.pm/elixir/Process.html#sleep/1) で代用します。

```elixir
1..100
|> Task.async_stream(
  fn n ->
    IO.puts("Request #{n}")
    Process.sleep(1_000) # 1秒待つ
  end,
  max_concurrency: 10
)
|> Stream.run()
```

実行すると、以下のように出力されます。

```
Request 1
Request 2
Request 3

...

Request 100
```

`max_concurrency: 10` を指定しているので、最大で10プロセスが並行で動きます。今回は全100件を10件ずつ処理し、1件あたり1秒かかるので、約10秒ですべての処理が完了します。簡単ですねぇ〜。

なお、`max_concurrency` を指定しない場合でもプロセスが無尽蔵に起動されるわけではありません。

> - `:max_concurrency` - sets the maximum number of tasks to run at the same time. Defaults to [System.schedulers_online/0](https://hexdocs.pm/elixir/System.html#schedulers_online/0).

とあるように、デフォルトで `System.schedulers_online/0` の戻り値分だけプロセスが並行で動きます。この値は環境依存なので、必要に応じて（特に外部のAPIを実行する場合はRate Limitを気にしますね） `max_concurrency` を明示的に指定しておくとより安心です :blush: 

---

これで Elixir Advent Calendar 2024 はおしまいです！今年もお疲れ様でした :tea:
Terraform Data Sources を使ってみたら便利だった

# Terraform Data Sources とは

Terraform の data ブロックで定義できるデータリソースのこと。
特定のリソースからデータを読み取り、結果をエクスポートすることで、リソースブロックからの読み取りを可能にする。

terraform のドキュメントに記載のあるものしかデータを取得できない。しかし、現時点で google_provider では GCP の大半のリソースのデータソースが用意されている。

# きっかけ

GCP 上の特定のプロジェクトをフィルタした予算を作成するのに、プロジェクト番号を拾ってくる必要があったため

# 使用方法

使用環境は以下
* terraform == 1.3.9
* google_provide == 4.83.0

```terraform
data "google_projects" "billing_budget_projects" {
  filter = "name:billing-*"
}

data "google_billing_account" "account" {
  billing_account = "000000-0000000-0000000-000000"
}

resource "google_billing_budget" "budget" {
  billing_account = data.google_billing_account.account.id
  display_name = "Example Billing Budget"

  budget_filter {
    projects = for project in google_projects.billing_budget_projects.number : "projects/${project}"
  }

  amount {
    specified_amount {
      currency_code = "USD"
      units = "1000"
    }
  }
  threshold_rules {
      threshold_percent =  0.5
  }
}

```
長く働くためには

70歳定年が企業の努力義務とされ、年金支給額も期待できないし、税金・社会保険の負担も大きい。出来る限り長く働かないといけない未来がやってきます。
長く働き続けるために私がやってきたこと、考えていることを書こうと思います。

## 健康に気を付ける

まずは健康であることが最も重要です。長く働くには健康が重要です。病気、けがで長期間、働けなくなることは避けたい。
また、年齢を重ねても健康で居続けることはとても難しいですが、規則正しい生活を心がけて、健康でいる期間を長く続くように努力しています。

## 頑張り過ぎない

基本的に仕事は大変であることが多いので、つい頑張ってしまいますが、無理をすると心身ともに疲弊してしまうので、頑張り過ぎないように心がけています。
「頑張るな」と言われても頑張ってしまうものなので、「頑張り過ぎない」ように気を付けています。

## 継続的な勉強

仕事をストレスなく進めていくには、スキルが必要です。何を勉強すれば良いのか、といつも悩みますが、今のプロジェクトが滞りなく進めるような技術、将来的に必要になるだろうと思われる技術を勉強するようにしています。
私は本を読むことくらいしかしていないですが、なるべく沢山の本を読むようにしています。勉強時間は少なくても継続し続けることが重要と信じて、隙間時間を見つけてやっています。

## 会社以外の居場所を作る

家庭と職場以外の3つ目のコミュニティがあると精神的に安定すると言われています。
家庭の居場所もなく、仕事も辛い…、そんな時でも3つ目のコミュニティがあると逃げ込むことが出来ます。
逃げ場所を作るというのも、長く働くためには必要なことだと思います。

## まとめ

まだまだ改善してく余地はあると思いますが、まずは上記を続けてみようと思います。
あと20年以上働くつもりなので。
ISUCON14に初参加した話

# 技術的なお話というよりは体験談です

事前準備とか、ネットで多くの人が共有されているので、私は初めて参加した体験談を残しておきます。

# ISUCONとは

> ISUCONとはLINEヤフー株式会社が運営窓口となって開催している、お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトルです

参考：https://isucon.net/

# はじまりはお手洗いで。。。

[ISUCON](https://isucon.net/)という言葉すら知らない私を、誘ってくれた会社の方と参加しました。
普段私は社内のweb開発で、誘っていただいた方はセキュリティで、普段の業務で関わりは少ないものの、誘ってくれた時は何かはわからなかったですが嬉しかったです。

# で、何やるの

まずは大会の参加登録が必要で、githubのアカウントとdiscordのアカウントが必要になってきます。
ちゃんと登録済みにならないと参加できません。

## githubアカウントは何に使うの
参加登録に必要でした。

## discordのアカウントは何に使うの 
大会運営側からお知らせが来たり、運営へ質問する窓口に必要です。

## awsアカウントは何に使うの
チューニングバトルに使用するサイトをaws上に自分たちで構築しないといけません。
当日にcloudfomationのテンプレートが配布されます。

私が参加する時は、メンバーの一人がawsアカウントを用意していただきました。
大変ありがたい。。。

メンバーに一人はawsに慣れた人がいないといけないです

# 本番当日までに

有志の方達が、過去問を残してくれていました。
自分は[orb](https://orbstack.dev/)で再現できる範囲の過去問をやってみました。

https://github.com/matsuu/cloud-init-isucon

ある程度解説もついていたので調べながらできました。
普段HTTPの世界がメインのweb開発していたら使わないようなネットワーク系のコマンドや設定があるとつまずきやすいと思います。
この時はChatGPTとかに聞いて解決できていたので、当日もこれでいけるなとたかを括っていました。
生成AIの使用は禁止されていませんでした。

# 何をするのか順序立てておくの大事

私は初参加で右も左もわからなかったですが、他メンバーは経験者だったのでとても助かりました。
何をするのか・詳細・参考コマンド・できなかった時の代替の手段などできるだけ残しておいたのは当日助かりました。
チームのslackチャンネルに、参考サイトやスプレッドシートなどのリンクをのっけておくのもいいかなと

# 早く寝れた
前日は、すぐ見れるように、必要そうなリンクをgoogleタブに残しておいて何もせず寝ました。

# 朝、続々と

YoutubeライブでISUCONの中継が始まり、discordにもおはようと参加者たちの挨拶も流れてきて、いよいよ感が出てきました。

https://www.youtube.com/watch?v=sT_9E0pTlns

どういう賞があるのか、各企業スポンサーさんからの提供が流れていたのですが、賞金100万以外にもたくさん用意されていてテンション上がりました。

# 始まり
始まって、準備しておいたスクリプトや準備をチームのメンバーがこなしていってくれてました。
途中、NewRelicが使えなかったりがあったのですが、代替え手段を用意したりととても助かりました。
その間自分は、アプリのコードを読んだり実際に動かしてみたり、ドキュメントを読んだりしていました。

# 8時間ぶっ通し
SQLを効率化したり、コードで無用なループ処理をしたりしているのを改善はしてみましたが、あまり手応えがなかった覚えがあります。
今回のは配車アプリが用意されていたのですが、あまりコードに対するツッコミどころがなく難しかったのを覚えています。
結局、集中していたら10時から始まり、お昼も食べず18時まであっという間でした。
自分はスコアにあまり貢献できずチームメンバーに助けられてばかりでした。

# 次も頑張ろうと思った
手応えがなく終わってしまったので、今回参加したことに意義があったのかなぁと反省。

4ヶ月前にトイレで誘われるまで言葉すら知らなかった自分みたいな、ISUCONという言葉自体を知らない人にも是非参加をお勧めしたいです。

チームメンバーの方々、誘っていただきありがとうございます！
個人的ロードマップ整理メモ

## 概要
![スクリーンショット 2024-12-20 14.18.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/8f7b1918-34f9-8be6-0351-1e1238b8fc1b.png)
Azure DatabricksでUnity Catalogテーブル毎のストレージ容量を一覧表示する


# 目的
- データエンジニアにとってテーブル毎のサイズ（使用容量）を見たいニーズが多いと思いますが、DatabricksのUnity Catalogで管理するテーブルに対してサイズを一覧表示する方法です。
- system.information_schema.tablesのstorage_pathと、データを保管するAzure Data Lake Storage Gen2 (ADLS)のPythonライブラリを使用してサイズを算出しデータフレームに表示します。

# 動作環境

下記の環境で動作を確認しています。

* Databricks ノートブックのサーバーレス コンピューティング
* サーバーレス クライアント イメージ 2 （Azureライブラリのpip installは不要です）
 
:::note warn
* 実行するとAzure DatabricksやADLSの操作課金が発生しますのでご注意下さい。
* ストリーミングテーブルは表示されません（storage_pathがnullのため）。
:::

# 実装

(1) ノートブックのサーバーレス コンピューティングを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186585/8ea39355-1125-746b-3d95-37cf97c7581e.png)

(2) サーバーレス クライアント イメージ 2 を選択し適用する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186585/e3c1b575-e139-7501-b7b2-3ca0a9234e33.png)

(3) ADLSのアカウント名、コンテナ名、SASトークンを設定しコードを実行

```python

import re
from azure.storage.filedatalake import DataLakeServiceClient
from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType

# 環境設定
account_name = "your account name"
file_system_name = "your container name"
# sas_token
credential = "your sas token"

# 抽出するテーブル一覧の条件をカスタマイズして指定（下記はsamplesカタログを除外）
list_table_query = "SELECT * FROM system.information_schema.tables where table_catalog != 'samples' and storage_path is not null"

def extract_blob_path(url):
    match = re.search(r"abfss://[^/]+/(.+)", url)
    if match:
        return match.group(1)
    return None

def get_total_size_gb_of_folder(service_client, file_system_name, folder_path):
    total_size = 0
    paths = service_client.get_file_system_client(file_system_name).get_paths(path=extract_blob_path(folder_path))
    for path in paths:
        if not path.is_directory:
            total_size += path.content_length
    return round(total_size / (1024 ** 3), 2)  # Convert bytes to GB

# サイズ算出関数をUDFとして宣言
@udf(returnType=DoubleType())
def get_folder_size_udf(folder_path):
    return get_total_size_gb_of_folder(service_client, file_system_name, folder_path)

service_client = DataLakeServiceClient(account_url=f"https://{account_name}.dfs.core.windows.net", credential=credential)

tables_df = spark.sql(list_table_query)
tables_df = tables_df.withColumn("total_size_GB", get_folder_size_udf(tables_df["storage_path"]))

# サイズの降順でデータフレームを表示
display(tables_df.select("table_catalog", "table_schema", "table_name", "total_size_GB", "storage_path").sort("total_size_GB", ascending=False))

```
(4)下記のようにGB単位のサイズを確認することができます。
使用状況を確認したり、サイズや容量課金が大きいテーブルを特定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186585/fcc9edb1-21b0-25ed-cf63-6123c9f0c800.png)
【UE5】AI触って身についた自分の知見

# 概要
AIの設計や学習をしてて、身について知見をまとめます。
一つだけだと数行で終わってしまうので、いくつか書いてみます。

# 毎回実行してほしいタスクを作る
※もっといいやり方があったら知りたいです！
## 事前　SelectorとSequencerについて
処理分岐に関して、SelectorとSequencerというのがあります。
分かりやすい情報⇒https://historia.co.jp/archives/29055/

今回は、敵が攻撃する対象に優先度をつけ、発見した対象に対して近づいて攻撃するような仕組みを行うため、Selectorを用いてます。
以下のような形で分岐させてます、そのうえでこの記事を書いていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/11f90c74-3712-5eb4-2d57-0b70f072abf1.png)
※ルートがNoneなのは画像用です。


## 1.BTTask_BlueprintBaseを継承して新しいタスクを作成
雑に「NewBlueprint」という名前のタスクにしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/736fe7b5-47c4-9b82-4c46-869c61a5b0db.png)


## 2.Receive Execute AIをオーバーライドして作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/68f9930a-6699-8432-1d4e-e0fc5353ba88.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/8661bcd6-5455-0fa7-f19f-467df9e6c841.png)

## 3.Finish Executeを呼び出してノードをつなげる
今回用いているのはSelectorのため、Successはチェックを入れないままにしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/a7d81265-079d-a678-42cb-0b078b1ac384.png)

## 4.タスクをビヘイビアツリーでつなげる
Selector先で一番最初にタスクが実行されるようにすれば、必ず処理されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/dd75a26c-7f4e-8426-ff1d-9fe2debc38ff.png)


# アクターのBPに通知する
タスクからインターフェースを利用してアクターに通知させて処理を実行させてます。

## 事前 インターフェースについて
分かりやすい情報⇒https://zenn.dev/posita33/books/ue5_starter_cpp_and_bp_001/viewer/chap_03_bp-interface

## 1.インターフェースを作成
「BPI_Test」という名前にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/7d19505b-0b2e-fb7b-6cb2-9f348f06843f.png)

## 2.関数を作成
ブループリントを開くと関数名を決めさせられるので、「DoPlay」としておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/98711595-de00-1bfd-b3f9-a39110724371.png)

## 3.アクターとタスクにインターフェースを追加
アクターBPとタスクBPのクラス設定を編集からインターフェースの追加をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/7bdd314e-faec-0856-13e6-b61224e36579.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/3f6208ed-8dcb-feeb-de63-ad2fe5d30def.png)

## 4.アクターに「DoPlay」のイベントを呼ぶ
インターフェースを追加したことにより、イベントの追加が行えるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/a65be944-5309-df4d-a460-71ba7d6f0ef6.png)
試しに処理をこうやって置いておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/2a34af56-9aab-0bcc-c0fc-dcb2582061f7.png)

## 5.タスクで「DoPlay」を実行
メッセージのほうで「DoPlay」を呼んで実行させるようにします。
タスクはさっきやってたものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/f028b057-c5de-b74f-2e79-97fda9d0a47b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/7567fbed-bb12-a4d3-2a27-2b8a5a31101b.png)

## 6.アクターのほうで呼んでることを確認
Helloが出たのを確認できたので、意図通りに処理されていそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/042ef22a-f0e9-a713-7b71-16cd7c2acb08.png)
ActiveDirectory

# ActiveDirectory
ActiveDirectoryはMicrosoftが提供するディレクトリサービスでWindowsServer環境でのネットワーク管理や認証を効率化するためのシステム。特に企業や大規模な組織でのユーザー、コンピュータ、グループ、ポリシー管理に広く利用されている。

## 主な機能と特徴
> ①認証と認可

ユーザーやデバイスがネットワークにアクセスする際、IDとパスワードを使った認証を提供。またアクセス制御リスト（ACL）を通じてリソースへの権限を管理。

> ②ディレクトリの構造化

ActiveDirectoryは階層構造（ツリーやフォレスト）を採用しており組織のリソースを効率的に整理・管理。

> ③グループポリシー

グループポリシーオブジェクト（GPO）を利用してユーザーやコンピュータの設定を一括管理できる（例：セキュリティポリシーやデスクトップ設定など）

> ④スケーラビリティ

小規模なネットワークから大規模な企業ネットワークまで対応可能でフォレストやドメインの分割による柔軟な管理が可能

> ⑤統合管理

ユーザーアカウント、デバイス、グループ、ネットワークリソースを1つのシステムで統合的に管理できる。

## 主なコンポーネント（構成要素）

> ①ドメインコントローラー（DC）

ActveDirectoryの中核となるサーバーでディレクトリデータを保存し認証や検索のリクエストに応答

> ②ドメイン

ActiveDirectoryの基本単位で同じポリシーやセキュリティ設定を共有するリソースが集まったもの

> ③ツリーとフォレスト

- ツリー：複数のドメインを階層的に構成したもの
- フォレスト：複数のツリーを統合したもの

> ④オーガニゼーショナルユニット（OU）

ドメイン内でリソースを論理的に整理する単位、管理権限を委任する際に便利

> ⑤グローバルカタログ

ドメイン間での検索を高速化するためにディレクトリ情報の一部を保存した特別なデータベース

## 主な利用例
- ユーザー管理：従業員のアカウント作成、削除、権限管理
- デバイス管理：PCやサーバー、プリンターの登録と管理
- セキュリティ強化：グループポリシーでセキュリティ設定を一括適用
- 認証基盤の提供：シグナルサインオン（SSO）の実現

---
**ActiveDirectoryを活用するこで管理者は手作業を減らし、効率的かつ安全なネットワーク管理を実現できる**
無料QRコードジェネレーター：「 https://free-qr.site 」を日本へ

はじめに

情報を簡単に共有できる方法があれば便利だと思いませんか？それがまさにQRコードです！この白黒のパターンが描かれた小さな四角形は、デジタルコミュニケーションの現代的な奇跡です。特に日本では、QRコードはビジネスから日常生活に至るまで欠かせないツールとなっています。QRコードの世界を掘り下げ、「https://free-qr.site」で無料で作成する方法をご紹介します。

QRコードとは？

QRコード（クイックレスポンスコード）は、データを保存する2次元バーコードです。それはまるで、ウェブサイトやアプリ、さらにはWi-Fi設定への小さなポータルのようなもの。スマートフォンのカメラを向けるだけで、瞬時にアクセスできます！

なぜQRコードが日本で重要なのか

日本のハイテク文化は、QRコードを完全に受け入れています。レストランのメニューや電車の駅、広告の中など、どこにでも見つかります。なぜでしょうか？それは、デジタルと物理的な世界を結びつける迅速かつ簡単な方法だからです。また、日本の効率性と利便性に対する重点とも完璧に一致しています。

高品質な出力：どのデバイスでもスキャン可能なコードを確保します。

https://free-qr.site
watsonx.aiのLLMをPythonから呼び出すための準備

watsonx.aiのLLMをPythonから呼び出すためには、以下の３つを用意する必要があります。
- APIキー
- watsonx.ai Runtimeが関連付けられた「プロジェクト ID」
- watsonx.ai Runtimeの「サービス・エンドポイント」

# APIキーの作成
[watsonx](https://jp-tok.dataplatform.cloud.ibm.com/wx/home?context=wx)のハンバーガーメニューから「アクセス（IAM)」にアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/af5f2319-9cfd-30be-d789-085c73ddab9e.png)

「APIキー」を選び「作成」クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2d02d098-1ae4-8895-1951-f552749b14a9.png)

適当な名前をつけて「作成」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7f1f8b5d-4ea6-be9c-5783-db4074701411.png)

「コピー」や「ダウンロード」をして保存しておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/02de5c4b-4f79-bd70-cca8-5fa0858bad2d.png)
# プロジェクトの準備
watsonx.ai Studioで「新規プロジェクト」を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6413e7ec-a596-e635-7e09-b867f38f037a.png)

適当に名前をつけて「作成」します。ここでは「240308xai」という名前にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1f34cf13-0bb4-4050-d2df-2bb6bc7da058.png)

「管理」タブでwatsonx.ai Runtime（旧Watson Machine Learning）というエンジンのサービスを関連付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6492c217-51fc-b136-1460-7115dba8d07a.png)

あらかじめ用意しておいたwatsonx.ai Runtime（旧Watson Machine Learning）のサービスを「アソシエイト」します。もし用意していなければ「新規サービス」から追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ab96f02f-5d4f-b675-7710-80f07951379f.png)

# プロジェクトID取得
プロジェクトに入り、「管理」タブの「一般」を選び、「プロジェクト ID」をコピーして、書き留めておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f1c73211-921c-fe94-3088-c99854847a63.png)

# watsonx.ai Runtimeのサービス・エンドポイントの確認
サービス・エンドポイントはリージョンごとに異なっています。

以下だと東京リージョンになっています(正確には、この表示はwatsonx.ai Studioのリージョンですが、watsonx.ai Studioとwatsonx.ai Runtimeは同じリージョンであるのでwatsonx.ai Runtimeも東京になります)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cd76cf89-4766-2f98-5c4c-fe34609f47e0.png)

各リージョンのサービス・エンドポイントは以下から探してください。

パブリック・エンドポイントは以下です。

https://cloud.ibm.com/apidocs/machine-learning


プライベート・エンドポイントは以下です。

https://www.ibm.com/docs/ja/watsonx/saas?topic=assets-service-endpoints

東京のパブリックエンドポイントであれば
```
https://jp-tok.ml.cloud.ibm.com
```
となります。


# まとめ
これで、「APIキー」、watsonx.ai Runtimeが関連付けられた「プロジェクト ID」、「watsonx.ai Runtimeのサービス・エンドポイント」の三つが揃いました。


# 参考

#### コンソールでの API キーの作成
https://cloud.ibm.com/docs/account?topic=account-userapikey&interface=ui#create_user_key

#### プロジェクトの作成 — Docs | IBM watsonx 
https://dataplatform.cloud.ibm.com/docs/content/wsj/getting-started/projects.html?context=wx&locale=ja&audience=wdp

#### プロジェクトへの関連サービスの追加 — Docs | IBM watsonx 
https://dataplatform.cloud.ibm.com/docs/content/wsj/getting-started/assoc-services.html?context=wx&locale=ja&audience=wdp
AWSCLIでS3の使用データ量をみてみよう。

今使用しているS3のこのバケットで全部でどれくらいデータ量があるかを知りたい！
でもAWSコンソール上じゃ確認できないので接続してターミナルからコマンド打つ必要がある！って時に使います。

## まず、Amazon CLI をインストールしましょう。

ここからインストール。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

## 次に、接続したいアカウントの設定をしましょう。
ターミナルで以下を入力。

`aws configure`

プロンプトに従って入力しよう。

- AWS Access Key ID: IAM のアクセスキー ID
- AWS Secret Access Key: IAM のシークレットキー
- Default region name: 利用するリージョン（例: us-east-1）
- Default output format: 出力形式（通常は json）

※ここで設定したアクセスキーが「有効」であるかは事前にコンソールから確認すること。
入力した内容に変更されているか確認。
`aws configure list`
![スクリーンショット 2024-12-20 13.48.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318046/95aedc44-ddaa-f0ae-6a55-ff4a9c6f275c.png)


 ## コマンドを実行してみる。

コマンド的にはこんな感じ。

`aws s3 ls s3://[バケット名]/[フォルダ名]/  --recursive --human --sum`

バケット全体のストレージが知りたい場合は、フォルダ名不要です。

## こんな感じで出てくる。

![スクリーンショット 2024-12-20 13.49.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318046/880c186d-d4c5-e54f-ddef-e14ef5768fbc.png)


他にも色々コマンドあるので機会があればぜひ。
https://qiita.com/uhooi/items/48ef6ef2b34162988295
思考方式の重要性: 困難な時期を乗り越えるために

こんにちは！👋🏼
Pranav です。東京で働いているソフトウェア開発者で、株式会社エアークローゼットに勤務しています。

この記事を書くのは初めてなので、よろしくお願いします。


## **マインドセットが大事**

_困難な時期に、波を乗り越える助けになるのは、自分のマインドセットだけです_ 🌊

---

### **はじめに**

人生や仕事では、限界を試されるような挑戦がつきものです。プロジェクトでの挫折や個人の成長を目指す中で、マインドセットは困難を乗り越える上での基盤となります。

強いマインドセットは、一貫性、粘り強さ、そして進歩を促し、目標達成を可能にします。この記事では、私が学んだマインドセットについての教訓を、関連するデータや数学的な概念、そして視覚的な説明を交えながら共有します。

---

## **マインドセットについて学んだこと** 📚

### **1. 一貫性は成長を積み重ねる** 🔄📈

一貫性は成功の土台です。どんなに小さな改善でも、時間をかけて蓄積することで指数的な成長を生み出します。この現象は、金融の複利の概念に似ています。

#### **一貫性の数学**

例えば、1日1%の改善を考えてみましょう：

:::note info
**公式:**

`最終値 = 初期値 × (1.01)^日数`

1年後（365日）の計算：

**計算:**

`最終値 = 1 × (1.01)^365 ≈ 37.78`
:::

つまり、小さな改善を積み重ねることで、1年間で**37倍**良くなることができます。これを停滞（`1^365 = 1`）や断続的な努力と比較してみてください。

#### **視覚化**

一貫性と断続性の成長を比較したグラフ：

- **一貫した成長**: 時間をかけた指数的な改善。
- **断続的な成長**: 最小限の進歩。

![Consistency Compounds Growth](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935547/61c9568f-6cf9-081e-371c-31bb4799b915.png)

#### **実生活での応用**

ソフトウェア開発を考えてみてください。毎日少しずつクリーンでテスト済みのコードを書くことで、信頼性が高くスケーラブルなアプリケーションが完成します。一方、断続的なコーディングでは技術的負債や納期遅延を招くことがよくあります。

---

### **2. 成功か教訓か** ✌✍

失敗は成功の反対ではなく、旅の一部です。失敗を学びの機会として受け入れることで、長期的な成長が可能になります。

#### **データの裏付け**

- *"平均的な起業家は最初の成功までに3.8回失敗する。"* ([出典: Forbes](https://www.forbes.com))
- 成功したスタートアップの調査によると、**失敗後のピボット**は成功率を**48%**向上させることがわかっています。

#### **視覚化**
:::note info
著名な人物の失敗回数と成功の節目を示した棒グラフ：

- J.K.Rowling: 12回の出版社からの拒否 ➔ ハリーポッター。
- SpaceX: 3回の打ち上げ失敗 ➔ ファルコン1の成功。
:::

![Success vs. Failures](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935547/bdc3cbcd-05e7-26d4-740f-cada45899ca0.png)

#### **実生活での例**

テクノロジーの分野では、アジャイル手法は「早く失敗する」というアプローチを採用しており、スプリント内の早期失敗がより良い反復と堅牢な最終製品につながります。

---

### **3. 粘り強さ** 👊

粘り強さは、結果がすぐに出なくても続ける能力です。どんなに複雑な問題でも、時間をかけた一貫した努力で解決できます。

:::note info
問題の複雑さと努力を示すグラフ：

- **初期の複雑さ**: 高い。
- **努力の適用**: 徐々に減少。
- **結果**: 解決可能な問題。
:::
![Persistence Over Time](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935547/4e397460-11dd-f0df-ed65-6b5bc2abb588.png)

#### **ケーススタディ**

複雑なコードベースの問題をデバッグすることを考えてみてください。体系的なテスト、ログの記録、エッジケースの見直しを通じた粘り強さが、しばしば突破口につながります。一方、粘り強さが欠けていると、問題が未解決のままになり、プロジェクトのスケジュールに影響を与えることがあります。

---

### **4. 自分を信じる** 🧿

自己疑念が湧いたときこそ、自分を信じるべき瞬間です。自己信念は前向きな視点を育み、問題により効果的に取り組む助けとなります。

#### **データの裏付け**

- 自己信念が高い個人は、複雑な問題を解決する可能性が **25%** 高くなります。
- 自信は意思決定のスピードを **30%** 向上させます。

#### **実生活での例**

自信を持つ開発者は革新的なソリューションを試す可能性が高く、それが突破口につながります。一方、自信が低いと、機会を逃してしまうことがあります。

---

### **5. 一度に1つずつ** 🕰☝️

大きな問題は圧倒されることがありますが、小さく分割して対処可能なタスクにすることで解決できます。このアプローチは「分割統治」として知られ、着実な進歩を保証します。

#### **視覚化**

タスク完了を示すガントチャートまたはタイムラインの例：

![output (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935547/291a23c3-3994-e2a5-38ce-9ad168de0001.png)

---

### **6. 常に最高を目指す** 🥇

最高を目指すことは、献身、一貫性、そして強いマインドセットを必要とします。それは努力と回復力を求める旅です。

#### **データの裏付け**

- Cristiano Ronaldo は、平均的なアスリートを超えて、毎日**3〜4時間**の厳しいトレーニングを行っています。
- 高い志を持つ個人は、同僚を **20〜30%** 上回る成果を達成します。

---

### **結論**

マインドセットは成功の基盤です。一貫性を持ち、失敗から学び、粘り強さを保ち、自分を信じ、一度に一歩ずつ進み、高い目標を持つことで、どんな課題にも対応できます。

成功への道は直線的ではありませんが、マインドセットが前進を保証します。小さく始め、一貫性を保ち、時間をかけて成長が積み重なるのを見てください。

この記事が助けになれば幸いです。マインドセットを改善し、困難を乗り越えるための一助となれば嬉しいです。


---
VALORANTのAPIを使って情報を取得してみる

# はじめに
初めまして！
今回はAPIの学習の一環としてVALORANTのAPIを使用して情報を取得したいと思います。
よろしくお願いします！

# APIでデータを取得する手順
今回VALORANTの情報を以下の手順で取得します。

**1.Riot Gamesの開発者用サイトにアクセスする**
**2.Riotアカウントでログインする(アカウントがない場合は作成する)**
**3.APIキーを発行する**
**4.リクエストを送信する**
**5.情報の取得**

## 1.Riot Gamesの開発者用サイトにアクセスする
まず最初にRiot Gamesの開発者用のサイトにアクセスします。
下のリンクからアクセスできます↓
https://developer.riotgames.com/

## 2.Riotアカウントでログインする
 Riot Gamesの開発者用サイトにアクセスした後、ログインしていない場合はログインを行なってください。
 サイトの右上にLOGINと書いてある部分をクリックすることでログインページに飛ぶことができます。自身のアカウントを所持していない場合はこのページでアカウントを作成してください。
 画面の右上に自分のアカウント名が書いてあればログイン完了です。

 ## 3.APIキーを発行する
 ログイン完了後右上の自身のアカウント名をクリックし、**DASHBORD**をクリックしてください。
 するとこの画面に遷移します。
 ![スクリーンショット 2024-12-18 10.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3960474/7a21f9ed-7a21-c7a9-7c39-4c8f8ece7ee1.png)
この画面でShowボタンを押すと自身のAPIキーを確認できます。
APIキーが発行されていなかったり、Expireのところに表示されている有効期限が切れていた場合は新しくAPIキーを発行してください。
これでAPIキーの発行は完了です。

## 4.リクエストを送信する
次にAPIにリクエストを送信してみましょう。まず右上のアカウント名をクリックし、APPSをクリックしてください。
するとこのような画面に遷移します。
![スクリーンショット 2024-12-19 19.08.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3960474/40b5fb9c-407e-c59c-d98e-7bf22eca366b.png)
今回はVALORANTのキャラクターの情報を取得したいので、val-status-v1を探し、クリックしてください。
するとそのAPIで取得できるデータを確認することができます。
では一度リクエストを送信してみましょう。
画面を下までスクロールするとこの表示があると思います。
![スクリーンショット 2024-12-18 10.51.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3960474/e6683a87-e2ff-87e3-dd64-f935ade9d6d8.png)
一度この画像の通りに情報を入力し、EXCUTE REQUESTをクリックしてください。(処理には時間がかかります。)
そうすると実際にレスポンスを確認することができると思います！


### pythonで実際に取得してみる
これからは実際にVALORANTのキャラクター名をAPIを使って取得してみましょう。
今回はキャラクター名を取得したいので、charactersのnameを取得したいと思います。
まずターミナルで以下のパッケージをダウンロードしてください。
```
pip install requests
```
これでパッケージをインストールすることができました。

コードは以下の通りです。
```python
import requests

# APIキーを設定
api_key = 'RGAPI-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'#先ほど確認したAPIキーに変更してください

# APIエンドポイントURL
url = 'https://ap.api.riotgames.com/val/content/v1/contents'

# ヘッダーにAPIキーを追加
headers = {
    'X-Riot-Token': api_key
}

# APIリクエストを送信
response = requests.get(url, headers=headers)

# レスポンスをJSON形式で取得
agents_data = response.json()

# エージェント名を表示
for agent in agents_data['characters']:
    print(agent['name'])
```
このコードを実行することでAPIからキャラクター名を取得できました！

# 最後に
これでVALORANTのAPIを使用してキャラクターの名前を取得することができました！
RiotGamesが提供しているAPIは他にもLOLやTFTに関するものもあるのでぜひ試してみてください！
# おまけ
取得したデータを利用してランダムで構成を決めてくれるプログラムを追加しました。
もしVALORANTをプレイしていて構成に困った人やいつもの構成に飽きたという人は使ってみてください
```python
import requests
import random

# APIキーを設定
api_key = 'RGAPI-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'  # 先ほど確認したAPIキーに変更してください

# APIエンドポイントURL
url = 'https://ap.api.riotgames.com/val/content/v1/contents'

# ヘッダーにAPIキーを追加
headers = {
    'X-Riot-Token': api_key
}

# APIリクエストを送信
response = requests.get(url, headers=headers)

# レスポンスをJSON形式で取得
agents_data = response.json()

# エージェント名を取得
agent_names = [agent['name'] for agent in agents_data['characters'] if agent['name'] != "Null UI Data!"]

# ランダムで5つのエージェント名を表示
random_agents = random.sample(agent_names, 5)
for agent in random_agents:
    print(agent)
```
YAMLのThe Norway Problemを検知する



# The Norway Problemについて
YAMLでは、特定の文字列が意図せず特定の型に変換されてしまうことがあります。例えば、`NO`という文字列は真偽値の`False`として解釈されます。どうやらこのような現象のことを[The Norway Problem](https://hitchdev.com/strictyaml/why/implicit-typing-removed/)というらしいです。ノルウェーをISO国コードで訳すと、`NO`なのでそのような名前になっているそう。


```norway.yaml
country: NO
```

```load_yaml.py
import yaml

with open('norway.yaml') as file:
    data = yaml.safe_load(file)
    print(data)
```

```
$ python load_yaml.py
{'country': False}
```

これに対する解決策は簡単で、ただ`NO`をquoteで囲うだけです。
```norway.yaml
contry: 'NO'
```

なんとなく今回はそのようなYAMLを検知するようなコードを考えてみました。


# 実際に検知するようなコードを考える
基本的にpyyamlなどは使えないので、YAMLファイルをテキストモードで読み込んで、正規表現でひっかける感じです。

```check_norway_problem.py
import re


class YAMLNorwayProblemChecker:
    
    BOOLEAN_REPRESENT_VALUES = {
        "y", "Y", "yes", "Yes", "YES",
        "n", "N", "no", "No", "NO",
        "true", "True", "TRUE",
        "false", "False", "FALSE",
        "on", "On", "ON",
        "off", "Off", "OFF"
    }

    def __init__(self, file_path):
        self.file_path = file_path
        self.raw_lines = self.load_raw_yaml()

    def load_raw_yaml(self):
        
        with open(self.file_path, 'r', encoding='utf-8') as f:
            return f.readlines()

    def check_norway_problem(self):
       
        # 真偽値が入ることが前提のキーを除外
        exclude_keys = {}

        # YAMLのkey: valueパターンを定義
        yaml_pattern = r'^\s*-?\s*(\S+):\s*(\S+)$'

        norway_problem_detected = False

        for i, line in enumerate(self.raw_lines, start=1):
            # 空白削除
            line = line.strip()
            # 空行やコメント行はスキップ
            if not line or line.startswith('#'):
                continue

            # 正規表現でkey: valueのペアを取得
            match = re.match(yaml_pattern, line)
            if match:
                key, value = match.groups()

                # 除外対象のキーをスキップ
                if key in exclude_keys:
                    continue

                # キーが真偽値として解釈されるかチェック
                if key in self.BOOLEAN_REPRESENT_VALUES:
                    print(f"ノルウェー問題が検出されました。\n{i}行目: キー '{key}' を引用符で囲んでください。")
                    norway_problem_detected = True

                # 値が真偽値として解釈されるかチェック
                if value in self.BOOLEAN_REPRESENT_VALUES:
                    print(f"ノルウェー問題が検出されました。\n{i}行目: 値 '{value}' を引用符で囲んでください。")
                    norway_problem_detected = True

        if not norway_problem_detected:
            print("ノルウェー問題は検出されませんでした。")

if __name__ == "__main__":
    yaml_file_path = "example.yaml"
    checker = YAMLNorwayProblemChecker(yaml_file_path)
    checker.check_norway_problem()

```

```example.yaml
country: "NO"
switch: ON
confirm: YES
```

```
$ python check_norway_problem.py
ノルウェー問題が検出されました。
2行目: 値 'ON' を引用符で囲んでください。
ノルウェー問題が検出されました。
3行目: 値 'YES' を引用符で囲んでください。
```

# 参考
https://hitchdev.com/strictyaml/why/implicit-typing-removed/
OMC238B(1153)

https://onlinemathcontest.com/contests/omc238/tasks/11653

![OMC238B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543462/625a83a4-5217-b96a-3a6f-d1cf785b2291.png)

$a_{5}≦5$、$a_{10}≦10$である広義単調増加な$(a_{0},a_{1},...,a_{10})$の組み合わせなので、
上図の$a_{0}$の左側の$0$の位置をスタートし、$a_{10}$の右側の$10$の位置をゴールとする経路問題です。
ただし、$a_{5}$を通るときに$0～5$である必要があります。

$a_{5}=0$を通る場合の組み合わせは、
${}_5C_5×{}_1{}_5C_5$
$=\frac{15×14×13×12×11}{5×4×3×2×1}$
$=3003$通りです。

$a_{5}=1$は、
${}_6C_5×{}_1{}_4C_5$
$=\frac{6}{1}\frac{14×13×12×11×10}{5×4×3×2×1}$
$=12012$通りです。

$a_{5}=2$は、
${}_7C_5×{}_1{}_3C_5$
$=\frac{7×6}{2×1}\frac{13×12×11×10×9}{5×4×3×2×1}$
$=27027$通りです。

$a_{5}=3$は、
${}_8C_5×{}_1{}_2C_5$
$=\frac{8×7×6}{3×2×1}\frac{12×11×10×9×8}{5×4×3×2×1}$
$=44352$通りです。

$a_{5}=4$は、
${}_9C_5×{}_1{}_1C_5$
$=\frac{9×8×7×6}{4×3×2×1}\frac{11×10×9×8×7}{5×4×3×2×1}$
$=58212$通りです。

$a_{5}=5$は、
${}_1{}_0C_5×{}_1{}_0C_5$
$=\frac{10×9×8×7×6}{5×4×3×2×1}\frac{10×9×8×7×6}{5×4×3×2×1}$
$=63504$通りです。

したがって、解は、
$3003+12012+27027+44352+58212+63504=208110$
となります。

余談ですが、
公式解説では、$\frac{{}_2{}_1C_1{}_0+(_1{}_0C_5)^2}{2}$と書かれています。
${}_2{}_1C_1{}_0$は、$a_5=0～10$すべてを通ったときの組み合わせです。

それから、$a_5=0$を通るときの組み合わせは${}_5C_5×{}_1{}_5C_5$で、$a_5=10$を通るときの組み合わせは${}_1{}_5C_5×{}_5C_5$です。(計算の順序は変わっていますが、結果は同じです。)
$a_5=1$と$a_5=9$を通る場合も同じになります。
ということで、$a_5=0～4$を通る場合と$a_5=10～6$を通る場合の組み合わせは同じです。
($a_5=5$の場合だけペアがありません。)

したがって、途中の計算は省きますが、
$\frac{{}_2{}_1C_1{}_0+(_1{}_0C_5)^2}{2}$は、$a_5=0～5$を通った場合の和ということになります。
ShadCnのアバターが丸くならない時の対処法[Next.js, SCSS, ShadCn]

下のようにAvatorを使っていたときになぜかavatorが標準の丸い状態になっておらず、困ったのですが修正することができたのでその方法をメモとして残しておこうと思います。

https://ui.shadcn.com/docs/components/avatar

```tsx:index.tsx
<div className={style.icons}>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Avatar className={style.avatar}>
              <AvatarImage src={userIcon} />
              <AvatarFallback>CN</AvatarFallback>
            </Avatar>
          </DropdownMenuTrigger>
          <DropdownMenuContent>
            <DropdownMenuLabel>{currentUser?.name}</DropdownMenuLabel>
            <DropdownMenuSeparator />
            <DropdownMenuItem asChild>
              <Link href="/profile">
                <User />
                <span>Profile</span>
              </Link>
            </DropdownMenuItem>
            <DropdownMenuItem asChild>
              <Link href="/profile/setting/user">
                <Settings />
                <span>setting</span>
              </Link>
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <a href="/invite" className={style.icon}>
          <Invite size={60} />
          <span className={style.badge}>{inviteNum}</span>
        </a>
        <a href="/chat" className={style.icon}>
          <MailIcon count={mailNum} size={40} />
        </a>
      </div>
```

```scss:index.module.scss
.avatar {
  width: 50px;
  height: 50px;
  border-radius: 100%;
}
```

# 解決方法
`overflow:hidden`を追加するだけでいけました。

```scss:index.module.scss
.avatar {
  width: 50px;
  height: 50px;
  border-radius: 100%;
  overflow: hidden;
}
```

`overflow`はコンテンツがパディングボックスに収まらないときに使えるプロパティです。

`hidden`はパディングボックスに収まるようにしてくれます。

他にも以下の設定を指定することができます。

|設定|機能
|---|---
|visible|パディングボックスの外側にも表示されます。
|hidden|溢れたコンテンツは要素のパディングボックスで切り取られます。
|clip|溢れたコンテンツは、overflow-clip-margin プロパティで定義された要素のはみ出しクリップ辺で切り取られます。
|scroll|溢れたコンテンツはスクロールさせることで表示させることができます。
|auto|溢れたコンテンツは要素のパディングボックスで切り取られて、スクロールさせることができるようになります。

https://developer.mozilla.org/ja/docs/Web/CSS/overflow#visible

ぜひ困ったときに参考にしてください。
Databricks でスポットインスタンスを検討する際のTips

# はじめに
Databricks でクラスターを立ち上げる際にワーカーノードでスポットインスタンスを利用することも多いかと思います。
執筆時点では明示的にすべてオンデマンドインスタンスを使うような設定にしていない限り、デフォルトでスポットインスタンスを使うような設定になっています。
非常に便利ではあるもののメリット・デメリットもあるかとは思いましたので、私自身の実体験も交えながら今回 Tips として残しておきます。

# 前提条件
本記事では Databricks on AWS 前提で話していますが、他クラウドでも考え方はそこまで変わらないかと思います。

# スポットインスタンスとは
スポットインスタンスは AWS クラウドのなかで、使われていない余ったリソースのことを借りる仕組みのことです。
オンデマンドのインスタンスよりも大幅に安い価格で利用可能になることがメリットにはなりますが、インスタンスの需要が高まると突如リソースが回収されて使えなくなることがあります。
そのため、途中で止まっても問題のないデータ処理やバッチ作業、検証用のアプリケーションに向いています。コストを抑えたいときや一時的な計算作業に便利な選択肢です。

# 実際に体験したこと
Databricks の Job や Delta live tables を活用して、ETLパイプラインを定期的に稼働させていました。
1回あたりの処理時間は通常約30分程度ではありますが、時々処理完了に倍近くの1時間かかったりすることがありました。
特にエラーが起きるわけでもなく、ソースコードなどその他の設定も何も変えておらず、処理するデータ量も毎回大きく変動するわけではないため時々起きるこの現象に不思議に思っていました。
ある時クラスターの Event log をチェックすると、倍近く処理時間がかかっている実行に対してのみスポットインスタンスが落ちていることに気づきます。
試しにスポットインスタンスを利用せず、パイプラインをすべてオンデマンドインスタンスを利用して実行するようにしたら処理時間は安定しました。

# 考察
もしDatabricks上で実行中のパイプラインでスポットインスタンスが途中に落ちた場合、欠けたワーカーノードの復旧と、再実行も自動的に行われてその分処理時間がのびてしまうのではと考えられます。

そのため、以下のような場合だとスポットインスタンスを控えてオンデマンドインスタンスを利用した方がよさそうです。

- 大規模なパイプライン
- 許容可能な処理時間がシビアに決められている
- 中断率の高いインスタンスタイプを使っている
    - [こちら](https://aws.amazon.com/jp/ec2/spot/instance-advisor/)で中断率は確認可能

インスタンス料金を安くすませるためにスポットインスタンスを使っているにも関わらず、処理時間が倍になりその分従量課金される金額が大きくなってしまえば本末転倒になりますね。。
逆に上記で当てはまれないような、一時的な作業などにはスポットインスタンスが向いているかと思います。

# まとめ
Databricks ではクラスターの復旧や、パイプラインの再実行等も色々とよしなに自動的に行ってくれるので非常に便利ではありますが、何か問題があった際に遅れないようにこういった具体的な例もひとつ知っておくのもいいかと思います。
Databricks では[システムテーブル](https://docs.databricks.com/ja/admin/system-tables/index.html)に蓄積されるログ等も豊富なので、それらとアラート機能を活用して問題を検知していく仕組みもいいかと思います。
RustのVim設定周りの備忘録

## はじめに
こんにちは！ITスクールRareTECHにてCS（Customer Support）を担当している池村です。
今回の記事はRustのVimプラグインについてです。

Vimmerにしか役に立たない気がしますが、備忘録として残しておきます。
ただ私はnvimを使っているので、vimrcは使わず、init.vimに設定を記述していってます。

## rust.vim
https://github.com/rust-lang/rust.vim

まずはフォーマットの修正を自動で行ってほしいので、こちらをインストールしていきます。Rustの公式が出しているプラグインのようですね。設定次第で、自動保存時に勝手にフォーマットを整えてくれるので便利です。

```Bash:init.vimの書き方
all plug#begin()
Plug 'rust-lang/rust.vim'
call plug#end()
```

:::note info
私はvim-plugを使っていますが、プラグインマネージャーによってはインストール方法など違ってくるのでご注意ください。
:::

```Bash:自動フォーマットの設定
let g:rustfmt_autosave = 1
```
これで保存時に勝手にフォーマットを整えてくれます。

:::note warn
Vimにはvim-autoformatというプラグインもあり、rustfmtがPCに入っているのであればvim-autoformatでもOKです。このプラグインの場合、多言語などもまとめてフォーマットしてくれるので便利です。

ただ、Rustに特化したい場合はシンプルな設定で済むのでrust.vimの方がいいと思います。
:::



## coc.nvim

https://github.com/neoclide/coc.nvim

こちらのプラグインはコードの補完とか定義ジャンプなどの機能を提供してくれるプラグインですね。Language Server Protcol、通称LSPでリクエストに応じたレスポンスを返してくれます。エディタを通して便利な機能を提供してくれます。

これを使ってRust（Rust以外も）のコードを補完したり、関数ジャンプ等できるようにしていきます。

```Bash:init.vimの書き方
all plug#begin()
Plug 'rust-lang/rust.vim'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
call plug#end()
```
`:PlugInstall`でインストールしていきます。

ただ、このプラグインを入れただけではRustのためのコード補完などはしてくれません。
Rust用のLanguage Serverを入れる必要があります。
シェル上で以下のコマンドを実行します。
```Bash:書き方
rustup component add rust-analyzer
```

このrust-analyzerがLanguage Serverであり、お使いのエディタと連携することで補完が可能になります。

次にVimを開いて、以下を叩きCocの設定を開きます。
```Bash:Vim上で
:CocConfig
```
Configファイルが開かれるので、そこに以下の記述を追記します。
```Config:書き方
{
  "languageserver": {
    "rust-analyzer": {
      "command": "rust-analyzer",
      "filetypes": ["rust"],
      "rootPatterns": ["Cargo.toml", "rust-project.json"]
    }
  }
}
```
これで補完できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/3a89e7ad-12d8-758d-2fe7-86a9fe4fffcb.png)


## おわりに
割とこれだけでRustを書く環境は整っている感じでした。あとは`telescope.nvim`とかあればファイルの移動や文字列検索なども問題ないし、お好きにファイラーなども追加してもいいでしょう。
telescope.nvimはこちら。

https://github.com/nvim-telescope/telescope.nvim

あと私はこのファイラー使ってます。

https://github.com/lambdalisue/vim-fern

いつか自分のVimの設定を全て公開する記事も書いていこうと思います。
エディタは宗教戦争なので、無理にVimを使う必要はないと思っています。自分が使っているのは、憧れのエンジニアの方が使っていて、しかも爆速だったのを見て自分もそうなりたい！となったからです。

まだまだVimmerとしてはひよっこですが、どんどん使い込んでいきたいですね。Vimmerを目指す方、一緒に頑張りましょう！
![97c3bdee-3df6-4d05-a799-0d51887b6f03_720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/fac4c3c9-c7a1-41b7-6571-7ad65ff56347.png)


## 余談
これを書いている時が2024年の年末ということで、そろそろ何をして年末時間を潰すか考えないとですね。例年友人宅で豪華な食事を用意して忘年会->そのまま年明けという流れですが、家族が近くにいない人はどんな年越ししているんでしょう？気になります。
Linuxコマンド: seq

# Linuxコマンド: `seq`

`seq` コマンドは、指定した範囲の数値を生成するために使用されるLinuxの便利なツールです。このコマンドは、簡単な連続番号リストを作成したり、スクリプトでループ処理を行う際に役立ちます。

---

## 基本構文

```bash
seq [オプション]... 最終値
seq [オプション]... 開始値 最終値
seq [オプション]... 開始値 増分 最終値
```

- **開始値**: 数値の生成を開始する値（省略可能、デフォルトは`1`）。
- **増分**: 各ステップで加算する値（省略可能、デフォルトは`1`）。
- **最終値**: 数値の生成を終了する値。

---

## 使用例

### 1. 1から10までの数値を生成

```bash
seq 10
```
**出力:**
```
1
2
3
4
5
6
7
8
9
10
```

### 2. 開始値と終了値を指定

```bash
seq 3 7
```
**出力:**
```
3
4
5
6
7
```

### 3. 増分を指定

```bash
seq 1 2 9
```
**出力:**
```
1
3
5
7
9
```

### 4. 減少する数列を生成

```bash
seq 10 -2 2
```
**出力:**
```
10
8
6
4
2
```

---

## オプション

### `-f` または `--format`

数値のフォーマットを指定できます。例えば、小数点を含むフォーマットやゼロパディングが可能です。

#### 使用例: 小数点付き
```bash
seq -f "%.2f" 1 0.5 3
```
**出力:**
```
1.00
1.50
2.00
2.50
3.00
```

#### 使用例: ゼロパディング
```bash
seq -f "%03g" 1 5
```
**出力:**
```
001
002
003
004
005
```

### `-s` または `--separator`

区切り文字を指定します（デフォルトは改行）。

#### 使用例: コンマ区切り
```bash
seq -s "," 1 5
```
**出力:**
```
1,2,3,4,5
```

### `-w` または `--equal-width`

すべての数値を同じ幅に揃えます（ゼロパディングを適用）。

#### 使用例
```bash
seq -w 1 10
```
**出力:**
```
01
02
03
04
05
06
07
08
09
10
```

---

## 応用例

### スクリプトでのループ処理

```bash
for i in $(seq 1 5); do
    echo "Processing item $i"
done
```
**出力:**
```
Processing item 1
Processing item 2
Processing item 3
Processing item 4
Processing item 5
```

### 数列をファイルに出力

```bash
seq 1 100 > numbers.txt
```

### 複雑な数列の生成

#### 負の増分を使用
```bash
seq 5 -1 -5
```
**出力:**
```
5
4
3
2
1
0
-1
-2
-3
-4
-5
```

#### 小数値の生成
```bash
seq 0 0.1 0.5
```
**出力:**
```
0.0
0.1
0.2
0.3
0.4
0.5
```

---

## よくある質問

### Q1. `seq`で生成した数値をカンマ区切りで保存するには？

```bash
seq -s "," 1 10 > numbers.csv
```

### Q2. 小数点を含む減少数列を作成できますか？

```bash
seq 1.0 -0.2 0.0
```

---

## まとめ

`seq` コマンドはシンプルながらも非常に柔軟で、多くの場面で便利に活用できます。数値のリストが必要な場合や、簡単なスクリプトの作成時にぜひ利用してみてください！
Simulink モデルを以前のバーションに変換する方法

　たまに使用するこの機能．すぐに忘れてしまうので，忘備録として投稿します．

　MATLAB の M ファイルはテキストなので，古いバージョンで開くことがでできます．それに対して，Simulink モデルを古いバージョンで開くためには，作成したバージョン以降で Simulink モデルを開き，以下のように「以前のバージョンにエクスポート」という作業を行う必要があります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/e683463c-b018-0c21-65fd-7d5c8f992f4f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/485c032e-6a95-7e64-2fa7-24b3b5820e44.png)

変更したい Simulink モデルがたくさんあったり，複数のバージョンに変換したいような場合，いちいち，マウスでこのような作業をするのはめっちゃ面倒．

　というわけで，ここでは，コマンドベースで Simulink モデルを以前のバーションに変換する方法を説明します（需要は少ないでしょうが）．

　カレントディレクトリを

* $\verb+D:\Advent_Calendar_2024+$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/da22bc36-9854-3788-b1ed-88348d0faed3.png)

とし，

* $\verb+D:\Advent_Calendar_2024\R2024b\hoge.slx+$（以前のバージョンで使用できるように変換）
* $\verb+D:\Advent_Calendar_2024\R2024b\design.m+$（単なるコピー）

を以前のバージョン用に変換します．そのために，スクリプト M ファイル 

```matlab:$\verb+trans_ver_simulink.m+$ 
mkdir R2018a
mkdir R2022a
mkdir R2023a
mkdir R2024a

open_system('R2024b/hoge.slx');
Simulink.exportToVersion('hoge','R2018a/hoge_R2018a.slx','R2018a')
Simulink.exportToVersion('hoge','R2022a/hoge_R2022a.slx','R2022a')
Simulink.exportToVersion('hoge','R2023a/hoge_R2023a.slx','R2023a')
Simulink.exportToVersion('hoge','R2024a/hoge_R2024a.slx','R2024a')
close_system('R2024b/hoge.slx');

copyfile('R2024b/design.m','R2018a/design.m');
copyfile('R2024b/design.m','R2022a/design.m');
copyfile('R2024b/design.m','R2023a/design.m');
copyfile('R2024b/design.m','R2024a/design.m');
```

を実行します．その結果，

```matlab:trans_ver_simulink.m の実行結果
>> trans_ver_simulink
エクスポートに成功しました: Simulink R2018a で使用するために 'D:\Advent_Calendar_2024\R2018a\hoge_R2018a.slx' が作成されました。
ans =
    'D:\Advent_Calendar_2024\R2018a\hoge_R2018a.slx'
エクスポートに成功しました: Simulink R2022a で使用するために 'D:\Advent_Calendar_2024\R2022a\hoge_R2022a.slx' が作成されました。
ans =
    'D:\Advent_Calendar_2024\R2022a\hoge_R2022a.slx'
エクスポートに成功しました: Simulink R2023a で使用するために 'D:\Advent_Calendar_2024\R2023a\hoge_R2023a.slx' が作成されました。
ans =
    'D:\Advent_Calendar_2024\R2023a\hoge_R2023a.slx'
エクスポートに成功しました: Simulink R2024a で使用するために 'D:\Advent_Calendar_2024\R2024a\hoge_R2024a.slx' が作成されました。
ans =
    'D:\Advent_Calendar_2024\R2024a\hoge_R2024a.slx'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/aeffd651-fa64-26ce-5c64-93b1f3434c0d.png)

という結果が得られます．

　古いバージョン R2018a 用に変換された Simulink モデルを実行すると，正常に動作することが確認できます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/456eb2b7-b47f-e3c3-3798-ace28fe5f55f.png)

　以上，小ネタでした．