OmniAICreator/Qiita-1.07M huggingface dataset:
AI分野におけるリーダーボードとは

## AIリーダーボードとは

AIリーダーボードは、様々なAIモデルの性能を客観的に比較・評価するオンラインプラットフォームです。共通のテストデータを用いて、各モデルの性能を自動的に評価し、結果を一覧表示します。

## 重要な役割

1. **客観的評価**: 全てのモデルを同じ条件で評価し、開発者が自身のモデルの性能を正確に把握できます
2. **技術革新の促進**: 他のモデルとの比較を通じて改善点が明確になり、効果的な開発方向性を示します
3. **知見の共有**: 成功事例や技術的課題の共有により、AI開発コミュニティ全体の発展に貢献します

## 主要なリーダーボード

### 1. HELM（スタンフォード大学）
- 言語モデルの総合的評価
- 事実性、バイアス、有害性など多面的な検証
- 学術的・包括的な評価アプローチ

https://crfm.stanford.edu/helm/lite/latest/

### 2. Artificial Analysis
- 実用的観点からの分析
- 応答速度、コスト、品質の比較
- 企業導入向けの実践的な評価

https://artificialanalysis.ai/leaderboards/models

### 3. Nejumi LLMリーダーボード
- 日本語言語モデルに特化
- 日本語特有の言語現象や文化的文脈を評価
- 商用からオープンソースまで幅広く対象

https://wandb.ai/wandb-japan/llm-leaderboard3/reports/Nejumi-LLM-3--Vmlldzo3OTg2NjM2

## まとめ

AIリーダーボードは、モデル開発の重要な基盤として定着しています。HELMのような包括的な評価プラットフォーム、ArtificialAnalysisのような実用的な比較ツール、そしてNejumi LLMのような地域特化型の評価システムなど、それぞれが独自の特徴を持ち、異なるニーズに応えています。

---

最新の評価結果や詳細な分析については、各リーダーボードのウェブサイトを参照してください。
電源ボタンを押してからメモリマップまでメモ

メモ
1. 電源ボタンを押す
1. マザーボードの各種部位に電源が供給される
1. PSUがPowerGoodシグナルをマザーボードに送る
1. マザーボードがCPUを起動する
1. CPUがリセットベクタ（CPU設計段階で定まっているエントリポイントのアドレス）（メモリコントローラはハードウェアレベルでいくつかの領域を特定のデバイスに接続されるようマッピングしており、リセットベクタアドレスはその1つでフラッシュメモリに接続する）からUEFIが起動

if x86の場合
  1. x86の命令セットにはIN,OUTという命令がある。これにより、チップセット(I/Oポート)が使える。つまり、通常のメモリアクセス空間以外への命令を送れる。これを利用して、PCIeルートコンプレックスへアクセスでき、PCIeデバイスEnumerationができる。
elsif riscV, armの場合
  1. デバイスツリーに、メモリコントローラに設定するべき値が入っている。つまり、どの物理アドレスとどのPCIeデバイスのレジスタのどのアドレスを対応させる必要があるか。これのおかげで、CPUはPCIeデバイスへアクセスできる。BDFのうちBの情報しかデバイスツリーには入っていないので、DFが全体として何があるのかをEnumerationする。
end

1. 列挙と同時にPCIeデバイスのコンフィギュレーションを取得
1. UEFIがデバイスのBAR領域に0xFFFFFFFFを設定するリクエスト
1. デバイスが要求するメモリサイズが返却される(0xFFFFF000なら、0が3つなので0x1000bit=4KB)
1. UEFIがMMIO用の物理アドレスを決定する(まだMMIOは実現していない)
1. UEFIがMMIOを設定することにしたベースアドレスを各PCIeデバイスに返却(BARへの設定リクエスト)
1. ハードウェア的にアドレスデコーダはBARと同期しているので、今後はデバイスへのメモリアクセスがアドレスデコーダによってデバイスへルーティングされるようになる(ここからMMIO開始)

以降、MMIO経由でPCIeデバイスのレジスタとPCIeパケット通信

1. UEFIからカーネルに移譲
1. カーネルはBARがマップされたメモリを見て、状況を把握（MMUは低レイヤーすぎるためアクセスしずらい）（カーネルはPCIサブシステムを通じてMMIO領域にアクセス）

メモのメモ
PCIeルートコンプレックスの中にはPCIeホストコントローラと呼ばれる物理的な部品があり、PCIeデバイスEnumerationなどを行う。

デバイスツリーのデータの意味
ranges = <0x81000000 0 0x50000000 0x50000000 0 0x100000>;

PCIeベースアドレス: 0x50000000(第3)
ホストベースアドレス: 0x50000000(第4)
マップメモリサイズ: 0x100000(第6)(=16MB)

の静的なMMIOのためのメモリマップがUTFIプログラムの中に入っている。

ページテーブル
論理アドレスと物理アドレスの変換テーブル(RAMに保存)
MMUが利用

メモリマップ
（MMUが物理アドレスに変換した後、）物理アドレスを具体的なデバイスへ転送する際に利用(メモリコントローラのレジスタに保存）
メモリコントローラが利用
アドレスの変換は行わない

SATAコントローラやUSBコントローラ
SATAコントローラやUSBコントローラは、PCIeデバイス側に存在する。PCIe経由で送られてきたPCIeパケットにより設定されるレジスタをもつハードウェア。
PCIe拡張スロットにこれらコントローラを指すと、普段使うHDDやUSBが使えるようになる。
ノートPCなどでUSBスロットがあってUSBを指せして使えるのは、PCIeスロットにすでにUSBコントローラを差し込んでいるから

知ったこと
メモリコントローラの存在と役割
x86のIN,OUT命令の存在と、RiscVやarmにそれらはないこと
SATAコントローラなどはPCIeデバイスとして、CPUから見てPCIeルートコンプレックスの反対側にある
PCIeパケットのこと
PCIeポートとUSBポート違い
DOP合格体験記

# はじめに
DOPを6月に受験して合格したので、だいぶ期間は空きましたが体験記を書きました。
今後DOPを受験する予定のある方の参考になれば幸いです。

※SAA・DVA・SOAの記録まとめは以下からご覧ください！

https://qiita.com/hoshi7_n/items/bed0c94fc92d23a9c5c7

https://qiita.com/hoshi7_n/items/afb3fce717867be0787e

# DOPの記録まとめ
以下DOPの記録をまとめたものになります。

  - 結果：**798点**(750点合格)
  - 勉強時間：**約50時間**
  - 勉強開始から本番までの日数：**28日**
  - 解いた問題数：**約800問**(重複あり)
  - 勉強方法：[公式問題集](https://explore.skillbuilder.aws/learn/course/external/view/elearning/14541/aws-certified-devops-engineer-professional-official-practice-question-set-dop-c02-japanese) / 実務でのハンズオン / CloudLisence / YouTube / Udemy
  - かかったお金(受験費用8250円除く)：**5000円**
  - 試験終了から結果が出るまでの時間：**1時間20分**

今回はプロ資格で難易度が高かったため、問題を解いてわからないサービスがあれば復習するということを徹底しました。また[YouTube](https://youtu.be/4-BKclyndOg?feature=shared)も隙間時間に見てインプットしていました。

# 当日の過ごし方

7:30 追い込み勉強スタート
10:00 朝食
13:30 追い込み勉強終了
14:30 コーヒー、ラムネ摂取(&お手洗い)
14:45 試験開始
18:00 試験終了

最後の最後まで粘りたかったので、午前中は丸々勉強時間に費やしました。
また、試験は3時間ほどあるため、眠くならないようにご飯の時間を気をつけました。(この日は昼食を食べる時間がなくなってしまったので、参考にはならないかもですが、試験の2〜3時間前まで！など調整しておくことをおすすめします)
試験直前はコーヒーとラムネを摂取しました。そのおかげもあって3時間集中力が切れることなく、試験に臨むことができました。
また、試験時間が長いため、試験直前にお手洗いを済ませておきました。


# おわりに
3時間の試験は、過去の試験よりも集中力を持たせるのが大変ということもあって、今までの試験の勉強方法に加え、どうすれば自分が本番にコンディションよく解けるかを事前に考えていたことも合格に繋がったのかなと思いました。
後日談ですが、DOPをとった後にAWS SummitのGameDayに参加したらボコボコにされたので、実務で使えるよう実践力を高めていきたいと思います。
ちなみにボコボコにされた体験談はこちらから読めます。（笑）

https://qiita.com/hoshi7_n/items/ee798772bcbc461c2a9f

# 追記
私が当時使用していた問題集のCloudLicenceは、下記のような噂もあるようなので、使用されている方がいらっしゃれば、控えるのがよさそうです。

https://nokonokonetwork.com/certificate/aws/dubious-reputation_aws_koiwa_techstock.html
vagrant 2.4.2-1 にアップグレードしたら動かない！

# 問題
`vagrant` の `plugin` が使えなくなった
```bash
$ vagrant up
Bringing machine 'local' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:

Vagrant:
* Unknown configuration section 'hostmanager'.
```

`hostmanager` もインストールできない
```bash
$ vagrant plugin install vagrant-hostmanager
Installing the 'vagrant-hostmanager' plugin. This can take a few minutes...
Vagrant failed to properly resolve required dependencies. These
errors can commonly be caused by misconfigured plugin installations
or transient network issues. The reported error is:

conflicting dependencies logger (= 1.6.0) and logger (= 1.6.1)
  Activated logger-1.6.1
  which does not match conflicting dependency (= 1.6.0)

  Conflicting dependency chains:
    logger (= 1.6.1), 1.6.1 activated

  versus:
    logger (= 1.6.0)

  Gems matching logger (= 1.6.0):
    logger-1.6.0
```

同じ人がかなり多くいるっぽい

https://github.com/hashicorp/vagrant/issues/13534

https://github.com/hashicorp/vagrant/issues/13527

# 一旦解決策
このバージョン (`2.4.2-1`) は壊れているので、一個前のバージョンをインストールし直す

```bash
# (check versions)
apt list -a vagrant
# 一覧表示... 完了
# vagrant/jammy,now 2.4.2-1 amd64 [インストール済み]
# vagrant/jammy 2.4.1-1 amd64
# vagrant/jammy 2.4.0-1 amd64
# vagrant/jammy 2.3.7-1 amd64
# vagrant/jammy 2.3.6-1 amd64
# ... (以下略)

# 一個前をインストールする
sudo apt install vagrant=2.4.1-1

# hostmanager を再インストール
vagrant plugin install vagrant-hostmanager
```

最新バージョンが壊れているっぽいので、一個前に戻すことで解決。早く直ることを祈る。
SeamlessTravelでLevel遷移時にデータ受け渡し方法


SeamlessTravelでLevel遷移時にデータを渡す

# 遷移前のPlayerStateにて
* EventCopyPropetiesが呼ばれる
    * 引数：NewPlayerState　これが新しいPlayerState
    * 渡されたときにいろいろデータを処理しようとしてもまだPawnなどが作成されていないので工夫が必要。

# 注意
配列などのデータはメモリ解放されてしまうのでしっかりとコピーを行うこと
Nginx Proxy Manager

ブラウザからリバースプロキシの設定が可能。

## 参考

https://nginxproxymanager.com/guide/


## 設定

* docker-compose.yml

```yaml
version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
```

```sh
docker-compose up -d
```

* http://127.0.0.1:81

```
Email:    admin@example.com
Password: changeme
```


## 以下が生成される

* data/nginx/proxy_host/1.conf 

http://dev1.local にアクセスしたら http://192.168.10.5 を表示する例

```nginx
# ------------------------------------------------------------
# dev1.local
# ------------------------------------------------------------

map $scheme $hsts_header {
    https   "max-age=63072000; preload";
}

server {
  set $forward_scheme http;
  set $server         "192.168.10.5";
  set $port           80;

  listen 80;
  listen [::]:80;


  server_name dev1.local;

  access_log /data/logs/proxy-host-1_access.log proxy;
  error_log /data/logs/proxy-host-1_error.log warn;

  location / {
    # Proxy!
    include conf.d/include/proxy.conf;
  }

  # Custom
  include /data/nginx/custom/server_proxy[.]conf;
```

* /etc/nginx/conf.d/include/proxy.conf

```nginx
add_header       X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto  $scheme;
proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP          $remote_addr;
proxy_pass       $forward_scheme://$server:$port$request_uri;
```
sqlcでトランザクションのロールバックエラーを適切に処理する方法

## 背景
sqlcでトランザクションを使うことについて、公式ドキュメントを見ていると、少し気になるところがあったので、自分なりにコードを改善してみました。

https://docs.sqlc.dev/en/stable/howto/transactions.html

## 公式のコード

```go
func bumpCounter(ctx context.Context, db *sql.DB, queries *tutorial.Queries, id int32) error {
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()
	qtx := queries.WithTx(tx)
	r, err := qtx.GetRecord(ctx, id)
	if err != nil {
		return err
	}
	if err := qtx.UpdateRecord(ctx, tutorial.UpdateRecordParams{
		ID:      r.ID,
		Counter: r.Counter + 1,
	}); err != nil {
		return err
	}
	return tx.Commit()
}
```

## `tx.Rollback()`のエラーをキャッチしたい

```diff_go
- func bumpCounter(ctx context.Context, db *sql.DB, queries *tutorial.Queries, id int32) error {
+ func bumpCounter(ctx context.Context, db *sql.DB, queries *tutorial.Queries, id int32) (err error) {
	tx, err := db.Begin()
	if err != nil {
		return err
	}
-	defer tx.Rollback()
+	defer func() {
+		err = errors.Join(err, tx.Rollback())
+	}()
	qtx := queries.WithTx(tx)
	r, err := qtx.GetRecord(ctx, id)
	if err != nil {
		return err
	}
	if err := qtx.UpdateRecord(ctx, tutorial.UpdateRecordParams{
		ID:      r.ID,
		Counter: r.Counter + 1,
	}); err != nil {
		return err
	}
	return tx.Commit()
}
```
`tx.Rollback()`のエラーをキャッチするため、名前付き戻り値を採用し、`erros.Join()`を使って、`tx.Rollback()`のエラーを返すようにしました。
しかしこのままでは、正常にコミットされても、`tx.Rollback()`が実行されてしまい、以下のようなエラーが発生します。
```sh
sql: transaction has already been committed or rolled back
```

## DB操作が失敗した時にのみ、`tx.Rollback()`を実行する

```diff_go
func bumpCounter(ctx context.Context, db *sql.DB, queries *tutorial.Queries, id int32) (err error) {
	tx, err := db.Begin()
	if err != nil {
		return err
	}
-	defer func() {
-		err = errors.Join(err, tx.Rollback())
-	}()
	qtx := queries.WithTx(tx)
	r, err := qtx.GetRecord(ctx, id)
	if err != nil {
-		return err
+		return errors.Join(err, tx.Rollback())
	}
	if err := qtx.UpdateRecord(ctx, tutorial.UpdateRecordParams{
		ID:      r.ID,
		Counter: r.Counter + 1,
	}); err != nil {
-		return err
+		return errors.Join(err, tx.Rollback())
	}
	return tx.Commit()
}
```

上記のようにすることで、`tx.Rollback()`が実行され、ロールバック時のエラーもキャッチできます。

## 最後に
> 多くのデータベースシステムでは、既にコミットされたトランザクションに対して `Rollback()` を呼び出しても、エラーは発生せず、単に無視されます。

とのことなので、別に気にしなくても良いのかもしれません。
仮想環境を用いたCellposeの実行

Cellposeは、機械学習を用いて細胞の顕微鏡画像から細胞をセグメンテーションするためのツールである。

今回は、Cellposeのインストールから実行環境の立ち上げまで自分の備忘録用にまとめる。

なお、基本的には以下のレポジトリのREADME（特に、[オプション 2: Python の venv を使用したインストール手順](https://github.com/MouseLand/cellpose#option-2-installation-instructions-with-pythons-venv)）に書かれていることをそのまま実行している。

https://github.com/MouseLand/cellpose

また、GPU（GeForceを使用）で学習するため、cudaは元からインストールされている。

環境：windows10, python3.12
pythonは、事前に3.8以降をインストールしておく必要あり。


# インストール
以下、ターミナルで実行。Mac, Linuxだとコマンドが若干異なるので注意。

1. 仮想環境を立ち上げるディレクトリに移動し、仮想環境を立ち上げる
```terminal
python3.12 -m venv .venv/Cellpose
```
　
2\. 仮想環境のアクティベート
```terminal
.\.venv\Cellpose\Scripts\activate
```
アクティベートの際、「このシステムではスクリプトの実行が無効になっているため、ファイル xxx .venv\Cellpose\Scripts\Activate.ps1 を読み込むことができません。」というエラーが出てきた。 以下を参考に解決。
　
参考：**VSCode insiders venv activate時の「このシステムではスクリプトの実行が無効になっているため～」 エラーの解決**

https://qiita.com/startours777/items/2d35f2c6de12071a4c77

解決すると、仮想環境に移動される。

3\. 仮想環境にCellposeをインストール
```
(Cellpose)$ python -m pip install cellpose
```
GUIも一緒にインストール
```
(Cellpose)$ python -m pip install cellpose[gui]
```

4\. 実行確認
仮想環境で以下を実行するとcellposeが実行される。
```
(Cellpose)$ cellpose.exe
```
　

# 参考
[オプション 2: Python の venv を使用したインストール手順](https://github.com/MouseLand/cellpose#option-2-installation-instructions-with-pythons-venv)

[VSCode insiders venv activate時の「このシステムではスクリプトの実行が無効になっているため～」 エラーの解決](https://qiita.com/startours777/items/2d35f2c6de12071a4c77)
Miniconda 24.9.2-0 におけるchannelsの設定

## はじめに
Anacondaの有償化に伴って`defaults`チャンネルを使用せず，`conda-forge`を使用するよう気を付けている．condaで`conda-forge`を使用するよう設定変更する際，[この記事](https://qiita.com/kimisyo/items/986802ea52974b92df27)を参考にしていたが，Miniconda 24.9.2-0では同様の手順で変更できなさそう．本記事は，バージョン24.9.2-0でのchannelsの設定方法の備忘録である．

## `defaults`チャンネルの削除ができない
このバージョンのMinicondaで，特に設定はいじらずに適当な環境を作り，channels関連の挙動を見てみた．
- `conda install`するときは`defaults`チャンネルが表示される
- `conda config --show channels`では`defaults`が表示されない．代わりに`https://repo.anaconda.com/pkgs/main`と`https://repo.anaconda.com/pkgs/r`が表示される（おそらくこれが`defaults`に対応）．
- `conda config --remove channels defaults`を実行すると，その値はコンフィグにないと怒られる
- `conda config --remove channels`で2つのURLを削除し，`conda config --add conda-forge`した後，`conda install`を実行しても`defaults`が使用されてしまう

`conda install`を実行するたびに`--override-channels`をつけるのは面倒なので，どうにかしたい．

## 手順
[バージョン24.9.2のリリースノート](https://docs.anaconda.com/miniconda/miniconda-release-notes/#miniconda-24-9-2-0-oct-23-2024)では，channelsの設定について `A .condarc file is written into the installation directory to set the channel to Anaconda’s defaults channels.` と書いてある．つまり，Minicondaがインストールされたディレクトリにある`.condarc`を書き換えてchannelsを設定するようになったらしい．設定内容については[ここ](https://docs.conda.io/projects/conda/en/latest/user-guide/configuration/settings.html#allowlist-channels-and-denylist-channels-allow-or-deny-specific-channels)に詳しく乗っている．

1. [Minicondaをインストール](https://docs.anaconda.com/miniconda/)．今回は`~/miniconda3`にインストールすることを想定．

1. `~/miniconda3/.condarc`には
    ```yaml
    channels:
      - https://repo.anaconda.com/pkgs/main
      - https://repo.anaconda.com/pkgs/r
    ```
    と書いてあるので，以下のように変更．
    ```yaml
    channels:
      - conda-forge
    ```

1. 適当な仮想環境を新たに作る
    ```bash
    $ conda create -n test
    Channels:
     - conda-forge
    ...
    ```

1. channelsが`conda-forge`のみになっていることを確認
    ```bash
    $ conda activate test
    $ conda config --show channels
    channels:
      - conda-forge
    $ conda install numpy
    Channels:
     - conda-forge
    ...
    ```

`.condarc`の変更内容は，`base`などの既存環境には適用されず，変更後に新規作成した仮想環境にのみ適用される模様．

## おわりに
`conda config`で`defaults`エイリアスが使えなくなったのがかなり面倒．やはりcondaは避けるべきなのか...？
プロジェクト内のコードをロードした sbt console を起動する方法

## 方法１

sbtコンソール上で

```sh
sbt> project my-project
sbt> console
```
## 方法２

シェル上で、

```sh
$ sbt "project my-project" console
```

## その他の方法

プロジェクト内に scala script を置いても良さそう。
プロジェクト内のモジュールをインポートして使うことができるのを確認した。
Lambdaからシークレットマネージャーにある認証情報を取得

# ①SecretsManagerでシークレットを作成
RDSなどAWSリソースのシークレット情報を保存する場合はそのリソースを選択しますが、今回は軽い動作確認するだけなので「その他」を選択します。

保存したいシークレット情報を「key-value」で入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/c66410ba-bde9-5ac4-5211-1b7ab2de12fd.png)

シークレット名をtestにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/ced33876-3cea-66be-2713-639f7d4bf6f1.png)

動作確認するだけなので、今回はローテーションをしません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/bc5c255f-7e83-cbb0-4a9c-8e5744d117b3.png)

設定のレビュー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/688e1dab-2dd2-26ff-018a-f1fbb7480724.png)

レビュー画面の一番下にあるサンプルコードをコピーしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/7cb65382-7172-ba71-18b0-dab5da98265b.png)

これで設定完了

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/96448666-1f2e-78c5-e16d-71cbd5301f5a.png)

# ②IAMの設定

IAMポリシーを作ります。
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:your-region:your-account-id:secret:your-secret-id"
        }
    ]
}

```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/7539758c-2209-b382-72cb-032f5502256a.png)

このポリシーをLambda用のロールに付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/17004c45-d6dc-f94c-3213-646fbf6b7664.png)

# ③Lambdaを作成(Python)
関数作成時に、②で作られたロールを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/09670d6f-0c0a-dc0f-82b3-8c76295895a3.png)

ソース例

```
import boto3
import json
from botocore.exceptions import ClientError

def get_secret():
    secret_name = "test"
    region_name = "ap-northeast-1"

    # Secrets Managerクライアントの作成
    client = boto3.client('secretsmanager', region_name=region_name)

    try:
        # シークレットを取得
        response = client.get_secret_value(SecretId=secret_name)

        print(response)

        # シークレットが文字列の場合
        if 'SecretString' in response:
            secret = response['SecretString']
        else:
            # バイナリデータの場合
            secret = response['SecretBinary']
            # 必要に応じてデコード処理を行う
        return json.loads(secret)
    
    except ClientError as e:
        # エラーハンドリング
        print(f"Error retrieving secret: {e}")
        return None

def lambda_handler(event, context):
    secret = get_secret()
    if secret:
        # 認証情報を使用する処理
        print("Secret retrieved successfully")
        print(secret)
    else:
        print("Failed to retrieve secret")
```

Lambda側でテストを押すと、Secrect Managerからシークレット情報を取れました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/4978f8c4-0e79-ceaa-ba87-677f78db04ac.png)
IBM i 情報掲載一覧表

IBM TechXchange Japan Power User Communityの投稿にまとめました。
情報が見つからないとお声をちょくちょくいただくので、ぜひ参考になさってください。

[IBM i 情報掲載一覧表](https://community.ibm.com/community/user/power/blogs/sakura-koga/2024/05/26/ibm-i)



IBM TechXchange Japan Power User Communityにもぜひ登録してください、
イベント情報等も発信しています。
【Windows】Pythonがとりあえず動けばいい人向けの環境構築

# Pythonをダウンロードする

・自分の使っているユーザー名がすべてローマ字であることを確認する

・https://www.python.org/downloads/windows/　
  上記のサイトに飛んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/403f0a28-ccb6-f0ab-b123-e82aad9a40e0.png)
Stable Releasesの3.10以上のWindows installerをダウンロードする
64bitか32bitは各自のPCのCPUを確認してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/8eabd310-1736-ebba-abd9-f7352f8de04a.png)
インストーラーを起動したら上記のような画面が出る
赤のまるで囲った部分にチェックを入れ、そのまま指示に従ってインストールを進める

https://www.javadrive.jp/vscode/install/index1.html

VScodeのインストールは上記を参照

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/5b3b6d9f-e317-09ed-7638-fb683084d0a4.png)
インストールが終わったらVScodeを起動してPython用の拡張機能をインストールする

https://scrapbox.io/PythonOsaka/Visual_Studio_Code_%E3%81%AE_Python_%E7%94%A8%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

拡張機能のインストールは上記を参照


VScodeでファイル→新しいファイルを選択して"test.py"を作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/1322cd32-7dea-2a82-9195-a8e8ac1a470b.png)
右下にPythonのバージョンが表示されずによくわからないマークが出ている場合はそこをクリックしてインストールしたPythonのバージョンを選択する。


```python
print("Hello World!")
```

をtest.pyに入力して、右上の実行ボタンまたはCtrl + Alt + Nを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/51871e75-f15e-165c-72de-2e9aff06b9ce.png)

実行される
Wordで編集中のSharePoint上のファイルに対応するローカルのOneDriveフォルダを開く

SharePoint上のファイルをWordで編集していると自動保存等が効いたり嬉しいのですが、いざメールに添付したり何したりするためにローカルのフォルダを開こうとするとめんどくさいです。
AppleScriptで作ります。

```applescript
set SharePoint to "https://***.sharepoint.com/sites/msteams_***/Shared%20Documents/"
set LocalPath to "/Users/***/Library/CloudStorage/OneDrive-共有ライブラリ-**/** ** - ドキュメント/"

tell application "Microsoft Word"
	tell document of window 1
		set subpath to characters ((length of SharePoint) + 1) thru (length of (path as text)) of (path as text)
		tell application "Finder"
			open folder ((LocalPath & (subpath as text)) as POSIX file)
			activate
		end tell
	end tell
end tell

```

これをスクリプトフォルダに入れておけばメニューバーからさっと呼び出せるっちゅうわけよ。
# ToDo
- ファイルがSharePoint上かローカルか判定して、ローカルなら素直にローカルを開く
- ファイルがリモートな場合、リモートのどこかをいい感じに判定してローカルを開く。
とりあえず一番よく使うチームフォルダ決めうちで開くことにしてるけど、まぁ自分専用ツールならこんなもんで十分だったり。
# Javaのあれこれを調べたのものをAIで要約した記事

## Javaの歴史

- **1995年**: Sun MicrosystemsがJavaを開発。当初はインタラクティブテレビ向けに作られましたが、幅広いプラットフォームで使えることから、企業のソフトウェア開発にも利用されるようになりました。

- **1998年**: Javaのコミュニティ「Java Community Process (JCP)」が設立され、Javaの成長を支えるための組織的なサポートが開始されました。

- **2007年**: Javaがオープンソース化され、Sun Microsystemsがソースコードを公開。

- **2010年**: OracleがSun Microsystemsを買収し、Javaの管理を引き継ぎます。それ以降、OracleはJavaの商用サポートやアップデートの提供で中心的な役割を担っています。

- **2011年以降**: OracleはJava SEのオープンソース実装をリリースし、クラウドやセキュリティ対応といった企業ニーズに応える形でJavaが進化を続けています。

- **最近**: Javaはクラウドネイティブ技術やマイクロサービスに対応し、GraalVMといった新技術を導入することで、性能向上とリソース効率化が実現。コミュニティとOracleの協力で、Javaは今も改善が続けられています。

## Javaと新しい技術・フレームワーク

- **GraalVM**: Oracle Labsが開発したJavaのオープンソース仮想マシンで、起動が早く、リソースの効率が良いのが特徴。複数の言語（Ruby、R、Pythonなど）をJavaと一緒に実行できます。

- **クラウドネイティブ＆サーバーレス**: Javaは、クラウドネイティブな開発に対応。コンテナやマイクロサービス、サーバーレスといった技術と連携し、スケーラブルで柔軟なアーキテクチャ構築が可能です。

- **Java Management Service (JMS)**: Oracle CloudでJavaの資産を一元管理できるサービス。クラウド・オンプレミス環境でのセキュリティ管理にも役立ちます。

- **APIの拡充**: Javaは豊富なAPIを備えており、Foreign Linker API（Java 16）などの追加により、ネイティブライブラリとのアクセスが向上しました。

- **アジャイル開発とDevOps**: アジャイル開発やDevOpsとの相性も抜群。迅速な開発サイクルと継続的なデプロイがJavaで可能になっています。

## Javaの今後の展望

### エコシステムの拡充とコミュニティの発展
Javaは、Oracleやコミュニティの協力で多様なオープンソースプロジェクト（GraalVMやSpring Frameworkなど）を通じてさらに強化されています。新しいライブラリやフレームワークが登場し、エコシステムが拡充されています。

### 長期サポートとライフサイクル管理
JavaはLTS（長期サポート）を提供しており、新しいLTSリリースが2年ごとに発表されます。企業は安定したバージョンを長期間使いながら、バージョンアップもスムーズに行えます。

### 開発の多様化とJavaの地位
依然としてJavaは企業の主要な開発プラットフォームで、39%の開発者が利用中。他の言語が増える中でも、クラウドネイティブ開発やDX（デジタルトランスフォーメーション）推進でJavaが選ばれる傾向は変わりません。

### Javaのクラウドネイティブ対応
Javaはクラウド上での開発やデプロイにも効率的で、79%のJava開発者がクラウドネイティブアプリ開発で有効だと評価。Oracle Cloudと統合し、マルチクラウド対応も進んでいます。

### 新機能とリリースサイクル
Javaは6か月ごとのリリースサイクルで、仮想スレッドや暗号化強化などの新機能を追加。これにより、並行処理アプリの開発やセキュリティ強化がしやすくなっています。Oracleの継続的な投資により、Javaの機能とパフォーマンスは向上しています。

### 近代化されたアプリインフラの構築
Javaはリーダー企業で安定性と信頼性を重視した開発に役立ち、最新のKubernetes、サーバーレス技術、マルチクラスタ、ハイブリッドクラウドインフラとも適合します。

- **Kubernetes対応**: リーダー企業はKubernetesを使った開発を競合より2倍頻繁に行っています。
- **サーバーレス開発**: サーバーレス技術の採用率が95%高く、スケーラビリティと柔軟性が向上。
- **ハイブリッドクラウド**: 60%多くの企業がハイブリッドクラウド環境でアプリをデプロイ中。
devcontainer環境を既存のDocker compose環境に後付けしたい。

# devcontainerとは
devcontainerとはVS Codeの拡張機能の一種です。
ローカル環境を汚さず、VS Codeで扱う他の拡張機能やさまざまな設定を反映した「仮想環境」を作成でき、誰がどのデバイスで扱おうと、いつでも同じ環境を構築できる代物です。

# なぜ後付けしたいのか
flask adminlteを扱う際に、作成元がすでに構築したDocker Compose環境をdevcontainerで扱いたくなったため。

# 環境(ディレクトリ構成)
- flaskで扱うさまざまなフォルダたち
- docker-compose.yml
- Dockerfile

# .devcontainerフォルダを作成する
devcontainerの機能を扱う際にこのフォルダが参照されます。
正確にはフォルダ内に作成するdevcontainer.jsonファイルに書かれた内容によって作成される環境が決定します。

devcontainer.json
~~~json
{
    "dockerComposeFile": ["../docker-compose.yml", "docker-compose.yml"],
    "service": "元から存在したdocker-composeに記載のあるservice名",
    "workspaceFolder": "作業したいフォルダ"
}
~~~

ここで参照しているdocker-composeファイルが二つあることに気づいた方がいるかもしれません。
今回は既存のdocker-composeファイルに一切手を加えずに環境を作成しようとしているため、.devcontainer/内にもう一つのdocker-composeファイルを作成します。

docker-compose.yml
~~~yml
version: '3'

services:
    app: ←既存のdockercompose.ymlに記載のあるservice名
    command: sleep infinity
~~~

最終的な構成は以下の通りになります。
- .devcontainer
    - devcontainer.json
    - docker-compose.yml
- flaskで扱うさまざまなファイルたち
- docker-compose.yml
- Dockerfile

# 参考にさせていただいた記事
https://zenn.dev/shunjuio/articles/9cffc8d14c6684
「SREをはじめよう」を読んで得た学び

# はじめに
私は株式会社GENEROSITYのエンジニアです。
私自身SREについての知識はほぼゼロの状態です。
書籍「SREをはじめよう」を読み終え、学んだことをアウトプットのため記事にします。

:::note info
本記事でまとめた内容は私の理解に基づくため、解釈における相違や内容の誤りが生じる可能性がありますのでご容赦ください。
:::


# こんな人に読んでほしい
- SREになりたい
- SREになりたて
- システム運用をしている
- システムの信頼性を確保・向上させたい


# 「SREをはじめよう」はどんな本？
「個人がSREになるため」また「組織がSREを導入し、発展させるため」の指針をまとめた書籍です。
本書は以下の3部構成となっています。
- Ⅰ部：SRE入門
- Ⅱ部：個人がSREをはじめるには
- Ⅲ部：組織がSREをはじめるには

https://www.oreilly.co.jp/books/9784814400904/

# SREとは
「サイトリライアビリティエンジニア」と呼ばれる職種、あるいは「サイトリライアビリティエンジニアリング」という技能、活動のことです。
著者のDavidさんはSREとは以下であると述べています。
> サイトリライアビリティエンジニアリングは、組織がシステム、サービス、製品において適切なレベルの信頼性を持続的に達成できるよう支援することを目的とした工学分野である。


# 学び
本書に記載の内容をもとに、得られた学びを私なりの理解でまとめます。

## SREをきちんと理解するためには「信頼性」「適切」「持続的」の単語を理解する
### 信頼性
どれだけ高級な(優れた機能を持ち、大金を費やした)システムでも、顧客がそのシステムを使いたい時に動いていなければ損失を被る可能性がある。

### 適切
存先が100%信頼できるものではない可能性があるため、SREはシステムにおける適切な信頼性レベルを決定し、伝達し、それに向けて努力することを支援する。
体的には、サービスレベル指標(SLI) / サービスレベル目標(SLO)のようなプラクティスを行う。

### 持続的
運用を成功させるためには、持続可能である必要がある。

## SREの心構え
### 顧客重視の姿勢であれ
顧客が何をどのように受け止めるか、システムが顧客にどのように答えているのか を考える。
信頼性はコンポーネントの観点ではなく、顧客の観点から計測される。

### 信頼性とは共同作業である
信頼とはシステムに関わる同僚や顧客など様々な人たちとの間に成り立つ。

### 失敗から学ぶ
エラーは常にシステムの中に存在するものである。
信頼性を向上するためにはシステムを理解する必要があり、システムがどのような時に失敗するのかについて理解するためには、エラーを「表面化」する必要がある。

## SREの文化
信頼性を確保するためのSREの活動を文化として定着させ、これをモデル化することで組織(SREチームの外枠)を正しい方向(目標とする場所)へ導くことができる。
SREとして※トイル を排除するなどの活動をする→SREの活動を組織が幸せになるために必要な活動であると認識する→SREチーム以外のメンバーもSREの活動をするようになる→組織全体が正しい方向へ進み始める。
私は「SREを起点として組織全員がSRE活動を行う文化の定着が必要である」と理解しました。

:::note info
トイルとは
価値を生まないが運用において避けられない、繰り返し行われる手作業や、手間のかかるメンテナンス業務を指す
:::

## SREになるために
### コーディングの知識
以下の理由からコーディングの知識が必要となる。
(1)システムがどのように作られていて、それがどのような場合に故障する可能性があるかを理解するため
(2)システムの信頼性向上のため、コードレベルの変更を提案したり実行したりするため

### システムの基礎知識
より良いシステムを構築するために、基本的なシステムとその仕組み(OS、ネットワーク、プロトコルなど)を理解する。

## SREをどこから始めるか
信頼性を抱える組織がSREを開始するために、**Dickersonの信頼性の階層構造**が明確なマップとなる。
これは階層の一番下(1)から始めて、下の階層が強固になった時点で上(2~6)の階層に進むというもの。
各階層の概要を以下に示します。

| 階層 | 概要 | 内容 |
|:-:|:-|:-|
| 1　　 | 監視/オブザーバビリティ | 状況が良くなっているのか、それとも悪くなっているのかを監視する |
| 2　　 | インシデントレスポンス | 障害がどのように発生するのか、それをどのように対処するのかを明確化する |
| 3　　 | インシデント後のレビュー | 失敗から学び、次に活かす |
| 4　　 | テスト/リリース | 問題が本番環境へ到達する前に、その問題の発見を自動化する |
| 5　　 | キャパシティ/スケール | 変化や障害に適応するため事前に備える |
| 6　　 | 開発/UX | 信頼性の高いシステムをつくるために検討する |

:::note info
Dickersonの信頼性の階層構造のみでは十分でない
これがSREのすべてであるように見えるが、信頼性を構築するために必要な活動を独自の視点で見つけ、実施することが大切
:::

## SREを組織に組み込む
まずは実験的にSREの実践(SLI/SLOの定義、計測、またインシデント後のレビューなど)を試してみること。
SREを組織に統合するための適切なモデル(どのような規模で、どのような関わり方をするか)を見つける。また、それは良い結果が出るまで試行を繰り返す必要がある。
フィードバックループを構築し、改善活動を繰り返す。

:::note info
フィードバックループとは
システムやプロセスの出力を再び入力として戻し、結果を改善・調整する循環プロセス
:::

# さいごに
「SREをはじめよう」はSREとは何か、から個人〜組織へSREを普及するための考え方と知識を学ぶことができます。
今回私は「SREとは信頼性の改善・維持活動のきっかけを作り、活動を通して組織全体で同じ方向へ進むために改善を繰り返すことが重要である」と理解しました。
今後より多くのことを学んでまた読み返したいと思います。

本記事に記載した以外にもたくさんの学びがあると思いますので、ぜひ皆さんも読んでみてください。
ここまで読んでくださりありがとうございました！
RailsでURLのidのハッシュ化のやり方完全入門(初心者向け)

# ハッシュ化とは

ハッシュ化とは,ハッシュ化したい文字や数字をハッシュ関数という関数にかけるとハッシュ化された値がかえってくる.そのハッシュ化された値からは元の値を求めることはできないというものである.

# ハッシュ化するメリット
ハッシュ化された値からもとの値を求めることはできないため
セキュリティ対策に効果がある.URLのidはハッシュ化するべきであり,
**できていないととても危険!!!**

# やり方
# ①まずhashidsというパッケージをインストールする.
``Gemfile``にパッケージを記述する.
```
gem 'hashids'
```
上のコードを``Gemfile``に書いく.
次にターミナルでhashidsをインストールする.
```
bundle install
```
これでhashidsのインストールは完了である.

# ② ハッシュidの初期化
初期化をすることでセキュリティが向上する.
``application_controller.rb``にハッシュidを初期化するコードを書く.
``"your_salt"``には好きな文字列を入れる.これは**ソルト**であり,ソルトとはハッシュ化されたidに追加する文字列であり,追加することによりセキュリティ対策が向上する.後ろにハッシュ化した文字列の文字数を指定できる.今回は20文字にしている.
```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :initialize_hashids

  private

  def initialize_hashids
    @hashids = Hashids.new("your_salt",20)
  end
end

```
# ③最後にURLのidをハッシュ化する
``routes.rb``でidをハッシュ化する
params: :idをつけることでidをハッシュ化することができる.
```routes.rb
resources :users, param: :id do
```
このようにハッシュ化する

# ④ハッシュ化したidからもとのidに戻すには
``_controller.rb``でハッシュ化したidから元のidを求めるにはdecodeすることで求められる.

**やり方**
@hashids.decode関数の中にIDを入れて求める.
配列でかえってくるため,firstを用いて初めの値だけを受け取る.
@hashids.decode(prams[:ID]).first

**例**
```
def show
    item_id = @hashids.decode(params[:id]).first
    @item = Item.find_by(id: item_id)
end
```
# ⑤ViewsやControllerでidをハッシュ化する
**やり方**
@hashids.encode関数の中にIDを入れて求める.
@hashids.encode(ID)と書いてIDをencodeでハッシュ化する

**例**
``Views``の例
```
<%= link_to(item.title, item_path(@hashids.encode(item.id))) %>
```
``Controller``の例
```
redirect_to("/items/#{@hashids.encode(item_requested.id)}")
```
ROS2 Gazebo(Classic)地面の色の変え方

私の調べた限り情報がなかったため記録を残しておきます。

# 私の環境
Ubuntu 22.04
AMD Ryzen5 5625U
16Gb

## これに至った背景
大学の研究でGazeboを使用中、あるモデルと地面の色の相性がよろしくなく変更したかった....
自分で１からワールドを作るのもありだが、とあるモデルを参照しているためもとあるものを崩したくなかった

## 実際のやり方
### まず標準の色
標準の色はGrayとなっています。以下を打ち込んで確認します。

```
$ gazebo
```
![Screenshot from 2024-11-07 14-37-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052647/4570aaa7-d36c-c91e-3c2c-e442549890ff.png)

この地面はground_planeとして標準で勝手にmodelとして表示されていました。左上のModelsの中から確認できます。
![Screenshot from 2024-11-07 14-39-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052647/c18a3683-58c6-05f0-a776-14b3e6267743.png)

### やり方
実際にground_planeに関するファイルがどこにあるかを探したところ私の場合以下のパスにありました。

```
$ pwd
/usr/share/gazebo-11/models/ground_plane

$ ls
model.config  model.sdf
```

このmodel.sdfに書き込まれている内容を書き換えます。また変更できる色を確認します。35行目に書き込まれているパスのファイルに変更できる色が書き込まれていました。

```
<uri>file://media/materials/scripts/gazebo.material</uri>
```

わかりやすくファイルの場所を以下に記述しておきます。実際に開いてみてください。

```
$ pwd
/usr/share/gazebo-11/media/materials/scripts

$ vim gazebo.material
```

長ったらしいため省略しますが、下へスクロールしていくと material Gazebo/Gray とか material Gazebo/White など出てきます。これを用います。
先程のmodel.sdfをroot権限で書き換えます。好きなエディタを用いてください。

```
$ pwd
/usr/share/gazebo-11/models/ground_plane
$ sudo vim model.sdf
```
36行目のGrayとなっているところを変えます。今回は適当にYellowとしました。
```
35 | <uri>file://media/materials/scripts/gazebo.material</uri>
36 | <name>Gazebo/Yellow</name>
```
さぁ確認してみましょう。

![Screenshot from 2024-11-07 14-58-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052647/491ce52a-f002-435f-0cf3-67a2a2d929bd.png)

以上。
日記 11/7

## 日記 11/7

### 今日の進捗

opneposeのビルド済みバイナリをダウンロードした。

openposeは以下に
```
c:/opnepose
```
画像データなどは以下のディレクトリに保存
```
c:/workplace_opnepose
```

以下のコマンドでビルド済みバイナリを実行した．
```
.\bin\OpenPoseDemo.exe --image_dir C:\workplace_OpenPose\train\MOT16-09\img1
```

実行結果を画像で示す．

![スクリーンショット 2024-11-07 143600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928446/3d8e642f-58dd-e2d9-ab72-774424f88a01.png)

骨格情報を動画に上書きすることもできたが，動画の長さとfpsの設定がいまいちわからない．

### 明日やること

・骨格情報をファイルに出力
・ファイル形式の互換性を調べる
・3Dposebaselineの導入
いろんなコードを動かなくするサイト

どうもAtsu1209です。
今回はコード破壊ツールを作ります。(?)

# コード
```js
 function uglifyCode() {
            const x = document.getElementById('inputCode').value;
            let a = x.replace(/\s+/g, ' ');
            a = a.replace(/\/\*.*?\*\//g, '');
            a = a.replace(/\/\/.*(?=\n)/g, '');
            
            var result = "";
            for (let i = 0; i < a.length; i++) {
                if (i % 2 === 0) {
                    result += a[i].toUpperCase();
                } else {
                    result += a[i].toLowerCase();
                }
            }
            document.getElementById('outputCode').value = (function(n){return n;})(result);
        }
```
変数を`a`にしてちょっとだけクソコード要素入れておきました。

# 使ってみる
今回入力するコード
```js
function generateHTML() {
    const title = document.getElementById('title').value;
    const date = document.getElementById('date').value;
    const content = document.getElementById('content').value;
    
    const generatedHTML = generateBlogPage(title, date, content);
    
    document.getElementById('output').value = generatedHTML;
}
```
PCの中に転がってた何かしらのJSコード

```js:出力
FuNcTiOn gEnErAtEhTmL() { CoNsT TiTlE = DoCuMeNt.gEtElEmEnTbYiD('tItLe').vAlUe; CoNsT DaTe = dOcUmEnT.GeTeLeMeNtById('DaTe').vAlUe; CoNsT CoNtEnT = DoCuMeNt.gEtElEmEnTbYiD('cOnTeNt').vAlUe; CoNsT GeNeRaTeDhTmL = GeNeRaTeBlOgPaGe(tItLe, DaTe, CoNtEnT); DoCuMeNt.gEtElEmEnTbYiD('oUtPuT').VaLuE = GeNeRaTeDhTmL; }
```

もしかしたらGithubPagesで公開するかも
対照学習に入門してみる（理論編）

　お久しぶりです．ソリングです．東京工業大学大学院の情報工学系で機械学習の勉強をしています．私の研究テーマは「自己教師あり学習（Self-supervised Learning）」についてです．自己教師あり学習の代表的な手法である「対照学習（Contrastive Learning）」について勉強したので記事にまとめます．

 # 自己教師あり学習とはなにか

　 自己教師あり学習とは，簡単にいえばデータセットから教師を作り，それを予測することにより学習を行う方法です．
  
　英語で頭文字をとってSSLと略されることもありますが，これは「Semi-supervised learning（半教師あり学習）」と混同される可能性があるので，SSLという表現が出てきた場合，どちらを指しているのかは文脈から判断しましょう．本記事ではSSLという表現が出た場合，断りがなければ自己教師あり学習を指します．

## 類似の概念

　自己教師あり学習を理解するためには，類似の概念である「教師あり学習（Supervised learning）」，「教師なし学習（Unsupervised learning）」，「半教師あり学習（Semi-supervised learning）」について理解すると良いでしょう．

### 教師あり学習

　データ$x$とそれに対応する教師$y$が与えられており，$x$をもとに$y$を予測する学習方法．例えば，「分類」などがある．


### 教師なし学習

　データ$x$のみが与えられており，データ$x$が持つ構造や分布を学習する手法．例えば，「クラスタリング」などがある．

### 半教師あり学習

　データ$x$について，それに対応する教師$y$が**一部のデータだけ**に与えられている学習方法．一部はデータ$x$のみが与えられており，教師が与えられていない．

### 自己教師あり学習

　データ$x$について，$x$から何らかの方法で教師$y$を作成し，それをもとに訓練する方法．例えば，Mask Predictionなど．


### 注意点
　特に，教師なし学習と自己教師あり学習は混同されやすいので注意が必要です．教師なし学習では，教師という概念を使用しません．自己教師あり学習では，教師は与えられていませんが，自分でデータから教師を作成します．

## 自己教師あり学習のメリット

　自己教師あり学習はラベルのアノテーションが減らせるという利点が存在します．従来の教師あり学習においては，画像に大量にアノテーションをつける必要があるという問題点が存在しています．CIFAR10はまだ60000枚ですが，ImageNetは100万枚など，アノテーションコストが枚数に比例して多くなるという問題点があります．
 
　 JFT-300M（Google社内製のデータセット）はインターネットからスクレイピングした3億枚の画像とラベルがあるデータセットですが，これもノイズが多いという問題点があります．
  
  それに対して，自己教師あり学習は，「事前に人間のつけたラベルがなくても訓練できる」という明確な利点が挙げられます．自己教師あり学習で得た潜在表現をファインチューニングすることにより，少ないラベル付きデータでも効率的に学習できるようになります．

# 対照学習（理論）

　自己教師あり学習には「マスク予測」「Data2vec」などの様々な方法が提案されていますが，今回は対照学習に絞って解説します．

## コンセプト

　対照学習のコンセプトは，「同じものは潜在空間上で近くに，違うものは潜在空間上で遠くに」です．
 
 　サンプル$x$に何かしらの変形$f_1$を加えて得られるサンプル$X=f_1(x)$と，サンプル$y$に何かしらの変形$f_2$を加えて得られるサンプル$Y=f_2(y)$について考えます．また，ニューラルネットワーク$g$について，$X, Y$から得られる潜在表現をそれぞれ$X'=g(X), Y'=g(Y)$とします．

  このとき，$x=y$ならば$g(X)$と$g(Y)$の「離れ具合」が小さくなるように，逆に$x\neq y$ならば$g(X)$と$g(Y)$の「離れ具合」が大きくなるように$g$を学習しよう，というのが対照学習の基本的な考え方です．この離れ具合にも様々な定式化が考えられますが，一般的に使用されるのは内積を用いたContrastive Lossです．

 ## Contrastive Loss（導入）

 　ここでは，2つのベクトルの「離れ具合」を「内積」を用いて定量化します．$d$次元の潜在空間上にある2つのベクトル$x, y \in \mathbb{R}^d$の内積は，2つのベクトルの「なす角（高次元だと想像するのが難しいですが……）」が小さいほど，「長さ」が大きいほど値が大きくなるという性質があります．直感的には，内積が大きいほど2つのベクトルが「近い」ことになります．

　さて，$x=y$のときの$X'^{\top}_1 Y'$を大きく，$x\neq y$の$X'^{\top}_1 Y'$を小さくすれば「同じものは潜在空間上で近くに，違うものは潜在空間上で遠くに」という理念に一致した状態になると言えます．

　一般に，$n$個のベクトル$X'_1, X'_2,\cdots,X'_n \in \mathbb{R}^d$について，$Y'_1$と$X_i$の内積は$Y'^{\top}_1 X_i$で表されます．$Y'^{\top} X_1$は大きく，$Y'^{\top} X_i (i=2,\cdots,n)$は小さくなるように目的関数を設計します．数学的な扱いやすさから，以下の式が一般的に使用されています．ただし，$X=[X'_1  \quad X'_2 \quad \cdots \quad X'_n]$とおきます．ここで，$\tau$は温度と呼ばれるハイパーパラメータです．

 $$ L(Y_1', X) = -\log \dfrac{\exp(Y_1'^{\top} X_1/\tau)}{\sum^{n}_{i=1} \exp(Y_1'^{\top} X_i/\tau) } $$

この$\log$の引数に注目すると，「同じものは潜在空間上で近くに，違うものは潜在空間上で遠くに」という理念が満たされていることがわかります．一般的に損失関数は小さくするものですから，数式上ではマイナス1倍しています．
【C++】可変長配列のすっきりとした書き方

すぐ忘れるのでメモ
```c++
#include <iostream>
#include <vector>

using Array1D = std::vector<int>;
using Array2D = std::vector<Array1D>;
using Array3D = std::vector<Array2D>;

int main() {

	Array1D array1D;
	Array2D array2D;
	Array3D array3D;

	for (int i = 0; i < 10; ++i) {
		array1D.push_back(i);
	}

	for (int value : array1D) {
		std::cout << value << std::endl;
	}
}
```
AWS ECRのマルチステージビルドにおける脆弱性スキャンの挙動について

## はじめに

AWS ECR（Elastic Container Registry）の脆弱性スキャン機能は、コンテナイメージのセキュリティを確保する上で重要な役割を果たしています。

マルチステージビルドを使用する場合、その挙動について注意すべき点があることがわかりました。

## 重要な発見

マルチステージビルドにおけるECRの脆弱性スキャンには、以下のような特徴があります：

1. スキャン対象となるのは、最終的にプッシュされる最後のステージのイメージのみ
2. 中間ステージ（builderステージなど）はスキャン対象外

## 具体例で見る挙動

以下のような一般的なマルチステージビルドの`Dockerfile`を例に考えてみましょう：

```dockerfile
FROM node:21-alpine AS builder   # スキャン対象外
WORKDIR /app
COPY . .
RUN yarn install && yarn build

FROM node:21-alpine             # このイメージがスキャン対象
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]
```

### 重要なポイント

- `builder`ステージで使用されているパッケージやライブラリの脆弱性は、最終イメージに含まれていない限り、スキャンでは検出されません
- これは、builderステージのイメージがECRにプッシュされないためです

## 実務上の影響と注意点

この挙動は以下のような影響をもたらす可能性があります：

1. **見落としのリスク**
   - ビルド時に使用される脆弱性のあるパッケージが、最終的な成果物に影響を与える可能性
   - ビルドプロセス自体が攻撃の対象となるリスク

2. **セキュリティ対策**
   - ビルドステージでも安全なベースイメージとパッケージを使用することが重要
   - 必要に応じて、ビルドステージのイメージも個別にスキャンを検討

## まとめ

AWS ECRの脆弱性スキャンは、マルチステージビルドの最終イメージのみをスキャン対象としています。このため、ビルドプロセス全体のセキュリティを確保するためには、追加的な対策が必要となる場合があります。

開発チームは、この制限を理解した上で、適切なセキュリティ対策を実装することが重要ですね💡
Yarnのworkspacesコマンドの違いを理解する

## はじめに
Yarnを使ったモノレポ開発で、似たようなコマンドがいくつかあります：
- `yarn [command]`
- `yarn workspaces`
- `yarn workspaces foreach`

これらの違いについて、サンプルプロジェクトを使って具体的に解説します。

## サンプルプロジェクト構成
まずは簡単なモノレポ構成のプロジェクトを作ってみましょう：

```
my-monorepo/
├── package.json
├── packages/
│   ├── common/
│   │   ├── package.json
│   │   └── src/
│   ├── frontend/
│   │   ├── package.json
│   │   └── src/
│   └── backend/
│       ├── package.json
│       └── src/
```

### ルートの package.json
```json
{
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "scripts": {
    "lint": "eslint . -f stylish",
    "build": "echo 'Running root build'"
  }
}
```

### packages/common/package.json
```json
{
  "name": "@my-app/common",
  "version": "1.0.0",
  "scripts": {
    "build": "echo 'Building common package'"
  }
}
```

### packages/frontend/package.json
```json
{
  "name": "@my-app/frontend",
  "version": "1.0.0",
  "dependencies": {
    "@my-app/common": "1.0.0"
  },
  "scripts": {
    "build": "echo 'Building frontend package'"
  }
}
```

### packages/backend/package.json
```json
{
  "name": "@my-app/backend",
  "version": "1.0.0",
  "dependencies": {
    "@my-app/common": "1.0.0"
  },
  "scripts": {
    "build": "echo 'Building backend package'"
  }
}
```

## コマンドの違いを見てみよう

### 1. yarn [command]
これは単純にルートpackage.jsonに定義されたスクリプトを実行します。

```bash
$ yarn lint
# -> ルートのpackage.jsonで定義されたlintスクリプトを実行
# -> プロジェクト全体のlintが走る

$ yarn build
# -> "Running root build"と表示される
# -> サブパッケージのbuildは実行されない
```

### 2. yarn workspaces run [command]
全てのワークスペース（サブパッケージ）で同じコマンドを実行します。

```bash
$ yarn workspaces run build
# 出力:
# Building common package
# Building frontend package
# Building backend package
```

ただし：
- 実行順序は制御できない
- 特定のパッケージだけを実行することはできない
- 並列実行のオプションはない

### 3. yarn workspaces foreach [options] [command]
最も柔軟な制御が可能です。

```bash
# 並列実行（-p）
$ yarn workspaces foreach -p run build
# -> 全パッケージのbuildを並列で実行

# 依存関係順の実行（-t）
$ yarn workspaces foreach -t run build
# -> common → frontend/backend の順で実行

# 特定パッケージのみ実行
$ yarn workspaces foreach --from "@my-app/frontend" run build
# -> frontendパッケージのみビルド

# 除外して実行
$ yarn workspaces foreach --exclude "@my-app/backend" run build
# -> backend以外のパッケージをビルド
```

よく使用するオプション：
- `-p`: 並列実行
- `-t`: トポロジカル順（依存関係順）で実行
- `-R`: 再帰的に実行
- `-i`: インタラクティブモード
- `--from`: 対象パッケージを指定
- `--exclude`: 除外パッケージを指定

## まとめ
- 単一のコマンド実行 → `yarn [command]`
- 全ワークスペースで同じ操作 → `yarn workspaces run [command]`
- 高度な制御が必要 → `yarn workspaces foreach [options] [command]`

使用するコマンドは、実行したい操作と必要な制御レベルによって選択しましょう。`yarn workspaces foreach`は便利ですが、シンプルな操作には他のコマンドの方が適している場合もあります。
Bashのset -euxで堅牢なシェルスクリプトを書く

皆さんは普段シェルスクリプトを書くとき、どのようなオプションを使用していますか？

今回は、シェルスクリプトを安全に実行するための重要なオプション `set -eux` について詳しく解説します。

## TL;DR
シェルスクリプトの先頭に以下を追加することで、より安全な実行が可能になります：

```bash
#!/bin/bash
set -eux
```

## 各オプションの詳細
### set -e (Error)

エラーが発生した時点でスクリプトを即座に停止します。

```bash
set -e
cd /path/to/non/existent/directory  # この行でエラー発生
echo "この行は実行されない"  # スクリプトは前の行で終了
```

デフォルトでは、エラーが発生しても処理が継続されてしまいます：

```bash
# set -e がない場合
cd /path/to/non/existent/directory  # エラーが発生しても
echo "この行が実行されてしまう"    # 処理が継続される
```

### set -u (Undefined variable)

未定義の変数を参照した場合にエラーとして扱います。

```bash
set -u
name="Alice"
echo $name      # OK
echo $username  # Error: 未定義変数
```

デフォルトでは未定義変数は空文字として扱われるため、意図しない動作を引き起こす可能性があります：

```bash
# set -u がない場合
echo $undefined_variable  # 空文字として扱われる
rm -rf $undefined_variable/*  # 危険！ /* として解釈される
```

### set -x (eXecute trace)

実行されるコマンドとその引数を表示します。デバッグに非常に便利です。

```bash
set -x
name="Alice"
echo "Hello, $name"
```

実行結果：
```
+ name=Alice
+ echo 'Hello, Alice'
Hello, Alice
```

## 本番環境での使用

本番環境では、デバッグ出力は不要なため、通常は`-x`を外して`set -eu`とすることをお勧めします。開発時やデバッグ時には`-x`を追加して使用すると効果的です。

## まとめ

`set -eux`を使用することで：
- バグの早期発見
- 意図しない動作の防止
- デバッグの容易さ
が実現でき、より堅牢なシェルスクリプトを作成することができます。

是非、皆さんのシェルスクリプトでも活用してみてください！
GitHub Actions のmatrix - 配列の繰り返し処理のようなもの

## matrixって結局なに？

matrixは、**配列の要素を順番に処理していく**ような機能です。
プログラミングでいう「for文」のようなものです。

## 基本的な書き方

```yaml
jobs:
  example:
    strategy:
      matrix:
        name: [a, b, c]
    steps:
      - run: echo ${{ matrix.name }}
```

これは以下のようなコードのイメージです：
```python
names = ['a', 'b', 'c']
for name in names:
    print(name)
```

## もう少し実用的な例

```yaml
jobs:
  build:
    strategy:
      matrix:
        service: [frontend, backend, worker]
    steps:
      - run: docker build -f ${{ matrix.service }}/Dockerfile .
```

これは以下の処理が実行されます：
- `docker build -f frontend/Dockerfile .`
- `docker build -f backend/Dockerfile .`
- `docker build -f worker/Dockerfile .`

## 複数の配列も組み合わせられる

```yaml
strategy:
  matrix:
    name: [frontend, backend]
    env: [dev, stg, prod]
```

これは以下の組み合わせが実行されます：
- frontend + dev
- frontend + stg
- frontend + prod
- backend + dev
- backend + stg
- backend + prod

## まとめ

- matrixは配列の繰り返し処理みたいなもの
- 複数の配列を組み合わせることもできる

シンプルですが強力な機能なので、同じような処理を複数回実行するときに活用してみてください！
GitHub Actions: 特定のブランチパターンのマージ時にワークフローを実行する方法

## はじめに

GitHub Actionsを使用して、特定のパターンのブランチが特定のブランチにマージされた時だけワークフローを実行する方法を解説します。今回は「feature-」から始まるブランチ名からmainブランチへのマージをトリガーとするケースを例に説明します。

## ワークフロー設定の解説

まず、完全なワークフロー設定を見てみましょう：

```yaml
name: Branch Merge Workflow
on:
  pull_request:
    branches:
      - "main"
    types: [closed]
jobs:
  check-should-run:
    runs-on: ubuntu-latest
    outputs:
      should_run: ${{ steps.check.outputs.should_run }}
    steps:
      - name: Check should run
        id: check
        run: |
          if [[ "${{ github.event.pull_request.merged }}" == "true" && \
                "${{ startsWith(github.head_ref, 'feature-') }}" == "true" && \
                "${{ github.base_ref }}" == "main" ]]; then
            echo "should_run=true" >> $GITHUB_OUTPUT
          else
            echo "should_run=false" >> $GITHUB_OUTPUT
          fi
```

### 重要なポイントの解説

1. **トリガー条件の設定**
   ```yaml
   on:
     pull_request:
       branches:
         - "main"
       types: [closed]
   ```
   - `pull_request`イベントをトリガーとして使用
   - `main`ブランチへのPRが対象
   - `types: [closed]`でPRがクローズされた時のみ実行

2. **実行環境の設定**
   ```yaml
   runs-on: ubuntu-latest
   ```
   - GitHub提供の標準的なUbuntuランナーを使用
  
3. **条件チェックの実装**
   ```yaml
   if [[ "${{ github.event.pull_request.merged }}" == "true" && \
         "${{ startsWith(github.head_ref, 'feature-') }}" == "true" && \
         "${{ github.base_ref }}" == "main" ]]; then
   ```
   - `github.event.pull_request.merged`: PRがマージされたかチェック
   - `startsWith(github.head_ref, 'feature-')`: ブランチ名が"feature-"で始まるかチェック
   - `github.base_ref`: マージ先が"main"かチェック

4. **出力の設定**
   ```yaml
   outputs:
     should_run: ${{ steps.check.outputs.should_run }}
   ```
   - 条件に合致した場合は`true`、そうでない場合は`false`を出力
   - この出力は後続のジョブで条件分岐に使用可能

## 使用方法

1. このワークフローファイルを`.github/workflows/`ディレクトリに配置します（例：`branch-merge-workflow.yml`）

2. ブランチ名の例：
   - ✅ `feature-add-login` → main
   - ✅ `feature-update-ui` → main
   - ❌ `bugfix-xyz` → main（実行されない）
   - ❌ `feature-add-login` → staging（実行されない）

## カスタマイズのポイント

1. **ブランチ名のプレフィックス変更**
   ```yaml
   "${{ startsWith(github.head_ref, 'your-prefix-') }}"
   ```
   - `feature-`を任意のプレフィックスに変更可能

2. **ターゲットブランチの変更**
   ```yaml
   branches:
     - "your-branch"
   ```
   - `main`を任意のブランチ名に変更可能

3. **ランナーの変更**
   ```yaml
   runs-on: your-runner
   ```
   - 必要に応じて適切なランナーを選択

## 後続ジョブの例

```yaml
  next-job:
    needs: check-should-run
    if: needs.check-should-run.outputs.should_run == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
```

## まとめ

このワークフローを使用することで：
- 特定のパターンのブランチからのマージのみを検知
- 不要なワークフロー実行を防止
- 後続ジョブの制御が可能

カスタマイズ可能な部分を適切に設定することで、様々なワークフローに対応できます。
TypeScriptのassertNeverで型安全性を極める：switch文の完全ガイド

## はじめに

TypeScriptを使う上で、型安全性は常に重要なトピックです。特に、列挙型（enum）やユニオン型を扱うswitch文では、すべてのケースを漏れなく処理することが求められます。この記事では、`assertNever`関数を使って型安全性を高める方法を、switch文を中心に詳しく解説します。

## assertNeverとは

`assertNever`は、コンパイル時に到達してはいけないコードパスを明示的に示すための関数です。基本的な実装は以下のとおりです。

```typescript
function assertNever(x: never): never {
    throw new Error("Unexpected object: " + x);
}
```

この関数は、`never`型の引数を受け取り、常に例外をスローします。TypeScriptの型システムにおいて、`never`型は「決して発生しない」値の型を表します。

## switch文での使用例

交通信号の色を表す列挙型を例に、`assertNever`の使用方法を見ていきましょう。

```typescript
enum TrafficLight {
    Red,
    Yellow,
    Green
}
```

### パターン1: assertNeverを使用する場合

```typescript
function getAction(light: TrafficLight): string {
    switch (light) {
        case TrafficLight.Red:
            return "Stop";
        case TrafficLight.Yellow:
            return "Caution";
        case TrafficLight.Green:
            return "Go";
        default:
            return assertNever(light);
    }
}
```

このパターンでは、すべてのケースが処理されていることが保証されます。新しい値が`TrafficLight`に追加された場合、コンパイラがエラーを報告します。

### パターン2: defaultを書く場合

```typescript
function getAction(light: TrafficLight): string {
    switch (light) {
        case TrafficLight.Red:
            return "Stop";
        case TrafficLight.Yellow:
            return "Caution";
        case TrafficLight.Green:
            return "Go";
        default:
            return "Unknown action";
    }
}
```

このパターンでは、コンパイルエラーは発生しませんが、新しい値が`TrafficLight`に追加された際に気づきにくくなります。

### パターン3: defaultを書かない場合

```typescript
function getAction(light: TrafficLight): string {
    switch (light) {
        case TrafficLight.Red:
            return "Stop";
        case TrafficLight.Yellow:
            return "Caution";
        case TrafficLight.Green:
            return "Go";
    }
}
```

このパターンでは、TypeScriptの設定によって動作が異なります：

1. `--strictNullChecks`が有効な場合：コンパイラは、関数が`undefined`を返す可能性があることを警告します。
2. `--strictNullChecks`が無効な場合：警告なしで`undefined`が返される可能性があります。

## 各パターンの比較

| 特性 | assertNever | defaultあり | defaultなし |
|------|-------------|-------------|-------------|
| 型安全性 | 高 | 低 | 中（設定依存） |
| コード網羅性 | 完全保証 | 保証なし | 部分的（設定依存） |
| 保守性 | 高 | 低 | 中（設定依存） |

## assertNeverの利点

1. **網羅性の保証**: すべてのケースが処理されていることを保証します。
2. **リファクタリングの安全性**: 型の定義変更時に関連箇所の更新漏れを防ぎます。
3. **ランタイムの安全性**: 想定外の値に対して明示的なエラーをスローします。

## 注意点

1. `assertNever`は主にコンパイル時のチェックのために使用されます。
2. 実行時に`assertNever`関数が呼び出されることは、通常はバグを意味します。

## まとめ

`assertNever`を使用することで、TypeScriptの型システムをより活用し、コードの安全性と保守性を高めることができます。

## 参考リンク

- [TypeScript公式ドキュメント](https://www.typescriptlang.org/)
- [TypeScriptのnever型について](https://typescriptbook.jp/reference/statements/never#never%E3%81%AE%E7%89%B9%E6%80%A7)
- [TypeScriptのstrictNullChecks](https://www.typescriptlang.org/tsconfig#strictNullChecks)
Tiltの力を最大限に活用：tilt ciコマンドの徹底解説

## はじめに

Tiltは、Kubernetes環境での開発を効率化するツールとして広く知られていますが、その機能は開発環境だけにとどまりません。今回は、継続的インテグレーション（CI）環境でTiltを活用するための`tilt ci`コマンドについて詳しく解説します。

## `tilt ci`コマンドとは？

`tilt ci`コマンドは、Tiltを継続的インテグレーション環境で使用するために設計されたコマンドです。このコマンドを使用することで、CI/CDパイプラインにTiltのパワフルな機能を統合することができます。

## `tilt ci`の動作

`tilt ci`コマンドを実行すると、以下のような動作をします：

1. **Tiltfileの実行**：
   プロジェクトのルートディレクトリにあるTiltfileが読み込まれ、実行されます。

2. **非インタラクティブモード**：
   通常の`tilt up`と異なり、インタラクティブなTUI（テキストユーザーインターフェース）を起動しません。

3. **リソースのビルドと更新**：
   Tiltfileに定義されたすべてのリソースをビルドし、更新します。

4. **エラー処理**：
   いずれかのリソースでエラーが発生した場合、プロセスは失敗し、非ゼロの終了コードを返します。

5. **自動終了**：
   すべてのリソースが正常にビルドされ、更新されると、プロセスは自動的に終了します。

6. **ログ出力**：
   ビルドと更新のプロセスに関する詳細なログが標準出力に表示されます。

7. **環境変数の考慮**：
   CI環境で一般的に使用される環境変数（例：`CI=true`）を自動的に検出し、それに応じて動作を調整します。

## `tilt up`との主な違い

| 特徴 | `tilt up` | `tilt ci` |
|------|-----------|-----------|
| 実行モード | 対話型で継続的に実行 | 非対話型でタスク完了後に自動終了 |
| UI | ターミナルベースのUIを提供 | UIなし、ログのみ出力 |
| エラー処理 | エラーが発生しても実行を継続 | エラーが発生すると即座に失敗し終了 |
| 主な用途 | ローカル開発環境 | CI/CDパイプライン |

## `tilt ci`の活用シーン

1. **CIパイプラインでのTiltfile検証**：
   プルリクエストごとにTiltfileの設定をテストし、問題を早期に発見できます。

2. **自動ビルドプロセス**：
   複雑なマイクロサービスアーキテクチャのビルドを自動化し、一貫性を保つことができます。

3. **環境間の一貫性確保**：
   開発環境と本番環境の差異を最小限に抑え、「ローカルでは動くけど本番では動かない」問題を軽減します。

## 実践例：GitHub Actionsでの使用

GitHub Actionsは多くの開発者に利用されている人気のCIプラットフォームです。以下に、GitHub Actionsで`tilt ci`を使用する具体的な例を示します。

`.github/workflows/tilt-ci.yml`ファイルの内容：

```yaml
name: Tilt CI

on:
  pull_request:
    branches: [ main ]
  push:
    branches: [ main ]

jobs:
  tilt-ci:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1
    
    - name: Install Tilt
      run: |
        curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash

    - name: Run tilt ci
      run: tilt ci
      env:
        CI: true
```

この設定では以下のことを行っています：

1. プルリクエストがメインブランチに対して作成された時、またはメインブランチにプッシュされた時にワークフローが実行されます。

2. Ubuntu環境でジョブを実行します。

3. リポジトリのコードをチェックアウトします。

4. Docker Buildxをセットアップします。これは、Tiltが使用する可能性のあるDockerビルド機能のためです。

5. 最新版のTiltをインストールします。

6. `tilt ci`コマンドを実行します。環境変数`CI=true`を設定することで、CIモードで実行されていることをTiltに伝えます。

### 注意点

- この例では、Tiltfileがプロジェクトのルートディレクトリに存在することを前提としています。
- 実際の使用では、プロジェクトの特性に応じて追加の設定（例：環境変数の設定、依存関係のインストールなど）が必要になる場合があります。
- セキュリティ上重要な情報（APIキーなど）を扱う場合は、GitHub Secretsを使用してください。

この GitHub Actions の設定は、`tilt ci`を CI/CD パイプラインに統合する簡単な方法を示しています。プロジェクトの要件に合わせてカスタマイズすることで、より強力な検証プロセスを構築できるでしょう。

## まとめ

`tilt ci`コマンドは、TiltのパワフルなKubernetes開発機能をCI/CD環境に持ち込むための強力なツールです。これを活用することで、開発からデプロイメントまでの一貫性を保ち、効率的で信頼性の高い開発プロセスを構築することができます。

GitHub Actionsとの統合例で示したように、`tilt ci`は現代的なCI/CDパイプラインに簡単に組み込むことができます。これにより、Tiltfileの検証や複雑なビルドプロセスの自動化が可能になり、開発チームの生産性を大きく向上させることができます。

Tiltを使った開発に携わる方々は、ぜひ`tilt ci`コマンドの活用を検討してみてください。

## 参考リンク

- [Tilt公式ドキュメント](https://docs.tilt.dev/)
- [Tilt GitHub リポジトリ](https://github.com/tilt-dev/tilt)
- [GitHub Actions 公式ドキュメント](https://docs.github.com/ja/actions)
リアルでもGitHubでも整理ができない話

どうもAtsu1209です。

いきなりですがまずはこちらを御覧ください。

![GitHub - Atsu1209_home-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3374328/96b31c8c-3f13-7893-d3a9-0096a914d309.png)
なんと言うことでしょう。 スクショに入り切らない量のHTMLファイル
レポジトリ・ファイルを分けずに一つの場所に大量のファイルを入れる始末。
私が思うに少量ならいいと思うけどこの量は流石にひどい

:::note info
(独り言)後日整理すると決心した件
:::
:::note warn
GitHub初心者なのでおかしなところは気にせずに
:::
# 詳しい話
私Atsu1209は現役の中学生なのですが、自分のロッカーを開けると
教科書・整理用に買ったブックエンドまでもが落ちてくるんです。^^
流石に自分でも整理したいのですが、なかなかめんどくさい...
みなさんもGitHubでも何でもいいので整理はしましょう

##### おわり