OmniAICreator/Qiita-1.07M huggingface dataset:
サーバー管理を簡単に！Cockpitを使ったWebベースの管理環境構築

サーバーの管理は煩雑になりがちですが、**Cockpit**というツールを使えば、シンプルに、しかも強力なWebベースの管理インターフェースを提供してくれます。これにより、サーバーの操作や監視がとても効率的になります。

## **インストール手順**

まずは、Cockpitをサーバーにインストールする方法を紹介します。

### **1. Cockpitのインストール**

```bash
$ sudo apt update
$ sudo apt install cockpit
```

これで、Cockpitがインストールされます。

### **2. サービスの開始とステータス確認**

Cockpitのインストール後は、サービスを開始し、ステータスを確認する必要があります。

```bash
$ sudo systemctl enable --now cockpit.socket
$ sudo systemctl status cockpit.socket
```

これにより、CockpitのWebインターフェースを提供する`cockpit.socket`が起動し、自動起動が設定されます。

### **3. WebUIへのアクセス**

ブラウザを開き、次のURLにアクセスします。

```
http://{サーバーのIPアドレス}:9090
```

ここで、サーバーの管理者アカウントのユーザー名とパスワードを入力すれば、Cockpitのダッシュボードにログインできます。

---

## **機能の詳細解説**

Cockpitは非常に多機能で、サーバー管理者にとって非常に便利なツールです。主な機能を以下で紹介します。

### **1. システム情報**

Cockpitでは、サーバーの全体的な状態を簡単に確認できます。ダッシュボードでは、以下の情報を確認できます。

- **CPU使用率**: 現在のCPU使用率をグラフで表示
- **メモリ使用量**: 現在使用中のRAMの割合を表示
- **ロードアベレージ**: サーバーの平均負荷を表示
- **ディスク使用量**: ディスクの使用状況（容量・利用中の領域・空き容量など）

これにより、システム全体のパフォーマンスをリアルタイムで把握できます。

### **2. ログ**

サーバーのシステムログをWebUIから簡単に確認できます。例えば、以下のようなログが表示されます。

- **システムログ**: サーバーが生成した全てのログ（エラーメッセージや警告など）を表示
- **サービスログ**: 各サービスの状態や履歴ログ
- **カスタムログ**: 特定のアプリケーションやスクリプトによるログも表示可能

ログの監視が容易になり、サーバーのトラブルシューティングが速やかに行えます。

### **3. ストレージ**

Cockpitのストレージ機能では、ディスクの利用状況をグラフィカルに表示できます。

- **ディスク容量**: 物理ディスク、パーティションの容量と空き容量
- **IOパフォーマンス**: ディスクの読み書き速度をグラフ化
- **LVMやRAIDの管理**: 複雑なディスク管理をWebUIで簡単に行えます

これにより、ディスクの状態を可視化し、ストレージの最適化が可能です。

### **4. ネットワーキング**

Cockpitでは、サーバーのネットワーク状態を簡単に監視・管理できます。

- **ネットワークインターフェース**: 接続されているネットワークインターフェースの状況（IPアドレス、接続速度など）
- **トラフィックの監視**: インターネットやローカルネットワークのトラフィックをリアルタイムで監視
- **ネットワーク設定**: IPアドレスの設定やネットワークインターフェースの管理も行えます

ネットワークのトラブルシューティングや監視が簡単にできるようになります。

### **5. アカウント管理**

サーバーに登録されているユーザーアカウントの管理が簡単にできます。

- **ユーザー一覧**: サーバー上の全ユーザーとその権限、所属するグループの表示
- **ユーザー管理**: 新規ユーザーの追加、削除、権限変更がGUIで行えます

これにより、複数のユーザーがアクセスするサーバーでも管理が容易になります。

### **6. サービス管理**

サーバー上で動作しているサービスを管理することができます。

- **サービスの一覧**: 動作中のサービス、停止しているサービス、エラーが発生しているサービスなどを一目で確認
- **サービスの開始・停止・再起動**: サービスの状態を変更したり、必要に応じて再起動することができます
- **サービスの有効化・無効化**: サーバーの起動時にサービスを自動的に開始するかどうかを設定できます

これにより、サーバーのサービスを直感的に管理できるようになります。

### **7. ターミナルアクセス**

Cockpit内から直接サーバーのターミナルにアクセスできます。

- **ターミナル**: GUI上でターミナルを開き、コマンドライン操作を行えます
- **複数ターミナルの管理**: 複数のターミナルセッションを並行して管理できます

これにより、ブラウザから離れずに必要な操作を迅速に行えます。

---

## **まとめ**

**Cockpit**は、サーバー管理を簡単に行える強力なツールです。特に、自宅サーバーや中小規模のサーバー管理者にとって、WebUIで直感的に管理できる点が魅力的です。必要な機能が揃っており、インストールから使い始めるまでの手順も非常にシンプルです。

是非自宅サーバーや開発環境に導入して、管理業務を効率化してみてください！
Svelte で 3D 表示を行うライブラリ Threlte Ex2: Threlte 8 が控えているのを察知した

# はじめに

こちらは、Threlte の Ex(エクストラ、余談的な)シリーズの記事の一つ。

先のアドベントカレンダーにて、Threlte 8 が縦鼻中であることが分かったので、ならば、その内容を見られる範囲で追ってみようかというネタ。

https://threlte.xyz

# Threlte の現状

Threlte は、Svelte の Three.js ラッパーとして存在する。
そんな立場であるが故、Svelte のバージョンには敏感になるというのが事実としてある。

逆に Three.js に対してはどうか？というと、意外と Three.js に関しては、本質的な変化は特になく、基本時術は変わらないので、そちらはそこまで気にする必要はない。
もちろん、USD などのパイプラインに絡むレベルの話は追っておく必要があるので、そこまで気にするのであれば、Three.js を生で使うのが良いという解決策になる。
それが故に、あえて言うのであれば、Svelte のバージョン変化にセンシティブになっていればいいというだけではある。

# Threlete 8 の変化

さて、本題の Threlete の 8 バージョンに関して、どういう登場を控えているかを整理したい。

## Svelte 5 への対応

ここ数か月の多きな話題といえば Svelte 5 の登場だろう。
Rune を導入したり、export prop の仕方も変化し、より洗練された Svelte としてのフロントエンドフレームワークとして成り立ってきた。

とあれば、Threlte はそれに追従することになる。
という事で第一は Svelte 5 への対応。それこそが Threlte 8 の大きなマイルストーンとなっている。

Threlte 側は、この Svelte 5 の対応に関して GitHub プロジェクト側で公開している。

https://github.com/orgs/threlte/projects/4

### `{@render children()}` への対応

その中でも `{@render children()}` への対応は、Svelte 5 らしいなと感じた。

https://github.com/threlte/threlte/pull/983

### `userSize()` の廃止

Threlte 8 では、`userSize()` を廃止し、親コンポーネントのサイズの影響を受ける事ができるようになった。
これによって、Web サイト上の埋め込みとしてもデザインコントロールがしやすいようになる。

```svelte
<div style="width: 500px; height: 300px;">
  <Canvas>...</Canvas>
</div>
```

https://github.com/orgs/threlte/projects/4/views/1?pane=issue&itemId=68354160&issue=threlte%7Cthrelte%7C997

## より保守性を目指したタイプ生成への移行

これまでのコンポーネントにたいして、ほとんどがマニュアルでタイプファイルを作成したとのこと（す、すげぇ…）。
でもまぁ、やはり、こうして Svelte 5 といった根柢フレームワーク側の変更が行われると、その部分も追従するには把握の困難も極めるというもの。

Threlte 8 では、より生成側で自動でサポートされる運用にシフトしようとしている様子。

https://github.com/threlte/threlte/issues/1161

# さいごに

実際のところ、根柢の設計に対する大きな変更はそこまで大きなものはない様子。
むしろ Svelte 5 への変化をよく意識するようにし、それに合わせて Threlte を使用していくとよいということだろう。

これから、自らで作成していくものは Svelte 5 ベースで行きたいので、ぜThrelte 8 のリリースも期待したい。
Pythonにおける動的時間伸縮法（DTW: Dynamic Time Warping）のサンプルコード

# はじめに
動的時間伸縮法（DTW: Dynamic Time Warping）とは2つの波形データの類似度を測定する手法です。

本記事では、Pythonで ```fastdtw``` というライブラリを用いて、DTW を簡易的に計算します。

DTW のアルゴリズムについては次の記事で解説しています。

https://qiita.com/skm_bnn/items/233458acff5654406582

また、ライブラリを用いずに DTW の実装する方法については次の記事にコードを載せています。

https://qiita.com/skm_bnn/items/2db6509939561cb8d5dd

# サンプルコード
## 環境構築
以降にあるコードを実行するためには、 ```fastdtw``` ライブラリをインストールする必要があります。

### 仮想環境の構築
Python 環境を特に気にしない場合は [次に](#ライブラリのインストール) 進んでください。

お手持ちの環境を変更したくない場合は、ターミナルで次のコマンドを実行して仮想環境を用意しましょう。

```python``` コマンドが通らない場合は、 ```python3``` や ```py``` をお試しください。

- Windows の場合

    ```py: 仮想環境の作成と有効化
    python -m venv .venv
    .venv/Script/actvate
    ```

- Mac / Linux の場合

    ```py: 仮想環境の作成と有効化
    python -m venv .venv
    . .venv/bin/activate
    ```

    もしくは

    ```py: 仮想環境の作成と有効化
    python -m venv .venv
    source .venv/bin/activate
    ```

次のように、ターミナルに仮想環境名（上記のコマンドの場合 ```.venv``` ）が表示されるようになります。

```sh: 仮想環境が有効になっているかの確認
(.venv) $
```

### ライブラリのインストール
ターミナルで次のコマンドを実行してライブラリをインストールします。

```py: ライブラリのインストール
pip install fastdtw scipy numpy matplotlib japanize-matplotlib
```

|ライブラリ|目的|
|---|---|
|```fastdtw```、```scipy```、```numpy```|DTWを簡易的に実装するため|
|```matplotlib```|図を作成するため|
|```japanize-matplotlib```|図で日本語を表示させるため|

なお、VSCode でノートブック形式（ ```.ipynb``` ）を実行する場合は ```ipykernel``` ライブラリも必要です。

```py: ライブラリのインストール
pip install ipykernel
```

## 波形データの用意
本記事では疑似的なデータとして、[前回の記事](https://qiita.com/skm_bnn/items/233458acff5654406582) と同様の波形を用意します。

```py: 波形データの用意
Q = [3, 4, 3, 3, 2, 3]
S = [1, 6, 4, 4, 1, 5]
```

次のコードで各波形データの形状を確認できます。

```py: 波形データの確認
from matplotlib import pyplot as plt
import japanize_matplotlib

# 2つの時系列データをプロットする
plt.plot(Q, label='Q')
plt.plot(S, label='S')

# 凡例の表示
plt.legend()

# グラフタイトル
plt.title('波形データ')

# グラフを表示する
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/1cf237b6-b145-99e2-d7f2-1fb4fe1ffdd1.png)

## DTW距離の計算
次のコードで DTW 距離を計算します。

```py: DTW距離の計算
import numpy as np
from scipy.spatial.distance import euclidean
from fastdtw import fastdtw

# データの整形
Q = np.array(Q).reshape(-1, 1)
S = np.array(S).reshape(-1, 1)

dist, path = fastdtw(Q, S, dist=euclidean)

print(f"DTW距離: {dist}")
print(f"各点のパス:{path}")
```

次が出力されると成功です。

```
TW距離: 9.0
各点のパス:[(0, 0), (1, 1), (1, 2), (1, 3), (2, 3), (3, 3), (4, 4), (5, 5)]
```

次のコードでデータポイント間の対応関係を確認できます。

```py: DTW の結果をプロットする
# 2つの時系列データをプロットする
plt.plot(Q, label='Q')
plt.plot(S, label='S')

# データポイントの対応関係をプロットする
for index_Q, index_S in path:
  plt.plot([index_Q, index_S], [Q[index_Q], S[index_S]], color='gray', linestyle='dotted', linewidth=1)

# プロット
plt.legend()
plt.title(f'波形データ（DTW距離={dist}）')
plt.show()
```

上記のコードを実行すると、次のグラフがプロットされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/d7606fa4-40a0-412e-2cb4-1ea928da22ef.png)

$(横軸, 縦軸) = (1, 4), (2, 4), (2, 3), (3, 4)$ の点にご注目ください。

$(1, 4), (2, 4)$ 間と $(2, 3), (3, 4)$ 間のパスについて、不自然な対応となっています。

この原因として ```fastdtw``` は計算量を抑えるために近似的な処理をしていることが考えられます。

# 参考
https://magazine.techacademy.jp/magazine/31149
テスト設計の話

Last Update 2024.11.30

## 「テスト設計」ってなんだろう？


「テスト設計」、と一言にいっても、組織によってその中身は様々です。
項目を羅列したものや、マトリクスをテスト設計というところもあれば、
テストケースでしょ？というところもあります。
ですので、普段一緒に仕事をしていないエンジニアと話すときには、
内容を確認しながら話をすることになります。

ここでは、項目書を書くことではなく、どういうテストをするか、を、
まとめる話をします。


## テストフレームを作っておく
ここで、前日おはなしした、テストフレームの出番です。
テストフレームは、いわばテストの引き出しのようなもので、テストする要件に合わせて、
どういったテストが必要かを、チェック形式で選ぶことができます。
たとえば、今回はリグレッションだけでよいけど、別のプロジェクトは機能テストが必要、
だとか、さらに組み合わせテストが必要、というように。

そうすることで、時間の見積もりがしやすく、テストがいつまでに終わりそうか
まとめやすくなります。全体的な時間と効果の兼ね合いも見通しがつくようになります。
少なくとも、いつ終わるのかわからない、という状態にはなりにくいので、
テストコントロールがしやすくなるでしょう。

反対に、期日に間に合わないことがすぐに分かった場合、調整もしやすいですね。

![TestStrategy2023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156898/3a6a7c9e-88a8-7fc0-f033-a5b2604e0b32.png)

自分のテストフレームワークを作ろう：
https://qiita.com/EgaSaQA/items/1eb643ebda0cceafa4bb


## 実行するテストを選ぶ
では、つくったフレームのなかから、プロジェクトで使うテスト技法を選びましょう。

上の黄色いフレームは、テスト設計でつかう技法が記載されています。
細かい説明は別記事に譲りますが、テスト設計はそれなりに神経を使う、というのは、
マスの数を比べてもご想像いただけるかと思います。

毎回こんなにやっている時間がないよ、という場合は、隙間時間に
モデリングや因子出し、エンティティの整理や、テストコンディションの洗い出しなどを
行っておくと、少しずつ出来合いの設計がたまっていきます。
あとは呼び出して使いまわします。

こうして作り置きしておいたテストを、テストスイートと呼びます。
（テストスイートの定義は、さまざま見かけるので、こちらも調べてみてください。）

テストスイートを用意しておけば、時短につながりますね！


## テスト用語について
記述の中にわからない用語がある場合、インターネットでの検索のほか、JSTQBの用語集を
確認するとよいでしょう。インターネットでの解釈には揺らぎがあるので、
まずはそちらの参照をお勧めいたします。
https://jstqb.jp/dl/JSTQB-glossary-introduction.V3.2.J01.pdf
（リンクは変わる可能性があります）


#
### 用語解説

#### 因子
テストすべき条件、または要素。

#### 因子出し
テスト対象の因子を洗い出す作業をこう呼んでいます。
例：　年齢と住んでいる地域によって、表示を分ける場合、
年齢と住所が因子であると、ピックアップする作業をさします


#### テストコンディション
テストの条件を指す
例：　メールアドレスのドメインがフリーの場合は・・・という仕様があった場合、
ドメインがテストコンディションになります
JetBrains Riderで `MSBuildが見つからない` エラーの解決

# 概要
新しいPCでRiderをインストールした後、画像のようなエラーが出た。

![スクリーンショット 2024-11-30 20.56.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/7c698e77-ed33-a737-b05a-579961093c45.png)

```
プロジェクト 'Assembly-CSharp-Editor' の読み込みとビルドには MSBuild (Microsoft Build Engine) が必要です。
```

一瞬で解決できるが、備忘録的に残しておく

# 解決方法
1. `.NET Core または Mono をインストールして .NET アプリケーションを開発…`を選択
![スクリーンショット 2024-11-30 20.57.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/4b7bbddd-4b3e-34f9-3637-af81bc52cd19.png)


2. .NETをインストール
![スクリーンショット 2024-11-30 20.59.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/cb5f09cc-cdfe-1651-40ae-aa7b3c4d6cbb.png)


3. Monoをインストール
1でエラーは消えるが、別の警告が出るのでMonoもインストールする
![スクリーンショット 2024-11-30 21.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/022bfcf6-f88a-443d-541c-a769d661217b.png)

4. 解決

# 補足
### MSBuildを切り替えたい時
設定 >> ビルド、実行、デプロイ >> ツールセットとビルド
![スクリーンショット 2024-12-01 2.52.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/6f9f2933-936e-5c41-abc5-5b5f02ff9f77.png)
![スクリーンショット 2024-12-01 2.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/39f47dfb-07ab-38c6-29fb-5ff7a8b67ffb.png)

たまに.NETのバージョンを上げたり下げたりした時、ここでMSBuildの調整ができる

 - Riderで[MSB4198]が出たときの対策
https://zenn.dev/chorome/articles/c7f2a6778f89bd
> どうやらアセンブリに含まれる一部のスクリプトのパスが長すぎるのが原因っぽい。
対策: Riderで指定するMSBuildを変えた

こういうこともあるらしい

### C# interactiveでプロジェクトファイルを参照できないときの対策
プロジェクトを読み込もうとすると、こういうエラーが出る
```
> #r "/Users/hoge/Documents/Development/Unity/UISample/Temp/Bin/Debug/Assembly-CSharp/Assembly-CSharp.dll"
> (1,109): error CS1025: Single-line comment or end-of-line expected
```

まだビルドまえでdllが生成されていないので、読み込む時にビルドを挟むように設定する

設定> >> 言語 & フレームワーク >> C# Interactive
`'C# インタラクティブの参照'はプロジェクトをビルドします`にチェックをいれる

```
> #r "/Users/hoge/Documents/Development/Unity/UISample/Temp/Bin/Debug/Assembly-CSharp/Assembly-CSharp.dll"
> 
```
すると成功するようになる

ここでのビルドはReSharper用のMsBuildが使われているよう
自分の環境では以下が使われていた
```
~/Applications/Rider.app/Contents/lib/ReSharperHost/JetBrains.Platform.MsBuildTask.v15.dll
```
ビルド内容はプロジェクトフォルダの `Temp/`内に出力されている

### Monoのロゴが猿なのなんで
![Mono_project_logo.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/c8b10631-6c72-ce7a-f4f8-54be0941a908.png)

```
Mono is the word for ‘monkey’ in Spanish. We like monkeys.

モノはスペイン語で「猿」を意味します。私たちは猿が好きです。
```
https://www.mono-project.com/docs/faq/general/

可愛い
私がWEBエンジニアになるまでの話

# はじめに
今回は、私がエンジニアになるまでの過程を紹介していきたいと思います。
フリーター → IT専門学校 → 新卒でWEBエンジニアという決して平坦ではない道を歩んできたので、これから似たような道をいく人の参考になれば幸いです。

ちなみに、この記事がちょうどQiita連続投稿50周目の記事となります！

## 要約
- 結構人生行き詰ったけどなんとかなったよ
- IT系専門学校は２種類あって、どちらを選ぶかは人生を左右するかも
- 結局当人のやる気次第
- 就活にはアプリを作って挑もう

## フリーター時代
高校卒業後２年間、特にやりたいこともなくバイトしつつ遊びつつな生活を続けていました。

勉強が得意なわけではなく、好きなこと以外は続けられないタチだったので打ち込む事を見つけようとしていました。

が、このままではいけないと思い立ち、コロナ禍が明けようとしていたこともあり以前から興味があったエンジニアを目指そうと専門学校に行くことを決意。(このタイミングと専門に行くことも含め結果めちゃくちゃ英断だった)

ちなみにこの時点でのプログラミング経験は全くのゼロ。

### 専門学校選び
突然ですが、IT専門学校には大きく分けて2つあります。

- 資格勉強メインで、基本情報なんかを取得して資格を武器に就活を行う座学系
- 開発をメインにしていき、成果物やポートフォリオを武器に就活を行う実技系

前者の方が圧倒的に数が多いのですが、本当に偶然、座学系の方のオーキャンに行った時チラッと話に出てきた実技系の学科に興味を持てたことで見つけました。

自身の性格を踏まえて考えると、座学系の方に行っていたらドロップアウトしていただろうなと思います...

## 専門学校入学
いざエンジニアにならん、と私にしては固い決意のもと入学した２年制の専門学校。
ここでダメなら人生全てダメって気持ちで入学しました。

IT系専門学校に通うことは、結構賛否分かれるところがあるかと思いますが、結果私にとっては大正解でした。(ただし資格メインの学科については否寄りです。あくまで前述した実技メインの学科に限る)

やる気のある人、やりたいことが定まっている人にとっては最高の環境でした。学校というかコワーキングスペースに近かった気がします。(特に２年は)

また、1年に4回、成果発表の会がありそこで自分なりにモノが作れているならいいよ。みたいな...

サボろうと思えばいくらでもサボれる環境ではあるので、本当に当人と固まっている生徒のやる気に左右される諸刃の刃みたいな環境ではありました。

入学し、最初の席(席は名前順で固定だった)のメンバーがプログラミングの経験者揃いでやる気もあり、完全初心者だった私を引き上げてくれたことは非常に幸運でした。

### Flutterを始める
そんな中で、興味があったモバイルアプリの開発を行うためFlutterの学習を始めます。
HTMLやJavaScriptなんかはほぼわかりませんでした。結構なレアケースかと思います。

周りの生徒や教師陣にもFlutterを書ける人がいなかったので相当な苦労をしました。(chatGPTもまだ出ていない頃でした。これも今考えると幸運かも...)

が、投げ出すほど辛いというもなく、楽しいという感情の方が優っていたのでなんとか乗り越えます。
１つのエラー解決に夜通しかかり朝日を浴びて登校、なんてことも頻繁にしていました。

そんなこんなで、できる限りの時間を注ぎ込み、やっと学生にしてはそこそこ頑張ってるねぐらいのレベル感には到達しました。

### 就活
時は１年生の12月ごろ、変わらずアプリ作ってたりしていたのですが、最初の席のメンバーであり恩人のクラスメイトが就活をしていました。

調べると、ITエンジニアの就活は早期化しており、なんなら12月から始めるのは遅いまであるととのこと。

これに驚き、私も急ぎ就活をはじめます。

まだ大多数のクラスメイトは就活などしていなかったので、ここで危機感を持って就活を始めたのはいい判断でした！

就活も色々と苦労はしましたが、自分なりに頑張って開発したモバイルアプリを引っ提げてアピールし、結果東京にオフィスを置く受託系企業に内定をいただき、私としては大満足の結果になりました。

専門学生という、学歴にあまり有意性の無いなかでアプリを作ったことがあるという点は特に高い評価を受けていた印象があります。

### React・TypeScriptを始める
学科の2年生では、チームを作ってチーム開発をすることになっていました。

そこで、Webアプリケーションのフロントエンド開発担当となり、React・TypeScriptの学習を始めます。

ここでReact・TypeScriptを学んでいたおかげで、就職後に大きな恩恵を受けることができました。
Web系に就職したいならReact、TypeScriptは必須級なので学生のうちから触っておくのを強くオススメします。

## さいごに
Qiita連続投稿50周目&アドカレ１記事目のということで、思い切ってポエム系の記事に挑戦してみましたが、難しいですね..

長々と自分語りをしてしまいましたが、私から同じルートでエンジニアを目指したい人に伝えたいことは散りばめられたかなと！

まだまだ技術やそのほか色々な面で足りて無いモノが多すぎるのですが、自分のペースで習得していこうと思っています。
【UE5】CallStackをログに出力する

# 0. 最初
こちらの記事はUnrealEngine Advent Calendar 2024 シリーズ3の8日目の記事になります

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

プロジェクジェクトのログは以下
```cpp
"\プロジェクト名\Saved\Logs\プロジェクト名.log"
```

# 1. エディタでコール順を確認する
通常、エディタでコール順を確認するときには
「Debug」→「Blueprint Debugger」を起動「Call Stack」タブ
対象のノードで「F9」を押下しブレークポイントを付け「Play」

![無題の動画-‐-Clipchampで作成-_7_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/fcd53607-d0f8-1444-5898-a4b431a2ffee.gif)

この「Call Stack」をログで出力します

# 2. 「Stack Trace」を使用する
このノードを使用するとログに「Call Stack」を表示することができます
![スクリーンショット 2024-12-02 000205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/766cad39-436e-142c-9bc2-ead53e216acf.png)

以下のBPを組み実際に試してみます
「GetActor of Class」で取得できないようになっているためNullを返ります
![スクリーンショット 2024-12-01 220151.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/919ef652-3c35-d9f5-b215-d78a3a1bc74f.png)


「Stack Trace」の有無が以下のログ
![名称未設定_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/4f1c08a0-5b71-32d2-daf0-9540f9d50a8d.png)

# 3. 終わり
エディタで作業をしているときには恩恵は少なそうですが
パッケージの際にコール順を表示したりなど使用できる箇所は多いと思います！
【UE5】ActorComponentを腑に落とすきっかけの話

# 0. 最初

こちらの記事はUnrealEngine Advent Calendar 2024 シリーズ3の7日目の記事になります

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


# 1,「ActorComponent」の理解について
UEをある程度触っていると「ActorComponent」という単語
色々なサイトを見てある程度使用方法を覚えて実際に使用できるようになっていました
ですが、何故か腑に落ちていませんでした
この疑問を解決したキッカケを紹介します。
これをきっかけに「ActorComponent」の理解が進めば幸いです。


# 1. うどんさんの記事
最初にはうどんさんの記事でした。
記事では「ActorComponent」を使用することで得られるメリットを解説されています

https://zenn.dev/udondev/articles/0389fe50f8cae7

# 2. 間接的に操作するということ
本記事のきっかけになったのでは関節的に「Cameraの操作」でした。
実装してみます「ThirdPersonTemplate」の作成して視野を変更してみます

通常だと90°が設定されています
![スクリーンショット 2024-12-01 034326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/15ca8186-9722-b5da-9a42-1917525bbb23.png)

これをActorComponent使用して150°に変更します
![スクリーンショット 2024-12-01 034358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/18d135df-10a2-34fa-a107-933a1fdbcbd9.png)




「AC_CameraController」という名前を付けて「BP_ThirdPersonCharacter」にアタッチします

![スクリーンショット 2024-12-01 034713.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/8abdf28f-9bdd-a74c-c644-6b3b63a8b3cc.png)


![スクリーンショット 2024-12-01 035247.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/9d9cb5ed-b639-e6c6-b684-cbdb1bc84d82.png)

「CameraController」が「BP_ThirdPersonCharacter」の代わりに操作してくれるようになりました

イメージはこんな感じ
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/d1153284-5c8a-a39d-58f9-7643968ea85d.png)

自分がこの実装を見たときに上記の図が浮かび「ActorComponent」の仕様を自分の中で腑に落とすことができました


3. 「移譲」の理解
プログラムを勉強すると「移譲」という言葉をよく耳にすることがあります。
この「移譲」をUnreal Engineでは「ActorComponent」を使用することで再現することができます

:::note warn
警告
「interface」「Delegate」が移譲度100%なら
「ActorComponent」は移譲度80％ほど(主目的は「機能を追加すること」)
:::



# 3. 終わり
理解できる人ならなんてことないことですが、上記の図を頭で想像できるようになってから
「ActorComponent」を自分の裁量で使用できるようになりました

初心者の方がこの記事で「ActorComponent」を少しでも自由に扱えるようになれば嬉しいです！
Python Pickleの基本的な使い方と脆弱性

Pythonの`pickle`モジュールは、Pythonオブジェクトをバイトストリームにシリアライズ（直列化）し、後でデシリアライズ（逆直列化）するための便利なツールです。しかし、信頼できないソースからのデータをデシリアライズすると、深刻なセキュリティリスクが生じる可能性があります。

### 基本的な使い方

`pickle`モジュールを使ってオブジェクトをシリアライズするには、`pickle.dumps()`関数を使用します。

```python
import pickle

data = {'name': 'Alice', 'age': 30}
pickled_data = pickle.dumps(data)

print(pickled_data) # b'\x80\x04\x95 ... ' のようなバイト列が出力される
```

デシリアライズするには、`pickle.loads()`関数を使用します。

```python
import pickle

pickled_data = b'\x80\x04\x95 ... ' # シリアライズされたデータ
original_data = pickle.loads(pickled_data)

print(original_data) # {'name': 'Alice', 'age': 30} が出力される
```

### 脆弱性

`pickle`の脆弱性は、信頼できないソースからのデータを`pickle.loads()`でデシリアライズする際に発生します。`pickle`は任意のコードを実行できるため、悪意のあるコードが注入されたデータをデシリアライズすると、リモートコード実行（RCE）などの攻撃を受ける可能性があります。

`__reduce__()`メソッドを悪用した攻撃が代表的です。このメソッドは、オブジェクトを再構築する方法を定義するために使用されますが、攻撃者はこれを悪用して任意のコードを実行させることができます。

```python
import pickle
import os

class Exploit:
    def __reduce__(self):
        return (os.system, ('ls -l',)) # 危険なコマンド

# 攻撃者が作成する悪意のあるデータ
exploit = Exploit()
malicious_pickle = pickle.dumps(exploit)

# 信頼できないソースからデータを読み込む場合
# loaded_data = pickle.load(open("malicious_file.pkl", "rb"))

# 上記のようにファイルから読み込むだけでなく、ネットワーク経由で受け取ったデータなど、
# 信頼できないソースからのデータは全て危険です。

# デシリアライズ時に悪意のあるコードが実行される
loaded_data = pickle.loads(malicious_pickle) 
```

### Sleepy Pickle

Sleepy Pickleは、この`pickle`の脆弱性を悪用した攻撃手法の一つです。機械学習モデルを`pickle`形式で保存・配布する際に、悪意のあるコードを注入し、モデルの動作を改ざんしたり、機密データを盗み出したりします。


### 対処法

* **信頼できないソースからの`pickle`データは絶対にデシリアライズしない**: ネットワーク経由で受信したデータや、検証されていないファイルなど、信頼できないソースからの`pickle`データは`pickle.loads()`で処理しないでください。

* **`pickle`の代わりに安全なシリアライズ形式を使用する**: JSONやYAMLなど、より安全なシリアライズ形式を使用することを検討してください。特に、外部とのデータ交換を行う場合は、`pickle`の使用は避けるべきです。

* **制限付きのアンピクリング**:  どうしても`pickle`を使う必要がある場合、信頼できるクラスのホワイトリストを作成し、それ以外のクラスのデシリアライズを拒否するなどの対策を講じてください。

* **Safetensors**: 機械学習モデルの保存には、`pickle`の代わりにSafetensorsの使用を検討してください。Safetensorsは、Pythonオブジェクトではなくテンソルデータのみを扱うため、任意コード実行のリスクを軽減します。

### まとめ

`pickle`は便利なツールですが、セキュリティリスクを理解し、適切な対策を講じる必要があります。信頼できないデータの取り扱いには細心の注意を払い、可能な限り安全な代替手段を使用してください。特に、機械学習モデルのような機密性の高いデータを扱う場合は、Sleepy Pickleのような攻撃に注意し、Safetensorsなどの安全な形式を使用することが重要です。


### 参考文献
- https://www.sisainfosec.com/weekly-threat-watch/new-sleepy-pickle-exploit-puts-ml-models-at-risk/
- https://www.darkreading.com/threat-intelligence/sleepy-pickle-exploit-subtly-poisons-ml-models
- https://innovatopia.jp/cyber-security/cyber-security-news/31642/
[Git] mergeコマンドの復習

こんにちは！

開発で git merge コマンドを利用してますが、よく忘れるのでまとめ。（使いそうなものだけ）

ネタ元は[こちら](https://git-scm.com/docs/git-merge)。

# 基本コマンド

### 1. 通常のマージ
```bash
git merge <ブランチ名>
```
指定したブランチの変更を現在のブランチに統合します。

## オプション

### 1. マージコミットの制御
- `--ff`（デフォルト）
  - 可能な場合はfast-forwardで実行
  - マージコミットを作成しない

※fast-forward は、マージコミットを作成せず、単純にブランチのポインタを最新のコミットまで進める、ということらしい。

- `--no-ff`
  - 必ずマージコミットを作成
  - ブランチの統合履歴を明確に残したい場合に使用

- `--ff-only`
  - fast-forwardできる場合のみマージを実行
  - できない場合は中止

### 2. コミット制御
- `--no-commit`
  - マージ後のコミットを自動で行わない
  - マージ結果を確認してから手動でコミットしたい場合に使用

- `--squash`
  - ブランチの全変更を1つのコミットにまとめる
  - 履歴をシンプルに保ちたい場合に有効

### 3. コンフリクト発生時（発生後）のオプション
- `--abort`
  - マージを中止して元の状態に戻る

- `--continue`
  - マージを続行（解決した場合）

※コンフリクト発生に備えたものではなく、コンフリクト発生後、
```
git merge --abort
```
のように、中止するか、継続するかのオプションです。

### 4. その他
- `-m "<メッセージ>"`
  - マージコミットのメッセージを指定

- `--stat`
  - マージ時の変更統計を表示
  - どのファイルが変更されたかを確認可能

```
$ git merge xxx-branch --stat

# 以下のような統計情報が表示されます
src/main.js        | 25 +++++++++++++++----------
src/utils.js       |  8 ++++++++
test/main.test.js  |  5 +++--
3 files changed, 26 insertions(+), 12 deletions(-)
```

# まとめ
`git marge` コマンドは非常に便利ですが、コミットを作るか、履歴をどうするか等、リポジトリの運用に関わる部分があります。

開発体制にもよりますが、リポジトリの運用方針を確認し、適切に使いましょう。
【超基礎】TypeScript配列について

## 前提
この記事は、初学者の私が、サバイバルTypeScriptで学んだこと+調べたことをまとめたものになります。

従って、経験則に基づいた発言ではないため、一部慣習とは違っていたり、認知にずれがあったりする可能性がありますので、ぜひコメントで指摘していただけると幸いです。

https://typescriptbook.jp/

## 環境
記事内のコードは以下の環境で動作確認済みです。
- Node.js: v22.10.0
- TypeScript: Version 5.6.3

## TypeScriptにおける配列
- 「型」に関する部分以外は基本的にc++と同じような文法
- **インデックス**で要素にアクセスできる
- **特殊な種類のオブジェクト**という立ち位置
- 多次元配列や、オブジェクトの配列も作れる

### 基本
 `[]`で囲み、`,`で区切る　例:[a,b,c] [1,2,3]
```typescript
const numbers: number[] = [1,2,3]
```

### 空の配列の作成
空配列の宣言には以下の2種類の方法がある。後者は要素数を指定できる。

各要素は`undefined`
```typescript
//空の配列
const nums1: number[] =[]
//要素数5の空の配列
const nums2: number=new Array(5)

console.log(nums[2])// =>undefined
```

### 型注釈
型注釈は`Type[]`か`Array<Type>`

 `(Type|Type)[]`のようにすることで複数の型を一つの配列に入れられる

```typescript
const strs1: string[] = ["a","b","c"]

const strs2: Array<string> = ["a","b","c"]

const strNums: (string|number)[] = ["a","b",3]
```
### 要素へのアクセス
インデックスを使ってアクセスする

 例の様に0からスタート
```typescript
const nums: number[] =[1,2,3,4,5]

console.log(nums[0])//=>1
```
### 多次元配列
Type[][]のようにすることで、多次元配列を実現できる

インデックスによりアクセス可能
```typescript
const nums: number[][]=[
    [1,2,3],
    [4,5,6],
    [7,8,9]
]

console.log(nums[0][0])//=>1
```

### オブジェクトの配列
オブジェクトで配列を作ることができる

インデックスとプロパティによる参照を組み合わせて要素にアクセスする
```typescript
const arrObj =[
    {name: "Taro",age: 1},
    {name: "Hanako",age: 51},    
]

console.log(arrObj[1].name)//=>Hanako
```
## 配列の操作
JavaScriptの配列捜査と同じメソッドが使えます

https://qiita.com/araarara/items/06ef990b7a78985afa90

## 配列はオブジェクト？
JS,TSにおいて**配列は特殊なオブジェクト**という立ち位置にある。
```typescript
console.log(typeof []) //=>object
```
したがって、`const`で宣言しても、要素の変更は可能である
```typescript
const strs :string[]= ["a", "b", "c"];
strs[2]="k";//変更可能
console.log(strs)//=>;["a", "b", "k"];
```
また、代入は値を渡すのではなく、参照を共有するため、代入先の配列を変更すると代入元も変わる
```typescript
const strs1: string[] = ["a", "b", "c"];

const strs2: string[] = strs1//新しい配列strs2にstrs1を代入

strs2[2] = "k"//今作った配列を編集

console.log(strs1)//=>;["a", "b", "k"];
```



## まとめ
以上になります。


当方初学者なため、認知のずれや、モダンな開発現場ではもう使わない表現などがありましたらコメントで指摘していただけると幸いです。😸

## 参考

https://typescriptbook.jp/reference/values-types-variables/array

https://qiita.com/qq_kaq/items/a7f43abcf781392c11a5
【Flutter】YouTubeの動画をアプリ内でストリーミング再生する方法

## 1. はじめに

YouTubeは直接的な動画URLのストリーミングを制限しており、YouTubeの動画をアプリ内で再生するためには、YouTubeの公式APIや埋め込み機能を利用する必要があります。YouTubeの動画をFlutterアプリで再生する方法として、`youtube_player_flutter` というパッケージを使うのが一般的です。このパッケージは、YouTube動画を簡単に埋め込み、再生できるウィジェットを提供しています。本記事では、`youtube_player_flutter`を使ってYouTube動画をストリーミング再生する方法を解説します。

---

## 2. 動作環境

- M1 MacBook Pro
- VS Code

---

## 3. パッケージのインストール

まず、Flutterプロジェクトに`youtube_player_flutter`パッケージを追加します。
以下のコマンドでパッケージをインストールします。

```bash
flutter pub add youtube_player_flutter
```

---

## 4. 実装

### 4.1 YouTube動画を埋め込む

以下のコードでは、YouTube動画のURL（動画ID）を指定して、アプリ内で再生する方法を紹介します。

```dart
import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: VideoPlayerScreen(),
    );
  }
}

class VideoPlayerScreen extends StatefulWidget {
  const VideoPlayerScreen({super.key});

  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  late YoutubePlayerController _controller;

  @override
  void initState() {
    super.initState();
    // YouTubeの動画IDを指定してコントローラーを初期化
    _controller = YoutubePlayerController(
      initialVideoId: '0mwxiFOi1GQ',  // ここにYouTube動画のIDを指定
      flags: const YoutubePlayerFlags(
        autoPlay: true,    // 自動再生を有効にする
        mute: false,       // 音声を有効にする
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();  // YouTubeプレイヤーを破棄
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('YouTube Video Player'),
      ),
      body: Center(
        // YouTubeの動画を表示
        child: YoutubePlayer(
          controller: _controller,
          // 動画の進捗バーを表示
          showVideoProgressIndicator: true,
        ),
      ),
    );
  }
}
```

### 4.2 コードの解説

- **`YoutubePlayerController`**: YouTube動画を管理するためのコントローラーです。`initialVideoId`には、YouTube動画のID（URLの`v=`の後ろの部分）を指定します。
  - 例: `https://www.youtube.com/watch?v=0mwxiFOi1GQ` の場合、`0mwxiFOi1GQ`が動画IDになります。
- **`YoutubePlayer`**: YouTube動画を表示するウィジェットです。`controller`には、先ほど作成した`YoutubePlayerController`を指定します。

### 4.3 動画IDの取得

YouTube動画のIDは、YouTubeのURLから取得できます。

例えば、以下のURLの場合：

```
https://www.youtube.com/watch?v=0mwxiFOi1GQ
```

`0mwxiFOi1GQ`の部分が動画IDです。

---

## 5. おわりに

FlutterでYouTubeの動画をアプリに埋め込んで再生するには、`youtube_player_flutter`パッケージを使用するのが最も簡単で効率的な方法です。このパッケージを使うことで、YouTube動画のストリーミング再生、再生・停止・音量調整などの基本的な機能が簡単に実現できます。

この実装をベースにして、複数の動画を再生したり、動画の再生制御を追加したりすることもできます。`youtube_player_flutter`は非常に多機能で、動画のカスタマイズやインタラクションもサポートしているので、公式ドキュメントを参照しながら、自分のアプリに必要な機能を追加してみてください。

- [youtube_player_flutterの公式ドキュメント](https://pub.dev/packages/youtube_player_flutter)
忘備録： exploit code CVE-2017-12617について

１．nmapなので攻撃対象のサーバーを調べる
　今回は2017年に話題となった、Tomcatの脆弱性(CVE-2017-12617他)をれいにします。

CVE-2017-12617
　本脆弱性はTomcatにおいて書き込み可能な設定(readonly パラメータを false に設定し、HTTP PUT リクエストを受け付け可能としている場合)となっている状態のもののみが影響を受けるもので、細工したリクエストを送信されることで、遠隔から任意のコードをされてしまう恐れがあります。
　readonlyパラメータをfalseと設定されている場合には、PUTとDELETEメソッドを受け付けるようになっているため、htmlなどのコンテンツをアップロードすることは可能ですが、本来であればJSPファイルなどのファイルはTomcatの仕様上アップロードすることはできません。
　しかしながら、本脆弱性を利用し、細工したリクエストを送信することで、この制限を迂回して、任意のJSPファイルをPUTリクエストでアップロードすることが可能となってしまいます。
　これを利用し、Webshellのような指定したLinuxコマンドを実行するようなJSPファイルをアップロードすることで、リモートよりTomcatアプリケーションの動作権限にて任意のコマンドを実行されてしまう危険性があります。

 ２．https://www.exploit-db.com/に行き、 exploit codeをダウンロードする。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477527/565c16b9-82a2-ca5a-9e27-345b3c1ce367.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477527/89a8c3e5-0b3b-276a-42eb-b3a66ef33354.png)

３．以下のコマンドで攻撃コードを実行する。
　実行後、コマンドを入力できるようになり、コマンドを通じでフラグを取得できます。
> python 42966.py -u 攻撃先URL -pwn

４．サイトをリロードするとファイルがアップロードされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477527/e0c0a0de-ffb9-e766-7182-108dcea68755.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477527/502fc38e-a16a-d4dc-c3ec-f5b68d6cb04a.png)
[Git] cloneコマンドの復習（オプションが割と便利）

こんにちは！

普段から開発で `git clone` コマンドを多用してますが、オプションが便利だったので、まとめてみました。（使いそうなものだけ）

ネタ元は[こちら](https://git-scm.com/docs/git-clone)。

git cloneコマンドの主要なオプションについて、簡単にまとめます。

# Git clone の基本的なオプション

## 基本オプション

**-l, --local**
- ローカルリポジトリからクローンする際に使用
- オブジェクトの共有にハードリンクを使用して容量を節約

※使ったことないが、容量を節約できるのは良さそう

**-q, --quiet**
- 進捗状況を表示しない静かモード

**-v, --verbose**
- 詳細な情報を表示するモード

**-b <ブランチ名>, --branch <ブランチ名>**
- 指定したブランチをチェックアウト
- タグの指定も可能

※デフォルトだとmasterとかがチェックアウトされてしまうので、これはありがたい。

**--depth <数値>**
- 指定したコミット数だけの浅いクローンを作成
- リポジトリサイズを小さくしたい場合に有効

※確かに、全コミットはいらんことがある

## その他オプション

**--mirror**
- リモートの完全なミラーを作成
- すべてのブランチとタグを含む

**--no-checkout**
- クローン後に作業ディレクトリへのチェックアウトを行わない
　→ リモートリポジトリから.gitディレクトリの内容だけをコピー
- 大きなリポジトリで初期チェックアウトを避けたい場合などに便利
　→ 特定のブランチだけをチェックアウトしたい場合など

**--recurse-submodules**
- サブモジュールも含めて再帰的にクローン
- プロジェクトの依存関係もまとめて取得できる

**--shallow-submodules**
- サブモジュールを深さ1でクローン
- サブモジュールのサイズを抑えたい場合に有効


**--origin <名前>**
- リモートの名前をデフォルトの"origin"から変更

**--sparse**
- スパースチェックアウトを有効化
- 必要なファイルのみを取得可能

# 備考
上記オプションは、以下のように組み合わせて使ったりします。

```bash
# 特定のブランチを浅くクローンする
git clone --depth 1 -b develop <リポジトリURL>

# サブモジュールを含む完全なミラーを作成
git clone --mirror --recurse-submodules <リポジトリURL>
```

実務では特に `--depth`、`-b`、`--recurse-submodules` が使えそうですね。
これらの使い方を押さえておくといいかも。

# 補足
`--sparse`オプションについて補足。
以下の場合に使えそう。

**1. 巨大なモノレポの一部だけを扱いたい場合**
```
huge-monorepo/
  ├── frontend/     # Webフロントエンド
  ├── backend/      # バックエンドAPI
  ├── ios/          # iOSアプリ
  ├── android/      # Androidアプリ
  ├── docs/         # ドキュメント
  └── ml/           # 機械学習モデル
```

例えば、フロントエンド開発者は`frontend`ディレクトリのみが必要で、他は不要という場合：

```bash
# 1. sparseオプションでクローン
git clone --sparse https://github.com/company/huge-monorepo.git
cd huge-monorepo

# 2. 必要なディレクトリだけを指定
git sparse-checkout set frontend

# これで frontend/ 以下のファイルだけがチェックアウトされる
```

これ良さそうですよね。
利用ケースはそれなりにありそう。

# まとめ
普段、なんとなく使ってる `git clone` コマンドですが、大きなプロジェクトなど、オプションをうまく使うと、開発効率がアップします。
コマンドをうまく使って、ストレスの無い開発を目指しましょう！
Try Hack Me を始めるために

初めまして！セキュリティ初心者のものです。
今回アドベントカレンダーで学習習慣を得るために投稿しています。
さっそく内容を書いていきたいと思います。

## Try Hack Me とは
色々なサイトやセキュリティ関連ではかなり有名なものなので詳細は記載しません。
ペンテスター、脆弱性診断士など目指す上では得たいスキルがたくさんあると思います。
これとは別の`Hack The Box`という同じく合法的にハッキングが楽しめて学べるものがあります。
色々調べた結果はタイトルのTry Hack Me（THM）から始めると良いみたいです。
最終的にはOSCPを取得して転職するつもりです！
来年一年間で取得を目指します。
ともあれ、まずは目の前のことから始めていきたいと思います。

まず始めるために以下の書籍を参考に読んでみました。
https://www.amazon.co.jp/7%E6%97%A5%E9%96%93%E3%81%A7%E3%83%8F%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%9C%AC-TryHackMe%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E8%BA%AB%E4%BD%93%E3%81%A7%E8%A6%9A%E3%81%88%E3%82%8B%E6%94%BB%E6%92%83%E6%89%8B%E6%B3%95%E3%81%A8%E8%84%86%E5%BC%B1%E6%80%A7-%E9%87%8E%E6%BA%9D-%E3%81%AE%E3%81%BF%E3%81%9E%E3%81%86/dp/4798181579/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=35FHVGJFKZJN9&dib=eyJ2IjoiMSJ9.-B6cQz7xrb77ATtSXhyJPmxNept9bja6H32QoRCOxFCwsIpYxaGt1xb7q4tuBrd51z8ooidFxRNx_7CuI8MGWaCrQ1pkK-9dp40VLTgU7m9sjl_9urikKWls5lEqdtR65gzKz9ltaz-hmebO9z_1FiFtyKds4DAz5EUavl3rJqEPxKz1aOTLAK4nS1XSwDh77VvYLkNIm4fx9DB6iQWEcyrUYLWZ7bQWWxZEABbMds0UQoVFflvlU9yjOYF6tzGc6J2R60aCKi564PfLF-iwCbYS9ZUmL_I-KvFfBmR4_7A.JjAbO8ks70VWQyC4o8vEwxB9aLn1tm8wvGb6yOsqw4Q&dib_tag=se&keywords=%EF%BC%97%E6%97%A5%E9%96%93&qid=1732986255&sprefix=7%E6%97%A5%E9%96%93%2Caps%2C247&sr=8-1

経歴としては、プログラミング経験が５年程度、linuxのサーバーなどもかなり扱いましたので
この書籍の内容を理解するのは、容易でした。
ですが、いざ一人で行うとなるとどのように攻めていいかといった勘があまりにありませんでした。
ここの部分を養っていくことが大切と思い、とりあえずまずTHMに登録して頑張ろうと思います。

明日は実際に登録して流れを掴んでいこうと思います。
UE勉強日記2024/12/01 Overlap

ActorのBlueprintでよく利用するOverlap二種類あります。
左はactorを対象してOverlapを検知して、Event開始
右はcomponentを対象してOverlapを検知して、Event開始
![スクリーンショット 2024-12-01 015731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574567/2b760cbd-9749-5a70-d01c-ca51ec5b97fe.png)

Actorのほうはoverlapで検索するとすぐ出るが、
Componentのほうは、まず対象のcomponentをクリックして、Event graph何もないところに右ボタンおして、
検索したら出てきます。
![スクリーンショット 2024-12-01 020248.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574567/976a084a-4d0b-6a28-9571-23c96f2418d4.png)
QiitaのWebエディタのシステムを知ってアドベントカレンダー完走を目指そう！

:::note
アドベントカレンダーの啓蒙とともに、完走賞に向けた攻略記事という位置付けである
みんなで完走しよう！
:::

「普段全然意識していないであろうQiitaのWebエディタに注目してみた」というのが元々のタイトルだったが、語気強めに口角泡を飛ばした感じにしてみた。こちらの方が私っぽい気がする。

## 本題
### 1. Qiitaの記事のステータスを知ろう
当たり前の話だが、当たり前にしないために改めて見直すことにしよう。

- 公開
- 下書き
  - 公開済みの下書き（編集）
  - 未投稿の下書き（想定される下書き）
- 限定公開

ガチャガチャいじってると煩雑になってくるのではないだろうか？
気付いた頃に大掃除しよう、というのが本日の裏テーマ？である

### 2. ほしいステータス（機能）
ずばり、予約投稿！

:::note warn
そもそもQiitaに予約投稿が必要か？というと「Weekly・Monthlyバッジが欲しい」というモチベーションの場合に限られるように思う。
ちなみに、noteなどは予約を使うことでも達成可能だが、Dailyとかいうバッジもあるので予約機能を使えるうちは余裕なのだろう。
:::

アドベントカレンダーの時期になると「この記事は何日投稿にしよう」とかを決めておく事ができるのだが、これに近い機能はQiitaCLIとcrontabを組み合わせる方法しかない。
たとえば、スプレッドシートで記事IDと投稿日を持っておき、GASのトリガーで毎日監視するようにする。１日一回起動できる状態にしておけばよい。
もし心配であれば「投稿済み」ステータスを管理する項目を作り、投稿に成功したものをtrueなどつけておく方法もある。経験則として、QiitaCLIで投稿が成功した状態で投稿済みにするよりは、投稿後にQiitaAPIを使って記事情報を全件取得してIDを検索した方が確度が高いので、この方法をおすすめする。

が、ここで触れたいのは予約投稿を実現する方法ではなく「予約投稿したい記事をどうやって管理するか」である。それも、Webエディタで完結させたい。つまり、手動での運用を想定している。
たとえば、YYYY/MM/DDのようなプレフィクスを記事のタイトルに含めてしまう方法がわかりやすいだろう。
使い始めると思っている以上に便利（そもそも、こんな工夫をしなくても良いようになってほしいものである）であることに気付く。

そうなると、次のケースが課題になってくる。

### 3. 課題：記入中の下書きなのか、投稿待ちの状態なのかわからない
シンプルにプレフィクスが足りないのだ。
が、投稿予定日を記入しておいたところで、下書きは最終更新日順なので下書きの状態だけでは結局埋もれてしまう可能性も考えられる。
そこで、「下書き」と「予約投稿日待ち」と「編集中」を下書きだけで管理している状態の解消に目を向ける。
予約投稿日待ちの記事はいったん限定公開にあげてしまうという方法を使って差し支えないのであれば、その方が良いことがある。

#### 投稿キャンペーンに限った話で考える
念のため、下書きを限定公開に変更する場合は、たとえば今回でいうと2024/11/1以降が対象になるので、それまでは記事を下書きのまま寝かしっぱなしにしておく必要があるかもしれない。
なぜなら、限定公開をしてしまうと初回投稿日が確定してしまうからである。
この仕様を考えたときに、真の意味で安全に記事のストックを放出できるのは6月のエンジニアフェスタと、当月のアドベントカレンダーしかないことになる。
普段記事をストックしたい場合は、それこそQiitaCLIなどを活用して下書き状態をWebエディタから見れないようにしておくのが良いのかもしれない

### 4. 古い限定公開記事をどうするか問題
これはアドベントカレンダーの問題から離れるが、この運用方法は従来の限定公開での運用に差し支える可能性がある。
限定公開の記事を更新するタイミングが何度あるか、そもそも一般公開の記事は後日指摘があって書き換えたり、古いバージョンの内容を刷新したりする事はあるが、限定公開の場合はそれすらない事が多いのではなかろうか？

ということもあり、筆者は実質気にしない（＝無視）ようにしている。
のだが、こういった問題が生じる場合は「急がなければ予約日の後から」更新する方法はあるのではないだろうか？
というのも、予約日が過ぎれば元の限定公開記事一覧ページでしかないはずなので、ノイズになる存在も少ないかゼロになっているはず。
なので、極端な運用をしない限りは問題ない。もし管理が難しい状態になるようであれば、予約投稿のプレフィクスを見直したりする必要があるのかもしれない。

## 別解：Qiita外のシステムを使って運用する
今回私が採用している方法。厳密に言えば↑と併用して二重管理にしている。
ツールについては公開を目的にしているためGitHub IssueなりProjectsなりの記事に譲るとして、ここではあくまでQiitaそのものにフォーカスしてみよう。
まずQiitaは検索性が壊滅的なので、これを解消するためにタスク管理ツールを活用している。

もちろん、Qiitaの記事ページ上で管理する方法もある。
たとえば、管理専用の記事を作って以下のような記述をする方法

- [ ] 1/25 [記事ID] (記事リンク)
- [x] 2/25 ...

これを `https://qiita.com/(ユーザーID)/(items / private)/(記事ID)`とすれば記事リンクは作れる。
ありがたいことにQiitaのWebエディタはMarkdownのプレビューに強いので、記事１つで閲覧性を高められるなら方法としては悪くない。

ただし、専用の運用が必要であり、常にアドベントカレンダーだけをフォーカスして日々の業務を営んでいないというのがポイントになるため、Qiitaに入らなければ状況が把握できないのが悩みだ。
ちなみに、投稿管理だけであれば直接アドベントカレンダーのページに飛んでみるのが一番手っ取り早く確実だろう。

## 所感
この方法は今まさに実践中であり、結果がどうなるか。またやってみた感想などは同じくアドベントカレンダーの後半に書いて所見と反省をまとめてみようと思う。
ここでの知見は来年のエンジニアフェスタやアドベントカレンダーに活用できるかもしれない知見なので、私にとっては価値の高い情報になるのだが、一人で価値を感じても勿体ないのでぜひ活用できるところは持って行ってほしい。

なお、記事の書き方やネタだしは別途必要だが、本稿の目的ではないので別の場所で語ろう。
[Git] statusコマンドの復習

こんにちは！

今回は`git status` コマンドの復習です。
元ネタは[こちら](https://git-scm.com/docs/git-status)

# git status の概要
`git status`は、作業ディレクトリの状態を確認するためのコマンドです。
以下の情報を表示します：
- 変更済みのファイル
- ステージング済みの変更
- 未追跡（untracked）のファイル

# 基本的な使い方

### 1. 通常の確認
```bash
% git status
On branch TASK_MNG-2
Your branch is behind 'origin/TASK_MNG-2' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   src/App.tsx

no changes added to commit (use "git add" and/or "git commit -a")
```

### 2. 短い形式での表示
```bash
% git status -s
 M src/App.tsx
```

## ステータスの見方

### 短い形式（-s）での表示記号
- `??` : 未追跡のファイル
- ` M` : 変更があるが、まだステージングされていないファイル
- `M ` : 変更があり、ステージング済みのファイル
- `A ` : 新規追加されたファイル（ステージング済み）
- `D ` : 削除されたファイル

## 便利なオプション
- `-s` または `--short`: 短い形式で表示
- `-u`: 未追跡ファイルの表示をコントロール
  - `no`: 未追跡ファイルを表示しない
  - `normal`: 未追跡ファイルを表示（デフォルト）
  - `all`: 未追跡ディレクトリ内のファイルも表示

## 使用例

### 1. 変更状態の確認
```bash
% echo "新しい行" >> README.md

% git status   
On branch TASK_MNG-2
Your branch is behind 'origin/TASK_MNG-2' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md
	modified:   src/App.tsx

no changes added to commit (use "git add" and/or "git commit -a")
```

### 2. ファイルの新規作成
```bash
% touch new-file.txt

% git status -s     
 M README.md
 M src/App.tsx
?? new-file.txt
```

### 3. ステージング後の確認
```bash
% git add README.md

% git status -s    
M  README.md
 M src/App.tsx
?? new-file.txt
```

### 4. 追跡ファイルだけに絞る場合
上記で追加した`new-file.txt`が表示されなくなりました。
```bash
% git status -uno 
On branch TASK_MNG-2
Your branch is behind 'origin/TASK_MNG-2' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   src/App.tsx

Untracked files not listed (use -u option to show untracked files)
```

# まとめ
`git status`は、非常に便利なコマンドです。
ソースコードの状態について詳細な情報が得られるので、こちらも慣れておきたいですね。
2024年の terraform-jp 振り返り

# tl;dr

- この記事は[terraform Advent Calendar 2024](https://qiita.com/advent-calendar/2024/terraform)の1日目です
- [terraform-jp](https://join.slack.com/t/terraform-jp/shared_invite/enQtNTM2NTYzNDY0OTkyLTcxOTYxNmZhZmU3ZGIzOWU3M2RiODkyZTRmZTc0MjEwNjQ1NjMyZDAwMTExODc3MzkxNjAwNmU5ZDY1MTg3YTA) は昨年に引き続きオンライン以外の活動をしませんでした :bow: 

# 活動報告

- 2024年のオンライン活動はありませんでした
- 年の初めにはやるつもりだったのですが、毎月さまざまなイベントがあって、どこに差し込むか迷っているうちに年が終わってしまうという体たらくで申し訳ない

# terraform では

- v1.7.0 は2024年1月にリリースされました
- v1.8.0 は2024年4月にリリースされました
- v1.9.0 は2024年6月にリリースされました
- v1.10.0 は2024年11月27日にリリースされました
- v1.11.0 は現在ベータ版です
- 2024年12月01日）での最新は v1.10.0 です
- Terraform Cloud が HashiCorp Cloud Platform に組み込まれてとうとう HCP Terraform になりました
- Terraform Authoring and Operations Professional 試験が2024年9月に始まりました

# その他の HashiCorp 製品では

- 全体的に更新が停滞している感じ？
- nightly ビルドされている levant など更新チェックが難しい
- [hashicorp/hcp: HCP Command-Line Interface](https://github.com/hashicorp/hcp) が年始から動いているみたい？（開発自体はあまり活発でもない？）

# 来年は

- これだけやるやる詐欺しているとオフライン開催は難しそうなんですけど、なんとかしたい
- Terraform 単体で何か、というよりは組み合わせや各プロバイダに対する関心のほうが大きいと思われるので、コミュニティのあり方から考え直す必要がありそう

# 最後に

[terraform-jp](https://join.slack.com/t/terraform-jp/shared_invite/enQtNTM2NTYzNDY0OTkyLTcxOTYxNmZhZmU3ZGIzOWU3M2RiODkyZTRmZTc0MjEwNjQ1NjMyZDAwMTExODc3MzkxNjAwNmU5ZDY1MTg3YTA) を盛り上げてくれる人を引き続き募集しています。
useRefを理解する

## useRefとは
useRefは、[レンダー](https://ja.react.dev/learn/render-and-commit)時には不要な値を参照するためのフックです。

### 注意点
- `ref.current`はstateと違って変更が可能で、レンダーを跨いだ情報の保存ができます
- `ref.current`を変更しても再レンダーされません
- レンダー中に`ref.current`の値を読み取ったり書き込んだりするとコンポーネントの振る舞いが予測不能になります

### 使い方
```react
const initialValue = 100;
const ref = useRef(initialValue);
console.log(ref.current); // 100

const countUp = () => {
  ref.current += 100;
  console.log(ref.current); // 200
};

return (
  <>
    <button onClick={countUp}>useRef</button>
      {/* 画面は再レンダリングされないため100のまま */}
      <div>{ref.current}</div> 
    </div>
  </>
);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689023/b19a7b1c-fc4b-afea-a692-ae510a1354d6.png)

refは、変更しても画面上の値が変わらないため、外見に影響しないデータを保持することに適しています。

## DOMの操作

操作したいDOMノードのJSXのref属性にrefオブジェクトを渡すとcurrentプロパティにそのDOMノードが設定されます。
下記の例では、ボタンをクリックするとinputにフォーカスが当たります。

### 使い方
```React
  const inputRef = useRef<HTMLInputElement>(null);

  const handleClick = () => {
    inputRef.current?.focus();
    console.log(inputRef.current);
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={handleClick}>Click</button>
    </div>
  );
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689023/66ccb212-a8f4-2fec-d4de-458a131eb5e9.png)

参考
useRef：https://ja.react.dev/reference/react/useRef
refでDOMを操作する：https://ja.react.dev/learn/manipulating-the-dom-with-refs


小コンポーネントを親コンポーネントに公開：
https://ja.react.dev/reference/react/forwardRef
Slackアプリを作成する

## 概要

- Slackにてアプリを作成してincoming Webhookを設定する方法をまとめる。

## 前提

- 作成するアプリを連携するワークスペースとチャネルが事前に作成されていること。

## 方法

1. 下記にアクセスする。
    1. [https://api.slack.com/apps?new_app=1](https://api.slack.com/apps?new_app=1)
1. 「sign in to your Slack account」をクリックしてログインする。

    ![Slack_API__Applications___Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0ac064d9-1ed2-09e3-2fcd-de3720a42b7a.png)

1. 「Create an App」をクリックする。

    ![Slack_API__Applications___Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/359a016c-8938-be00-716a-75453447b732.png)

1. 「From scratch」をクリックする。

    ![Slack_API__Applications___Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/00026c22-ae5b-1ea2-3a55-1685883e18d3.png)

1. JSONを選択しnameキーに追加するSlackアプリ名を設定

    ![CleanShot 2024-09-02 at 23.05.52@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0b492a11-48ed-e793-fe2b-fcb1435d73e1.png)

1. 「Create」をクリック

    ![CleanShot 2024-09-02 at 23.07.49@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d2861427-f72a-c5dc-c6c6-5da3573245ed.png)
[Git] notesコマンドとは

こんにちは！

Gitコマンドについて調べていくうちに気になったので、`git notes` コマンドを使ってみました。 

元ネタは[こちら](https://git-scm.com/docs/git-notes)

### git notes とは
`git notes`は、既存のオブジェクト（主にコミット）に対して、そのオブジェクト自体を変更することなく、追加の情報（ノート）を付加できる機能です。デフォルトでは `refs/notes/commits` に保存されます。

### 主な使用目的
- コミットメッセージを変更せずに補足情報を追加したい場合
- コミット後に得られた情報（テスト結果など）を記録したい場合

### 基本的なサブコマンド
1. `git notes add`: ノートを追加
2. `git notes edit`: ノートを編集
3. `git notes show`: ノートを表示
4. `git notes remove`: ノートを削除
5. `git notes list`: ノート一覧を表示

### 実行例

まずは`git log`でコミットログを確認
```bash
% git log
commit 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec (origin/main, main)
Author: masashi yamashita <xxxxx@gmail.com>
Date:   Mon Sep 2 21:41:51 2024 +0900

    readmeを修正

```

このままnotesを確認すると、ノートが無いよ、と言われます。

```bash
% git notes show 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec
error: no note found for object 67a81df9128a78004f2ed41d85ee3d410b390eec.
```

このコミットに対して、ノートを追加します。

```bash
% git notes add -m 'noteコ マンドのテスト' 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec
```

ノートを確認してみます。

```bash
% git notes show 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec
noteコマンドのテスト
```

`git log`はどうなっているでしょうか。

```bash
% git log 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec
commit 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec (origin/main, main)
Author: masashi yamashita <xxxxx@gmail.com>
Date:   Mon Sep 2 21:41:51 2024 +0900

    readmeを修正

Notes:
    noteコマンドのテスト

```

Notesに追加されてましたね！
次に、上書きしてみます。

```bash
% git notes add -f -m 'ノートを上書き' 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec  
Overwriting existing notes for object 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec

% git log 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec                        
commit 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec (origin/main, main)
Author: masashi yamashita <xxxxx@gmail.com>
Date:   Mon Sep 2 21:41:51 2024 +0900

    readmeを修正

Notes:
    ノートを上書き

```

さらに、編集してみます。
コマンドを実行すると、エディタが起動し、編集できました。

```
% git notes edit 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec
```

```
ノートを編集

#
# Write/edit the notes for the following object:

# commit 67axxdf9128a78xx4f2ed41d85ee3d410xx90eec
# Author: masashi yamashita <xxxxx@gmail.com>
# Date:   Mon Sep 2 21:41:51 2024 +0900
#
#     readmeを修正
#
#  README.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
#  1 file changed, 76 insertions(+), 16 deletions(-)
```

確認すると、修正が反映されてました。

```
% git log 67a81df9128a78004f2ed41d85ee3d410b390eec
commit 67a81df9128a78004f2ed41d85ee3d410b390eec (origin/main, main)
Author: masashi yamashita <june.twelve.2010@gmail.com>
Date:   Mon Sep 2 21:41:51 2024 +0900

    readmeを修正

Notes:
    ノートを編集

```

# まとめ

`git notes` コマンドを使うと、コミット履歴をきれいに保ったままで、必要な補足情報を管理できます。
このコマンドを活用して、分かりやすい開発を行いましょう！
TerraformでOktaのアプリカタログからアプリケーションを作成する方法

## はじめに

この記事は[DENSO Advent Calendar 2024](https://qiita.com/advent-calendar/2024/denso)の3日目の記事です。
Terraform を使った Okta の構成について調査していた際に得た知見を紹介します。

## Okta アプリケーションの作り方

Okta のダッシュボードからアプリケーションの作成をする場合、`Create App Integration`、`Browse App Catalog` のどちらかから実行できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134812/1fa5eaf4-eabd-14e6-3998-a8b85f48ec85.png)

この `Browse App Catalog` からの作成では、ユーザーが一から設定を行う必要はなく、様々なアプリへの SSO を簡単に設定できるので、非常に便利です。Okta やアプリ側のドキュメントにて、この導線でのアプリ連携の方法は丁寧に解説されているので良く使っています。

例えば、Github との連携方法のドキュメントは以下です。

https://docs.github.com/ja/enterprise-cloud@latest/organizations/managing-saml-single-sign-on-for-your-organization/configuring-saml-single-sign-on-and-scim-using-okta

## Terraform での Okta アプリケーションの作り方

Terraform は Okta の構成管理にも使えます。

https://registry.terraform.io/providers/okta/okta/latest/docs

から、`okta_app_saml` を使います。

このリソースを作成する際に、`preconfigured_app` に所定のパラメータを与えることで、`Browse App Catalog` から選択してアプリを作成した場合と同じ様に SSO の設定を簡略化して実行することができます。

>preconfigured_app (String) Name of application from the Okta Integration Network. For instance 'slack'. If not included a custom app will be created. If not provided the following arguments are required: 'sso_url' 'recipient' 'destination' 'audience' 'subject_name_id_template' 'subject_name_id_format' 'signature_algorithm' 'digest_algorithm' 'authn_context_class_ref'

以下は Slack の SAML SSO アプリケーションを作成するサンプルコードになります。この様に記述した tf ファイルを作成して実行することで、`Browse App Catalog` で `slack` を検索して選択可能なカタログから作成したものと同等の設定でアプリケーションの作成を完了できます。

```
terraform {
  required_providers {
    okta = {
      source  = "okta/okta"
      version = "4.11.1"
    }
  }
}

provider "okta" {
  base_url = "okta.com"
}

resource "okta_app_saml" "slack_sso" {
  accessibility_self_service = false
  app_settings_json = jsonencode({
    domain = "your-workspace-domain.slack.com"
  })
  assertion_signed            = false
  auto_submit_toolbar         = true
  hide_ios                    = false
  hide_web                    = false
  honor_force_authn           = false
  implicit_assignment         = false
  label                       = "Slack SAML SSO"
  preconfigured_app           = "slack"
  response_signed             = false
  saml_signed_request_enabled = false
  saml_version                = "2.0"
  status                      = "ACTIVE"
  user_name_template          = "$${source.login}"
  user_name_template_type     = "BUILT_IN"
}
```
作成後、Okta アプリケーション内のメタデータを使って Slack 側の SSO 設定を完了させることで SSO 可能になります。`OKTA_API_TOKEN`, `OKTA_ORG_NAME` を環境変数に設定して実行するのを忘れないでください。

## `preconfigured_app`のパラメータの調べ方

`preconfigured_app` に指定するパラメータは、手動で `Browse App Catalog` から作成した所望のアプリケーションの `okta_app_saml` のデータを出力して確認することができます。

```
data "okta_app_saml" "hoge" {
  label = "Slack SAML SSO"
}

output "hoge" {
  value = data.okta_app_saml.hoge
}
```

上記のコードを tf ファイルに追記して、`terraform apply` を実行することで出力から `preconfigured_app` に指定すべき値を確認できます。

```
Changes to Outputs:
  + hoge = {
        :
      + name = "slack"  <- ここ
        :
    }
```

## 終わりに

`preconfigured_app` に指定する値の調べ方については、きっとより良い方法があると思うので、見つけたらアップデートします。
python基礎で押さえておきたいポイント

アウトプット用です。

https://www.udemy.com/course/python-ai/
私がこちらの講座を受講して押さえておきたいポイントについてアウトプットします。

## *args, **kwags
### *argsについて
1つしか定義していないのなら、渡す引数は1つだが
この可変長引数というもので不特定多数の引数を渡すことができる
**args**という文字は慣習的なもので別名に変更可能
ただ、特に理由がない場合は**args**を使用
```python
def delivery(*args):
    print(f"{args}を受け取った")

delivery("ご飯", "Apple", 5555)
# ("ご飯", "Apple", 5555)を受け取った！
```
このように3つ引数を渡してもエラーせずに処理をしてくれる
**return**はタプル型で返ってくる

### **kwargs
こちらは*argsと違ってくる部分はreturnがディクショナリー型で返ってくること。
```python
def func_kwargs(**kwargs):
    print(kwargs)

func_kwargs(param1=1, param2=3, param3=5)
# {'param1': 1, 'param2': 3, 'param3': 5}
```

## __ name __ と __ main __
とあるファイルを呼び出す際に実行しないようにするもの
具体的には以下の例がある

```module/mymodule.py
def todayfunc():
    print("This is today function!!")


def tomorrowfunc():
    print("this is tomorrow function!!")

print("This is todaymodule!!")
```


```module/yourmodule.py
import mymodule

def yourfunc():
    print("This is your function!!")

yourfunc()
mymodule.todayfunc()

# This is your function!!
# This is today function!!
# This is todaymodule!!
```
おかしい...
なんでmymodule.pyでprintしたものが実行されているの？!

こうなららないために**アレ**が必要なんです

### つまり__ name __ と __ main __　ってなんぞや？
一回printしてみましょう
```module/yourmodule.py
print(__name__)
```
```module/mymodule.py
print(f"mymodule.__name__:{__name__}")
```
この2つのprintを**yourmodule.py**で実行すると以下のような結果が返ってきました。（1行目がにyourumodule.py、2行目がmymodule.pyに記述されたもの）
```
# __main__

# mymodule.__name__:mymodule
```

:::note info
__ name __ はimportされると自分のモジュール名が入ってスクリプト自体が実行されると __ main __ が入る<br>
つまり実行される場所によって__ name __ の実行結果が変わる
:::
よってimportする際に実行されたくない部分があった際は以下のように書くと実行されなくなる
```module/mymodule.py
if __name__ == "__main__":
    print(f"mymodule.__name__: {__name__}")
```
随時更新します！