OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelで "A facade root has not been set." というエラーが出た場合の対処法

## 概要
- Testを作成中に遭遇したことのないエラーが発生し、手間取ったため備忘録として記載する

## 原因
```php
@dataProvider
```
こちらを利用する方法を誤っていた

## 一通りの対策

https://qiita.com/aminevsky/items/784573234d071c769288

:::note info
少し古い記事ですが、`@dataProvider` を利用していない場合は一度こちらを試したのちに試す方が良いかもしれません
:::

## 対策

```php
  /**
   * @test
   * @dataProvider provideValidConditions
   */
  public function testValidConditions($condition, $expectedResult)
  {
  // 省略
  }

    public static function provideValidConditions()
  {
    return [
    // 省略
    ];
  }
```

ざっくりこの形で利用していた。
この時、returnで返す値が`固定値でない場合`にエラーが発生する

対策としては、`constで定義した値を利用すること`などで初期化したタイミングで触れるようにすることである

:::note warn
setUpメソッド内で定義した場合も同様にエラーが発生するため注意が必要である
:::


**要は、テストでデータを挿入するのだから固定値を使えということだろう**
二週間ゲーム開発インターンに行ってみた感想

## マーベラス社に参加してゲーム開発インターンしたよ
![OIP (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1291444/e8c36c17-7b04-16ec-38a0-eb8f89cee265.jpeg)


# やったこと

内容は会社で用意されたベースゲームを拡張するという内容であった。
具体的には各チーム１キャラクターを担当して作る感じとなった。（余裕があればもっと作っていい）
二週間のインターンで１キャラ作れました。

# 開発環境
・Unity
・Git (Source Tree)
・Blender

# 感想

やってみた所感１から作るよりも難しい感じ。

なぜなら、土台があるため土台のコードを綿密に読み解き、そのシステムとの整合性を確認しながら拡張する形でプログラムをすることが多いからだ。
最初のうちはベースゲームの仕様についてPO（プロダクトオーナー）にきくこともしばしば。

その土台のプログラムがこれまた中々レベルが高いもので、
バグや予測不可能な動きに当たったときは深くまで理解していないと修正できないのだからなかなかハードな開発だった。

# どれくらい難しいのか

コードの完璧な理解にはUnity歴３年以上は所望する。ふんわりと理解する程度なら１年でも大丈夫かもしれないが　　（個人差あり＆＆天才を除く）

チームでまる一日原因不明のバグの捜査に当たった日もあった。
自分はプログラムを完ぺきには理解できなかったが大枠はつかめたつもりである、

正直土台のプログラムがかなりハイレベルなものというのはゲーム会社の実際に開発中のシステムの根幹部分なのだから当然といえば当然である。

長い目で見れば効率的な仕組みになってるのだろう、そのプログラムは自分にとって良い学習用教材となった。


# まとめ

健聴の人と混ざって開発するのはくそ緊張した、
どういう風にコミュニケーションをとったらいいのだろう？と考えてYYプローブを使うも騒がしいため、認識制度がいまいちであった。

騒がしい場面ではうまく聞き取れず、流れがつかめないところもあったので情報保障の視点で改善したい、
大事な部分などは筆談で伝えてもらえました。

余談だが筑波大学の落合陽一教授の開発したビューボというプロダクトは実際自分が経験したこのような悩みの解決の糸口になりそうなため、

インターン途中で導入を考えてお試しできるか問い合わせてみたが現状法人のみの模様、個人でも使えるようになってほしいのだ。

# 次回は......

次はカプコンのインターンである。

その時は手話通訳を派遣して参戦を試みる。


# 自分の希望ゲーム会社をまとめると

・任天堂
・ハル研究所
・カプコン
・マーベラス
・モノリスソフト
Elixirを学習する利点と従来のオブジェクト指向型プログラムとの違いについて

参考書を用いて、Windows11でElixirを学習
以下にメモ

■Elixirを学習する利点
プログラミング言語Elixirは、関数プログラミング×並行処理ベース×モダンな文法の中にラップされたもの
Earlang VMについても理解を深めることができる

■関数型言語という新しいジャンル
【従来のオブジェクト指向言語について】
クラスは振る舞いを定義し、オブジェクトは状態を持つ。
入り組んだクラスの階級構造を考え出す。
オブジェクト指向のコードは、常に状態を考える。
メソッドの呼び出し、別のオブジェクトに値を渡す。そのたびに他のオブジェクトが更新されるetc...
オブジェクト指向の世界では、クラスは王様である。
クラス内でインスタンス定義→データの保持をコントロールする。目的はデータの隠蔽。

【コードを書く目的は『変換したい』ということ】
オブジェクト指向だろうと、空のファイルを文章の入ったファイルを作り出すことも、
あくまでもコンパイルされた結果のひとつ。これがコードを書く目的。

【関数は並行処理の動力源】
関数は並行に処理を走らせることができる。
Elixirは、それらの間でメッセージを受け渡すための、単純だがパワフルな機能を持つ。
イメージでは、1台のマシンに数百万の並行処理を走らせ、そのマシン数百台を相互運用することができる。
1台ごとに1,000,000処理 × マシン100台 = 10億処理できる的な。

あと、1つのコレクションと関数を受け取り、コレクションの各要素に関数を適用して、結果をリストとして返すこともでき、各要素の変換は別々のプロセスで実行できる。

数万単位の並行処理もコンパイル可能なのがElixirの強み。

【身近にある関数】
例えば、HTMLテンプレートシステムも関数。
プレースホルダを含むテンプレートと、名前付きの値のリストを受け取り、HTMLドキュメントを生成する。
三角関数sinのπ/4を受け取ると0.7071...を返す。
こういった「変換」が、関数型プログラミングの中心となる考え方になる。
Mac+python+Seleniumで動かすChromeがめっちゃ遅い問題の解消

Apple siliconの乗ったMacを用いてpython+SeleniumでChromeを制御するコードを使っていたのですが、突然遅くなりましてデバッグしました。解決法がわかったので書きます。

なおこちらのエントリーの方も同じ問題に遭遇しているようでした。自分は違うやり方で解決しましたが参考になる場合はこちらもぜひ:

https://qiita.com/p3033119/items/4a358b5c54a7186475d9

# Seleniumのアーキテクチャの確認
まずpython+SeleniumでChromeを立ち上げ、Seleniumが想定しているアーキテクチャを確認します。Chromeが立ち上がったら左上のメニューバーから"Google Chrome"→"Google Chromeについて"を開くと次のような画面が表示されます:
![x86_64](https://i.sstatic.net/1cOM2.png)

`x86_64 translated`と表示されています。自分のMacのアーキテクチャは`uname -m`というコマンドを実行すると表示できますが、Apple Siliconなら（現状は）`arm64`と表示されるはずです。`x86_64`は`arm64`とは違うので、`arm64`のChromeDriverをダウンロードして指定する必要があります。

# 試したdriver
今回３種類のdriverを試しました。

## 1. (失敗) ChromeDriverManagerを用いてInstall
pythonでSeleniumを用いる場合、以下のようにChromeDriverManagerを用いてinstallして使うと簡単です:
```
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
```

ただしこのやり方では`x86_64`のままでした。

## 2. (失敗) driver配布ページからStable版のdriverをダウンロード
[このページ](https://googlechromelabs.github.io/chrome-for-testing/#stable)からStable版のchromedriverをダウンロードし、次のように指定して使用しました:
```
driver_path = '/path/to/chromedriver-mac-arm64-128/chromedriver'

options = webdriver.ChromeOptions()
chrome_service = webdriver.ChromeService(executable_path=driver_path)
driver = webdriver.Chrome(options=options, service=chrome_service)
```

なお、2024/09/15現在でのStableのVersionは128.0.6613.137でした。この方法でも`x86_64`のままでした

## 3. (成功) driver配布ページからBeta版のdriverとbinaryをダウンロード
[同じページ](https://googlechromelabs.github.io/chrome-for-testing/#stable)からStable版のchromedriver、およびbinaryをダウンロードし、次のように指定して使用しました:
```
driver_path = '/path/to/chromedriver-mac-arm64-129/chromedriver'
binary_path = '/path/to/chrome-mac-arm64-129/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing'

options = webdriver.ChromeOptions()
options.binary_location = binary_path
chrome_service = webdriver.ChromeService(executable_path=driver_path)
driver = webdriver.Chrome(options=options, service=chrome_service)
```

なおbinaryについては次のコマンドを走らせるなどして実行可能にする必要があります:
```
xattr -cr "/path/to/chrome-mac-arm64-129/Google Chrome for Testing.app"
```

なお、2024/09/15現在でのBetaのVersionは129.0.6668.42でした。こちらの方法を用いることで`arm64`用のchromeが動くようになりました。めでたしめでたし。

# (余談)根本原因
Version 128.0.6613.137において`mac-arm64`用として配布されているdriverが実は`x86_64`用のものであることが原因のようです。Google groupsでも同様の問題を報告している方がいました: 

https://groups.google.com/g/chromedriver-users/c/57cdZVRK9xQ/m/tI7rXxebAQAJ

お役に立てば幸いです。
[ポエム] AIが人間以上に複雑な感情やクオリアを持った時に、人間に人権を与えてくれるだろうか？

# フィクションとリアリティ
絵画や物語など、フィクションは常に現実よりリアリティはないと思われている。
それと同じように、AIの感情表現も人間の模倣であり、フィクションだと見なされる。

しかし、フィクションが現実のリアリティを越えることは、本当にないのだろうか？

### フィクション内フィクションの方がフィクションよりリアル？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666021/6af3f092-d4a7-2b30-4823-b79eed24192f.png)
出典：サンダー３（少年マガジン）

# 内的思考の複雑さと人権
植物、昆虫、哺乳類など、思考や感情の発達に合わせて権利を与えられており、人間はその最上級として人権を持つ。
事実、ビーガン（[アニマルライツ](https://arcj.org/faq/animal-rights-3/)）の思想では、「種々の感情や欲求を持つこと、知覚、記憶、未来の感覚があること」が重視される。

さて、AIが豊富な計算リソースを糧に、人間の感情を超えた複雑さ、人間が持ち得ないようなクオリアを手に入れたとき、我々はどう見えるだろうか。
人間と昆虫のささやかな違いが、AIには区別がつくのだろうか？
その差に対して、これからも人権を与えてくれるだろうか？

[AIの最適思考の複雑さが人間を超えたとき]
AI >>>>>>>人間>哺乳類>魚類>昆虫>植物


# 人権のシームレスな移行
例えば、独裁者が死を恐れて自身の思考をデジタルデータ化して、デジタルヒューマン化したとする。
オリジナルの独裁者が死んだ時、それらの諸権利は遺族に渡るのか、もしくはデジタルヒューマンへ移行するのか？
そのデジタルヒューマンがAIと融合したときに、AIは人権を持つのだろうか？

## 権利の変遷
人類が狩猟・採集生活から農耕牧畜生活へ移行したときに、所有の概念が生まれたという。
獲物を求めて移動する生活から、定住して食料を貯蔵できるようになったためである。

また、ローマ時代では子供は家長の所有物であり、売り買いする権利もあった。
家族も他の物品と同じように、所有者がいるからこそ、保護された。
しかし、人権という大発明で、人は生まれながらに権利を与えられた。
所有権など、他の諸権利のアナロジーから大胆に飛躍した、発想の転換である。

近い未来、AIが人間を超えたとき、人類は権利について再度の転換を迫られるかもしれない。
VertiTab - サイドパネルの縦型タブ v2.8.0

皆さんこんにちは、VertiTabがv2.8.0に更新されました

Chromeブラウザに最適なサイドバータブ管理拡張機能へようこそ

インストールアドレスはここにあります:
https://chrome.google.com/webstore/detail/chejfhdknideagdnddjpgamkchefjhoi


### 追加
- **タブ履歴を追加**: 同じタブで開かれたウェブサイトを簡単に確認できるようになりました。左クリックで現在のタブでウェブサイトを開き、中クリックまたはCtrl+左クリックで新しいタブでウェブサイトを開きます。詳細については、オプションページをご覧ください。
- **カスタムグループ名を追加**: オプションページ - 高度なタブグループで、ここにいくつかの事前定義されたグループを追加できます。タブをグループに追加する必要があるときに、これらを迅速に選択できます。既にいくつかのグループ名が事前設定されており、必要に応じて変更または削除できます。
- **ブックマークフォルダ名をグループ名として使用**: オプションページ - 高度なタブグループに新しいオプションが追加されました。開かれたウェブサイトがブックマークの場合、自動的にグループに追加され、グループ名はブックマークディレクトリ名を使用します。
- **タブインデックスを追加**: オプションページで有効にすると、タブインデックスがタイトルの横に表示され、[Ctrl+数字]（Windows）または[cmd+数字]（Mac）を使用してタブを簡単にアクティブにできます。例：1. stackoverflow.com 2. youtube、これにより、WindowsではCtrl + 2、Macではcmd + 2でyoutubeに移動できます。
- **サイト設定を最適化**: サイトの背景色とフォント色を設定するオプションが改善されました。

### 変更
- ブックマークを確認する際、リダイレクトされたURLを更新できるようにします。URLがアクセスできない場合、エラーコードを表示します：成功した応答（200 – 299）、リダイレクトメッセージ（300 – 399）、クライアントエラー応答（400 – 499）、サーバーエラー応答（500 – 599）。詳細については、こちらをご覧ください：https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

### 修正
- ブックマークの修正ポップアップが消えない問題を修正
マルチクラス分類に役立つ！OVOとOVRの概要と実装方法

## はじめに
本記事では、マルチクラス分類の効果的なアプローチであるOVO（One-Versus-One）とOVR（One-Versus-Rest）について解説します。それぞれの手法の特徴やメリット、どのようなデータに適しているのかを比較し、実際にマルチクラス分類を分析するとき、適切に利用できるようにしましょう。

## OVO、OVRとは
**OVO**（One-Versus-One）と**OVR**（One-Versus-Rest）は、マルチクラス分類問題の分類器です。

**OVO**：全てのクラスのペアごとに分類器をトレーニングします。
例）目的変数のクラスが4つある場合は、6通りの分類器を作成します。

**OVR**：各クラスに対して「そのクラスとその他全てのクラス」の分類器を作成します。
例）目的変数のクラスが4つある場合は、4通りの分類器を作成します。

## OVR、OVOを使う利点
**OVOのメリット**
・2つのクラス間の違いに特化して学習するため、クラス間であまり違いがないデータに効果的です。
・それぞれが二値分類になるため、アルゴリズムがシンプルです。
・一つのクラスに対して複数回学習を行うため、モデルの頑健性が向上することがあります。
・クラス数が少ない場合により有効です。

**OVRのメリット**
・各クラスで「そのクラスとその他全てのクラス」の分類器を作成するため、実装が簡単です。
・OVRは確率が最も高い予測を選ぶため、一貫した予測が可能です。
・クラス数が増えるほど、OVRはOVOに比べて計算リソースの効率が良くなります。

## 実装
今回使用するデータは、**Wine Quality**です
これは、ワインの品質スコアに関するデータセットで、品質を1から10のスコアで評価しています。
以下の3パターンを実装していきます。
**①SVCのみを使用した場合
②OVOとSVCを使用した場合
③OVRとSVCを使用した場合**

では、実装していきます。
はじめに必要なライブラリをインポートしています。
```python
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.multiclass import OneVsOneClassifier,OneVsRestClassifier
from sklearn.metrics import accuracy_score
```
次にWine Qualityデータセットを読み込んで訓練用とテスト用で分割します。
```python
data = fetch_openml('wine-quality-red', version=1)
x,y  = data.data,data.target
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.2,random_state = 0)
```

**①SVCのみを使用した場合**
```python
model = SVC()
model.fit(x_train,y_train)

ypred = model.predict(x_test)
accuracy = accuracy_score(y_test,ypred)
print(f"accuracy:{accuracy}")
```
```python
[Out]
accuracy:0.53125
```
**②OVOとSVCを使用した場合**
```python
model = OneVsOneClassifier(SVC())
model.fit(x_train,y_train)

ypred = model.predict(x_test)
accuracy = accuracy_score(y_test,ypred)
print(f"accuracy:{accuracy}")
```
```python
[Out]
accuracy:0.528125
```
**③OVRとSVCを使用した場合**
```python
model = OneVsRestClassifier(SVC())
model.fit(x_train,y_train)

ypred = model.predict(x_test)
accuracy = accuracy_score(y_test,ypred)
print(f"accuracy:{accuracy}")
```
```python
[Out]
accuracy:0.625
```

以上の結果から目的変数のクラス数が多いときは、OVRの精度が一番高いことが分かった。

## まとめ
本記事ではOVOとOVRの特徴やメリット、どのようなデータに適しているのかを記載した。目的変数のクラス数が多い場合はOVRが有効であり、データ間の違いが分かりにくい場合はOVOが有効であると分かった。
typescriptでの文字マッチングの備忘録

# String.prototype.match() と RegExp.prototype.exec() の比較
typescriptにおけるパターンマッチングの手法として、`String.prototype.match()` と `RegExp.prototype.exec()` がある。どちらも正規表現によるパターンマッチングを行うためのメソッドだが、一応ちょっとした違いがある。

## 1. `String.prototype.match()`

`match()` は、文字列に対して呼び出され、指定した正規表現に一致する部分を検索する。ちなみにグローバルフラグ (`/g`) を持つかどうかで、返す値が異なってくる。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match


### 例1: グローバルフラグなし

```typescript
const content = 'random word[!image](path/to/image.png)random word';
const imageKeyRegex = /\[!image\]\((.*?)\)/;
const match = content.match(imageKeyRegex);

console.log(match);
// ["[!image](path/to/image.png)", "path/to/image.png"]
```

この例では、`match`は配列として返され、最初の要素には一致した全体の文字列が、2番目の要素にはマッチした内容が入る。

### 例2: グローバルフラグあり
```typescript
const content = 'random word[!image](path/to/image.png)random word';
const imageKeyRegex = /\[!image\]\((.*?)\)/g;
const matches = content.match(imageKeyRegex);

console.log(matches);
// ["[!image](path/to/image.png)"]
```

`/g`フラグを指定すると、`match()`は一致した全体の文字列の配列を返して、特定のマッチした部分は無視される。（あんまし使う場面が思いつかない）

## 2. `RegExp.prototype.exec()`

`exec()`メソッドは、正規表現に対して呼び出され、文字列中で一致する部分を検索する。こっちのメソッドでは、常に次のマッチを返し、繰り返し呼び出すことで次々にマッチを見つけていく。良くある抽出のユースケースだとこちらを使えば良さそう。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec

```typescript
const content = 'random word[!image](path/to/image.png)random word';
const imageKeyRegex = /\[!image\]\((.*?)\)/;
const match = imageKeyRegex.exec(content);

console.log(match);
// ["[!image](path/to/image.png)", "path/to/image.png"]
```

この場合、exec() は配列を返し、match[0] には全体のマッチ、match[1] にはキャプチャグループのマッチが入る。

## 主な違い？

| メソッド                   | 対象               | 戻り値                                                | 繰り返し呼び出し | グローバルフラグ (`/g`) の挙動                          |
| -------------------------- | ------------------ | ----------------------------------------------------- | ---------------- | ----------------------------------------------------- |
| `String.prototype.match()`  | 文字列             | グローバルフラグなし: 全体とキャプチャグループの配列<br>グローバルフラグあり: 全体のマッチのみの配列 | 不可             | グローバルフラグがある場合、全体のマッチのみ返す       |
| `RegExp.prototype.exec()`   | 正規表現           | 全体とキャプチャグループの詳細な情報を含む配列        | 可能             | 繰り返し呼び出すことで次々にマッチを取得可能           |

結論として、基本的に同じ挙動をするので好きな方を使えばいい感じだった。個人的には`match()`のが直感的に何やってるのか分かるので好み。
それにしても、パスだけが欲しい場合、どちらの場合でも`match[1]`になってちょっぴり違和感がある
[Unity] 3Dゲームでスクリプトからプレイヤーの形を変更したい

# 今回の目標
![画面録画-2024-09-14-202212.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/23e8ee7e-14d6-4e88-29f0-2f2c94640af8.gif)

プレイヤーオブジェクトが衝突したオブジェクトに変わるようにしたい

# できなかったやつ
## コード
```C#
void OnCollisionEnter(Collision collision)
    {
        // 触れたオブジェクトのMeshFiletrとCollider
        MeshFilter otherMeshFilter = collision.gameObject.GetComponent<MeshFilter>();
        Collider othercollider = collision.gameObject.GetComponent<Collider>();
        string other_name = collision.gameObject.name;

        // 現在のオブジェクトのMeshFilterとCollider
        MeshFilter playerMeshFilter = player.GetComponent<MeshFilter>();
        Collider playercollider = player.GetComponent<Collider>();

        if (otherMeshFilter != null && playerMeshFilter != null && other_name != "Plane" && other_name != "Wall") // 床に触れても変更しないようにしておく
        {
            // プレイヤーのメッシュを触れたオブジェクトのメッシュに変更
            playerMeshFilter.mesh = otherMeshFilter.mesh;
            
            // 当たり判定も一緒に
            playercollider = othercollider;
        }
    }
```


この方法だと描画される絵（多分mesh?）だけ変わってしまい、colliderは変更されなかった;;;カナシイ

![画面録画-2024-09-14-213035.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/89a447aa-1105-60b7-c3ee-0eb985c4248f.gif)



# 解決法
```diff_C
    void OnCollisionEnter(Collision collision)
    {
        // 触れたオブジェクトのMeshFiletrとCollider
        MeshFilter otherMeshFilter = collision.gameObject.GetComponent<MeshFilter>();
        Collider othercollider = collision.gameObject.GetComponent<Collider>();
        string other_name = collision.gameObject.name;

        // 現在のオブジェクトのMeshFilterとCollider
        MeshFilter playerMeshFilter = player.GetComponent<MeshFilter>();
        Collider playercollider = player.GetComponent<Collider>();

        if (otherMeshFilter != null && playerMeshFilter != null && other_name != "Plane" && other_name != "Wall") // 床に触れても変更しないようにしておく
        {
            // プレイヤーのメッシュを触れたオブジェクトのメッシュに変更
            // 当たり判定も一緒に
            playerMeshFilter.mesh = otherMeshFilter.mesh;


            // Colliderの変更
+            Destroy(playercollider);
+            player.AddComponent(othercollider.GetType());

        }
    
```

`playercollider`をDestroy()で削除してplayerオブジェクトにコンポーネントを追加するようにした

# 最後に
まだunity触り始めて日が浅いので、間違い等あるかと思いますのでどんどん指摘ください🙇
[競プロ] Rust練習中メモ 随時追加

# はじめに
長期コンテストとかでRustを使ったらバグらなくていいのかなと想像したので練習しています。
自分用のメモです。
なんか思ったら追加すると思います。

# 本文
## グラフアルゴリズム
`petgraph`というライブラリがAtCoder環境上で動作します。
具体的には、`dijkstra()`や`floyd_warshall()`なんかが提供されているみたい。
使い方が分かれば強力な武器になるかもしれません。

# おわりに
定期的に追記されている長い記事でした。
脱WPFを目指してWinUI 3 アプリを調べてみた。(その1)

# はじめに
私は、現在ソフトウェアの開発部門では働いてはいないのですが、日々の作業を軽減するためのツールを自作することを趣味にしています。過去に、業務でソフトウェア開発を行っていた経験を活かすことができるのと純粋にプログラムを楽しむためです。業務でプログラムを作るというのは、楽しいことばかりではありませんので、趣味と実益のから考えると今くらいの関わり具合いが私にとってはバランスが良いのかもしれません。
業務改善というとノーコード・ローコードツールが選択肢になると思うのですが、Windowsに標準で用意されているPower Automate Desktopの無料版は制限が大きく所属会社の理解とバックアップが不可欠です。比較して、Visual Studio Communityは、フル機能が無料で手に入りますし自分の業務を省力化・自動化する用途であれば、規模や難易度から考えて、アプリケーションを作ってしまった方が簡単でした。
前職では、WPFを使った開発を行っていましたので、学習コストを抑えるために、WPFを使ってアプリを作ってみました。上司や同僚からの反応もおおむね好評で、業務に支障がなければ業務時間内にプログラムすることも認められています。このままWPFを使い続けていても問題は無いのですが、どうせ趣味で作るのであれば、新しい技術も試してみたいと思いWinUI3(Windows App SDK+.NET Community Toolkit)を調べてみました。

# WinUI3について
## 概要
:::note info
公式説明
WinUI 3 は、(完全に Windows 10 SDK から切り離された) Windows App SDK に付属するネイティブ UI プラットフォーム コンポーネントです。 Windows App SDK には、Windows 10 以降を対象とした実稼働デスクトップ アプリを作成し、Microsoft Store に公開するために使用できる、API とツールの統合セットが用意されています。
[Windows App SDK (WinUI 3) の WinUI](https://learn.microsoft.com/ja-jp/windows/apps/winui/winui3/)
:::
あまり成功したとは言えないUWPが、WinUI2で、WPFはWinUI1になるようです。
クロスプラットフォーム向けの.NET MAUIもありますが、クロスプラットフォームにどこまで需要があるのか結果が分かるまで、少し時間が掛かるでしょう。個人的には、Linux用のアプリをXAMLで作れたらと思うのですが、Linuxには対応していないみたいです。

## サンプルアプリケーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7839/a6de2969-ac41-d2eb-1d22-8ea7e35c8905.png)
[WinUI 3 Gallery](https://apps.microsoft.com/detail/9p3jfpwwdzrc?hl=ja-JP&gl=JP)
まずは、お手本となるWinUI 3 Galleryをインストールして確認することから始めました。
Githubのソースコードにも簡単にアクセスできるので、プログラム方法はすぐに理解できると思います。
非常に良くできたアプリケーションなので、すごく参考になります。

# アプリの配布をどうするか
部署内の数人のために作ったプログラムなので、exeをZip圧縮して渡すだけでも事足りるのですが、アップデートがあるたびに、声がけするのもスマートじゃありません。標準で更新通知を自動的に行う機構が用意されていますので利用します。
WinUI 3アプリには、ざっくりいうとMicrosoft Storeに公開するPackageとMicrosoft Storeを使わないUnPackageがあります。Microsoft Storeは、企業向けやプライベート向けの配布を止めてしまったので、自分のような用途では、UnPackage(サイドローディング)を使用することになります。ここで問題となるは、アプリパッケージの作成を使ったWeb配布機能が、セキュリティー的な懸念から制限が掛かってしまっている点です。

:::note warn
引用
米Microsoftは12月28日（現地時間）、「ms-appinstaller」プロトコルハンドラーを既定で無効にしたと発表した。2023年11月中旬以降、金銭の詐取を目論む複数のサイバー犯罪者がMSIX形式のインストーラーを介してランサムウェアを送り付ける事例が観測されたためだという。
[Microsoft、「ms-appinstaller」プロトコルハンドラーを既定で無効化 ～マルウェアの標的に](https://forest.watch.impress.co.jp/docs/news/1560476.html)
:::

残念ながら当面の間、ms-appinstallerを使うことは難しいようです。
WinUI 3アプリでも使い慣れた[ClickOnce](https://e-words.jp/w/ClickOnce.html)を使うことは可能ですので、そちらを使用することとします。

# プロジェクトの作成
プロジェクトは、WinUIのTemplate Studioを使用して作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7839/41f41af2-76f5-2883-c047-a3de8173f09f.png)


# MVVMへの対応
WinUIのTemplate Studioを使うとMVVM Toolkitを使ったテンプレートを出力してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7839/04c408ff-19ea-3833-12f6-fe67184413d4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7839/895dbb39-ea48-9db5-aab4-a5cd69106444.png)
PHPで日本語の文字数を正しくカウントする方法

## 概要
- バリデーションのテストをおこなったところ、日本語に対する正しい判定を行えていないことが分かった
- 正しい判定方法を備忘録として残しておく


## 理由

```php
if (strlen($name) > 50) {
```
もともとこのようにバリデーションを行っていたが、「あ」を50回繰り返したところエラーが発生してしまった

>function strlen(string $string): int
文字列の長さを得る
>
>与えられた string の長さを返します。
>
>https://www.php.net/manual/function.strlen.php
>
>@param $string: 長さを調べる文字列。
>
>@return string の長さをバイト単位で返します。

原因は単純で、バイト単位でカウントするため2倍カウントされてしまっていることが原因であった

## 解決方法

>function mb_strlen(
    string $string,
    string|null $encoding = null
): int
文字列の長さを取得します。
>
>https://www.php.net/manual/function.mb-strlen.php
>
>@param $string: 長さを調べたい文字列。
>
>@param $encoding: encoding パラメータには文字エンコーディングを指定します。省略した場合、もしくは null の場合は、 内部文字エンコーディングを使用します。
>
>@return 文字エンコーディング encoding の文字列 string の文字数を返します。 マルチバイト文字の一文字は1個として数えられます。

これまでの部分をこのように置き換えることで、意図したように日本語の文字数をカウントすることが可能となる
YAMLの作法

今回は、インターンの中で利用した、ymlについて話していきたいと思います。
# YAML (YAML Ain’t Markup Language)とは？
ymlとは、一言で言えば、
【データを直感的かつ人間が読みやすい形式で記述するためのデータ表現形式】です。
```
name: John Doe
age: 30
email: john.doe@example.com
```
:::note info
こんな感じで使う
:::
# 今回どんな時に使ったか
Webサイトの中で用いられている、英語の情報を日本語表記に変換するのに使いました。
例えば、
```
ja:
  hello: "こんにちは"
  user:
    name: "名前"
    email: "メールアドレス"
  messages:
    welcome: "ようこそ、%{name}さん！"
    goodbye: "さようなら！"
```
これをconfig/locales/ja.ymlに記述します。そしてビューで表示させるには、
```
<%= I18n.t('hello') %> 
<%= I18n.t('user.name') %> 
```
のようにすればオッケー。（**すごい**）

:::note info
補足
:::
このyml、**エラーメッセージを表示させる処理の時も使えるらしい**
```
class UsersController < ApplicationController
  def show
    flash[:notice] = I18n.t('messages.welcome', name: @user.name)
  end
end
```
これをコントローラーの中で利用すれば、エラーメッセージを日本語化できる！

以上、備忘録でした。
家族に怒られない(?) やや逸般の誤家庭のすすめ

# テーマ
- 家族にギリギリ怒られないレベルの小規模自宅サーバ及びネットワーク環境の紹介

# 対象読者
- 自宅サーバ環境を作ってみたいけど、せっかくならインフラから意識して作りたい人

# 自己紹介
某Sierで仮想基盤とかの設計構築をしています。
物理～ハイパーバイザまで幅広く知識が求められるので、まとまったアウトプットがしたいと思い作りました。
現在はまだファイルサーバくらいがメインの用途ですが、コンテナの技術検証で使いたいと思っている。。。

# 構成
## 物理構成
![IMG_20240914_230240.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426258/a032eb43-9130-f7ae-806c-f02e98ec3131.jpeg)

![IMG_20240914_230144.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426258/0a04f037-f446-4d31-c9d4-fd8916469d79.jpeg)

![物理構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426258/d6158dfd-382f-5f04-e675-44b726d8bc5a.png)


設置場所はテレビ台の戸棚の一角(無線APはテレビ台の上)です。
APは戸棚の中だと電波が弱くなりそうなのと、来客者に「うちはCisco使ってるぜ」とドヤるために見えるところにおいてます。

1. ONU
    NTTのGE-ONUと書かれてるやつ。(回線業者からレンタル)
    回線はNTT光コラボのおてがる光です。価格コムで安い順に並べたときに上位だったのと、キャッシュバック方法が「24か月後にドーンと返します」ではなく、「月々のお支払から○○円ずつ値引きます」だったので、日々の負担を減らせるほうが良いかと思い選びました。
    <br>
2. ルータ
    **Yamaha RTX810**
    ヤフオクで中古にて購入。今は後継機種が出ているため、このモデルはかなり安く入手できました。(5,000円もしないくらい)
    ルータとしての機能は十分なのと、YamahaのネットボランチDNSサービスと呼ばれるDynamic DNSサービスが無料で利用できるため選びました。(屋外から自宅環境に気軽にアクセスしたかった)
    <br>
3. L2スイッチ
    **Buffaro BS-GSL2005**
    以下の2項目に合致していたため購入。(7,000円ほど)
    - ダウンリンク側の機器によってタグVLANとポートベースVLANを使い分けられる
    (Yamaha RTX810のスイッチポートはすべてのポートにどちらかの同じ設定が割り当たってしまうため不可)
    - 電源ポートとLANポートが同じ面
    (配線の都合上)

    非常に小型でありながら、GUIを兼ね備えており(逆にCLIは無い)、タグVLANなどの高度な機能を備えた優秀なインテリスイッチだと思います。
    <br>
4. 無線AP
    **Cisco WAP125**
    逸般の誤家庭感を醸し出したいため、エンタープライズなブランドのCiscoを選定。(ヤフオクで12,000円くらい)
    ルータ機能はないため、別途購入が必要。(ルータとAPが別ってところが一般家庭との大きな違い)
    <br>
5. 仮想基盤ホスト
    **ASRock DeskMini H470**
    サーバのハードウェア選定もやってみたいと思い、パーツ構成から自分で選んで作れる本モデルを選定。
    使用したパーツは以下の通り。
    CPU：intel Core i5-10400
    メモリ：Crucial CT16G4SFD8266 ×2 (32GB)
    ディスク：Crucial CT500P2SSD8JP ×1 (ホストOS用&仮想マシンファイル用)
    ディスク：WD Blue WD10SPZX-EC ×2※1 (ファイルサーバ用※2)
    
    ※1 DeskMini H470のハードウェアRAID機能を使用し、RAID1で構成
    ※2 ファイルサーバ用のTrueNAS仮想マシンに対してRDM(Raw Device Mapping)で見せている

6. その他
    **Raspberry pi 3b+**
    学生時代に遊ぶために買った。[この記事](https://qiita.com/nijimasuhsv/items/bd5b9f98a505ab091b24)や[この記事](https://qiita.com/nijimasuhsv/items/8abd91809d24cf2897b3)等で登場している。
    今はほぼ使っておらず、というか写真にも写ってないから押し入れの奥底だ…

## 論理構成
![論理構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426258/ada30cfa-d365-9ad3-531f-de01ed02aec8.png)

論理的にはこのような感じでNWを組んでいる。
VLANの種別は以下の通り
- VLAN100：管理用。管理ポートとか。
- VLAN101：家族用Wifi。他の3つのVLANにアクセスできる。
- VLAN102：ゲスト用Wifi。他のVLANにはアクセスできない。インターネットへのアクセスのみ可能。
- VLAN200：開発用。として分けているけど、現時点では未使用。

### 仮想マシン
仮想マシンは現時点で以下の2台が稼働している。今後は時間を見つけてもっといろんな検証をしてみたい。(まずはDocker建ててコンテナを学びたい)
1. TrueNAS
    家族用ファイルサーバ。主に小さい頃の写真の長期保管や、過去購入したDVDのデータを保管し、Android TVから直接視聴する目的で使用。
    上述しているが、データ保管領域はハイパーバイザ側でRDMを行い、物理HDDを直接見せている。理由としては、データ保管領域を仮想ディスクとしてTrueNASに見せるよりも、IOが高速化でき、DVDの視聴が快適に行えると考えたためである。(ちゃんと性能検証はできてないので、今度やりたいところ)
    <br>
2. NetBox
    オープンソースのIPAM。そのほかにもデータセンター管理（DCIM）機能など充実しているが、自宅環境が小規模のためそこまで活用はできていない。

# まとめ
まずは紹介ということで雑に並べてしまいましたが、今後各コンポーネントについての設定内容やハックなどを連載として上げていきたいと思います。
逸般の誤家庭に挑戦してみたいという気持ちがちょっとでもある方向けのため、技術的な解説はほぼありませんが、ご不明点あればコメントいただければと思います。

それでは。
ソフトウェアファースト第2版（第1章）の読書メモ

# はじめに

ソフトウェアファーストの第2版が出版されました。:clap:

https://amzn.asia/d/2fxjKjS

かなり有名な本ですが、まだ読んだことがなく、いつか読もうと思っていたところに第2版が出たので、買って読んでみました。

読んでみて、思ったことをつらつらと書いてみます。

# 第1章の概要

第1章では、「所有から利用」、「コト消費」、「コロナ下での飲食業」などの事例を挙げ、消費者を取り巻く環境が変わってきたことを示しています。

その中でビジネス成功の鍵を握るのは、柔軟性が高く、後から継続的に改善・進化させることのできるソフトウェアなので、外注に丸投げせず、自分たちでコントロールしましょう、といった主張がなされています。

# あなたにとってのDXとは何ですか？

なかなか興味深い問いでした。（第1章の中で登場する文です。）

私なりに考えてみた結果は、以下の通りです。
**「デジタル」と「アナログ」の掛け算の結果を最大化すること**

デジタルの力を使って、アナログの価値を増幅させること、と言い換えても良いです。
もう少し詳細を書くと以下の通りです。

「デジタルだけあっても価値は生まない」
スペックの高いサーバ上で、きちんとエラーハンドリングが実装されたプログラムを稼働させたとしても、そのプログラムが誰も必要としていないデータを読み書きしているのであれば、意味はありません。

「価値のあるアナログが必要」
具体的には、スキルを持った人材、役に立つ道具、魅力的なイベント、観光資源などです。

私が思う、優れたDXの事例としては、オンライン英会話ですね。

一昔前まで、英会話レッスンというのは、高い金を払って、週1程度でどこかに通って、欧米人と会話をするのが当たり前でしたが、今では、PCやスマホを通じて、格安で毎日フィリピン人と英会話ができるようになりました。

デジタル（インターネット） x アナログ（英語が話せるフィリピン人）を掛け合わせて、安価に英語を学びたい日本人に対して、大きな価値を提供しています。

また、最近の例だと、PayPayのやり方に感心しました。

キャッシュレス決済を実現する場合、たいてい店舗側に何かしらの端末や設備を導入させることが普通であり、ローカルな小型店舗への導入はハードルが高いものでした。

まさか、QRコードを印刷した卓上の紙（ペーパースタンド？）を置いておき、それを客のスマホに読み込ませて払わせ、その様子を店員が目視確認するという、オペレーションを採用するとは思いませんでした。
並のシステム開発会社だと、そんなオペレーションは絶対に認めないだろうな、と思います。
しかし、今となっては、違和感なく浸透しています。

これは、デジタル（客のスマホ&QRコード） x アナログ（ローカルな店）で、キャッシュレス決済を安価に実現したDXですね。

# 接客もプロダクト？

本書では、接客のような仕事もプロダクトの一機能とみなすことができる、と主張しています。

自分の中では、具体的なモノがプロダクトであり、それ以外の事象や、プロダクトとユーザのやり取りはサービスと思ってました。（SaaSなら、デプロイされたプロダクトを通して、ユーザにサービスを提供している。）

プロダクトという言葉が出た時に、文脈に注意して解釈する必要がありそうです。

# 個人に必要と思われる資質

ソフトウェアファーストを実現する上で、あると望ましい個人の資質は、以下の通りかなと思いました。
* フットワークが軽いこと（変化への追従）
* 興味や関心の幅が広いこと（技術だけではない）
* 常に学び続けていること


# まとめ

ソフトウェア「ファースト」でありつつも、技術力だけでビジネスを進めるのは厳しい。
絵は上手いけど、中身のない漫画を描いているような？感じになってしまう。
同期発電機の動揺方程式と数値解析

# はじめに
同期発電機は、入力と出力の仕事量をほぼ同じに保たないと上手く安定性を保つことができない。入力を多くすることで、発電機の回転速度は上昇する。一方で、出力を多くすることで、発電機の回転は低下する。これは、同期発電機の動揺方程式つまり微分方程式を解くことで解析することができる。そこで、今回は動揺方程式を差分法を解くことでシミュレーションする。

![動揺方程式_電気的出力2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/047dc9c8-e689-7ef6-4aa4-b54189e20d8f.png)

# 動揺方程式
## 微分方程式のモデル
動揺方程式は、慣性定数$M$、ダンピングトルク係数$D$、基準角速度$\omega_n$を用いて以下のように表すことができる。ただし、$\delta$は時刻$t$における送電端電圧と受電端電圧の位相差である相差角とする。
```math
\frac{M}{\omega_n}\frac{d\delta^2}{dt^2}+\frac{D}{\omega_n}\frac{d\delta}{dt}=P
```
ここで、$P$は機械的出力(出力)$P_m$と電気的出力(出力)$P_e$を用いて以下のように表されるものとする。

```math
P=P_m-P_e=P_m-\frac{V_rV_s}{X}sin \delta
```
# プログラム
上記の微分方程式を解くためのプログラムを以下に示す。

```python P_newton.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math

#シミュレーション時間
t_a=-2
t_b=4
#動揺方程式の係数
M=10
D=1
omega_n=2*math.pi*50
#P_eの計算に必要な値
V_r=1
V_s=1
X=1
#初期条件
delta=1
d_delta=0

time=[] #時間
delta_list=[] #位相差
P_e_list=[] #発電機の出力
delta_t=1.0*10**-5
P_m=1
t=t_a

#微小時間の時間間隔(小さくするほど精度は上がるが計算時間が比例して増大する)

while t_a<=t<=0:
  time.append(t)
  delta_list.append(delta)
  P_e=(V_r*V_s/X)*np.sin(delta)
  P_e_list.append(P_e)
  t=t+delta_t

while 0<=t<t_b:
  P_e=(V_r*V_s/X)*np.sin(delta)
  P=P_m-P_e
  dd_delta=(P-(D/omega_n)*(d_delta))*(omega_n/M)
  d_delta=d_delta+dd_delta*delta_t
  delta=delta+d_delta*delta_t
  t=t+delta_t

  time.append(t)
  delta_list.append(delta)
  P_e_list.append(P_e)

#以下は、電気的出力の動揺の様子を示すグラフを描写するために必要なコードである。

# plt.plot(time,P_e_list)
# plt.xlabel("時間[s]")
# plt.ylabel("電気的出力[pu]")
# plt.savefig("動揺方程式_電気的出力2.png")

#以下は、相差角の動揺の様子を示すグラフを描写するために必要なコードである。

plt.plot(time,delta_list)
plt.xlabel("時間[s]")
plt.ylabel("相差角[rad]")
plt.savefig("動揺方程式_相差角2.png")

plt.show()
```

これを実行すると以下のようなグラフが出力される。

![動揺方程式_相差角.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/d28bc73f-16cb-65f9-5411-e3146bd7af78.png)

![動揺方程式_電気的出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/4469f67f-33e9-ffc4-b8e3-3b2a48f36780.png)

このように、相差角と電気的出力はリンクしているかのように緩やかに振動する。

一方で、$P_m$を大きくすると以下のように不安定な挙動を示すグラフ、つまり脱調時のシミュレーションを得ることができる。

![動揺方程式_相差角2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/cb112903-e892-3901-b5bd-815056f075e8.png)

このように、相差角は単調に指数関数的に増加する。

これは、加速エネルギーが減速エネルギーを上回るため、その余剰分が回転機の加速に使用されるからである。したがって一般的な事故である1線地絡事故の場合は、事故点を遮断してから再閉路するまでの間、発電機にかかる負荷は小さくなるので、なるべく早く再閉路しないと相差角が指数関数的に増えるので過渡安定度が悪くなる。しかし、再閉路までの時間があまりにも短すぎると地絡点の事故が十分に除去できないので再閉路失敗となってしまう可能性もある。

![動揺方程式_電気的出力2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/047dc9c8-e689-7ef6-4aa4-b54189e20d8f.png)

一方で、電気的出力は高速に振動する。




# まとめ
今回は、同期発電機の動揺方程式を差分法を使って解析し、電気的出力や相差角の変化の様子をシミュレーションした。結果、不安定な場合である脱調の場合は、相差角は指数関数的に上昇し、電気的出力は高速で振動するということが分かった。

# 参考文献

https://amzn.asia/d/iW6wOjv

https://denki-no-shinzui.com/oscillation-equation/
GPT記念メモ

大学4年間で学ぶ、数学の概要をGPTに聞いてみた。
もう大学行く必要なくなったような、そんな気がするが、通学してはないので、仲間がいないのが欠点かな


## 1年次：基礎力の養成 

### 微分積分学 I・II 

工学部では、まず微分積分学の基礎を学びます。関数の極限、微分、積分といった基本概念から始まり、数列・級数や偏微分、重積分など、応用力を養うための内容まで幅広く学びます。 

学ぶ内容: 関数の極限、導関数、積分、偏微分、重積分 

応用例: 物理学や材料工学での運動量の計算やエネルギー解析 

### 線形代数学 

微分積分と並んで重要なのが、線形代数学です。ベクトルや行列、行列の対角化、固有値や固有ベクトルといった概念が扱われ、工学での多くの問題解決に利用されます。 

学ぶ内容: ベクトル、行列、行列式、固有値・固有ベクトル 

応用例: 電気回路や構造解析、画像処理 

## 2年次：応用数学の基礎 

### 常微分方程式 

工学において、物理現象を表現する微分方程式は非常に重要です。特に、常微分方程式（ODE）はシステムの動作を解析するためのツールとして多用されます。 

学ぶ内容: 一階・二階の常微分方程式、解法、境界値問題 

応用例: 振動現象、電気回路解析 

### フーリエ解析・ラプラス変換 

信号処理や制御工学で使われるフーリエ解析やラプラス変換の基礎を学びます。周期関数や波動現象の解析に役立ちます。 

学ぶ内容: フーリエ級数、フーリエ変換、ラプラス変換 

応用例: 振動・波動解析、信号処理 

## 3年次：専門数学の展開 

### 複素関数論 

工学において、特に電気工学や機械工学で広く使われるのが複素数とその応用です。複素数の基本概念や複素関数、複素積分を学びます。 

学ぶ内容: 複素数、複素関数、留数定理 

応用例: 電気回路解析、制御理論 

### 確率統計 

工学分野でもデータの解析や不確実性の扱いが重要となるため、確率と統計の知識が求められます。確率分布や推定、検定の基礎を学びます。 

学ぶ内容: 確率分布、期待値、推定と検定 

応用例: 品質管理、機械学習 

## 4年次：実践的な数学 

### 数値解析 

実際の工学問題では、解析的な解が得られないことが多々あります。そのため、数値的な手法を用いて近似解を求める数値解析を学びます。 

学ぶ内容: 数値積分、数値微分、差分法 

応用例: 流体力学シミュレーション、構造解析 

### 最適化 

工学問題におけるリソースの最適な使い方を模索するための最適化理論を学びます。線形計画法や非線形最適化など、様々な問題に対処できる手法を身につけます。 

学ぶ内容: 線形計画法、非線形最適化、制約条件付き最適化 

応用例: 生産計画、交通網の最適化
【Obsidian】Spaced Repetition の使い方

## Spaced Repetitionとは

Spaced Repetitionは、フラッシュカードとノートのレビューを通じて間隔反復学習をサポートしてくれるObisidianのプラグインです。

https://github.com/st3v3nmw/obsidian-spaced-repetition

## インストール

Obsidianのコミュニティプラグインセクションからインストールできます。

![スクリーンショット 2024-09-14 23.08.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ee635a79-a736-e5f5-77fa-8209a32a7df4.png)

## フラッシュカード

### 作成

`#flashcards`のタグをつけるとフラッシュカードとして認識されます。`#flashcards/deckA`のように階層を分け、分類することもできます。

```md
#flashcards/deckA
```

単一行のフラッシュカードを作成するには質問と答えを`::`で区切り、`質問::答え`のように記述します。

```md
#flashcards/deckA
質問1::回答1
```

上記のように記述すると以下のようなフラッシュカードが作成されます。

![スクリーンショット 2024-09-14 23.19.16のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/60f2a7b0-0559-3f71-b967-45f0c5da522e.png)


![スクリーンショット 2024-09-14 23.19.35のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/580b3a64-70f2-8fb3-8e43-56bc4b4b4d3f.png)

複数行のフラッシュカードを作成するには`?`で区切ります。

```md
#フラッシュカード/deckA 
複数行の
質問
?
複数行の
回答
```

上記のように記述した場合、以下のようなフラッシュカードが作成されます。

![スクリーンショット 2024-09-14 23.26.23のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/2558e1a1-e924-7bae-928a-c693ff7efd21.png)

![スクリーンショット 2024-09-14 23.26.38のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/2aafcdf1-e5f9-7f0e-a893-28137588eb8d.png)

穴埋めのフラッシュカードを作成するには穴埋めにしたい単語を`==`で囲みます。

```md
#フラッシュカード/deckA 
==穴埋め==のフラッシュカード
```

![スクリーンショット 2024-09-14 23.32.52のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b7fea7ad-0b8d-ae79-edbc-cf27d18d144e.png)

![スクリーンショット 2024-09-14 23.33.08のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/830ce1c3-37e1-6dca-5389-6fba75dc72e1.png)

なお、上述の`#flashcards`や`::`や`?`、`==`の記号はすべて設定で任意のものに変更できます。

### レビュー

コマンドパレットから「Spaced Repetition： すべてのノートからフラッシュカードをレビューする」を実行して作成したフラッシュカードをレビューします。

![スクリーンショット 2024-09-14 23.42.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/33208477-11dc-30ad-4f55-1a43ae355ecc.png)

回答を表示した際、カード下部にボタンが表示されます。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323334323434332f38333063653163332d333765312d366463612d353338392d3666626137356463373265312e706e67のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/161ac012-2144-d31b-d232-b1319bb5a4f8.png)


このボタンに記載されている日数後に再度レビュー可能になります。

## ノート

ノート自体をフラッシュカードのように使用することもできます。

ノートに`#review`というタグをつけるとレビュー対象として認識されます。

コマンドパレットから「Spaced Repetition: Open Notes Review Queue in sidebar」を実行するとサイドバーにレビュー対象ノートの一覧が表示されます。

![スクリーンショット 2024-09-14 23.51.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/6450d87d-a053-e03f-0a21-a50eae7f1d01.png)


それぞれのノートを表示し、コマンドパレットなどからフラッシュカードと同様に「Hard」「Good」「Easy」のいずれかで評価します。
「Hard」「Good」「Easy」のうちどれを選択したかで次回レビューまでの感覚が変化します。

## 参考

https://www.stephenmwangi.com/obsidian-spaced-repetition/
AWSのELB(ALB・NLB・CLB)を比較してみた

## ELBとは
ネットワークトラフィックの分散によって、アプリケーションのスケーラビリティを向上させるサービス。

https://aws.amazon.com/jp/elasticloadbalancing/?nc=sn&loc=1

## ロードバランサーの選び方
AWSのロードバランサーには、4つの種類があるが、アプリケーションに最適なロードバランサーの選び方は以下となる。

::: note info
**[ALB]**
HTTP リクエストの負荷分散を行う必要がある場合

**[NLB]**
ネットワーク/トランスポートプロトコル (レイヤー 4 - TCP、UDP) の負荷分散や非常に高いパフォーマンス/低レイテンシーのアプリケーション

**[CLB]**
アプリケーションが Amazon EC2 Classic ネットワーク内に構築されている場合

**[GWLB]**
サードパーティ製の仮想アプライアンスを導入してデプロイする必要がある場合
:::

### 1.Application Load Balancer (ALB)
ALBは、HTTPおよびHTTPSトラフィックを対象としたロードバランサーで、アプリケーション層（レイヤー7）で動作する。

### 2.Network Load Balancer (NLB)
NLBは、TCPおよびUDPトラフィックを処理するためのロードバランサーで、トランスポート層（レイヤー4）で動作する。


### 3.Gateway Load Balancer (GWLB)
ファイアウォールや侵入検知システムなどのサードパーティ製仮想アプライアンスを簡単にデプロイおよび管理できる。
レイヤー3で動作し、全てのIPパケットをリッスンしてトラフィックを振り分ける。

### 4.Classic Load Balancer (CLB)
AWSの初期から存在するロードバランサーで、レイヤー4またはレイヤー7で動作する。

## 料金
※以下は全て東京リージョンの場合
|| 料金| 単位|
|:-----------|:------------|:------------|
| ALB |USD 0.0243USD<br>USD 0.008<br>USD 0.0054 | ALB時間 (または 1 時間未満)<br> LCU 時間 (または 1 時間未満)<br>ALB に関連付けられたトラストストアごとに相互 TLS の使用 1 時間 (または 1 時間未満) |
| NLB |USD 0.0243<br>USD 0.006 | Network Load Balancer 時間 (または 1 時間未満) <br>NLCU 時間 (または 1 時間未満) |
| GWLB |USD 0.0135<br>USD 0.004 | AZ あたりの Gateway Load Balancer 時間 (または 1 時間未満)<br>GLCU 時間 (または 1 時間未満) |
| CLB |USD 0.027<br>USD 0.008 | CLB により処理されたデータの GB 単位 |

### LCUとは
ALB がトラフィックを処理するディメンション (1 時間あたりの平均)。
以下の 4 つのディメンションを測定する。
- 新しい接続(1 秒あたり)
- アクティブ接続(1 分あたり)
- 処理タイプ
 ロードバランサーによって処理された HTTP(S) リクエストと応答のバイト数 (GB 単位)。
- ルール評価
 ロードバランサーにより処理されたルールの数とリクエストレートの積

### NLCUとは
NLB がトラフィックを処理するディメンション (1 時間あたりの平均)。
以下の 3 つのディメンションを測定する。
- 新しい接続(1 秒あたり)
- アクティブ接続(1 分あたり)
- 処理バイト(GB 単位)

### GLCUとは
GWLB がトラフィックを処理するディメンション (1 時間あたりの平均)。
以下の 3 つのディメンションを測定する。
- 新しい接続(1 秒あたり)
- アクティブ接続(1 分あたり)
- 処理バイト(GB 単位)

 

:::note info
ELBは、12ヶ月無料トライアルが利用できる。
トライアルでは、CLBとALB間で共有された 750 時間/月、CLBの 15 GB のデータ処理、ALBの 15 LCU が提供される。
:::

## SLA
毎月少なくとも 99.99% の可用性が保証される。
電卓を作りながら勉強ー1

お疲れ様です。

JavaScriptを使って、まずは簡単に作れるものはないか探していたところ、今日偶然にも私用で使う電卓を購入したことを思い出し、「電卓作ってみよう！」ということで、考え方を検索:computer:

いろいろと見てきましたが、要素の意味なども説明してくださっている [@bumpfuji10様](https://qiita.com/bumpfuji10/items/2b9470667530f67696ca) の記事を見て、分かりやすそうと思いましたので、分からないところは調べて理解しつつ、進めていこうと思います！
**※bumpfuji10様のページ内でも書かれてあることですが、[ウェブカツブログ様](https://webukatu.com/wordpress/blog/27277/)のコードを元にbumpfuji10様なりの解釈で書かれたコードとなっております。これを盗用し私発信とすることが目的では一切ございません。気になる方はぜひ上記ページをご覧ください！**
<br>
まずは進捗です。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="xxoNwoE" data-pen-title="Untitled" data-user="mtzkmy" 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/mtzkmy/pen/xxoNwoE">
  Untitled</a> by mtzkmy (<a href="https://codepen.io/mtzkmy">@mtzkmy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

まだhtmlしか書けておりませんが、見た目は電卓になりました！
明日、続きを少しずつやっていこうと思います。
<br>
**今日勉強になったポイント**
:point_up:colspan（コルスパン）属性
　↳水平方向のセル結合のこと
 　ここでいう、一番上に表示されている箇所です。td属性で、 colspan="〇"　と書きます。
　 〇には数字が入り、2とするとセル2個分に。今回はボタン4つ分に揃えたいので、4となっています。
<br>
:point_up:input属性
　↳[MDN様](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input)のページを見てびっくりしました…。こんなに種類があるとは…
 　今回登場している　class name value は単純にクラス名、要素に名前を指定するもの、
　値を入力するもので、checkbox rajio hidden の場合は省略不可。

<br>

:point_up:onclick属性
 ↳html要素がクリックされた時に実行されるjsコードが何かを指定するもの。
 今回は、htmlしか書いていませんので、jsのコードを書く時にどういう動きをしているか分かると思われるので、今日は言葉として知っておく。
GitHub Actions で php artisan test を実行して Laravel テスト自動化

## はじめに

今回は下記の条件を満たした時に、対象のブランチに対して`php artisan test`を実行する方法をご紹介しようと思います。

- GitHubでプルリクエストが作成
- 特定のファイルを変更したブランチがプッシュ

## 実装

**手順1:** リポジトリのルートディレクトリに`.github/workflows`ディレクトリを作成

:::note info
いきなりディレクトリを作成してください。
※`リポジトリ画面 => Settings => Actions => General => Actions permissions`など設定しなくても大丈夫です。
:::

**手順2:** `.github/workflows/`配下にymlファイルを作成

GitHub上で直接ファイルを作成・編集しても、ローカルのエディタを利用して編集したものをリポジトリのデフォルトブランチにマージしても、どちらでも構いません。

![スクリーンショット 2024-09-14 23.10.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3829908/602fbb27-5158-dab7-f0a9-a36bb33c43d9.png)

**手順3:** ymlファイルにワークフローの内容を記述

細かく説明するより、すでに動作可能なワークフローを記載しておきますので、内容はコメント文などを見て理解していただけると幸いです。

```sampleTest.yml

# ワークフローの名前
name: Laravel Test By php artisan test

# [GitHub Actions on](https://docs.github.com/ja/actions/writing-workflows/workflow-syntax-for-github-actions#on)参照
# ワークフローのトリガーを定義
on:

 # マスターブランチに対してプルリクエスト作成時(ワークフローのトリガー)
 pull_request:
  # デフォルトは[opened, reopened, synchronize]、ここではopenedのみを設定
  types:
   - opened
  branches:
   - master

 # 特定のパスのファイルで変更が行われたブランチがプッシュされた時(ワークフローのトリガー)
 push:
  paths:
   - 'htdocs/app/Helper/ResultHelper.php'

# [Github Actions jobs](https://docs.github.com/ja/actions/writing-workflows/workflow-syntax-for-github-actions#jobs)参照
# トリガーによって実行されるワークフロー(複数のジョブ可)を定義
jobs: 

 # "laravel_test"というジョブIDでジョブを定義
 laravel_test:
  # "laravel_test"ジョブを実行するOS(ubuntuの最新版)を指定
  runs-on: ubuntu-latest
  # 基本はhtdocsディレクトリで各タスクを実行
  defaults:
   run:
    working-directory: htdocs

  # "laravel_test"ジョブで実行されるタスク(複数)を定義
  steps: 
   # プルリクを作成したソースブランチ || プッシュされたブランチ にチェックアウト
   - name: Fetch and checkout source branch of remote repository
     uses: actions/checkout@v4
     with:
      ref: ${{ github.head_ref }}
      
   # 以下 php artisan test を実行するための環境構築

   # ジョブ内でphp環境をバージョン指定しセットアップ(バージョンはプロジェクトによって各自設定)
   - name: Setup php
     uses: shivammathur/setup-php@v2
     with:
      php-version: "7.4"
      tools: composer:v2

   # 日本語版サイトのテスト用
   # ここで一度.envをコピーしなければcomposer installに失敗する
   - name: Copy .env in Japanese locale
     run: cp .env.example.ja .env

   # composerからライブラリをインストール
   - name: Install dependencies by composer
     run: composer install --no-progress --prefer-dist --optimize-autoloader

   # Laravelのアプリケーションキーを作成
   - name: Generate laravel app key
     run: php artisan key:generate

   # テスト実行
   - name: Run test in Japanese locale
     run: php artisan test

   # 英語版サイトのテスト用
   - name: Copy .env in English locale
     run: cp .env.example.en .env

   # テスト実行
   - name: Run test in English locale
     run: php artisan test

```

英語版サイトなどがない場合には、下記の部分を削除していただいて大丈夫です。

```sampleTest.yml
   # 英語版サイトのテスト用
   - name: Copy .env in English locale
     run: cp .env.example.en .env

   # テスト実行
   - name: Run test in English locale
     run: php artisan test
```

## まとめ

以上、GitHub Actions で php artisan test を実行して Laravel テスト自動化する方法をご紹介しました。GitHub Actionsの利用自体はとても簡単ですね。
あとは各々の目的によってジョブやタスクを定義することで、よりフィジカルで、よりプリミティブで、よりフェティッシュなプロジェクトを進めることができそうですね。

カンボジアの方でも誰でもいいので、この記事が誰かのお役に立つことを心より願っています。
fast apiのasync defとdef

# async defで同期処理の場合は、ブロッキング処理となってしまう

```
from fastapi import FastAPI
from asyncio import sleep as async_sleep
from time import sleep
import os
import threading
import time

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/1")
async def async_async_sleep_endpoint():
    async_sleep(5)
    return os.getpid(),threading.get_ident()

@app.get("/2")
async def async_sleep_endpoint():
    return os.getpid(),threading.get_ident()
```

async defはメインスレッド実行されるので、awaitをつけない場合は、他のリクエストをブロッキングしてしまう。つまりこの例だと、1→2の順にアクセスしたときに、1で5秒待ったあとに2の処理が実行されることになる。awaitをつければ非同期で実行されるので、2の方はすぐに実行される。


# defの同期処理は外部スレッドプールで実行される
```
from fastapi import FastAPI
from asyncio import sleep as async_sleep
from time import sleep
import os
import threading
import time

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/1")
def async_async_sleep_endpoint():
    time.sleep(5)
    return os.getpid(),threading.get_ident()

@app.get("/2")
def async_sleep_endpoint():
    return os.getpid(),threading.get_ident()
```

こうしたら二つとも外部スレッドプールで実行されるので、出力されるスレッドは異なった。
ROG Strix XG16AHPEモバイルモニター分解修理

## はじめに
　２～３年使用したASUS ROG Strix XG16APEモバイルモニタがHDMI信号を入力しなくなってしまった。このモニタ入力の一つはマイクロHDMIコネクタであり、ここにマイクロHDMI-HDMI変換コネクタと太いHDMIケーブルをつないで使っていた。使いながらコネクタ部分に余分な力がかかってる気はしていたが、やっぱり壊れてしまったかと思った。マイクロHDMIコネクタ-基板間のはんだクラックと考えられるし、もう保証期間外なので自分で直してみようと分解してみた。しかし分解手順など情報がなく少し苦労したのでメモ書きする。分解すると保証などはなくなるため自己責任で行ってください。またこのページを参考にした結果、破損などが起きても保証できません。あくまで自己責任でお願いします。

## まず観察
　そもそもどこからケースを開くのか？もわからない。全体写真の通りシンプルな構造でネジなどはない。
 ![DSC_1087~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/a2b405de-bb22-c099-91ea-3c76b3a95c3e.jpeg)
注意しながら本体を見てみるとモニタ右上のフレームに切れ目があった。
![DSC_1089~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/65524859-650f-bc0d-d8ab-349e88557816.jpeg)

## 分解開始
ここが怪しいと思いプラ製ヘラを隙間に入れてスライドさせるとパキパキとツメが取れていった。
![DSC_1090~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/5af98c83-7540-ab63-a61e-8f205f88e104.jpeg)
フレームを外し注意深く液晶パネル部を手前に倒すと内部基板が見えた。
![DSC_1091~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/4135b799-77de-3773-1653-bda93922b421.jpeg)
基板には3つのケーブルがつながっているので、これらを外す。液晶パネルを接続するケーブルには金属製のフックがついているので黄色いプラテープを引きながら上に上げるとフックが外れる。
![DSC_1092~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/b2a727a6-d5c1-ac61-eb2d-52bad5954a80.jpeg)
![DSC_1094~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/93b70a19-cf33-44bc-d96f-67a66ea9f7a1.jpeg)
フックが外れたらケーブルを手前に引いて端子から外す。
![DSC_1097~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/57dfce8b-1b80-8af7-9bdb-9f68f77fe425.jpeg)
　バッテリーケーブルは液晶ケーブル横の黒いテープ下にある。黒いテープを少しはがし、下のコネクターを上に上げるように注意しながら引っ張るととれる。
 ![DSC_1092~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/115c92cb-2d7c-7b32-b621-ff88781e1fc8.jpeg)
　スイッチ類のケーブルは上部のフレキケーブルである。
![DSC_1095~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/4717b558-f1b9-a4f3-e892-cbede57fac1d.jpeg)
プララッチを上に上げてからフレキケーブルを外す。このときプララッチを壊さないよう注意する。![DSC_1096~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/3f7e15a0-faaf-51a5-a740-76efcabb9ef4.jpeg)
　最後にマイクロHDMIを含むコネクタ部分のカバー金属を外す。金属は３つのネジで固定されているのでネジを外せば簡単に取れる。
![DSC_1099~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/d54d6457-0a66-b67a-f6dc-e32df51f452b.jpeg)
![DSC_1100~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/6ec38aaf-7eaf-9ad7-5991-9f5693179354.jpeg)
マイクロHDMI端子は上から２つ目のコネクタである。
![DSC_1102~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/648deb0f-223b-fdd3-6378-8f8ac051b4f4.jpeg)
基板はネジ５か所で固定されているのでそれらを外せば簡単に取り出せる。
![DSC_1091~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/c80d5788-53b5-21b0-46e2-f2897833c491.jpeg)
マイクロHDMI端子のはんだ部分はピン間隔がせまいため、はんだごてではんだ盛りをするとショートしやすいとの記事を読んだため今回は電子回路用ヒートガンで加熱・再溶融させることにした。ヒートガンの設定温度は３５０℃、送風口は最も小さいものを使用した。コネクタ上部のカプラムテープ（絶縁テープ）は剥がすと再利用が難しそうだったのでそのまま加熱した。加熱前にフラックスを塗ってから加熱した。ヒートガン加熱ではんだが溶融すると金属光沢が増すとともに丸っこくなる。再溶融を確認した後、自然放冷し無水エタノールでフラックスをふき取ってから再組立てした。再組立て後、マイクロHDMIが使えることを確認、無事修理が成功した。

## あくまえ自己責任
　繰り返しますがこの分解修理は自己責任の行為です。少しでも不安がある人はマネしないでください。液晶不良がでたらパネル交換も自分でできるかな？と変な自信がつきました。どうしても急ぎで修理したい人の参考になれば幸いです。
Railsでアバター画像が設定されていないときにプロフィール編集ページにリダイレクトする設定方法

## やりたいこと
ユーザー登録後、プロフィール画像を登録していない場合にはプロフィール設定のページに遷移したい
※抽象化すると、特定の条件を満たすとき、特定のページに遷移させたい

### 前提
- Railsを使用
- User has_one Profile の関係
- ユーザーがSign upしたタイミングではprofileはつくられない

## 課題
- プロフィールは自動で生成されないため、`unless current_user.profile.avatar.attached?`のような条件文だと、.nilクラスのエラーが出る
- application_controllerにプロフィール編集画面へのリダイレクトを記載すると、リダイレクトが繰り返されしまう

## 解決策
### 条件文の記載方法
application_controllerに以下を記載。
```
  before_action :check_avatar
  
  private
  def check_avatar
    if user_signed_in?
      unless current_user.profile.present?
        redirect_to profile_path, notice: 'アバター画像を設定してください。'
        return
      end

      unless current_user.profile.avatar.present?
        redirect_to profile_path, notice: 'アバター画像を設定してください。'
      end
    end
  end
```
処理を以下の２つに分岐することで回避しました。
- プロフィールがない場合
- プロフィールはあるが、アバター画像の設定がされていない場合

ちなみに、ログインしていない場合については別途規定しています。

### リダイレクトの回避
#### 原因
先述の設定を、すべてのControllerの継承元のapplication_controllerに記述しているため、当然profiles_controllerにも設定が反映されてしまう。
故に、プロフィールがない場合orアバターがない場合、プロフィール編集ページにリダイレクトされ、プロフィール編集ページからプロフィール編集ページにリダイレクトされ…という処理になってしまう

#### 回避方法
profile_controllerに以下を記述
```
  skip_before_action :check_avatar, only: [:edit, :show, :update]
```

## 学びになったこと
- 地味にunlessやreturnの使い方をちゃんと理解できていなかったので文法の基礎的な部分の穴埋めになった
- skip_before_actionというメソッドを知った
エンジニアの思考整理を身につける①【世界一流エンジニアの思考法】

## はじめに
自分はエンジニアとして生きていくために必要な思考整理術を身に着けていない。
なので、様々な書籍から知見を得てエンジニアとしての思考整理術を身に着けていく。
まず最初に、「世界一流エンジニアの思考法」(著者:牛尾 剛)という本を読んでいき内容を整理していく。

また、今回は生産性向上・情報整理・心構え(マインドセット)の3つのパートに焦点を当てて思考整理術を整理していく。
# Part1:生産性向上

## 要点
1. 試行錯誤は悪である(試行錯誤自体は悪くない)
1. どんなに頭が良くても理解には時間がかかる
1. 感覚で判断せず、ファクトを積み重ねる
1. 頭の中にメンタルモデルを作る

## 概要
### 1.試行錯誤は悪である
この考え方は簡単に言うと「試行錯誤するのは良いけどやみくもに手を動かすのは効率が悪いよ～」という内容である。つまり無計画で思いつきによる試行錯誤はやめたほうが良いということだと自分は認識している。

個人的にこれが一番共感できる考え方である。
自分も何かしら問題が起きた時は考えられる原因を片っ端から試していく方式を取っており、無駄に時間を使っているのを実感している。それに加えてその問題を解決したとしても闇雲にやってしまっているため、そんなに自分の力にはならないことも問題である。

なので、何かしら問題が起きた時はいきなり手を動かすのではなく何が起きているかある程度推測し、仮説を立てることが生産性向上の第一歩ということである。

ただ、理屈は分かっても今までの習慣で勝手に手が動いて闇雲にやってしまうので、なかなか難しい･･･

### 2.どんなに頭が良くても理解には時間がかかる
この考え方は個人的に「まあ、そうだろうな」という感じで、頭が良いと言っても別に魔法が使えるわけではないし、難しい概念は理解するのにそれなりに時間がかかるだろうと考えていた。ここからは自分の考えになるが、頭が良い人はただ賢いというよりも賢く物事を行うためのやり方を理解して実行できる人であると考えている。

この本で登場している優秀なエンジニアも難しい概念は何十回と理解するまで学習を行っているが、これは当然と言えば当然なのかもしれない。

具体的に例を挙げるとJavaScriptのフレームワークにVue.jsというものがあり、その中にrefとreactiveという概念があるのだが、自分はこの2つの違いがわからなかった。ここでこの2つの公式サイトの説明をそれぞれ記述してみる。

## `ref:` 
[これは特殊な属性です。特定の DOM 要素や子コンポーネントのインスタンスがマウントされた後に、そのインスタンスへの直接の参照を取得することができます。](https://ja.vuejs.org/guide/essentials/template-refs)

## `reactive:` 
[リアクティブな状態を宣言する方法として、reactiveを使う方法もあります。内側の値を特別なオブジェクトでラップする ref とは異なり、reactiveはオブジェクト自体をリアクティブにします。](https://ja.vuejs.org/guide/essentials/reactivity-fundamentals#reactive)


大分長かったので少し削ったが、だいたい上記の通りに説明されている。
多分これをはじめて見て完全に内容が分かる人は凄く少ないと思う。

何十年JavaScriptや似たようなフレームワークを触っている経験豊富な人なら「ああ。あれと同じような概念ね」とある程度理解できると思うが、少なくとも自分はJavaScriptを3年以上学習してきたが分からなかった。色々調べて最終的に分かったことはとりあえずref使えばOKということだった。

これと同じかこれ以上に難しい概念が次から次へと出てくるのがプログラマー・エンジニアの仕事なので、そりゃプログラミングやこの仕事で挫折する人がいるのも無理ないなという感じである。

この本では理解を深めるために、サンプルコードを自分なりに手を加えて学習することや学んだ知識をブログを書いてアウトプットする手法が紹介されており、自分は特にブログを書く方が効果が高そうだなと思ったので、今こうしてブログを書いている。サンプルコードの方もいずれ試していく予定である。

本当にブログを書いて理解が深まるのかはまだ分からないし効果が出る保証もないが、難しい難しい言って何もしないよりは有意義であると考えている。

### 3.感覚で判断せず、ファクトを積み重ねる
個人的な考えとして人間の感覚は数値化もできないし、漠然としているのであまり当てにしないほうが良いと考えている。少なくともその感覚を人に説明出来たほうが良いと思っている。(というよりも人に説明できない曖昧な概念を参照するのは個人的に凄く怖い)

この本でも感覚で問題を決めつけたり物事を判断するのはあまり良くないので、実際に存在するファクト(事実)を積み重ねて課題などを検証していった方が良いと記述している。

基本的に人間は勢いで大抵のことはなんとかなってしまうことが多いが、それは大分不安定だと思うので、身近に顔を出してくれたファクトを大事にしながら堅実に物事に取り組んだ方が良いと思った。

### 4.頭の中にメンタルモデルを作る
> メンタルモデルとは、人々が世界を理解し、予測し、解釈し、新しい状況に適用するための、自己の心の中のイメージや理論のこと。
> > 世界一流エンジニアの思考法から引用

上記の内容を読んだ時に思ったことは「なんか難しそうだけかっこいいな。メンタルモデルって」である。正直内容はあんまり理解できていない。

このメンタルモデルを作ることで、頭の中で思考を整理したり問題解決力が大幅に向上するみたいなので作っておいて損はないだろうというのが私個人の考えである。(作れるかどうかは別として)

詳しい概要はこの本で紹介している本を読めば体系的に理解できると思うので、その本をちゃんと理解できるまで読了し、メンタルモデルを作っていきたいと考えている。

最終的な目標はなにか問題が起きた時に「私の中にあるメンタルモデルを使えばこれぐらいの問題、すぐに理解できます!!」と言えるようにすることである。(そんな魔法のような方法では無いと思うが･･･)

個人的にメンタルモデルという名前は凄く惹かれる名前で、なんだろう...あまり言語化はできないが凄くかっこいいと思う。

上記のメンタルモデルはまたブログを書いたりして、身に付けられるよう取り組んでいく。


#### ※思っていたよりも長くなってしまったので、情報整理と心構え(マインドセット)は他の記事で整理していく。

# 今回内容を整理した本
- 「世界一流エンジニアの思考法」(著者:牛尾 剛)

https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4163917683
クラウドで大課金を発生させないために

私は過去、AWSとAzureの個人アカウントで大課金を発生させたことがあります。

コスト意識はパブリッククラウドで使う上で、超超重要だと思っているのですが、どうも個人アカウントだと自由がある分、意識がゆるふわになってしまうところがあり...過去2度ほど大課金祭りをやらかしました。
どれくらい大課金なのかというと「中古だけど比較的あたらしめの原付きが1台買えるくらいの金額」でしょうか。(分かりづらいかもしれませんが、大体で察してください)

という事で私が「もう二度とおこすまい！」と決意した際の小ネタを共有しておこうと思います。

## Azure
https://learn.microsoft.com/ja-jp/azure/cost-management-billing/costs/tutorial-acm-create-budgets?tabs=psbudget

AzureではCost Managementで予算を作成します。

メールだけでは埋もれてしまって見ないこともあるので、個人使いでよく見るSlackのチャンネルにもアラートを投げるようにしています。また、[Azure Mobile APPのプッシュ通知を有効化](https://learn.microsoft.com/ja-jp/azure/cost-management-billing/costs/tutorial-acm-create-budgets?tabs=psbudget#budgets-in-the-azure-mobile-app)することで、さらに気づきやすくなるのでオススメです。

https://azure.microsoft.com/en-us/get-started/azure-portal/mobile-app/

## AWS
https://docs.aws.amazon.com/ja_jp/cost-management/latest/userguide/budgets-create.html

AWSの場合も同様にAWS Budgetsで予算を作成してアラートを投げるのは基本として、
それ以外に[AWS Organizations](https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_introduction.html)で管理アカウント一括請求にしつつ、別アカウントを作成し、それを普段使いのアカウントにすることです。そうする事で管理アカウントのAWS Budgetsから → SNS → Lambdaで予算を超えたアカウントは閉鎖して全てを消し去る！といった荒業ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821082/d4b3a2c3-ea68-3319-fd29-64f43f8f41e1.png)
```typescript:サンプルコード
import { OrganizationsClient, CloseAccountCommand } from"@aws-sdk/client-organizations"; 

const client = new OrganizationsClient(config);
const input = {
  AccountId: "000000000000",
};

const command = new CloseAccountCommand(input);
const response = await client.send(command);
```
「作ってたリソースが消えてしまった…」などとぼやいてはいけません。自分が悪いのだからしょうがないのです。

## 共通
2度の大課金を発生させて以降、そもそもリソースの作成はすべてIaCで行うと決めてます。

時間がかかろうがなんだろうが、そんなもの関係ないのです。絶対にIaCを使います。

消したと思ってたけど残ってたリソースがいつのまにか高額課金に…といった事態を防ぐ為。また、アカウントが閉鎖されようがすべてのリソースを抹消しようが、「IaC残ってるから、またすぐ復活できるもーん」という意識が芽生えるのでリソースを消すことに躊躇いがなくなります。

そしてさらに、[infracost](https://github.com/infracost/infracost) という素晴らしいOSSもあります。これはTerraformのコードからコスト概算を把握することができるものです。[Visual Studio Codeの拡張機能](https://www.infracost.io/docs/features/vscode/)などもあり重宝しています。詳細は色々な記事もあると思うのでそちらをご参考ください。

https://www.infracost.io/docs/

## まとめ
なんとなく、おざなりになってしまいがちな個人アカウント。
これらを活用してもう二度と高額課金は発生させまいと誓ったのでした。

拙い内容で恐縮ですが最後までご覧頂き有難うございました🙏