OmniAICreator/Qiita-1.07M huggingface dataset:
n数が少ない場合に自動的にマスクをかける処理をTableauで実装する方法


## ロジック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216166/59a533d1-e82e-8109-4042-d84a87cf7f11.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216166/9991c2d9-5458-d308-e05d-328be8ef39f4.png)


## 実装イメージ

グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216166/9411fd07-65d0-c238-2155-26e542de189f.png)

集計表
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216166/0f794b4a-0228-b393-d7bf-d9db5fdd3659.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216166/c0bff980-1041-c932-138b-7cb7dfb14a1d.png)


## 計算フィールド

### 01_マスク判定の前処理

- p-01_人数
```
SUM(cnt)
```

- p-02_ランク_人数
```
RANK_UNIQUE([p-01_人数],'asc')
```

- p-03_マスク対象件数
```
WINDOW_COUNT([p-01_人数])
-
WINDOW_COUNT(IF [p-01_人数]<=[00_閾値] THEN null ELSE [p-01_人数] END)
```

- p-04_マスク＆追加マスク対象判定
```
IF 
[p-01_人数]<=[00_閾値] 
OR
(
[p-03_マスク対象件数]>=1
AND
[p-02_ランク_人数]<=2
)
THEN 1 ELSE null END
```

- p-05-1_マスク対象判定
```
IF 
[p-01_人数]<=[00_閾値] 

THEN '*' ELSE null END
```

- p-05-2_追加マスク対象判定
```
IF 
[p-01_人数]>[00_閾値] 
AND
(
[p-03_マスク対象件数]>=1
AND
[p-02_ランク_人数]<=2
)
THEN '**' ELSE null END
```
---
### 02_グラフ作図用

- o-01_人数
```
SUM(cnt)
```

- o-02_人数_全体割合
```
[o-01_人数]/TOTAL([o-01_人数])
```

- o-03_売上
```
SUM([sales])
```
---
### 03_マスク済_テキスト表示用

- h-01_人数
```
IF [p-04_マスク＆追加マスク対象判定]=1 THEN null 
ELSE  [o-01_人数] END
```

- h-02_人数_全体割合
```
IF [p-04_マスク＆追加マスク対象判定]=1 THEN null 
ELSE [o-02_人数_全体割合] END
```

- h-03_売上
```
IF [p-04_マスク＆追加マスク対象判定]=1 THEN null 
ELSE  [o-03_売上] END
```
---

ラベル
```
<集計(p-05-1_マスク対象判定)><集計(p-05-2_追加マスク対象判定)><集計(h-02_人数_全体割合)>
```

## 参考データ

- サンプルデータ

|sex|age|cnt|sales|
|:-:|:-:|:-:|:-:|
|male|20|1|200|
|male|30|6|300|
|male|40|20|400|
|male|50|20|500|
|male|60|50|600|
|male|70|20|700|
|male|80|20|800|
|male|90|20|900|
|male|100|20|1000|
|female|10|1|100|
|female|20|6|200|
|female|30|6|300|
|female|40|20|400|
|female|50|20|500|
|female|60|50|600|
|female|70|20|700|
|female|80|20|800|
|female|90|20|900|
|female|100|20|1000|

- tableau
https://public.tableau.com/app/profile/hikaru.uchiya3499/viz/_17293081562350/2-2
Contract Upgrades with Incompatible Changes

[Previous << Guide for Solidity Developers](https://qiita.com/flowcadence/items/13279fc2ca2970c3e433)
[Next >> JSON-Cadence format](https://qiita.com/flowcadence/items/24135a1ea2f755e7fd19)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#cadenceの言語仕様を学ぶ

<h1 id="Problem">Problem</h1>

互換性のないスマートコントラクトのアップグレードがあります。これをデプロイするにはどうすればよいですか？

<h1 id="Solution">Solution</h1>

同じアカウント内のコントラクトバージョン間で互換性のないアップグレードを行わないでください。問題が発生する可能性が高すぎます。

[互換性のあるアップグレード](https://qiita.com/flowcadence/items/af1cfaf57838ed7f2401)を行い、必要に応じて新しいコントラクトコードでアップグレード後の関数を実行することができます。

コントラクトを更新するのではなく置き換える必要がある場合は、互換性のない変更を行うことに加えて、コントラクトコード内の任意の名前付きパスに接尾辞を追加または増やす（例：`/public/MyProjectVault`が`/public/MyProjectVault002`になる）という最もシンプルな方法があります。その後、新しいアカウントを作成し、更新したコントラクトをそこにデプロイします。

⚠️ Flowはアドレスに関連するタイプを識別するため、古いコントラクトのリソースを新しいコントラクトのリソースと交換するためのアップグレードトランザクションも提供する必要があります。ユーザーに、このタスクをいつどのように実行する必要があるかをできるだけ早く伝えるようにしてください。

互換性のないアップグレードを行う際に、どうしても古いアドレスを維持する必要がある場合は、ご自身の責任において行ってください。以下のアクションをこの順序で実行するようにしてください。

   1. コントラクトアカウントで使用されているリソース（例えば、管理リソース）を削除します。
   1. アカウントからコントラクトを削除します。
   1. アカウントに新しいコントラクトをデプロイします。

⚠️注意：ユーザーアカウントに、古いバージョンのコントラクトから新しいバージョンで互換性のないバージョンに置き換えられた`structs`または`resources`が含まれている場合、それらはロードされず、それらにアクセスしようとするトランザクションがクラッシュする可能性があります。このため、ユーザーがコントラクトから`structs`または`resources`を受け取った後は、互換性のないアップグレードを行うこの方法は試さないでください！

翻訳元

https://cadence-lang.org/docs/contract-upgrades

***
<b>[Previous << Guide for Solidity Developers](https://qiita.com/flowcadence/items/13279fc2ca2970c3e433)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Contract Upgrades with Incompatible Changes)

<b>[Next >> JSON-Cadence format](https://qiita.com/flowcadence/items/24135a1ea2f755e7fd19)</b>
無線LANのアクセス手順

# 手順
A:無線LANノードとB:アクセスポイントとの間で行われる
① AからBにビーコン信号の受信と接続
② BとA同士でSSIDの確認
③ BとA同士で暗号方式の確認

#### アクセスポイントとは
https://qiita.com/masatom86650860/items/007ff03845ff012d98ed

# ビーコン信号の受信と接続
>アクセスポイントは常に、`自身のSSIDを含むビーコン信号をブロードキャスト送信`しているので、無線LANを使うノードは、`このビーコンによりアクセスポイントを認識して通信を始めます`。ただし、`自身のSSIDを公にすると、誰でもSSIDが取得できてしまうため不正侵入の危険性が高く`なります。そこで、`SSIDの発信を停止する機能にステルス機能`があります。ステルス機能を用いると、事前にSSIDを知っているノードだけがアクセスできるようになります。

自宅のアクセスポイントはステルス機能になっているのか？
SSIDが取得できたとしてどうやって侵入するのか？

# SSIDの確認
>`基本的には、同一のSSIDを設定したノードだけに接続を許可`しますが、どのノードからの接続も受け入れるという場合もあります。この場合は`ANY接続`を許可します。ノードが`SSIDをANYとして接続すると無条件に接続が許可`されます。
　なお、`多くのアクセスポイントは、MACアドレスフィルタリングに対応`しています。`利用するノードのMacアドレスをあらかじめ登録しておくと、それ以外のノード空のアクセスを拒否してセキュリティを向上`できます。

同一のSSIDを設定したノードだけに接続許可するのか。
Macアドレスを登録しておくとそれ以外はアクセス拒否できることもできるのか。
any接続も調べたくなった。

# 暗号方式の確認
>送信するパケットを暗号化する手続きを行います。

暗号化に関しては

https://qiita.com/masatom86650860/items/17e761668460031620b9

ここからLANに接続されていくのか。

https://gihyo.jp/book/2023/978-4-297-13865-3

# 感想
次から次に調べ物が増えてくる。どこまで調べたらいいのだろうか？
楽しいからいいのだが
OMC231A

https://onlinemathcontest.com/contests/omc231/tasks/11682

$∣x∣+∣y∣+∣z∣≤1$を満たす範囲は、
$(1,0,0),(0,1,0),(0,0,1),(-1,0,0),(0,-1,0),(0,0,-1)$が頂点の正八面体の内側。

正三角形の一辺の長さが$\sqrt{2}$なので、高さは$\frac{\sqrt{2}×\sqrt{3}}{2}$となり、正三角形$1$つの面積は$\sqrt{2}×\frac{\sqrt{2}×\sqrt{3}}{2}÷2=\frac{\sqrt{3}}{2}$。

$x+y+z=0$($≥$ではなくて、まずは$=$)を満たす範囲は、$(0,0,0)$を通り$(1,1,1)$方向のベクトルと垂直な平面。
で、$x+y+z=0$は、正八面体の真ん中を通るので体積は正八面体の半分になる。

この問題は体積ではなく、表面積を問われている。
ただし表面積は、正三角形$8$個の半分の$4$個と切り口の面積なので切り口の形から考えていく。
($4$個は深く考えてないが、中心で分けたら対称になるだろうし、たぶん大丈夫。)

切り口の$x+y+z=0$は、たぶん$(1,0,0),(0,1,0),(0,0,1)$を通る平面と$(-1,0,0),(0,-1,0),(0,0,-1)$を通る平面のちょうど中間にある気がする。
正八面体の辺の数は$12$本。
上記の$2$つの三角形の辺の数$6$本を引くと、残り$6$本。
これは正六角形になる予感。
一辺は正三角形の一辺の半分の$\frac{\sqrt{2}}{2}$。なので正三角形$1$つの$\frac{3}{2}$倍の面積。
(ここまで何も根拠なしの思い込みで来てる。)

したがって、表面積は正三角形の面積$×(4+\frac{3}{2})$
$=\frac{\sqrt{3}}{2}×\frac{11}{2}$
$=\frac{11\sqrt{3}}{4}$
$=\sqrt{\frac{363}{16}}$

$a+b=363+16=379$

一応、根拠がないまま正解してしまったので、解説を確認したが、何を言っているのか理解できず、ユーザー解説に至ってはこの記事とまったく同じことをしていた。(この解き方が正しいかどうかの根拠は示されていなかった。)
クリーンアーキテクチャ本におけるユースケースのインターフェースの役割は何なのか？

# はじめに

クリーンアーキテクチャ本におけるユースケースのインターフェース（Usecase Input Port, Output Port）の役割について、個人的な見解を述べたいと思います。というのも、ユースケースを呼び出すのはユースケースの外側に位置するInterface Adapter層であり、依存性逆転を行わなくても依存関係は問題ないからです。つまり、ユースケースのインターフェースが存在しなくても、依存の方向には影響を与えないのではないか、あるいは不要ではないかということです。この場合、ヘキサゴナルアーキテクチャの考えについて理解を深めることで、その必要性が分かると思います。

※クリーンアーキテクチャとはなんぞや？という方向けに執筆した記事もありますので、必要であればそちらを先にお読みいただければと思います：**[クリーンアーキテクチャを少し説明できるようになれる記事](https://qiita.com/o-y/items/755cb47f733687e8331f)**

# 最初に結論
結論から言うと、**ユースケースのインターフェースはヘキサゴナルアーキテクチャのポートと同じ役割**を果たします。ユースケースのインターフェースは、依存性逆転を実現するというよりも、広い意味でのインターフェース（疎結合、交換容易性、明確な規約）としての意味が強いと考えています。

# ヘキサゴナルアーキテクチャとは
ヘキサゴナルアーキテクチャ（またはポート＆アダプタパターン）は、アプリケーションのビジネスロジックを中心に据え、その周囲に外部要素（データベース、外部サービスなど）を配置する設計手法です。これにより、内部のアプリケーションのビジネスロジックが外部要素の影響を受けないことを実現します。クリーンアーキテクチャはヘキサゴナルアーキテクチャの影響を受けており、根幹の考えは両者とも同じです。
ヘキサゴナルアーキテクチャでは、ユースケース（アプリケーションのコア）はポート（インターフェース）を介して外部（アダプタ）とやり取りを行います。これにより、アダプタの付け替えが簡単になります。

# クリーンアーキテクチャ本におけるユースケースのインターフェースの役割
依存性逆転ではなく、インターフェースを利用する一般的なメリットと同様です。
## テスト・交換容易性
前提としてクリーンアーキテクチャの考えとしては、あらゆる層でテストを容易にします。
- ユースケースを使う側（例えばコントローラーなど）の単体テストをやりやすくするためにユースケースをモックにする
- フロントエンド開発とサーバーサイド開発で分業されている場合、フロントエンド開発を行いやすくするためにユースケースをモックにして固定値を返すようにする

この場合特にモックにする必要性がなければ、必要になったタイミングでインターフェースを作成するでも良いかと思います。


## 明確な契約の提供
個人的にはこちらの役割が特に重要だと思います。インターフェースがあることで、ユースケースを利用する側にとって、ユースケースが何を期待し、どのような出力を生成するのかを明確に定義します。

PCを充電するというユースケースで例えてみましょう。PCがアプリケーションのコア、PCの側面にあるUSB Type-Cの接続穴がインターフェース（ポート）、充電ケーブルがアダプタです。PCの接続穴を見るだけで、「これはType-Cのケーブルを使えば充電できるな」と理解できます。アダプタである充電ケーブルは、100円ショップで買った安価なものでも、PC購入時に付属している純正のものでも、Type-Cに対応していれば何でも問題ありません。

ユースケースのシグネチャを見れば使い方が分かるので十分という方は、必要になったタイミングでインターフェースを作成するでも良いと思います。（不必要にインターフェースを用意すると逆に複雑性が増すと感じる方もいらっしゃるので）

# 終わりに
タイトルについて回答すると、「テスト・交換容易性」と「ユースケースを利用する側が、このユースケースは何を期待して、何を出力するのかをすぐに理解できる役割」を果たすと考えています。もしインターフェースが存在しない場合、使う側はユースケースの実装の詳細を理解する必要があります。小規模なアプリケーションであれば問題ないかもしれませんが、アプリケーションは複雑になるものです。インターフェースがあることで複雑になるデメリットもありますが、将来的なことを考えると、インターフェースを用意した方がクリーンアーキテクチャの思想に沿っていると思います。
一度実行したら消滅する自爆式バッチファイル

# 概要
一度実行したら自らを削除するバッチファイルの挙動について考察する．
どちらかといえば，筆者が気になったことの確認とその記録，という意味合いが強い．

# 詳細
次のようなバッチファイルを考える．
```bat:self-destruct.bat
chcp 65001
echo このバッチファイルは5秒後に消去されます
powershell sleep 5
del /Q "C:\Users\denkiuo604\self-destruct.bat"
```
この `self-destruct.bat` を実行すると，実行開始から5秒後に，実行終了とともに `self-destruct.bat` が削除される．

## 問題
次のバッチファイル `self-destruct-log.bat` を実行したとき，ファイル `self-destruct.log` は生成されるか．
```bat:self-destruct-log.bat
chcp 65001
echo このバッチファイルは5秒後に消去されます
powershell sleep 5
del /Q "C:\Users\denkiuo604\self-destruct-log.bat"
echo 実行ログを出力しました．バッチは5秒後に終了します． > "C:\Users\denkiuo604\self-destruct.log"
powershell sleep 5
```

<details><summary><strong>解答</strong></summary>

ファイル `self-destruct.log` は**生成されない**．

`del` コマンドが実行された時点でバッチは終了する．
ちなみに，`del` コマンド実行後は (一瞬しか表示されないが) 次のような出力になる．
```
C:\Users\denkiuo604>del /Q "C:\Users\denkiuo604\self-destruct-log.bat"
The batch file cannot be found.

[プロセスはコード 1 (0x00000001) で終了しました]
このターミナルを Ctrl+D で閉じるか、Enter キーを押して再起動できます。
```
</details>

# 参考文献
- [実行中のバッチファイルを書き換えるとどうなるか #バッチファイル - Qiita](https://qiita.com/szly/items/a98a67a098dfed4f774d)
アプリ開発に参照した文章リスト

アプリ開発に参照した文章リスト

1,【Mac不要】.NET製iOSアプリをiPhone実機配備する手順
https://qiita.com/kami_teru/items/58b6b5e4fd835248bf7a
(https://www.joshmorony.com/how-to-create-an-ios-provisioning-profile-and-p12-with-windows/)
【JavaScript】アロー関数でオブジェクトを返り値とする場合

## 前提
アロー関数には、ある条件を満たした場合のみ省略する書き方が存在する。
1\. 引数が1つの場合は、`()`を省略できる
```javascript
// 通常のアロー関数
const square = (number) => {
  return number * 2;
}

// 引数部分の()を省略
const square = number => {
  return number * 2;
}
```
2\. 関数の本体が1行であれば、`return`と`{}`を省略できる
```javascript
// 通常のアロー関数
const square = number => {
  return number * 2;
}

// `return` と `{}` を省略
const square = number => number * 2;
```
## 本題
前提2に記した方法でオブジェクトを返そうとした場合、
以下の書き方ではエラーとなってしまう。
```javascript
// NG：`{}`が1つだけ
const square = number => { result: number * 2 }

// NG：`{}`を2重にする
const square = number => {{ result: number * 2 }}
```
アロー関数でオブジェクトを返す場合は、返り値となるオブジェクトを`()`で囲う必要がある。
```javascript
// OK
const square = number => ({ result: number * 2 })
```
無線LANのアクセス手順に関する用語

#### ノード
>コンピューターやプログラムなどのネットワーク（システム）を構成する個々の要素をノードと呼びます。

https://www.hokuyo-aut.co.jp/products/data.php?id=335#:~:text=%E3%83%8E%E3%83%BC%E3%83%89%E3%81%A8%E3%81%AF,%E3%82%92%E3%83%8E%E3%83%BC%E3%83%89%E3%81%A8%E5%91%BC%E3%81%B3%E3%81%BE%E3%81%99%E3%80%82

#### アクセスポイント
https://qiita.com/masatom86650860/items/007ff03845ff012d98ed

ルーターと違いがあるようだがそれは今度

#### ビーコンとは
>`何かを誘導したり、信号を送ったりするものを指す「ビーコン（Beacon）」`は、航海や航空分野での`物理的な信号灯から、デジタル通信技術に至るまで幅広く利用`されています。例えば、航海においては灯台がビーコンとして、船舶が安全な航路を見つけるためのガイドとして重要な役割を果たしています。また、高速道路などに設置されているビーコンは、渋滞や交通規制などの道路交通情報を、リアルタイムにカーナビゲーションなどの車載器に送信しています。
>
>デジタル端末では、`ビーコンから無線による信号を発信し、信号を受信できる端末があればその位置を返す仕組みが用いられています`。この仕組みを利用して、位置情報をもとに訪問者のスマートフォンに対して情報を送信することにより、パーソナライズされた通知や案内を提供することが可能です。例えば、商業施設や駅、空港などの施設内でフロアガイドなどを配信したり、店舗で利用できるクーポンを配信したりなど、顧客体験の向上や効率的な情報伝達に役立つツールとして注目されています。また、鍵や財布など貴重品に小型のビーコンを取り付けておき、離れたときにスマートフォンに通知を送ることで、紛失を防止するサービスにも使われています。
>
>スマートフォンの普及によりBluetoothの信号を受信できる端末が増えたことで、今後も「ビーコン」の活用範囲が広がることが期待されています。

https://www.softbank.jp/sbnews/entry/20240321_02#:~:text=%E4%BD%95%E3%81%8B%E3%82%92%E8%AA%98%E5%B0%8E%E3%81%97%E3%81%9F,%E6%9C%9F%E5%BE%85%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

#### SSID
>SSID(Service Set Identifier)とは、`Wi-Fiネットワーク名`のことです。最大32文字の半角英数字で識別されます。
>
>スマホやパソコンなど、デバイス側でWi-Fiに接続するための設定をするときにWi-Fiネットワークの一覧に表示される名前がSSIDです。SSIDは通常、接続の際にデバイス側で入力するパスワード(暗号化キー)とセットで利用されます。

https://nttdocomo-ssw.com/nssw/dhkr/ouchinetpress/communication/article571/#:~:text=%E5%BD%B9%E7%AB%8B%E3%81%A6%E3%82%88%E3%81%86-,SSID%E3%81%A8%E3%81%AF,%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89(%E6%9A%97%E5%8F%B7%E5%8C%96%E3%82%AD%E3%83%BC)%E3%81%A8%E3%82%BB%E3%83%83%E3%83%88%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82,-SSID%E3%82%92%E7%A2%BA%E8%AA%8D

>街中や電車の中でスマートフォンのWi-Fi設定を見た時、周辺にあるアクセスポイントのリストがズラリと並んでいることがあります。そのリストに表示されている`各アクセスポイントの「名前」がSSID`です。

https://www.elecom.co.jp/pickup/column/wifi_column/vol09/#:~:text=%E8%A1%97%E4%B8%AD%E3%82%84%E9%9B%BB%E8%BB%8A%E3%81%AE%E4%B8%AD%E3%81%A7%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%B3%E3%81%AEWi%2DFi%E8%A8%AD%E5%AE%9A%E3%82%92%E8%A6%8B%E3%81%9F%E6%99%82%E3%80%81%E5%91%A8%E8%BE%BA%E3%81%AB%E3%81%82%E3%82%8B%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E3%83%AA%E3%82%B9%E3%83%88%E3%81%8C%E3%82%BA%E3%83%A9%E3%83%AA%E3%81%A8%E4%B8%A6%E3%82%93%E3%81%A7%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%E3%81%9D%E3%81%AE%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%90%84%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E3%80%8C%E5%90%8D%E5%89%8D%E3%80%8D%E3%81%8CSSID%E3%81%A7%E3%81%99%E3%80%82
ingressの後片付けをせずにGKE消したらえらいことになった

# 何が起きたか
検証目的でGKEクラスタをデプロイし、ingressでいくつかのサービスを公開したのち、マニフェストを削除せずにクラスタを削除した。その結果、ネットワーク関係のリソースがあちこちに残ってしまい、VPCとサブネットを削除できなくなった

# どう起こしたか
GKEおよびネットワークリソースをterraformで作成していた。その後、GKEクラスタ上にingressやgatewayリソース、およびdeploymentやserviceリソースをデプロイした。このとき、GKEのingressコントローラなどによってGoogleCloud上にロードバランサなどのネットワークリソースが作成された。
本来なら用済みになったリソースを削除するとき、まずGKEクラスタ上のリソースを削除することで、コントローラが削除したGoogleCloudのリソースを削除し、その後terraformでネットワークやGKEクラスタを削除する必要があった。しかしこの手順を失念し、いきなりterraformからGKEクラスタとVPCを削除しようとした。
その結果、まずGKEクラスタが削除され、その後VPCを削除する段でエラーが発生した。
```
google_compute_network.my_network: Destroying... [id=projects/project/global/networks/my-network]
google_compute_network.my_network: Still destroying... [id=projects/project/global/networks/my-network, 10s elapsed]
╷
│ Error: Error waiting for Deleting Network: The network resource 'projects/project/global/networks/my-network' is already being used by 'projects/project/global/firewalls/gkegw1-wlur-l7-my-network-global'
│ 
```
GKEクラスタが削除された際にクラスタ上のリソースも削除されたが、コントローラごと一度に削除されたため、本来実行されるべきコントローラが作成したリソースの削除が行われなかった。結果として、ロードバランサやファイアウォールルールなどのネットワークリソースが残ったままとなり、terraformがVPCを削除できなくなってしまった。

# どう解決したか
関連するネットワークリソースを一つ一つ手動で削除した。削除したリソースは以下のとおり。
* ファイアウォールルール
* ロードバランサ
* ロードバランサのバックエンド
* ネットワークエンドポイントグループ

今この記事では列挙できているが、実際のところ一つ消しては`terraform destroy`を実行し、VPCを使用中のリソースを確認しては削除し、という手順を踏んだので非常に面倒だった。

# どうするべきだったか
そもそもGKEクラスタを削除する前に、クラスタ上のリソースを全て削除しておけばよかった。本来コントローラが作成したリソースだから、コントローラに削除させればこの面倒はなかった。
また、リソースのタグ付けを行うことも有効だと感じた。実際のところファイアウォールルールなどは全てのリソースが列挙される上に、リソース名からGKEクラスタ名を手繰ることができない。特にロードバランサは完全にランダムな文字列で名付けられている。このため、どのリソースを削除するべきかの判断に困った。どのリソースが何の作業で作成したものか、タグ付けをしていればフィルタリングが容易だったと思う。
【初心者向け】知らなかった！justify-contentで垂直方向も簡単レイアウト！

こんにちは。
CSSでレイアウトを組む時にFlexbox(フレックスボックス)をよく使いますよね。
このFlexboxには、justify-contentというプロパティがあります。justify-contentといえば、水平方向に要素を配置するためのプロパティだと思っている方も多いのではないでしょうか。実は、私もその一人でした。しかし、最近になって、このプロパティが水平方向だけではなく、垂直方向も設定できることを知りました。
この記事では、justify-contentで垂直方向の配置を設定できるという新たな発見を共有したいと思います。

# Flexboxの主軸
justify-contentで垂直方向の配置を設定するためには、<font color="red">**Flexboxの主軸を理解することが不可欠**</font>です。
主軸の説明に関しては、MDNに掲載されておりましたので引用させていただきました。リンク先には、参考画像も掲載されていますので、興味のある方はご覧になってください。

>**Main Axis (主軸)**
flexbox における主軸は、flex-direction プロパティの設定方向によって定義されます。flex-direction が取り得る値は以下の 4 つです。

>row
row-reverse
column
column-reverse

>row または row-reverse を選んだ場合は、主軸はインライン要素の並ぶ方向に伸びる軸となります。
column または column-reverse を選んだ場合は、ページの上から下に向かってブロック要素の並ぶ方向に伸びる軸となります。

※引用：MDN

https://developer.mozilla.org/ja/docs/Glossary/Main_Axis

上記の通り、<font color="red">**主軸はflex-directionプロパティによって、水平方向や垂直方向に設定**</font>することができます。
補足になりますが、display:flexの初期状態は、flex-direction:rowです。つまり、要素は水平方向に並びます。

# 何故justify-contentで垂直方向の配置が設定できるのか
勘のいい方はすでにお気づきかと思いますが、<font color="red">**主軸が垂直方向に設定されると、その主軸に沿って、レイアウトを設定することができます。**</font>
どういうことか実際にやってみましょう。

以下の例では、主軸を変更することで要素の配置がどのように変化するか表現しています。**ボタン**を押して変化を確認してみてください。
※初期の主軸は水平方向です。

<p class="codepen" data-height="300" data-default-tab="html" data-slug-hash="MWNpWME" data-pen-title="justify-content:space-between  横軸＆縦軸" data-user="iwdulmiq-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/iwdulmiq-the-builder/pen/MWNpWME">
  justify-content:space-between  横軸＆縦軸</a> by 丸山悠希 (<a href="https://codepen.io/iwdulmiq-the-builder">@iwdulmiq-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
※ "Result"ボタンを押すとプレビューが表示されます。

解説をしますと…
**１．flex-direction:rowボタンを押した時**
水平方向にjustify-content: space-betweenが適用される。

**２．flex-direction:columnボタンを押した時**
垂直方向にjustify-content: space-betweenが適用される。

上記のように主軸に沿って、justify-contentが適用されているのが分かりましたね。これによって、垂直方向のレイアウトが簡単に行うことができます。

# まとめ
「justify-content」は、要素を主軸に沿って配置するための便利なプロパティです。私のように、水平方向に要素を配置するためのプロパティと理解している方もいるかと思い、垂直方向でも同様に使えることを紹介しました。
この記事を通して、Flexboxを使った新たなレイアウト法を身に付けることができたのではないでしょうか。引き続き、Webデザインに関する情報を発信していきますので、皆さんの学びに少しでも役に立てば幸いです。
ここまでお読みいただきありがとうございました。
RMeCabで頻出単語を抽出する

## はじめに

実務で、自由回答アンケート内の頻出単語をRMeCabで抽出し、可視化する機会があったため、メモ書きとして残しておくことにします。

なお、今回はChatGPTで作成したサンプルデータを使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/07a6c474-ae93-1de2-b9d5-7b559f67aad3.png)

## アウトプット

添付画像のような形で、アンケートに含まれる単語ごとの出現回数を棒グラフで可視化することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/d8085f46-fed3-992e-8fa0-6748da12539e.png)

また、wordcloud2というライブラリで別の可視化もしてみました。

![wordcloud2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/e5eb39ae-7ea4-754e-1085-68a995e52d94.png)

## コード

単語ごとの出現回数をCSVとしてエクスポートするまでのコードは以下の通りです。

なお、RMeCabの実行環境を一から構築するのは少々面倒なため、RをランタイムとしたColaboratryを使用しています。

``` R
system("apt-get install -y fonts-noto-cjk")

system('sudo apt-get install -y mecab', intern=TRUE)
system('sudo apt-get install -y libmecab-dev', intern=TRUE)
system('sudo apt-get install -y mecab-ipadic-utf8', intern=TRUE)

install.packages("RMeCab", repos = "http://rmecab.jp/R", type = "source")
install.packages("tidyverse")

library(RMeCab)
library(tidyverse)

df_survey_responses_fix <- RMeCabFreq("{filePath}") %>%
  arrange(desc(Freq)) %>%
  filter(Info1 == "名詞" & Info1 != "非自立") %>%
  select(Term, Freq)

df_survey_responses_fix

write_csv(df_survey_responses_fix, "df_survey_responses_fix")
```
ポイントは、```RMeCabFreq```メソッドです。


本メソッドの引数に、Colabratoryにアップロードしたアンケートデータ（サンプルデータ）のファイルパスを指定すれば、単語ごとの出現回数を集計してくれます。

コードを実行後、以下のデータフレームの内容がCSVとしてエクスポートされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/9039ee65-1d57-558c-afcd-1a82b40d51ce.png)

## 可視化

以降は、RStudioで可視化を行います。

### 棒グラフ

ggplot2で日本語を扱うと文字化けするため、以下の記述が必要です。

- ```theme_gray (base_family = "HiraKakuPro-W3")```

``` R
install.packages("readr")
install.packages("tidyverse")
install.packages("wordcloud2")

library(readr)
library(tidyverse)
library(wordcloud2)

df_survey_responses_fix <- read.csv("{filePath}") %>% 
  top_n(10, Freq)

g <- ggplot(df_survey_responses_fix, aes(x = reorder(Term, -Freq), y = Freq)) +
  geom_bar(stat = "identity") + 
  labs(x = "Term", y = "Freq") +
  ggtitle("Number of Occurrences per Word") +
  theme_gray (base_family = "HiraKakuPro-W3")

plot(g)
```

### ワードクラウド

ワードクラウドの利用は初めてでしたが、シンプルで分かりやすいですね。

``` R
install.packages("wordcloud2")
wordcloud2(df_survey_responses_fix, color = "black", backgroundColor = "white")
```

以上で可視化は完了です。

## おわりに

RMecabの中には他にも便利なメソッドがあり、余裕があれば調査してみたいです。

また、Rは可視化の自由度がかなり高いので棒グラフの可視化においても細かな調整ができるのはよいですね。
【HTML＆CSS】<dl>タグ: 説明リスト要素が万能すぎる

# はじめに
こんにちは。
最近、初めて使った``<dl>``: 説明リスト要素タグが個人的に万能すぎる！と思ったので、この記事ではそのタグの使い方を紹介したいと思います。

タグの説明は省かせていただきます。
代わりに参考となるリンクを以下に貼りましたので、興味のある方はご覧になってください。
>``<dl>`` は HTML の要素で、説明リストを表します。この要素は、一連の用語（``<dt>`` 要素を使用して指定）と説明（``<dd>`` 要素によって提供）をリスト化したものです。一般的な使用例として、用語集の作成やメタデータ（キーと値のペアのリスト）の表示が挙げられます。
引用：MDN

https://developer.mozilla.org/ja/docs/Web/HTML/Element/dl

https://webliker.info/html/13381/#google_vignette

# ``<dl>``タグを使う場面
``<dl>``タグは説明リスト要素であるため、用語の説明や情報を伝える場面で使うのがベストだと思います。
例えばWebサイトだと以下のようなシーンが考えられます。
* 料金表
* プロフィール
* 製品、サービスの仕様
* 用語集

# ``<dl>``タグ活用法
それでは実際に``<dl>``タグを使って料金表を作ってみます。
``<dl>``タグは、CSSでカスタマイズもできるので、簡単に表を作ることができます。

以下の例は縦軸の料金表になります。
とてもシンプルで見やすく表現できていると思います。
ちなみに``<dl>`` ``<dt>`` ``<dd>``タグはブロック要素であるため、縦に並んでいきます。

<p class="codepen" data-height="300" data-default-tab="html" data-slug-hash="VwojMgO" data-pen-title="&amp;lt;dl&amp;gt;タグ：料金表1" data-user="iwdulmiq-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/iwdulmiq-the-builder/pen/VwojMgO">
  &lt;dl&gt;タグ：料金表1</a> by 丸山悠希 (<a href="https://codepen.io/iwdulmiq-the-builder">@iwdulmiq-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
※ "Result"ボタンを押すとプレビューが表示されます。

次の例では、料金表を``display:flex``で横軸に表現してみました。
さらに疑似要素を加えたことで、推奨したいプランを強調しています。
<p class="codepen" data-height="300" data-default-tab="html" data-slug-hash="OJKWmXE" data-pen-title="&amp;lt;dl&amp;gt;タグ：料金表2" data-user="iwdulmiq-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/iwdulmiq-the-builder/pen/OJKWmXE">
  &lt;dl&gt;タグ：料金表2</a> by 丸山悠希 (<a href="https://codepen.io/iwdulmiq-the-builder">@iwdulmiq-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
※ "Result"ボタンを押すとプレビューが表示されます。<br>
※プレビュー画面を0.5xにすると適正に表示されます。

# まとめ
``<dl>``タグを使った表はシンプルかつ柔軟性があります。CSSでカスタマイズすれば、強調したい要素を目立たせたり、アイコンを埋め込むこともできたりと非常に見やすくなります。
また、複雑な表を作りたい時は``table``タグ、シンプルな表は``dl``タグと、必要に応じて使うのも良いアイディアかもしれません。皆さんも参考にしてみてください。
長々とありがとうございました。
個人の目標設定で私が気をつけているポイント3選

こんにちは。Kaneyasuです。

これを書いているのは10月です。
だいたい、どこの組織でも下期の目標設定を実施中 or 実施済みですよね。
ということで今回は、個人目標設定で気をつけているポイントを3つご紹介します。

# ポイント1：失敗をカウントする目標を避ける

例えば、本番リリース後のバグがゼロ件であることを目標にするとかです。
品質重視なのはいいことです。そこに疑いの余地はありません。

ですが、これをそのまま個人の目標にするのはよく考えた方がよいと私は考えます。
バグがゼロ件を目指すと、下手すると挑戦をしないのが正解になる可能性があります。
例えば、新規開発を行った場合、程度の差こそあれ、バグをゼロ件にするのは不可能ではないでしょうか。
せめて、バグはバグでも程度を考慮して、単純なバグの数を基準にするのは避けたいですね。

品質管理を目標にするのであれば、活動に着目して、テスト環境やドキュメントを整備するとか、CI/CDの導入を目指すとか、そういった方向性の方がよいと思います。
物足りなければ、活動するまでを一つの目標にし、活動の成果を共有するなどを更なる目標にする方向が考えられます。
品質管理で数値を目標にするのであれば、バグの数ではなく、カバレッジ率などのCI/CDで測れるソースのメトリクスを目標にするのもありかと思います。

念のためもう一度書きますが、単純に失敗をカウントする目標は避けたいと言っているだけです。
現実を考慮して、程度が加味されてあればまあ大丈夫です。

でも、できれば失敗をカウントするよりも、同じ品質管理でも活動する・導入する・広げるといった方向性を目標にする方が、成長を促すという意味でよいと思います。

# ポイント2：一発勝負を避ける

例えば、数ヶ月のプロジェクトの担当者となったら、そのプロジェクトを成功させることを目標にするとかです。
もちろん、どのプロジェクトにアサインされるかは個人の意思ではないこともありますが、可能なら小さくてもいいので他のプロジェクトの成果の平均を目標にするとかして、ちょっとでも負荷分散を図るといいと考えます。

人は失敗の方が記憶に残りやすいと言われています。
一発勝負の目標で失敗すると、その一つの失敗に評価が引っ張られる可能性があります。
他に頑張ったことがあるのにそれが無視されるようなことがないように、目標自体も負荷分散できる構造にしておくと良いでしょう。
目標設定で一発勝負をして自分にプレッシャーをかけすぎる必要はないと思います。

ちなみに、一発勝負を避けるという意味では、IPAの資格取得を目標にするのはあまりおすすめできません。
IPAの資格は有用ですが、半年に一回しか受験できないので、目標設定のサイクルとあまり相性がよくないんですよね。
目標としてもよいですが、メインには据えないとか、他にも資格取得を掲げとくとか、そういった方向性を考えるといいかと思います。

# ポイント3：他人に依存する目標は高いランクに据える

例えば、CI/CDを導入することを考えたとします。
この場合、CI/CDの導入、CI/CDのノウハウの共有、CI/CDのチームへの浸透は、目標のランクを分けた方がいいと思います。
2つ目までは自身の努力でなんとかなる範囲ですが、3つ目は他人に依存する部分が大きいからです。
他人に影響を与える目標は、達成できれば大きな評価が得られますが、自分以外の人間の状況と思想の深いところは当人にしかわかりません。
自分ができるからといって、他人もできるとは限りませんしね。
なので、他人に依存する目標は、挙げてもよいが、高ランクに設定して達成できなくてもダメージが少ないようにするといいと思います。

# まとめ

以上、個人目標設定で気をつけているポイントを3つご紹介しました。
ご自身に合った目標設定を行い、自信の成長を促すことができるといいですね。
console.logが出力されない？開発者ツールのフィルタ設定が原因かも！対処法を解説

## 背景
開発を進める中で、console.log が正しく出力されない現象に遭遇しました。コンソールにログが出力されないことで、デバッグが難しく、何が問題なのかを特定するのに時間がかかりました。最終的にはブラウザの開発者ツールの設定が原因だったことが判明したので、その解決方法を共有します。

## 問題
JavaScriptやjQueryを使った処理が動いているにもかかわらず、console.log が出力されないという現象が発生しました。以下のようなシンプルなログ出力でも、コンソールに何も表示されません。
```
console.log("処理が実行されました");
```
動作自体は正常に行われているものの、ログが表示されないため、原因の特定に時間がかかりました。

## 単語（検証ツール）について
開発中によく使用する ブラウザの検証ツール（開発者ツール） には、さまざまなログを表示するための機能が備わっています。以下は検証ツールの主要なタブです。

・Console: console.log などの出力を確認する場所。
・Network: リクエストの送受信状況を確認できる。
・Sources: 実際に読み込まれているJavaScriptファイルを確認できる。

特にコンソールタブでは、ログの種類（Info、Warnings、Errorsなど）ごとにフィルタリングが可能です。このフィルタリングが今回の問題の原因となっていました。

## 試したこと
console.log が出力されない原因を探るために以下の方法を試しました。

・コードの再確認: console.log の位置などを確認しましたが問題はありませんでした。
・ブラウザのキャッシュをクリア: 最新のJavaScriptコードが正しく読み込まれているか確認しましたが、効果はありませんでした。
・他のブラウザでテスト: 複数のブラウザで同じコードをテストしましたが、どのブラウザでもログが出力されませんでした。
・ネットワークリクエストの確認: ネットワークリクエストは正常に動作していることが確認できました。

## 原因
最終的に、ブラウザの開発者ツールの「Console」タブの設定が原因でした。
console.log はデフォルトで 「Info」 レベルのログとして扱われていますが、開発者ツールの設定で 「Info」 がフィルタリングされていたため、console.log が表示されていませんでした。

## 解決策
解決策はシンプルです。開発者ツールの Consoleタブのフィルタリング設定 を確認し、「Info」が無効化されていた場合は、これを有効化することで console.log のメッセージが再び表示されるようになります。

手順は以下の通りです：

・開発者ツールを開く（F12 キーなど）。
・Consoleタブ を選択する。
・フィルタリングメニューを開き、「Info」にチェックを入れる（「Default」や「Verbose」に設定してもOK）。

・console.log が表示されることを確認。

## まとめ
今回の問題の原因は、console.log が Infoレベルのログ として出力されていたにもかかわらず、開発者ツールで「Info」ログがフィルタリングされていたことでした。開発者ツールの設定は非常に便利ですが、フィルタリングによって一部のログが表示されなくなることがあるため、状況に応じて設定を確認することが重要です。

同様の問題に直面した方は、まず検証ツールの設定を見直してみることをお勧めします。特に「Info」フィルタが外れていないか確認してみてください。
Reactのスタイルの適用方法をまとめる

## スタイルの当て方
いくつかあるようなので、使ったものだけ備忘としてまとめる。

### インライン
タグの`style`属性にJavaScriptのオブジェクト表記でスタイルを指定する方法。
注意点として、要素名はキャメルケースで記述し、値は数値以外は文字列として記述する必要がある。

```jsx
export const InlineStyle = () => {
  const containerStyle = {
    border: 'solid 2px #392eff',
  };
  const titleStyle = {
    margin: 0,
    color: '#3d84a8',
  };
  const buttonStyle = {
    backgroundColor: '#abedd8',
  };
  return (
    <div style={containerStyle}>
      <p style={titleStyle}>- Inline Styles -</p>
      <button style={buttonStyle}>FIGHT</button>
    </div>
  );
};
```

### styled components
コンポーネントを記述するようにスタイルを指定できる。
ボタンであれば、`styled.button`の後にバッククォートで囲み、
その中に通常のCSSと同様の記法で記述する。

```jsx
export const TestButton = (props) => {
  const { children } = props;
  return <TButton>Test</TButton>;
};

export const TButton = styled.button`
  color: #fff;
  padding: 6px 24px;
  border: none;
  border-radius: 9999px;
  outline: none;
  &:hover{
    cursor: pointer:
    opacity: 0.8;
  }
`;
```

```jsx:BaseButton.jsx
import styled from 'styled-components';

export const BButton = styled.button`
  color: #fff;
  padding: 6px 24px;
  border: none;
  border-radius: 9999px;
  outline: none;
  &:hover{
    cursor: pointer:
    opacity: 0.8;
  }
`;
```

指定をstyle(\<component\>)にすると、\<component\>に指定したスタイルを引き継ぎ、差分のみ指定することができる。
```jsx:PrimaryButton.jsx
import styled from 'styled-components';
import { BaseButton } from './BaseButton';

export const PrimaryButton = (props) => {
  const { children } = props;
  return <SButton>{children}</SButton>;
};

//BaseButtonコンポーネントのスタイル指定を引き継ぐ
const SButton = styled(BaseButton)`
  background-color:#40514e;
`;
```
ピアソンVUEオンライン受験でシステムテストエラー対処分かったので共有します！

# システムテストでのエラーを解決する方法 
資格を色々受けてるのですが、テストセンターに行くのが面倒くなり、自宅でオンライン受験することが多くなりました。
**試験監督を英語にすると、会場受験よりスケジュールに融通が利いて便利です。**
しかし、大変なのが自宅での環境準備です。
↓のエラーがでたとき、試行錯誤の末解決できましたので共有します。
![スクリーンショット 2024-08-08 092743.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/a95c2ee6-a547-2bc7-1b98-281841896d90.png)

## 一言でいうと

Windowsのシステムで「リアルタイム保護」をオフにすると、特定のエラーが解消されました。

## 詳しい説明

### ① 表示されたエラー
![スクリーンショット 2024-08-08 092743.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/8ba8c240-ed6f-08fe-4206-c0f83838aa7d.png)

以下のようなエラーメッセージが表示されました。

> 結果とトラブルシューティングのヒント  
> インターネット速度の結果と更新: ダウンロード速度はほぼ期待を満たしています。  
> ネットワークPingの結果と更新: 配信に必要なすべてのURLへのPingとアクセスに失敗しました。  
> ビデオストリーミング接続の結果と更新:  
> お使いのホーム・オフィスネットワークで、必要なビデオストリーミングサービスに接続できませんでした。  
> ストリーミング会社は、Wowza.comへのアクセスを許可し、アップロード／ダウンロード速度が1Mb以上の安定した接続が求められます。  
> **ビデオストリーミングサービスへの接続方法**  
> ネットワークの管理者に確認して、以下をご確認ください。  
> ネットワークファイアウォールソフトが邪魔していないこと。  
> TCPポート80、443、1935で**.cloud.wowza.comへのWebRTC WebSocket接続を許可する必要があります。

ポートを開けたり、スキャンしてみたりしましたが、よくわからず、、、
Windows10のPCでは表示されませんでしたが、同じ設定のWindows11ではこのエラーが頻発していました。

### ② たどり着いた解決策

色々試していくうちに、一時的に **リアルタイム保護**をオフにするを解消することができました。

1. **リアルタイム保護をオフにする手順**

   - 「スタート」メニューを開き、「設定」をクリックします。
   - 「プライバシーとセキュリティ」をクリックし、「Windowsセキュリティ」を選択します。
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/de179208-ad0b-04f3-a0eb-71819ecdefec.png)
   - 左側のメニューから「Windows セキュリティを開く」をクリックし、「ウイルスと脅威の防止」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/d592d4af-45b4-273a-ca90-4abbf279a7a9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/8b3cf29c-be9d-4c7b-ee32-1c9019150264.png)

   - 「ウイルスと脅威の防止の設定」内の「設定の管理」をクリックすると、「リアルタイム保護」が「オフ」に切り替えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/83f4f558-0661-27f5-d1e9-bf3a4716093f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/d41f40e6-bde2-9a38-95a0-62766e76f46a.png)

※確認のポップアップが出ますが、「はい」をクリックしてください。

この手順でリアルタイム保護を一時的に無効にすることで、ビデオストリーミングサービスへの接続が正常に行われるようになりました。

### ③ 注意点

これはシステムテストエラーを回避する方法として使ってます。
時間経つと自動でオンになるようです。

※リアルタイム保護を長期間オフにするのは推奨されません。テストのために必要な場合にのみ使用し、テストが終わったらリアルタイム保護を再度オンにしてください。

参考にした記事：

https://qiita.com/u2929ka/items/4ae7269660c03e88d35c

https://dynabook.biz/trouble_soft/13104/

### 雑談（アイドリングストップ）
会場受験だと「もうテスト受けてもいいなあ」って思ってるけどいざ受けるまでタイムラグありますよね。
なんとなく仕事中も脳裏にテストが思い出されて、余分なエネルギーを消耗している気がしてました。
しかしオンライン受験だと、**試験監督は英語、試験問題を日本語**にすることで、「もう完璧だ、明日すぐ受けたい！」みたいなときに、すぐにスケジュールを組めることが多いです。

（このことに関して、またいつか記事にしようかなと思います。）
因みに個人的におすすめな受験会場は「**お風呂場**」です。
SeederでDBにテストデータを用意

## 前提
最初にシーダ―（seeder）でテストデータを用意しておくとよい。
- ダミーデータがサクッと準備できるのでスムーズに開発に入れる
- データをすぐ元通りにできる

以下のようなcustomersテーブルを例にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1830892/9f676fab-aace-ba94-4ec3-c0c51d185a62.png)
※手順内のモデル名、テーブル名は適宜書き替えること

マイグレーションファイル
<details><summary>【補足1 customersのマイグレーションファイル】</summary>

```database\migrations\2024_10_17_015108_create_customers_table.php
<?php
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
        {
            /**
             * Run the migrations.
             *
             * @return void
             */
            public function up()
            {
                Schema::create("customers", function (Blueprint $table) {
                $table->increments('id');
                $table->string('name');
                $table->string('phone')->nullable();
                $table->timestamps();               
                });
            }

            /**
             * Reverse the migrations.
             *
             * @return void
             */
            public function down()
            {
                Schema::dropIfExists("customers");
            }
        };
```
</details>

## 手順

### seederファイルの生成
```
php artisan make:seeder CustomerSeeder
```

### seederファイルに追記
```database\seeders\CustomerSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use DateTime;

class CustomerSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        DB::table('customers')->insert(array(
            0 => 
            array (
                'name' => 'tanaka',
                'phone' => '07012345678',
                'created_at' => '2024-10-18 11:28:35', //固定の日時の場合
            ),
            1 => 
            array (
                'name' => 'yamada',
                'phone' => '08056781234',
                'created_at' => new DateTime(), //現在日時の場合
            ),
        ));
    }
}
```

```database\seeders\DatabaseSeeder.php
<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        $this->call([
            CustomerSeeder::class, //ここにseederファイルを追記
        ]);
    }
}
```

### テーブルを再作成し、テストデータを投入
```
php artisan migrate:fresh --seed
```
PHPStorm日本語化の手順が変わってた 2024.2

## 環境

2024.2.3

## 手順

`Settings` -> `Appearance & Behavior` -> `System Settings` -> `Language & Region`で日本語を選択

日本語を選択するにはプラグインがONになってることが前提
Shitキー2回押して `japanese`でプラグインがONになってることを確認する

https://blog.jetbrains.com/ja/2024/08/07/202402changejpui/


## 雑記

今まではプラグインでON・OFFすれば切り替えられたがデフォルトで中国語や韓国語が追加されたため切替が必要になった様子
ちなみにRegionを選択しても現時点は中国以外は関係ないらしい（2024.10.18現在）
自分は基本は英語で作業して(英語版に慣れてしまったし`rebase`が`リベース`になってたりするのをみて直感的に理解できなかった)細かいところを設定するときだけ日本語にするので遭遇した
【C#】三項演算子は可読性が悪い

# はじめに
可読性が悪いことで有名な三項演算子について調べました

## 三項演算子とは?
>3 つのオペランドをとる演算子です。条件に続いて疑問符 (?)、そして条件が真値であった場合に実行する式、コロン (:) が続き、条件が偽値であった場合に実行する式が最後に来ます。この演算子は、 if 文の代替としてよく用いられます。

## 使い方
C#でコードの説明をします。

```C#
int a = 2;
int b = 2;
System.Console.WriteLine( a == b ? "OK" : "NG");
```
条件を？の前までに記載し、Trueならば２番目、Falseならば３番目になります。

## 実際に実装した例
実装した例です。このプログラムは変数msg1の文字列と変数2の文字列が一致したら「Yes」一致しない場合は「No」を標準出力に出力します。

```C#
using System;

class Program
{
    static void Main()
    {
        // 自分の得意な言語で
        // Let's チャレンジ！！
        string msg1 = Console.ReadLine();
        string msg2 = Console.ReadLine();
        Console.WriteLine(msg1 == msg2 ? "OK" : "NG" );
    }
}
```

## 問題点
他の人がソースコードを見た時に可読性が悪いので、if文を使いましょう。

# 最後に
三項演算子について取り上げました。
要素を非表示かつスペースをなくして値を送信したい

# 背景
業務で以下のチェックボックスを削除する依頼が入りました。

:::note
ビジネス要件の為、現時点では抽象的な表現になっています
後続で具体的な対応について説明します
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/4ab4af61-68da-d09e-264f-16d3c1572c0d.png)

前提）
このチェックボックスはformで送信され、DBが更新されます。
チェックボックスの初期値はDBに登録されているデータです。
開発はABテストのような進め方をしていましたので、特定の条件下ではこのチェックボックスを表示させる必要があります。

:::note
結論）フロントエンドの修正のみに留めることになりました。
上司から以下の助言を頂いたので次の章で具体的な実現方法の検討に入ります。

「チェックボックスの初期値にはDBで登録されている値が設定されているので、特定の条件で非表示にさせるだけで良い」
:::

以下は当初考えていた対応なので読まなくても大丈夫です。

没案）
formに隠し要素を用意する
```html
<input type="hidden" name="sample-hidden"/>
```

Controller側でリクエストのペイロードにこのkey（sample-hidden）があるか判定する

- チェックボックスを表示させる必要がある場合
    チェックボックスの値を送信します
- チェックボックスを削除する必要がある場合
    チェックボックスの値を送信せず、DBに登録されている既存の値を取得して送信し直す

上司から指摘された問題点）
今回、Controller側で修正を加えるとデグレのリスクが大きいということ

そこでフロントエンドの対応に留める方針を考え直しました。

# 要素を非表示にするが値を送信したい

## `display:none`
これだと要素は非表示になりますが、存在しない要素として扱われるのでform送信の対象にならないです。
よって不採用です。

https://developer.mozilla.org/ja/docs/Web/CSS/display#none

## `visivility:hidden`
要素を非表示にしますがレイアウトからは削除されません。つまりform送信の対象になります。
ですが、要素が持つスペース自体はなくならないので不採用です。

https://developer.mozilla.org/ja/docs/Web/CSS/visibility

## 隠し要素を`type=checkbox`から`type=hidden`に変える
```html:blade.php
<input type="hidden" name="sample" value="{{$model && $model -> key ? 1 : 0 }}" />
```

このようにすると、要素のスペースが完全になくなりますが、formの送信対象になります。
よってこちらを採用することになりました。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/hidden

# 最後に
ビジネスの要件、デグレリスクも踏まえて的確な実装ができるようになりたいです。
こうした基礎的な知識を業務から遅延学習しキャッチアップします。

# 参考
https://qiita.com/rico/items/0f645e84028d4fe00be6
久しぶりにGNS3（その37：VXLAN）

# VXLAN
VXLANとはUDPパケット内にL2（Ethernetフレーム）を含めるもの。また、VLANタグ数（4096）の制約を事実上解消するためでもある。

## ネットワーク（実現するもの）
GNS3で最も簡単に実現できそうなルーターやスイッチを探すと、OpenvSwitchらしいことがわかったので、それを利用する。
![vxlan2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c80ca1fb-ad94-d21b-9d6d-3a8002384088.png)
- OpenvSwtichによるVXLAN
- 末端に2つのVLAN（10,20）が存在
- OpenvSwitch-L2Switch間はトランク（802.1Q）
- VXLAN間はタグ（802.1Q）付きEthernetフレーム

## OpenvSwitchのGNS3への導入
[OpenvSwitchアプライアンス](https://gns3.com/marketplace/appliances/open-vswitch)をダウンロードして、GNS3へインポートする（File → Import aapliance）。
![Import.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/497dd814-43a9-7ac9-eead-e311d7529009.png)
![Import3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/67266c90-9f5a-3422-1729-64a729631dac.png)
（見かけの）Importが終わると、Switchのところにインストールされる。
![Switches.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/ee1b0ebe-7688-43a5-f579-29a42868b8d4.png)
DragAndDropしようとすると、ここで初めてイメージをダウンロードするようだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7425454c-5cf0-6094-7636-92e5897ed555.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3fdef491-2d23-712d-0219-e8c3aa3a6550.png)
起動後のConsole状況は下記。
![Console.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c42e18ad-9c20-4e6a-3c6d-6f84bbf889ed.png)


## 設定
### PC
自明のため省略。

### L2Swtich
![L2Switch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/5481e498-82a3-1d9b-3945-d6f8117d1831.png)
- ネットワークI/F e0がトランクポート
- e1はアクセスポートVLAN10
- e2はアクセスポートVLAN20

### OpenvSwitch
- ネットワークI/F eth0: OpenvSwitch間接続
- eth1: トランクポート
- vxlan0: VXLAN仮想ポート
- newbr: eth1とvxlan0とをつなぐブリッジ

下記は左側のOpenvSwitchの設定である。右側はIPアドレスのみ異なる。
- インストール初期時には既存ブリッジbr0にeth0及びeth1が属していたので、両者をbr0から取り除く（１回だけ）
```
$ ovs-vsctl del-port br0 eth0
$ ovs-vsctl del-port br0 eth1
```
- ブリッジnewbrを作成
```
$ ovs-vsctl add-br newbr
```
- eth0に物理IPアドレスアサイン
```
$ ip addr add dev eth0 10.1.1.1/24
```
- eth1をブリッジnewbrに追加
```
$ ovs-vsctl add-port newbr eth1
```
- eth1はトランクポート（VLAN10,20）
```
$ ovs-vsctl set port eth1 trunk=10,20
```
- vxlan0を作成してブリッジnewbrに追加
    - VNI100
    - 接続先OpenvSwitch IPアドレス指定
```
$ ovs-vsctl add-port newbr vxlan0 -- set interface vxlan0 type=vxlan options:key=100 options:remote_ip=10.1.1.2
```

設定状況は下記となる。
```
$ ovs-vsctl show
...

    Bridge newbr
        Port eth1
            trunks: [10, 20]
            Interface eth1
        Port newbr
            Interface newbr
                type: internal
        Port vxlan0
            Interface vxlan0
                type: vxlan
                options: {key="100", remote_ip="10.1.1.2"}
```

### 検証
PC1からPC3へpingした時のVXLAN区間のWiresharkデータは下記となる。
![w1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/6b350a67-58fa-d9fe-ae97-6f888486ae43.png)
下記が確認できる。
- VXLAN VNI: 100
- VXLAN Port: UDP 4789
- VLAN ID: 10
- Outer IP address: 10.1.1.1, 10.1.1.2
- Inter IP address: 192.168.1.10, 192.168.1.20

EOF
Azure Cosmos DB for MongoDB の Free Tier を mongosh から試してみた

クラウドサービスには Free Tier で使用できる製品がいくつかあります。今回は Azure Cosmos DB for MongoDB の Free Tier を mongosh から試してみました。

## Azure Cosmos DB for MongoDB の Free Tier を作成

```zsh:zsh
prefix=mnrmdb
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az cosmosdb create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --enable-free-tier true \
  --kind MongoDB

az cosmosdb mongodb database create \
  --name testdb \
  --account-name ${prefix} \
  --resource-group ${prefix}-rg \

dbpw=$(az cosmosdb keys list \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --type keys \
  --query primaryMasterKey \
  --output tsv)
```

## Azure ポータルで Free Tier を確認

![azure-mongodb-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/151e7043-671b-fa4a-bbdd-1c370dfb8894.png)


## mongosh で Azure Cosmos DB for MongoDB に接続

```zsh:zsh
mongosh "mongodb://$prefix:$dbpw@$prefix.mongo.cosmos.azure.com:10255/testdb?ssl=true&retrywrites=false"
```

## MongoDB の動作確認

```sh:mongodb
show databases

show collections

db.users.insertOned( { name: "Taro" } )

db.users.find()

db.users.find( { name: "Taro" } )

db.users.updateOne( { name: "Taro" }, { $set: { type: "Customer" } } )

db.users.find( { name: "Taro" } )

db.users.deleteMany( { name: "Taro" } )

db.users.find()

quit
```

## 後片付け

```zsh:zsh
az group delete \
  --name ${prefix}-rg \
  --yes
```

## 参考

https://learn.microsoft.com/ja-jp/azure/cosmos-db/mongodb/vcore/free-tier

https://learn.microsoft.com/ja-jp/azure/cosmos-db/mongodb/connect-account
Mac M.2にVagrantをインストール

Mac M.2に使われているOSアーキテクチャは、Windowsと異なりARM64であるため、VagrantのBoxファイルは、ARM64に対応したものを使用する必要がある。

Discover Vagrant Boxes（ https://portal.cloud.hashicorp.com/vagrant/discover ）からARM64に対応したBoxファイルを調べると、`vmware_desktop`、`parallels`が大半であった。そのほか、`hyperv`、`qemu`もARM64に対応したものがあるが、動作検証を行った結果、いろいろと制限があり、開発に使えるものではなかった。vagrantでは、`hyperv`、`qemu`を使用しない方が良いだろう。

今回、Apple MacOS(M1,M2)でVagrant環境を用意する必要があったため、メモとして残す。

### 必要なソフトウェア
- Vagrant 
http://www.vagrantup.com/downloads.html
- VirtualBox
Virtualboxは、未だMac.M2などのCPUに対応していないため、BETA版を利用する必要がある。（ https://www.virtualbox.org/wiki/Testbuilds ）
※本環境を構築した段階では、対応していなかったが、最新バージョンでは対応されているかもしれない。
- Parallels Desktop Pro Edition for Mac (有償)
  - 注意）Standardでは動作しない
  - https://www.parallels.com/jp/products/desktop/pro/
  - 無償版をダウンロードして、ProのサブスクリプションをアクティベートするとProになる。
  - 動作確認は、Parallels Desktop 19で実施している。

### 必要なvagrantプラグイン

````
vagrant plugin install vagrant-parallels
````

### Vagrantfileの記述（サンプル）

````ruby
Vagrant.configure('2') do |config|
  # Setup default vm
  config.vm.define 'default', primary: true do |node|
    node.vm.box = 'bento/ubuntu-22.04-arm64' #ARM64に対応したboxを指定
    node.vm.hostname = 'vagrant-arm64'

    node.vm.network :forwarded_port, guest: 22, host: 2285, id: 'ssh'
    node.vm.network :private_network, ip: '10.0.0.85'

    node.vm.provider :parallels do |vb| # providerをparallelsにする
      vb.memory = 4096
    end
    
    node.vm.synced_folder './environment', '/home/vagrant/environment'
    node.vm.synced_folder './develop', '/home/vagrant/source'
  end
end
````
Macでjsonファイルに対して、base64ができない(base64: invalid argument xxx.json)

# はじめに
瑣末なことで少しはまったので、メモします。

# 問題
jsonファイルに対して、base64ができない。
以下エラーが出る。
```
base64: invalid argument xxx.json
```

lsコマンドでディレクトリにファイルがあることを確認
```
ユーザー名@MacBook-Air ディレクトリ名 % ls
xxx.json
```

base64コマンドを実行するも、エラーになる。
```
ユーザー名@MacBook-Air ディレクトリ名 % base64 xxx.json
base64: invalid argument xxx.json
Usage:	base64 [-hDd] [-b num] [-i in_file] [-o out_file]
  -h, --help     display this message
  -Dd, --decode   decodes input
  -b, --break    break encoded string into num character lines
  -i, --input    input file (default: "-" for stdin)
  -o, --output   output file (default: "-" for stdout)
```

# 解決方法
フルパスで解決することができた。
```
% base64 -i /Users/ユーザー名/ディレクトリ/ディレクトリ/xxx.json | pbcopy
```

 ただ、コマンドとエラー内容を良くみたら「-i」というオプションコマンドが必要だった様子。 

# おわりに
Chatgptに頼りすぎは良くないと思いました。
エラー内容、説明を良くみるようにします。
Next.jsで更新したDBデータがフロントエンドに反映されなかった話

# Next.jsで更新したDBデータがフロントエンドに反映されなかった話 - SSG, ISRの理解

## はじめに

Next.js触り始めた人、Webアプリケーション開発初心者向け

# Background

2ヶ月前くらいからWebアプリの作り方を勉強し初めて、なぜかDBデータを更新してもフロントエンドに反映されずにハマったのでまとめる

## 結論から

どうやらNext.jsが高機能であるが故、デフォルトで最適なページをキャッシュしていることが原因だったらしい。
`revalidate`オプションを使用してISRでレンダリングすることで、Webページでデータが更新された。

## 概要

### 構成

* Backend: Node.js + MongoDB
* Frontend: Next.js

### 状況

* `app/title/[id]/page.tsx`にDBから取得したデータを表示させている
* MongoDBの3日分のデータを30日分のデータに変更
* dbを更新したはずなのにデータが更新されない。3日分のデータが表示される。

## 調べてわかったこと

Next.jsはキャッシュ機能を持っており、デフォルトでは静的なページをキャッシュしている。

### レンダリング方法について

そもそも、レンダリング方法にはいくつか種類がある。
違いとしては主に、「いつ」「どこで」HTMLが生成されるか

* CSR (Client Side Rendering): ブラウザでWebサーバーから取得したHTML, JS, CSSを元に、ページHTMLがレンダリングされる
* SSR (Server Side Rendering): ブラウザからのリクエストごとに、WebサーバーがHTML JS, CSSを元にページHTMLをレンダリングし、ブラウザに返す
* SSG (Static Site Generator): アプリケーションのビルド時にHTMLをプリレンダリングしてページHTMLを生成し、それをブラウザに渡す
* ISR (Incremental Static Regeneration): SSGと似ていますが、一定期間ごとに静的ページの再生成をサーバー側で行う

ref.) [SSR vs CSR vs ISR vs SSG](https://www.educative.io/answers/ssr-vs-csr-vs-isr-vs-ssg)

### 今回のケース

今回の場合、Static Site Generation(SSG)によって生成されたページがキャッシュされ、更新がかからなかったことが問題だった。Next.jsはデフォルトで、`getStaticProps`を使用しない場合、ページはBuild時に静的に生成される。

### 解決方法

データの更新頻度が少ない場合（たとえば１日1回）に合わせてISRを実装する。
`revalidate`オプションをページ内に追加することで実現可能

``` ts
export const revalidate = 86400; // 24 hours, added

export default async function PageName({ params }: { params: PageNameProps) {
  // ... existing code
}
```

ISRを使用するメリットとしては、SSGの利点である高速レスポンスとSEOに強いなどの特徴を活かしつつ、定期的な更新を行うことができるなどが挙げられる。

### おまけ: その他の解決方法

* オンデマンド再検証: 特定のイベント（例：DBの更新）をトリガーにしてページを再生成する
* 動的レンダリング: `export const dynamic = 'force-dynamic'`を使用して、毎回サーバーサイドでページを生成する

## まとめ

Next.jsが高機能であるが故、Next.jsのデフォルトのSSG動作により、DBの更新がフロントエンドに反映されない問題に遭遇。デフォルトで最適なページをキャッシュしていることが原因だったらしい。
`revalidate`オプションを使用してISRでレンダリングすることで、Webページでデータが更新された。
フレームワークに振り回されないためにもレンダリングの違いを理解することが身に沁みた。

## 参考文献

* [Next.js - Incremental Static Regeneration (ISR)](https://nextjs.org/docs/canary/pages/building-your-application/data-fetching/incremental-static-regeneration)
* [Next.js（App Router）でISRを使用する際の基本的な構成、レンダリングやキャッシュに関する設定と注意点](https://zenn.dev/chot/articles/e067a177d698ab)
【React Hook Form】React Hook FormでのonChangeの書き方

# はじめに
React Hook Formを使ってバリデーションを実装する中で、inputに対してonChangeを定義した際に警告が発生したため、その解決方法についてまとめました。

# 実装方法

```react
<Input {...register("name", { required: true })} placeholder="名前" value={name} mb="2" onChange={onchangeName} />;
```
このように`input`に対してonChangeを定義していました。しかし「***<font color="Red">onChangeが複数設定されている</font>***」と警告されてしまいました。

解決策として、`register`内に`onChange`を組み込む方法を見つけました。

```react
<Input {...register("name", { required: true, onChange: onchangeName })} placeholder="名前" value={name} mb="2"/>;
```
このように`register`の中に`onChange`を定義することで正しく動作します。
`register`にあらかじめ`onChange`イベントが内部に設定されているようです。

https://react-hook-form.com/docs/useform/register#registerRef

# 終わりに
今回の経験を通じて、React Hook Formの使い方をさらに理解できました。今後も引き続き学習を頑張りたいと思います。

# 参考文献
https://react-hook-form.com/docs/useform/register#registerRef

『react-hook-formの使い方まとめ』

https://qiita.com/Nozomuts/items/60d15d97eeef71993f06
ゼロから始めるAIシステム開発 #04.5 「AWS CloudFormationとは」

今回はAWS CloudFormationについて調べたことを書く。
## AWS CloudFormationとは
- AWSのリソース構築を自動で行うサービス
- AWSリソースをコードとして管理するためのサービス
- AWS内の全てのリソースを自動でプロビジョニングできるAWSサービス
- テキストファイルでAWSリソースを自動で作成するサービス
- AWSのインフラリソースをテンプレートを使って一括で作成・更新・削除できるサービス
- AWSのインフラストラクチャ管理のためのサービス
PerplexityなどテキストAIを含むいろんなサイトで調べてみたが、微妙に表現が違っていて面白い。利点が多様だからだろうか。まとめると**AWSのリソース構築をコードで自動管理できるサービス**という感じ。
## 特徴
- テンプレートによりリソースを構築できる
JSONやYAML形式でテキストファイルを作成。テンプレによって異なる環境で同じものを簡単に構築できる。
- スタックによりリソースを管理する
プロビジョニング（必要なリソースを使えるように準備しておくこと）したAWSリソースの集まりをスタックという。
- パラメータでカスタマイズできる
柔軟に設定でき、テンプレートの再利用性が向上する。
- 料金は無料（リソース自体は有料のものもある）
テンプレートの作成やスタック管理、デプロイ等に料金はかからないが、S3バケットなどのAWSリソースの使用自体は有料。
## メリット
- リソースの構築が早い
インフラ構築をテンプレート化することによってスピードアップし生産性を向上させる。
- 再現性、一貫性が高い
テンプレートを呼び出すことによって常に同じ設定を使用できる。
- リソースの削除が確実
リソースがスタック単位でまとまっており依存関係に混乱することがなく、有料のリソースなどを消し忘れにくい。
## まとめ
先日四苦八苦しながらワークショップをやった結果かある程度概念の理解が進んだように思う。また複数のサイトの表現の違いに注目することで概念の輪郭がわかりやすくなった。
今週はちょっと体調がすぐれず進捗が悪かったので反省。今回は#4.5としたので第5回は来週早めに出したいところ。
gcpioを入れてみた

FreeBSDのcpioやtarコマンドはlibarchiveに依存していて、このライブラリや依存が巨大なため、8M Flashのターゲットでも入れることはありませんでした。

||イメージサイズ|増加分|
|:--|:--|:--|
|無し|3573760|-|
|cpio,lib入り|4592128|1018368|

イメージは圧縮されていて一つのコマンドに1Mも使われてしまったので、たまったものではありません。

libarchiveのソースを見ても小さくビルドする設定はなさそうです。

FreeBSDはもともとは1.4Mのフロッピーで起動してインストールできたので、その中に入れる基本的な操作で使うコマンドは小さく作られていました。これは初期のi386マシンはフロッピーかHDDからしかブートできなかったためです。フロッピーにインストールイメージが入らなくなったりCDからもブートできるようになって、その事は忘れ去られました。

いろいろ調べて考えてGNU版のcpioをportsもどきに追加してみました。gcpioはlibcだけ有れば動くようです。2.13とちょっと古いものになっていますが。CVEの脆弱性はつぶされたものです。

||イメージサイズ|増加分|
|:--|:--|:--|
|gcpio入り|3635712|61952|

tarはともかくcpioみたいなコマンドは元のまま小さいものにしておくべきだったと思います。

flashにバックアップ

```
# cat test
abc
# ls -1 test | /usr/local/bin/gcpio -C 65536 -o | dd of=/dev/flash/spi1 bs=64k
1 block
1+0 records in
1+0 records out
65536 bytes transferred in 0.519613 secs (126125 bytes/sec)
```

戻す時

```
# dd if=/dev/flash/spi1 bs=64k | /usr/local/bin/gcpio -i
1 block
# cat test
abc
```

flashにバックアップがない場合の判断ですが、zeroを書き込んだmd5値を確認して、もしそれと同じだたら入ってないと判断して、処理をしない方法が考えられます。

libarchiveは作りが雑な感じがします。bsdcpio敗れたり。

追記：

FreeBSDにはcpioと互換のある4.4BSD由来のpaxコマンドが入っていました。


||イメージサイズ|増加分|
|:--|:--|:--|
|pax入り|3608576|34816|

paxがあったのでcpioやtarを拡張したのかもしれません。paxは真のBSDコマンドです。:)

入れ替える前はFreeBSDにはGNU tarが入ってようです。これはpaxのできがいまいちだったからなのかもしれません。BSDでもすべてが良いものとは限りません。:(

paxのブロックサイズの上限が64512で64Kより小さいので上記のような使い方は出来ないようです。

また展開の時にgcpioはアーカイブの終端でstdinをcloseするようですが、paxはすべて読み込んでいるようです。

flashに一日一回バックアップを書き込んだとして、flashが10万回の書き込み保証がある場合、274年使えます。