OmniAICreator/Qiita-1.07M huggingface dataset:
Unity Hubの「インストールは失敗しました: validation failed」を解決する方法

# 前提
ダウンロードバージョン - 「Unity 2022 3.9 f1」をダウンロードしようとしたら、エディターアプリケーションの欄で表題のエラーが出る。それに対し以下のことを試した。

・何度も更新ボタン押したけど、ダメ
・Unity Hubを「管理者権限で実行」した状態でダウンロードしても　ダメ
・セキュリティソフトのシールド機能を無効にしても　ダメ
　↳なんならアンストしても　ダメ
・再起動ももちろん　ダメ

# 解決方法

##### ・Unityダウンロードアーカイブからexeで直接ダウンロードする。

###### ①アーカイブ( https://unity.com/releases/editor/archive )に飛ぶ

###### ②ダウンロードしたいバージョンの「Download(Win)」→「Unity Editor 64-bit」を選ぶ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602533/a9fc90ec-60a1-9aef-b645-ab6d6032b177.png)

###### ③exeファイルを開いたら、フォルダ指定を「バージョン保存しているフォルダ」に変更する
（ふつうは「C:\UnityEditorVersions」に保存されているハズ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602533/0abfdb96-5514-7f53-063b-c80b6ed8f5ba.png)

###### ④ダウンロードが完了したら、UnityHubの「インストール」→「リストに追加」から「インストールしたいバージョンフォルダ」→「Editor」→「Unity.exe」でインストール完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602533/6755866d-15d1-fb91-071f-1a7304b9cfa8.png)
CIImageを指定サイズにリサイズする

CIImageをリサイズしたい、CGImageとかUIImageに変換してからでもいいけど、CIImageのままリサイズもできます。

# すぐ使えるよ

```swift
extension CIImage {
    func resize(as size: CGSize) -> CIImage {
        let selfSize = extent.size
        let transform = CGAffineTransform(scaleX: size.width / selfSize.width, y: size.height / selfSize.height)
        return transformed(by: transform)
    }
}
```

```swift
ciImage.resize(as:CGSize(width: 1024, height: 512)
```

![cat3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b2ca02fd-0336-48b0-1b07-0c9ff901f1ae.jpeg)
![スクリーンショット 2023-09-13 22.35.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d4345dcf-dc73-6db2-b155-823b9f47850c.png)

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
【GASエラー】	Exception: The parameters (number) don't match the method signature for SpreadsheetApp.Range.setValues.




getRange().setValues(val)
# 【GAS】setValues関数でパラメーターの設定ミスにより生じたエラー

<b>Exception: The parameters (number) don't match the method signature for SpreadsheetApp.Range.setValues.</b>

上記のエラーメッセージが表示されました。
## 原因となった箇所
```js:setValues.gs
    let setVal = '1,2,3,4';
    let trgRange = sheet.getRange(1, 1, 4, 1);
    trgRange.setValues(setVal);
```
変数setValの設定方法が間違っていました。

## エラー解決方法
```js:setValues.gs
    let setVal = [[1],[2],[3],[4]];
    let trgRange = sheet.getRange(1, 1, 4, 1);
    trgRange.setValues(setVal);
```
setValuesは二次元配列でスプレッドシートにデータをセットします。
スプレッドシートのセルは二次元配列で表現されます。
A1⇒[0][0]
B5⇒[1][4]

今回は A1 ( [0] [0] )から A4 ( [0] [3] )の範囲に値をセットしました。

それを配列にすると [ [1] , [2] , [3] , [4] ] になります。

### おわりに
GASでsetValuesを使おうとしてはまりました。
エラー備忘録に。
ubuntu(virtual box)にClamAVをインストールしてみた

参照サイト
https://self-development.info/%E3%80%90ubuntu%E3%80%91%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E5%AF%BE%E7%AD%96%E3%82%BD%E3%83%95%E3%83%88clamav%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/

# インストール・設定
## clamav clamav-daemonをインストール
```terminal:terminal
sudo apt install -y clamav clamav-daemon
```
## clamav-freshclamを停止(ウイルス定義データベース更新のため)
```terminal:terminal
sudo systemctl stop clamav-freshclam
```

## ウイルス定義データベースを更新
```terminal:terminal
sudo freshclam
```
## freshclamをOS起動時に実行するよう設定
```terminal:terminal
sudo systemctl enable clamav-freshclam 
```

## clamav-freshclamを実行
```terminal:terminal
sudo systemctl start clamav-freshclam
```


# 動作検証
## テキストファイルを生成する
```terminal:terminal
cd ../Document
vi test.txt
ls -la 
total 24
drwxr-xr-x  2 user user 4096  9月 13 21:57 .
drwxr-x--- 14 user user 4096  9月 13 22:13 ..
-rw-rw-r--  1 user user    5  9月 13 21:51 testfile.txt
```

## スキャンを実行する
```terminal:terminal
clamscan
/home/user/Documents/testfile.txt: OK

----------- SCAN SUMMARY -----------
Known viruses: 8672382
Engine version: 0.103.9
Scanned directories: 1
Scanned files: 1
Infected files: 0
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 12.172 sec (0 m 12 s)
Start Date: 2023:09:13 21:52:07
End Date:   2023:09:13 21:52:20
```
- Infected files: 0(感染ファイル0)を確認する

## テスト用ウイルスファイルをダウンロードする

```terminal:terminal
wget http://www.eicar.org/download/eicar.com
ls -la
total 24
drwxr-xr-x  2 user user 4096  9月 13 21:57 .
drwxr-x--- 14 user user 4096  9月 13 22:13 ..
-rw-rw-r--  1 user user   68  5月  3  2022 eicar.com
-rw-rw-r--  1 user user    5  9月 13 21:51 testfile.txt
```

## スキャンを実行する
```terminal:terminal
/home/user/Documents/eicar.com: Win.Test.EICAR_HDB-1 FOUND
/home/user/Documents/testfile.txt: OK

----------- SCAN SUMMARY -----------
Known viruses: 8672382
Engine version: 0.103.9
Scanned directories: 1
Scanned files: 2
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 12.587 sec (0 m 12 s)
Start Date: 2023:09:13 21:57:00
End Date:   2023:09:13 21:57:12
```
- Infected files: 1(感染ファイル1)を確認する

正常に動作していることを確認できた。
WindowsPCでElectronアプリをMac用にビルドする方法（備忘録）

# 初めに
WindowsPCでElectronアプリを開発した際にMac用インストーラーがビルドできなかったので試してみたこと備忘録として記録しています。
# 試してみたこと
1. **MacPCで開発環境を作ってプロジェクトをクローンする。**
    まず最初に思いついたのがこの方法。幸い手元にMacPCがあったので開発環境を作ってビルドしてみたところ、無事作成できました。しかしビルドしたPCではアプリをインストールできるのにインストーラーを他MacPCで実行しようとするとライセンス等の問題でインストールできませんでした。

2. **VirtualBoxを使って仮想マシン（Mac）に開発環境を作成しビルドする。**
        この方法だと少し手間はかかるがMacPCがなくてもビルドすることができます。手順としてはまずMacOsをダウンロードし、それをもとにVirtualBoxで仮想マシンを作成する。MacOsの仮想マシンの作成は少しややこしいので以下に参考にした記事、動画を紹介してます。あとは１と一緒で開発環境を作ってビルドするだけです。当たり前ですがこの方法でもほかのMacPCではインストールできません。

    参考にした記事・動画
    [How to Install macOS Mojave on VirtualBox on Windows -ISO](https://www.wikigain.com/install-macos-mojave-on-virtualbox-windows/)
    [How to Install macOS Mojave Final on VirtualBox on Windows PC?](https://www.youtube.com/watch?v=Nhnf0Kmf6vI)
    
    

# まとめ
インストーラーを作成すること自体はできますがAppleの開発者ライセンスを購入しないと配布はできないようです。
自分用のアプリなら問題ありません。

[Apple Developer Program](https://developer.apple.com/jp/programs/)
ubuntu(virtual box)でユーザーにsudo権限を付与してみた

参照サイト
https://www.server-memo.net/ubuntu/ubuntu_add_sudo.html#:~:text=sudo%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%ABsudo%E3%82%92,%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%AB%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

# ユーザーを追加する 
```terminal:terminal
adduser user
```

# sudoグループに追加する
```terminal:terminal
gpasswd -a user sudo
```

# 設定を確認する
```terminal:terminal
cat /etc/group | grep sudo
```

- sudoにユーザーが追加されている
情報セキュリティと暗号技術

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/5c0b04b8-9150-573a-d12d-48aa801f8045.png)
１：情報セキュリティ
　情報セキュリティとは、機密性、完全性、可用性を維持することです。このうち、機密性と完全性は、暗号技術の利用によって維持します。情報セキュリティにおける暗号技術の役割は大変に大きなものです。暗号方式として、共通鍵暗号方式と公開鍵暗号方式があることを覚える。

「情報セキュリティのCIA」
①機密性（Confidentiality）：情報の秘密を保つ
②完全性（Integrity）：情報の改ざんを受けない、情報の破壊を受けない。
③可用性（Availability）：権限のあるものがいつでも使いたい時に使える。

　機密性を維持するためには、データを暗号化して第三者には読めないようにしておきます。完全性を維持するためにはディジタル署名をつけ、第三者の改ざんしたことを検知できるようにしておきます。可溶性を維持するためには、システムの冗長化を行い、負荷の上昇や故障に備えます。

「情報セキュリティの追加特性」
①真正性：サーバ、クライアント、利用者、ソフトウェア、サービスなどが本物であること。
②責任追跡性：誰が何をしたのかを追跡できるようにすること。
③否認防止：後から、「そのようなことはしていない」などと否定できないようにすること。
④信頼性：動作が意図した通りの信頼できる結果であること。
Bing Chat Enterpriseで、PDF要約がうまくいかない時に試す方法

# この記事の目的
生成AIを手軽に活用できるMicrosoftの検索エンジンのチャット Bing Chat Enterpriseで、
Webページ上のPDFファイルやローカル保存のPDFファイルの内容を要約したいにもかかわらず、
Bing Chat Enterpriseが指示通り要約せずに、サードパーティの要約ツールの紹介をしたり、Edgeブラウザで要約できることをただ語ったりする時…
この記事の操作手順で設定を見直してみてください。

↓ PDF要約できない時のスクリーンショット例
![BCEうまくいかない.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/16780394-04a3-5069-48d1-3a9b1fdca52e.png)











# 操作手順
①Bing Chat Enterpriseのウィンドウで、右上の縦3点リーダー「︙」をクリック
②通知とアプリの設定をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/35678146-d1a3-91f4-605c-37101617c304.png)


③「任意のWebページまたはPDFへのアクセスを許可する」をONにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/a5b3da57-eae2-da5e-e2ae-1d14cb5902e2.png)


④ウィンドウ左側にPDFを開いた状態で、「ページの概要を生成する」等指示を出す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/e43471b9-2be1-ba14-6c6e-46ea77fb377d.png)

↓ 成功例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/33252d12-53a7-b2a0-45bb-dda36af8d53d.png)
🌼左ウィンドウのページ内で情報が検索されるようになりました！





# おわりに
「任意のWebページまたはPDFへのアクセスを許可する」がOFFのまま、PDF要約リクエストを出すと、BingはPDFを見に行くことができず、要約がうまくいかない事象が発生してしまうのでした。

↓ 改めて、失敗例の考察
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/932c510c-25e3-ac07-72a3-b6229a228a2d.png)
🌼左側のウィンドウ内容を無視して、広いインターネットの世界に情報を探しに行ってしまっています。
🌼設定変更しない限り、プロンプトで指示を出してもファイルを要約できないようです。

この手順で、がんがん長文PDFを要約し、便利で楽しいBing Chat Enterpriseライフをお過ごしください😺

# おまけ～再読込/再起動で不調が直ることも
Bing Chat Enterpriseで、思うような反応が返ってこない場合、
リロードの矢印マークや箒マークを押して、チャットをリフレッシュして再度プロンプト入力することも試してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669905/c488fa11-ea7b-a1ce-ad0d-a93e49d1d44c.png)


# 参考URL
↓ 手順を作成するためのヒントとさせていただいたサイト

https://zenn.dev/hulk510/articles/81803693da1944#%E3%82%84%E3%81%A3%E3%81%A8%E3%81%8F%E3%81%A8%E8%89%AF%E3%81%84%E8%A8%AD%E5%AE%9A

https://dev.classmethod.jp/articles/new-bing-pdf-summary/


↓ Microsoft Bingの公式情報

https://learn.microsoft.com/ja-jp/bing-chat-enterprise/overview
【HoloLens2】ハンドトラッキングでの操作を有効にしつつ，ポインターは常にアイトラッキングで動かす方法【Unity】

Unity2019.4.22f1，LegacyXR，MRTK v2.5.1です（多分それ以降のバージョンのMRTKでも同じです）．

HoloLens2はアイトラッキング（視線トラッキング）ができますが，視線で動かすポインタはあくまでハンドトラッキングでの入力補助目的（例：ボタンに視線でポインタを合わせた状態で「ボタンを押してください」と話すことでボタンを押せるようにするなど）という思想で作られているらしいです．そのため，通常はアイトラッキングを有効にしていても，カメラから手が検出された場合，ハンドレイでのポインター操作に自動的に切り替わってしまい，ハンドトラッキングそのものを無効化するか，ハンドレイを無効化しておかなければアイトラッキングによるポインタの操作は無効になってしまいます．また，これは要検証ですが，おそらくアイトラッキングを常に許可するという処理を明示的に記述しておかないと，MRC（HoloLens2の画面録画機能）で録画を行うときポインターが消えてしまいます．

そのため，ハンドトラッキングで手の動きを取得しつつ，視線入力でのみ常にポインターを動かすためには，以下のようなスクリプトを作成する必要があります．

```PointerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit.Input;

public class PointerController : MonoBehaviour
{
    void Start()
    {
        // すべてのハンドレイをオフにする（ハンドレイの先にポインターがあり，これを記述することでハンドによるポインター操作が無効になる）
        PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);
        // 視線ポインターを常にオン（明示的に書いておかないとほかのポインター操作やカメラに上書きされる）
        PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOn);
    }
}

```
これを空のGameObjectなどに貼り付けてシーンに置けばOKです．録画中にも無事ポインターは生存していました．

___

【参考記事】
↓ MRTK2.6より前の公式ドキュメント．2023年9月13日現在，すでに日本語対応は終了してしまったようです
[Eyes + hand interaction How to support look + hand motions (eye gaze & hand gestures)](https://microsoft.github.io/MixedRealityToolkit-Unity/version/releases/2.5.1/Documentation/EyeTracking/EyeTracking_EyesAndHands.html)
[Controllers, pointers, and focus](https://microsoft.github.io/MixedRealityToolkit-Unity/version/releases/2.5.1/Documentation/Architecture/InputSystem/ControllersPointersAndFocus.html)

↓ MRTK2.6以降の新しい公式ドキュメント．このあたりの内容はMRTKが更新されても変わってなさそうなので英語が読めない方はこちらを読むと良いかもしれません．
[目と手　ルック アンド ハンド モーションをサポートする方法 (目の視線入力と&手のジェスチャ)](https://learn.microsoft.com/ja-jp/windows/mixed-reality/mrtk-unity/mrtk2/features/input/eye-tracking/eye-tracking-eyes-and-hands?view=mrtkunity-2022-05)
電波法(電気通信事業)に抵触しないように(まとめ)

# 死蔵のデータを生かそう（電波法簡易判別リスト）

https://github.com/mi-kaneyon/man-yard/tree/main/Businesss

**こちらに保存しました電波法セット**

:::note info
- 電波法テック.ipynb
- 電波法.xlsx
素直にEXCELファイル観た方がいいかもしれません。
:::

# Rマークは簡単に検索できる

https://www.tele.soumu.go.jp/giteki/SearchServlet?pageID=js01

## Tは見つからないかもしれないので、メーカに聞いてみましょう。


https://www.tele.soumu.go.jp/j/adm/monitoring/summary/qa/giteki_mark/




# 外国製品は注意


>外国製無線機に関すること
質問21	外国製の無線機（トランシーバー）にも技適マークが付いていますか？
<details><summary>回答21</summary>
回答21	外国製無線機（トランシーバー）の場合でも、日本国内で使用できる機種は、殆どのものに技適マークが付いています。
（個人輸入などで入手したトランシーバーの中には、日本国内では使用できないものがありますので、技適マークの有無をご確認下さい。）
</details>
質問22	外国製の無線機（トランシーバー）を買いましたが、使用すると電波法違反となるでしょうか？
<details><summary>回答22</summary>
>>回答22	技適マークが付いていない無線機の場合は、そのまま使用すると電波法違反（※）になる場合があります。
外国製無線機（トランシーバー）の場合でも、日本国内で使用できる機種は、殆どのものに技適マークが付いていますので技適マークの有無をご確認下さい。
詳しくは、最寄りの総合通信局へお問い合わせ下さい。
（※電波法違反の場合、１年以下の懲役又は１００万円以下の罰金の対象となります。また、公共性の高い無線局に妨害を与えた場合は、５年以下の懲役又は２５０万円以下の罰金の対象となります。）
</details>

質問23	ＦＲＳ、ＧＭＲＳの使用は電波法違反ではないですか？

<details><summary>回答23</summary>
>>回答23	FRS（Family Radio Service)及びGMRS(General Mobile Radio Service)は、米国の規格に基づき製造された、専ら米国内での使用目的で販売される無線機（トランシーバー）ですので、日本国内の使用は、電波法違反（※）になります。
（日本国内で、FRSやGMRSを使用すると、放送局の無線や消防無線、防災行政無線などに妨害を与える恐れがあります。）
FRSやGMRSと称する無線機には、技適マークが付いていません。購入・使用しないようにしましょう。
（※電波法違反の場合、１年以下の懲役又は１００万円以下の罰金の対象となります。また、公共性の高い無線局に妨害を与えた場合は、５年以下の懲役又は２５０万円以下の罰金の対象となります。）
</details>
質問24	外国規格のベビーモニターを買いましたが、使用できますか？
<details><summary>回答24</summary>
回答24	技適マークのついていないベビーモニターは、日本国内では使用できません。技適マークの有無をお確かめください。
日本国内で、外国規格の（技適マークの付いていない）ベビーモニターを使用すると電波法違反（※）になる可能性があるだけでなく、携帯電話等の重要な無線に妨害を与える恐れがあります。購入・使用は十分ご注意下さい。
（※電波法違反の場合、１年以下の懲役又は１００万円以下の罰金の対象となります。また、公共性の高い無線局に妨害を与えた場合は、５年以下の懲役又は２５０万円以下の罰金の対象となります。）
</details>
質問25	外国製のアニマルマーカーの使用は電波法違反ではないですか？
<details><summary>回答25</summary>
回答25	技適マークが付いていない外国製のアニマルマーカーの使用は、電波法違反（※）になる恐れがあります。
総務省の調査では、外国製のアニマルマーカーで、日本の技術基準に適合しているものは確認されていません。
アニマルマーカーの購入・使用は十分ご注意下さい。
（※電波法違反の場合、１年以下の懲役又は１００万円以下の罰金の対象となります。また、公共性の高い無線局に妨害を与えた場合は、５年以下の懲役又は２５０万円以下の罰金の対象となります。）
</details>

質問26	外国製のアニマルマーカーは免許を受ければ使えますか？
<details><summary>回答26 </summary>
>回答26	外国製のアニマルマーカーで使用している周波数は国内では他の用途に割り当てられており、免許を受けることはできません。
総務省の調査では、外国製のアニマルマーカーで免許が受けられる合法的な商品は確認されていません。
アニマルマーカーの購入・使用は十分ご注意下さい。
</details>
質問27	どうして外国製品はだめなのですか？
<details><summary>回答27</summary>
>>回答27	電波は多くの人が利用しており、現在の社会生活に欠かすことのできない重要なものですので、国ごとに様々なルールが決められています。
技適マークが付いていない外国製無線機の多くは、日本で使用するためのルールに従っていません。このような無線機を使用すると、知らずに他人の通信を妨害したり、ひいては社会生活に混乱を来すことになります。
外国製品の場合でも、日本国内で使用できる機種は、殆どのものに技適マークが付いています。
技適マークが付いていない製品の購入・使用は十分ご注意下さい。
</details>
質問28	外国製のアマチュア無線機も免許が受けられないのですか？
<details><summary>回答28</summary>
>>回答28	アマチュア無線機の場合は、技適マークが付いていなくても無線機の系統図などを添付して免許申請することができます。
免許申請されたものが電波法令の基準に適合していると認められれば免許が受けられます。
なお、免許の取得前に設置又は運用すると電波法違反（※）で処罰の対象になりますので十分ご注意下さい。
（※電波法違反の場合、１年以下の懲役又は１００万円以下の罰金の対象となります。また、公共性の高い無線局に妨害を与えた場合は、５年以下の懲役又は２５０万円以下の罰金の対象となります。）
</details>

:::note warn

警告
見つからなければいいじゃありませんよ！

:::
【iOS】多言語対応がめんどうなのでChatGPTに一括で翻訳してもらう

# はじめに
今まで個人開発アプリを多言語化するためにDeepLなどの翻訳機を使って翻訳していました。
しかし、時間がかかりすぎるのでChatGPTに任せることにしました。

プロンプトが固まったので記事にしておきます。

# プロンプト
```
iOS開発を行なっています。
アプリを多言語対応させるために、ローカライズが必要です。
[Base.lproj:]を[対応言語:]にそれぞれ翻訳してください

[対応言語:]
- 英語
- 日本語
- フランス語

[Base.lproj:]
"ContentView.Text1.label" = "おはよう";
"ContentView.Text2.label" = "こんにちは";
"ContentView.Text3.label" = "こんばんは";
```

# 結果
![スクリーンショット 2023-09-13 20.40.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8adcd256-90b6-0524-4a3b-da8cb657bc99.png)

# おわり
めっちゃ効率化できましたー
ただ翻訳があっているかは最終確認が必要そうです
【All In One】DevContainers+WSL2で開発環境整備

## この記事の目的

- Dev Containersを利用した記事は多いが環境切り替えを前提としているものが多い。また特にディスク周りのパフォーマンスが気になり一部退避するなどの設定が煩わしい。
- 以前からWSL2+Ubuntu内でコンテナ開発を行っていた際にはパフォーマンスは問題ないと感じていた。
- そこでDev Containersに同様のパターンを適用したところ想定通りの環境構築に成功した。

今回のパターンの記事は見かけないため、その手順を記載させていただきました。

### Dev Containersとは

- VSCodeの拡張機能でDockerコンテナ内で開発ができる機能。
- JSONで定義して環境を構築が可能。ファイルもホストとコンテナ間で同期される前提で設定される。
- また既に実行中のコンテナに対しても接続できるため、コンテナ内のファイルを直接確認や編集することもできる。
- また、コンテナ内でサーバ機能を立ち上げた際にVSCodeがポートを開いてくれるため、ブラウザ等外部からアクセスできる。

など、非常に魅力的な機能が満載です。
その一方でDocker DesktopやRancher Desktopなどを利用する記事が多いため、そのまま適用するとDockerのバインドマウントでのパフォーマンスの悪さが気になってしまうのではないかと思いました。

## パフォーマンスの問題回避方法とは

- WSL2+Ubuntu上でDev Containersを構築することで、バインドマウント先をWSL2のUbuntu上のファイルシステムとすることでパフォーマンス問題を回避させる。
- そのため、個別に特定フォルダをvolumeに退避する必要がなく実行できる。
- また、その場合には拡張機能でWSLへ接続後にDev Containersに接続するという2段階の手順が必要になるが、その手間も回避できる。

というものです。

### WSL2の設定

- まず、WSL2とUbuntuは通常通りにインストールする。
  - この時、Ubuntuのバージョンは22.04を利用するとdockerサービスが自動起動する。
```sh:PowerShell
wsl --install Ubuntu-22.04
```

- また、Ubuntuのデフォルトユーザは`root`とした。
  - 賛否両論あるかと思うが、dockerコンテナ内でファイルを作成すると、ホスト側のユーザは`root`となってしまうため、最初からホスト側も`root`とした。
  - 共有PCとかだと厳しい設定かもしれないが、開発者が扱うPCであれば問題ないと判断した。
  - また、エクスプローラーからアクセスする際のユーザも`root`となるため、コンテナ内で編集したファイルも直接扱える。
```sh:PowerShell
ubuntu2204 config --default-user root
```

### .devcontainerフォルダの作成

- Terminalなどを立ち上げ、Ubuntu内で作業をする。（`root`ユーザを想定）
- 開発に使用するフォルダを作成し、その中へ移動する。
```sh:ubuntu
mkdir ~/workspaces
cd ~/workspaces
```

- 作業フォルダの中に`.devcontainer`フォルダを作成する。
  - このフォルダ内に`devcontainer.json`を作成することで、VSCodeの拡張機能である`Dev Containers`が認識する。
```sh:ubuntu
mkdir .devcontainer
```
```json:devcontainer.json
{
  "name": "dev",
  "image": "debian:latest"
}
```

### VSCodeの起動

- 作業フォルダに戻り、VSCodeを起動する。
```sh:ubuntu
code .
```

- VSCodeが起動し、Dev Containersの拡張機能がインストールされていれば、右下に`Reopen in Container`というボタンが表示されるので、そのボタンを押下する。
  - コマンドパレットから`Dev Containers: Reopen in Container`でも可。
- すると、VSCodeが再起動し、`devcontainer.json`の内容に従って（初回は時間がかかるが）コンテナが起動する。
- なお、Windows上のVSCodeのアイコンを右クリックすると、フォルダの履歴が表示されてピン止めできるので、次回からはそこから起動すると一発でDev Containersまで接続できて便利。

![ピン留め](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87991/19606cd2-8a73-41ec-c37b-4187ff5a7103.png)

## ベースイメージについて

- 以前からコンテナ開発を行っていたため、必要な開発ツール等が入ったベースイメージを自作している。

https://github.com/tamuto/devenviron

- Dev Containersではfeaturesなどで必要な機能を追加することができるが、こちらのベースイメージを利用することで、その手間を省くことができる。
  - 最終的にはfeaturesに書けるように分離したいとは思っているが、利便性とのトレードオフかと思う。
  - とにかく細かいプロジェクトを同時並行的に扱うため、VSCodeでの環境の切り替えではなく必要なものを一つのコンテナにまとめている。
  - そのため、ベースイメージには多くの開発ツールが入っている。
- 一旦、こちらには`devcontainer.json`に拡張機能まで設定したものもありますので、参考までにどうぞ。

https://github.com/tamuto/devenviron/blob/main/template/devcontainer.json

## 最後に

- パフォーマンスについては測定しておりません。（申し訳ございません。）
  - ですがファイルをWindowsまで持っていくよりも段違いで速いです。
  - また、個別のvolumeを作成するとpnpmを利用している場合には、ボリュームが違うと怒られてしまってpnpmの本来のメリットが活かせない事情もあります。
- なお、紹介しているdevenvironのベースイメージはオープンソースで開発を行っております。
  - そのため、不具合や改善点などありましたら、IssueやPRなどお気軽にお願いします。
  - また、この記事の内容についても、不明点や改善点などありましたら、コメントなどお気軽にお願いします。
Figma のデータ、少し楽になるかもしれない作り方

## この記事の概要

variants や component properties など、Figma でのデータ作りには様々なテクニックがあります。
この記事では、少しニッチなシチュエーションにおいて、楽にデータを作れる方法を紹介します。

## フォーカスリング付きの UI

以下の画像のように、通常時のボタンと、フォーカスが当たったときのボタンを作成したいとします。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8a9ebf8a-c017-ab31-8b0a-159875d66644.png)

このとき、アウトラインのオフセット表現は、通常の `Stroke` では実現できません。

そこで `Absolute position` と `Constraints`を使います。

まず通常時のボタンはこのような構成です。
至って普通の作り方です。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/84ab4b2e-ff14-e423-fa3f-505fedd4cd41.png)

次に、フォーカスリング付きのボタンの構成です。
元のボタンよりもひとまわり（ここでは上下左右それぞれ 3px ずつ）大きい四角形を作り、Absolute position で配置しました。
そして `Constraints` を `Left and right`, `Top and bottom` に指定します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1f88a1cf-589d-5ac3-e1b3-74f743345274.png)

これで、このようにラベルに追従してフォーカスリングも伸び縮みするようになりました。
また、`Absolute position` で配置しているので、CSS での outline と同様レイアウトの計算には含まれません。
コードとの統一性という意味でも良いと思います。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/e9106ad6-abb7-c1f6-fc53-b1b32a85c324.png)

## 背景色の有無のバージョンがある UI

例えば[Apple 公式リソース](https://www.figma.com/community/file/1248375255495415511/Apple-Design-Resources-%E2%80%93-iOS-17-and-iPadOS-17) にある Navigation Bar のように、背景色の有無で バリエーションを作りたいときがあります。
下の画像のように variants を作ってももちろん良いのですが、手動で複製しないといけないので組み合わせが多いとややしんどい印象があります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/f87199be-4f19-c64f-4bd6-afdaee4f2734.png)

こちらは `Absolute position` と `boolean property` を利用して、組み合わせを減らします。
検索フィールドの有無[^1] * 背景の有無で本来 4 種類作らないといけないのを、2 種類で実現できました。

[^1]: 検索フィールドの有無は boolean property で制御した方が楽ですが、ここでは「バリエーションが増えるとデータ管理が大変」の雰囲気を出すためにこのように表現しました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/10603ec5-2b97-93b9-e582-85da1f3c06de.png)

このように、トグルで背景の有無を選べます。
もちろんサイズが変わっても対応しています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fb8c809a-d4fc-88ac-da68-8d1a347af01b.png)

## 開閉する UI

色々な箇所が開閉するので、愚直に作ると組み合わせ爆発が起きるような UI を楽に作ります。
文章で説明するのが難しいので gif をご覧ください。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/d8f1fdc2-8064-2fd0-5184-97075408f0e6.gif)

すべての開閉パターンを網羅するのはしんどいですし、今後メニュー数が変わったときの更新性も低いです。

方針としては、個別のパーツを Interactive component 化し、それを組み合わせて全体を実現します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1f7eb643-c33a-8432-499e-b7c334524722.png)

この作り方であれば、今後項目数が増えても割と更新しやすいはずです。

## 最後に

「ここまで頑張ってデータの作りを考えず、ひたすら作っても良いんじゃないか？」という声も聞こえてくる気がします。
実際、毎回毎回このような作り方をする必要は無いでしょう。

ただ、こういったテクニックを知っておくことで、不意に効率化できることもあると思います。
小ネタの 1 つとして捉えておいてください。

---

最後まで読んでくださってありがとうございます！
[X (Twitter)](https://twitter.com/xrxoxcxox)でも情報を発信しているので、良かったらフォローお願いします！

[Devトーク](https://jobs.qiita.com/employers/qiita-inc/dev_talks/489)でお話してくださる方も募集中です！
Amazon EventBridge Schedulerのイマイチだったところ

## はじめに

本記事はAmazon EventBridge Schedulerのイマイチな部分を説明する予定でしたが、
投稿日時点では改善されていて良い機能になっているという内容になります

検証をすることにした経緯も書いていますが、結論だけ読みたい方はスキップしてください

## Amazon EventBridge Schedulerを検証することになった経緯

とある業務システムを構築している際に、指定の時間になったらLambdaを実行する機能を実装することになりました。
繰り返し実行するのではなく、1回のみ実行することになります
簡単に説明すると、スマホのアラームのように、WEB画面から時刻を入力し、その時刻になればLambdaを実行させるシンプルな機能です

時刻の登録は画面から行うため、AWSコンソールでポチポチ設定することができません
WEBアプリとして一連の流れを実現させる必要がありました

アーキテクチャとしては、本記事の投稿時点では、Amazon EventBridge Schedulerが発表されていますが、それ以前に実装を行なったため、Amazon EventBridgeを駆使して実装しました

実装後Amazon EventBridgeでしばらく運用していましたが、問題が発生したため解決策を調査していたところ、解決策になりそうなAmazon EventBridge Schedulerが発表されていたため検証を開始しました

## アーキテクチャについて

要件を満たすために以下のアーキテクチャを採用しました

① 実行の予約 
　画面 → API Gateway → Lambda → EventBridge

② 実行
　EventBridge → Lambda


![eventbridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356664/9d2bde41-794b-d55b-8b09-ccbdad1b6bd6.png)


画面の内容は省略します。一般的なS3ホスティングしているwebアプリです

①では、画面から入力されたパラメーターを元に、EventBridgeのルールを作成して処理を終了します
②では、①で設定した時刻になったらEventBridgeがLambdaをinvokeします

今回、②で実行する処理は簡単なものだったのでLambdaを採用しています
起動されるLambdaは常に同じLambda関数です


## アーキテクチャの問題点

EventBridgeで1回のみLambdaを実行する設定は行えません
そのため、cron式を利用して、年1回の起動の設定を行い、実行が終わったらルールを削除する実装を行なっていました
要件通りの動作はしますが、シンプルではありませんし、ルールを削除をするロジックがエラーとなった場合にルールが残り続けることになるので、もやもやする実装になっています

最大の問題点としては、ルールの設定数上限が、イベントバスごとに300件となっている点です
こちらはサポートに申請すれば緩和可能なようですが、それでも上限は2000件になっているようです

また、イベントバスはアカウントの上限で100件となっており、登録できるルールとしては最大で100件*2000件で20万件となっています
https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-quota.html

一見十分に思えますが、何も考えずに使っていると最初に上限に達するのは300件になります
イベントバスを管理するのもロジックが複雑になるため、イベントバスを増やしてまでルールの上限数を増やしたくありません

## Amazon EventBridge Schedulerの登場

Amazon EventBridge Schedulerが登場したことによって、Amazon EventBridgeの問題が解決しました
まず、デフォルトで300件だったルールの上限数が100万件になっています
さらに、cronを駆使してなんちゃって1回実行としていたところが、Amazon EventBridge Schedulerの機能でできるようになりました

![スクリーンショット 2023-09-13 16.57.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356664/b306191c-b868-f55e-de73-95f1737cb581.png)

## Amazon EventBridge Schedulerのイマイチだったところ

Amazon EventBridge Schedulerは発表された時点では、1回限りのスケジュールでLambdaを実行しても、ルールが残り続けていました
上限が100万件になったとはいえ、削除を意図的に行わなければいずれ上限を迎えるイマイチな仕様でした
発表当時は欲しかった機能がでた！とウキウキしながら検証してガッカリした記憶があります

その点が2023/8に改善されていました
https://aws.amazon.com/jp/about-aws/whats-new/2023/08/amazon-eventbridge-scheduler-deletion-completion/

![スクリーンショット 2023-09-13 17.07.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356664/566a558c-380a-00a7-7c4a-ef663f7a70bc.png)

「スケジュール完了後のアクション」でDELETEを選択することで、実行が終わったルールが削除されるようになるので、開発者はルールの上限数をほとんど意識しなくてもよくなり、EventBridgeの上限数に怯えながら生活することはなくなりました

## 結論

Amazon EventBridge SchedulerはAmazon EventBridgeよりも時刻による起動管理が行いやすくなっています
Amazon EventBridgeではルールを登録できる上限がありましたが、Amazon EventBridge Schedulerでは解決されています

|  | Amazon EventBridge | Amazon EventBridge Scheduler |
|:-----------|:------------:|:------------:|
| スケジュール数のクォータ       | 300 | 100万 |

cron式を使って1回のみ起動する必要はなくなり、EventBridge Schedulerの機能で行えるようになりまし
Proxmox VE 8 の Win11 で Alder Lake (NUC12) の GPU を Passthrough で使用する

# はじめに

Intel Alder Lakeを搭載したNUC12をProxmoxのテスト機として利用するにあたり、GPUのPassthroughを実現する実験プロジェクトの記事にしたがい、セットアップと動作確認を行った。セットアップ手順は、紹介する記事によくまとめられているので、そちらに譲り、留意点と動作確認状況を補足する。

:::note warn
2023/11/08記
カーネルのバージョンを**6.2.16-19-pve**に更新したところ、dkms moduleのbuildに失敗し、セットアップできなくなりました。
2023/11/13記
エラーメッセージに従い、比較的軽微なコード修正でbuildが通るようになりました(当方、intel_dp.c 5609行の#else以下が致命的なエラーを起こしていました)。腕に自信のない方は、むやみにUpdateをかけないほうが無難です。
:::

# セットアップと留意点

Proxmox VE 8の標準では、Alder LakeのGPUのPassthroughに対応していない。
これに対し、dkms moduleとして、SR-IOVに対応したi915ドライバの開発プロジェクトがある。ただし、**'highly experimental(まだまだ、とっても実験段階)'** とされているので注意。 

https://github.com/strongtz/i915-sriov-dkms

このドライバーを用いて、Win11の環境を構築する手順については、以下の記事に詳しいので繰り返さない。以下、手間取りやすい箇所を留意点に示す。

なお、Virt-IOドライバーの導入手順が記されているが、GPU導入には関係しない。

https://www.derekseaman.com/2023/06/proxmox-ve-8-windows-11-vgpu-vt-d-passthrough-with-intel-alder-lake.html

## 留意点1 PCIデバイスの導入

NodeのHardwareにGPUに対応するPCIデバイスを登録する際、
**pcie=1 (設定箇所はAdvanced内)**, **x-vga=1**を指定する。

![node_hardware.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/0fcfe322-6f25-def3-31aa-64ac9425a771.jpeg "該当箇所は最後の行")

## 留意点2 グラフィックスドライバーの導入

Intelのグラフィックスドライバーを導入する際、「インテル© ドライバー & サポート・アシスタント」を用いると、GPUが無効とされたので、グラフィックスドライバー(本記事では、gfx_win_101.4676.exe)を直接導入するのが安全と思われる。

![HWiNFO_FAIL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/3cb0ef77-4996-9c05-5766-379257060e81.jpeg "GPUが無効とされた例")


# 動作確認状況

Win11でグラフィックスドライバーの導入に成功したあとの、確認状況を示す。

## HWiNFOの表記

HWiNFOの表記で、EU数やALU数が表示される。'DISABLED'の表記はそのままだが。

![HWiNFO_SUCCESS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/8b29c1f3-d71b-5618-c656-ae1e2722bfc9.jpeg)

## デバイスマネージャーの表記

ディスプレイアダプターの項にIntelのグラフィックスアダプターが表記される。
また、タスクマネージャーでもGPUの欄が表示される。

留意点2で示したグラフィックスドライバーの導入が正常に行われない場合、デバイスマネージャーには表示されても、タスクマネージャーに表示されない状況になる。

![デバイスマネージャ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/a2b74382-6498-7b7b-bf8a-ec5683548608.jpeg)

## DirectX診断ツール

レンダーとディスプレイに分かれて表示される。ここの意味するところは、理解が及ばないので、状況のみ示す。

GPUは、レンダーとして表示。

![dxdiag1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/e4fef28c-b167-0e2b-b02b-d38c0fe474d8.jpeg)

他の機能は、Remote Display Adapterの方に表示。

![dxdiag2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/6c217f53-4518-c3fd-6e5f-a097b50aeb17.jpeg)


## 3Dベンチマーク

3DMark(2.10.6797のSky Diver, Night Raid)、FFベンチ(14,15)、DQベンチ(10)、いずれも動作せず。

ゲーム自体は、MicrosoftのSolitareなどは問題なく動作する。

## OpenTKを用いたOpenCLのデモアプリの動作

次のデモアプリを用いて、動作を確認した。使用したOpenTKのバージョンは、4.8.0。

https://github.com/Nikkinoodl/OpenCL-Demo

これは、OpenTKプロジェクト内のテストコードを元にしたもの。ただし、テストコードは、このままではOpenTK 4では動作しない。ToGrayscaleが未対応のようである。

https://github.com/opentk/opentk/tree/master/tests/OpenToolkit.OpenCL.Tests

![OpenCL-Demo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/25be5a93-48f1-5a36-7f98-7c2ea78eef30.jpeg)

なお、Form上のプラットフォーム名の表記部分('Intel(R) OpenCL Graphics')は、こちらで付け加えたもの。

# おわりに

曲がりなりにもAlder Lake内蔵のGPUのPassthroughを確認できた。軽めのゲームなら実行できそう、というのもあるが、GPUを使ったアプリ開発ができそう、というのが大きい。演算力は大きくないが、NUC12の最大メモリ量(64GB)の半分をGPUメモリとして利用できるのは面白いかもしれない。
Learn Git Branchingを使ってみる。

ChatGPTを使いながら勉強してます。

# rampup1(2-1)
ポインタがよくわからないので調べてみた。

Gitにおいて「ポインタ」とは、特定のコミットオブジェクトを指し示す参照（reference）のことを指します。GitのブランチやHEADは、内部的には特定のコミットオブジェクトのハッシュに対する参照として機能しています。

git checkout コマンドは、Gitにおけるポインタの位置、特に HEAD ポインタの位置を変更する役割を果たします。
git checkout やその他のコマンドによって、HEAD ポインタとその他のブランチポインタの位置は変更され、どのコミットが現在チェックアウトされているか（すなわち作業ディレクトリの内容がどのコミットに基づいているか）が変わります。

# rampup2(2-2)
相対リファレンスとは？

Gitの相対リファレンスは、特定のコミットを基点にして他のコミットを指定するための記法です。

# rampup4(2-4)

git resetは業務では以下がよく使うかも
```
git reset --soft HEAD^ 
```
HEAD^ は現在のブランチの親コミットを指します。つまり、直前のコミットを指すことになります。
--soft オプションは、インデックス（ステージングエリア）と作業ディレクトリにあるファイルはそのままにして、HEADだけを指定したコミット（この場合は HEAD^）に移動します。
結果として、直前のコミットが「未コミットの変更」としてステージングエリアに残ります。つまり、git commit コマンドを再実行することで、新しいコミットを作成することができます。

git revertのユースケース

不具合の修正
誤ってバグを導入してしまったコミットがある場合、git revert でそのコミットを打ち消すことができます。

機能の一時的な無効化
特定の機能が不具合を引き起こしているが、そのコード自体は将来的には必要な場合、git revert でその機能を一時的に無効にできます。

公開済みコミットの安全な取り消し
既に push されてしまったコミットを取り消す必要がある場合、git revert はそのコミットの変更を打ち消す新しいコミットを作成するため、他の人との共同作業に問題を引き起こすことなく安全に変更を元に戻せます。
などなど気になったらGPTに聞く。

# おわり
２章が終わったので明日は３章です。
torchインストール時に出るzipfile.BadZipFile: Bad CRC-32 for file 'torch/lib/cudnn_ops_infer64_8.dll'関係のエラーについて

# 発生

[CUDA11.8](https://developer.nvidia.com/cuda-11-8-0-download-archive) をインストールし、
[PyTorch](https://pytorch.org/get-started/locally/) に書いてあるコマンド通りにインストールすると、

```bash
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 
```

`zipfile.BadZipFile: Bad CRC-32 for file 'torch/lib/cudnn_ops_infer64_8.dll'`みたいなエラーが出る

# 解決

`--no-cache` オプションをつけることで解決できるらしいので、`--force-reinstall` と合わせて実行すると成功した

```bash
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 --force-reinstall --no-cache
```


# 参考
https://github.com/bmaltais/kohya_ss/issues/732
💭はじめてのLaravel

***:cherries:学んだことを随時まとめてく:cherries:***
<font color="MistyRose">間違っている点があれば是非教えていただきたいです<font>

# 対象者:fist_tone1:
- Rails学習者（私）
- PHPもLaravelも初学者(私)
# ざっくり似てるところ
- <font color="IndianRed">MVCアーキテクチャ採用/ルーティング</font>
    <dl><strong>:cloud:モデル:blossom:ビュー:sunny:コントローラ</strong>
          <dt>Rails</dt><dd>:cloud:models/Xxx.rb</dd><dd>:blossom:app/views/xxx.html.erb</dd><dd>:sunny:app/controllers/xxx_controller.rb</dd>
          <dt>Laravel</dt>
       <dd>:cloud:models/Xxx.php</dd><dd>:blossom:resources/views/xxx.blade.php</dd><dd>:sunny:app/Http/ControllersXxxController.php</dd>
        </dl>

    <dl><strong>:sparkles:ルーティング</strong>
      <dt>Rails</dt>
      <dd>config/routes.rb</dd>
      <dt>Laravel</dt>
      <dd>routes/web.php(ウェブアプリケーションのルーティング定義)</dd>
      <dd>routes/api.php(APIエンドポイントのルーティング定義)</dd>

- <font color="IndianRed">ORM モデルを介してデータベーステーブルとのやり取りを直感的に</font>
    <details><summary>RailsのORM</summary>
        :thought_balloon:Railsでは、Active Recordが提供されている<br>
        :thought_balloon:Active Recordは、dbテーブルとオブジェクト指向のモデルクラスをマッピング<br>
        :thought_balloon:モデルクラスはActive Recordの基底クラスを継承し、dbテーブルとの対話を行う<br>:thought_balloon:カラムやリレーションはdbスキーマと対応<br>
        :thought_balloon:Active Recordでは、CRUD操作を行うためのメソッドやクエリインターフェースが提供されている
    　　</details>
    <details><summary>LaravelのORM</summary>
    :thought_balloon:Laravelでは、Eloquent ORMが提供されている<br>
    :thought_balloon:Eloquent ORMは、dbテーブルと対応するモデルクラスを定義し、そのモデルを使用してdb操作を行う<br>
    :thought_balloon:Eloquentではモデルクラスのプロパティはカラムと対応し、モデルのインスタンスはテーブルのレコードと対応する<br>
    :thought_balloon:Eloquent ORMは、データの取得、保存、更新、削除などの操作を行うための便利なメソッドやクエリビルダを提供している<br>
    　　</details>
wslでelixir その56

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
Phoenixで、ファイルアップロードページを作れ。

# 方針
form_for使う。
routerを書く
controlerを書く
csrf対策

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/34a9c098-43a2-2162-f4be-b3ccaf5522ce.png)

# 手順

- hello2/lib/hello2_web/templates/page/index.html.heexを修正。

```
<%= form_for @conn, "/upload", [as: :upload, multipart: true], fn f -> %>
	<div>
		<%= file_input f, :input_file %>
	</div>
	<div>
		<%= submit "submit" %>
	</div>
<% end %>
```

- hello2/lib/hello2_web/router.exを修正。

```
	post "/upload", PageController, :upload

```

- hello2/lib/hello2_web/contlorers/page_controler.exを修正。

```
	def upload(conn, %{"upload" => upload}) do
		file = upload["input_file"]
		cp_filename = "copy_" <> file.filename
		File.copy(file.path, cp_filename)
		map = Map.from_struct(file)
		result = Map.put(map, :save_filename, cp_filename)
		json(conn, result)
	end
```

以上。
💭はじめてのPHP

***:cherries:学んだことを随時まとめてく:cherries:***
<font color="MistyRose">間違っている点があれば是非教えていただきたいです<font>
改修中
***
# 対象者:fist_tone1:
- Rails学習者（私）
- PHP初学者(私)


# 文法ルールの基本
```php5:
<?php
  // コメント  # コメント　　/* コメント */
  echo '出力';      // ''を使用し文末は；を使用する
  $xxx = '変数';    // $XXX ≠ $xxx
  echo '$xxxは'.$xxx. 'です';  //.は結合演算子
  echo "$xxxは{$xxx}です";     //"{変数名}"で変数の展開
  var_dump(値);    //値の型（値）を出力（デバッグ用）
?>
<?= ?>  <?php# echo '';?>を省略したもの
```
# データ型
 PHP が実行時に型を決定するのでデフォルトでは変数の型を指定する必要がない。
ただし、 型宣言を使うことで、その一部に静的に型を指定することができる。

式の型と値を知りたい場合は、 `var_dump()` 関数を使用
- null
- bool
- int
- float (浮動小数点数)
- string
- array
- object
- callable
- resource

# キャスト演算
```php
$xxx = '10' + '10'   //rubyなら文字列型1010になるがphpは２０になる(暗黙の型変換)
=> 20

echo (string) 10    //(変換したいデータ型) "値"
=> string(2) "10"    //データ型(長さ)"値"
```

# if文
```php
<?php
  if (bool型の値や条件文){
    処理内容
  }else if (条件文){
    処理内容
  }else {
    処理内容
  }
?>
```
# 配列
```php
<?php
  $array = [
    'key1' => 'value1',
    'key2' => 'value2',
    'key3' => 'value3'
  ]
?>
echo $array['key1']
=> value1
```
# for文と色々
```php:
<?php
  for (初期化処理; 継続条件; 更新処理){
    // 処理内容
    if (条件){
      //処理内容
      break;  //ループを中断する
      continue;  //次のループへ
    }
  }
?>

```
# while文
```php:
<?php
  while(継続条件式){
    //処理
  }
?>

```

# forearch文
連想配列の要素を1つずつ取りだしたい時に使用する
```php:
<?php
  forearch($連想配列 as $変数名){
    //処理
  }
?>

```

# 関数の呼び出し
```php:
<?php
  関数名(引数);
?>

```
# 関数の作り方(ユーザ定義関数)
```php:
<?php
  function 関数名($引数){
    //処理

    return 返り値;
  }

  関数名($引数);  //呼び出し
?>

```

# Class定義とオブジェクト
```php:
<?php
  class Xxx{  //2単語以上はxxxYyy
    アクセス修飾詞 $プロパティ
    public $xxx    //クラスの外に公開する(参照や変更を許可する)
    protect $yyy   //クラス継承のアクセス修飾詞?
    private $zzz   //クラスの外に公開しない

    public function メソッド名(){
      //処理
    }

    $xxx = new Xxx();    //コンストラクタの呼び出し
    $xxx->メソッド名();    //メソッドの呼び出し


  }

?>

```
AWSで、Terraformを利用する方法をまとめてみた(3/10)

バージョン管理ツールtfenvとは？
--
tfenvはTerraformのバージョン管理ツールであり、異なるバージョンのTerraformを切り替えて使用できるようにするために使用されます。以下はtfenvを使用してTerraformをインストール、バージョン管理する方法の詳細です。

まず、Git Bashをインストールします。Git Bashは、Windows上でUnixシェル環境を提供するツールであり、Linuxと同様のコマンドを使用して作業することができます。

次に、tfenvをインストールします。Git Bashを起動し、ターミナルウィンドウを開いて、以下の手順を実行します。

cd ~を入力して、ユーザーディレクトリに移動します。
次のコマンドを入力して、tfenvをクローンします。
~~~
git clone https://github.com/tfutils/tfenv.git ~/.tfenv
~~~
.bashrcに環境変数を追加します。
~~~
PATH=$PATH:/c/Users/<USER_NAME>/.packer/bin 
~~~
これにより、Git Bashが起動するたびにtfenvが自動的に初期化され、Packerの実行ファイルがパスに追加されます。

利用可能なTerraformバージョンを表示する
tfenvで利用可能なTerraformのバージョンを確認するには、以下のコマンドを実行します。
~~~
$ tfenv list-remote
0.11.0
0.11.1
・・・
0.14.18
1.0.0
1.0.1
・・・
1.0.20
~~~
これにより、利用可能なTerraformのバージョンが表示されます。

Terraformのバージョンをインストールする
Terraformの特定のバージョンをインストールするには、以下のコマンドを実行します。
~~~
tfenv install <version> 
~~~
<version>には、インストールするTerraformのバージョンを指定します。

Terraformのバージョンを使用する
Terraformの特定のバージョンを使用するには、以下のコマンドを実行します。
~~~
tfenv use <version> 
~~~
<version>には、使用するTerraformのバージョンを指定します。


Terraformのバージョンを確認する
現在のTerraformのバージョンを確認するには、以下のコマンドを実行します。
~~~
terraform version 
~~~


terraform versionを入力して、現在のTerraformバージョンを確認します。
これにより、現在のTerraformのバージョンが表示されます。また、追加したPackerの実行ファイルもパスに追加されていることが確認できます。

これで、Terraformのインストールとバージョン管理が完了しました。以降、tfenv use [version]を使用して、切り替えたいTerraformバージョンを指定することができます。また、tfenv listを使用して、ローカルにインストールされているTerraformバージョンを確認することもできます。

AWSで、Terraformを利用する方法をまとめてみた(1/10)
https://qiita.com/kimuni-i/items/ffde2f8df96fe5d9513f
AWSで、Terraformを利用する方法をまとめてみた(2/10)
https://qiita.com/kimuni-i/items/6298ed10adc6ad450488
AWSで、Terraformを利用する方法をまとめてみた(4/10)
https://qiita.com/kimuni-i/items/b97089a820cc06ed2d9c
AWSで、Terraformを利用する方法をまとめてみた(5/10)
https://qiita.com/kimuni-i/items/11efb60b9a731d212211
AWSで、Terraformを利用する方法をまとめてみた(6/10)
https://qiita.com/kimuni-i/items/943daf8f4e80af12b70e
AWSで、Terraformを利用する方法をまとめてみた(7/10)
https://qiita.com/kimuni-i/items/b2cc6e1e4b5d5c1a92cb
AWSで、Terraformを利用する方法をまとめてみた(8/10)
https://qiita.com/kimuni-i/items/2934372c385ba0561425
AWSで、Terraformを利用する方法をまとめてみた(9/10)
https://qiita.com/kimuni-i/items/edbdc88f0bca9c0354d2
AWSで、Terraformを利用する方法をまとめてみた(10/10)
https://qiita.com/kimuni-i/items/2f900d792c38ad93979c
DatabricksのShared ComputeだとMLランタイムが使えない問題

# Unity Catalogに対応したクラスターに制限がある
Unity Catalogを使用したDatabricks環境だと、Unity Catalogにアクセスできるセキュリティモードが
- シングルユーザー
- ユーザー分離共有

に限定される。シングルユーザーの場合は制約はそれほどないので特に問題はない。ユーザー分離共有の場合となると、DatabricksのMLランタイムがそもそも選択できない。とは言えMLランタイムでなくとも、mlflowは`pip install`すれば使えるし、分散処理しないのであればsklearnやlightgbmも`pip install`で使えば良い。
問題はSparkMLを使いたい場合だ。シングルユーザーのクラスターは問題なくSparkMLを使えるが、ユーザー分離共有のクラスターはそもそもMLランタイムを選択できない。その状況下で無理やりSparkMLを使うとどうなるだろうか？

SparkML自体はsparkのライブラリに内包されているので、import自体は可能。しかし、いざインスタンス化しようとするとエラーになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158676/bb1071a5-c0d4-d39d-d8c6-9427825f33d7.png)

エラーログを見ると`Constructor public org.apache.spark.ml.regression.LinearRegression(java.lang.String) is not whitelisted.`と書いてある。[これは`Py4JSecurity`が影響している模様。](https://community.databricks.com/t5/data-governance/cannot-use-rdd-and-cannot-set-quot-spark-databricks-pyspark/td-p/8296)
共有モードのクラスターだと`spark.databricks.pyspark.enablePy4JSecurity`が`true`になり、`spark.jvm.class.allowlist`に追加されていない一部のクラスが使えなくなるようだ（共有モードでMLランタイムが選択できないのも、恐らくこれが理由）。
じゃあこの設定を無効化するか、`spark.jvm.class.allowlist`にホワイトリスト登録すればいいじゃん、と思ったがこれは不可能。

この影響で、Unity CatalogにアクセスしてSparkMLを使った機械学習の並列分散処理を行うためには、「シングルユーザー」のクラスターを使う以外に選択肢がない。

さらに厄介なのはpyspark pandas APIを使っていると、一部のメソッドの内部でsparkMLのクラスを参照してエラーになる場合がある（pyspark pandas APIの`df.corr()`でエラーになった）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158676/69c6edae-bcda-cfff-d98b-c060148738e8.png)

クラスターの作成権限を制限している組織は多そうなので、Unity Catalogに移行すると機械学習の並列分散処理が実質的にできなくなるケースもありそう。なのでSparkMLを使っている組織は、Unity Catalogへの移行は検討事項が増えるので注意が必要。
基本的な使い方 husky v8 コミット時に自動ビルド or 自動テスト 失敗時にコミットは実行されない。 成功時は通常通り。

# 導入の経緯

Next.jsで、`npm run dev`と`npm run build`を実行したところ、前者は正常に動作し、動作確認が取れたと思い込んでいましたが、後者は失敗していたことがありました。そのため、`npm run build`の自動実行をしてくれる **husky** を取り入れることにしました。



# 前提知識
git の一通りの知識。



# husky v8 の特徴

最近のバージョンでは、自動インストールが可能になりました。コマンドを一つ実行するだけで、自動的にインストールと設定が行われます。ただし、モノレポなどの複雑な環境はわかりません。



# huskyについて

huskyはある特定のタイミングで指定したコマンドをバックグラウンドで実行させます。
npm scriptを複数自動実行してくれます。

例
ビルド
テスト
リント
設定すれば、複数コマンドをバックグラウンドで自動実行されます。

※ `npm run dev` を実行している時にコミットをすると、↑これらのコマンドは自動実行はされますが、ビルドコマンドはpermission エラーとなって失敗します。



# 公式サイト

https://typicode.github.io/husky/getting-started.html

現在のバージョン
"husky": "^8.0.0"



# husky インストール

自動インストール（推奨）

```
npx husky-init && npm install

```

このコマンドだけでよしなにしてくれます、インストールされる中の詳細は公式サイトを御覧ください。



## 手動編集でコマンドを追加する方法

↓ファイルを開いて編集します。

```.husky\pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run build   #＜＜＜ここに実行したいnpm scriptを書きます。

```

これでコミット時に「バックグラウンド」で `npm run build` が走り
buildコマンドが失敗するとコミットがされません。＜＜便利
buildコマンドが成功するとコミットは通常通りです。

※ビルドだけを実行したい場合はここで終了です。



# コミット時にビルドを必要としない場合

```.husky\pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# npm run build   #コメントアウトすると実行されません。

```

↑不要なコマンドの先頭にコメントアウトしておけば実行されません。



# 導入したいコマンドを、CLI から husky に追加したい場合

`npm test`を追加したい場合、ターミナルから

```terminal
npx husky add .husky/pre-commit "npm test"

```

↓コマンドの実行結果

```.husky\pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run build
npm test

```

これでコミット時に ビルドとテストが自動実行されます。

他にも、`npm run lint` などを追加したい場合など、各自工夫をしてみてください。
Laravelでcookieが取得できない場合の対処法と暗号化の除外に正規表現を使う方法

# 概要
Laravelではブラウザに保存されているcookieは`EncryptCookies`というMiddlewareにより暗号化される。
その結果、cookieのバリューに`null`が設定されてしまい正しくcookieが取得できない。

```.php
dd($request->cookie());

// "test_cookie" => null
```

# 対処法
対処法は2つある。
### 1.PHPのグローバル変数である$_COOKIEを使う
```.php
$_COOKIE['test_cookie']

// "test_cookie" => 12345
```
PHPのグローバル変数である`$_COOKIE`を使えば取得できるが、Laravelのシステムでは、Laravelのお作法に則った方がよいため、こちらは`最終手段`にしたほうが良い。

https://www.php.net/manual/ja/reserved.variables.cookies.php

### 2.EncryptCookiesの$exceptで暗号化の対象から除外したいcookieを設定する

`EncryptCookies`では暗号化の対象から除外するcookieの`キー`を設定できるため、これを使うのが正攻法だろう。
方法は下記の様に`$exceptプロパティ`に暗号化の対象から除外したいcookieの`キー`を設定するだけで良い。

```app\Http\Middleware\EncryptCookies.php

class EncryptCookies extends Middleware
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [
        'test_cookie'
    ];

```

https://readouble.com/laravel/9.x/ja/responses.html

#### cookieのキーを正規表現で設定したい

例えば、`test_`から始まるcookieだけ暗号化の対象から除外したい場合はどうしたらよいだろうか？

方法としては、

1.`EncryptCookies`の`handle`メソッドをオーバーロードする
2.暗号化前のcookieをすべて取得する
3.cookieの`null`を除去する
4.`array_flip()`でキーとバリューを入れ替える
5.`preg_grep()`で`test_`から始まるcookieを取得する
6.`array_keys()`で`キー`だけを取得し`$this->except`に追加する

```app\Http\Middleware\EncryptCookies.php

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handle($request, Closure $next)
    {
        $cookies = $request->cookie();
        $cookies = array_filter($cookies, function($value) { return $value !== null; });
        $cookies = array_flip($cookies);
        $cookie = preg_grep('/^test_/',$cookies);
        $this->except = array_keys(array_flip($cookie));

        return $this->encrypt($next($this->decrypt($request)));
    }
```

# 参考
https://qiita.com/pinekta/items/7ed2b73b90c7be8e5fe6
Eclipseでmvn deployするとpom.xmlは成功するがjarが401で失敗

https://stackoverflow.com/questions/64006644/maven-bintray-distribution-in-eclipse-is-not-uploading-jar-files-error-code-401 の例にあるように、Eclipseでmvn deployするとpom.xmlは成功するがjarのアップロードは401で失敗する場合がある。

# 原因
https://bugs.eclipse.org/bugs/show_bug.cgi?id=566513 にあるように、マルチスレッドの動作にバグがあるらしい。

# 回避策
1. Eclipseのembedded mavenではなく別バージョンを明示的に指定して使用する。
1. JVM引数に ```-Daether.connector.basic.threads=1``` を指定する。
[VS Code / Python] Variable Viewer で変数に格納された値を確認する

### はじめに

こんにちは。初心者エンジニアです。

私は Matlab を使っていたので、Python 開発では似た見た目の Spyder を使っていたのですが、Git と連携をスムーズにするために VS Code を用いることにしました。

Matlab や Spyder のように、都度変数の値を確認したいので、VS Code でそれを実現する方法を調べたのでまとめます。

### 方法
1.  コードエディタ上の任意の場所で右クリック
1.  Run in Interactive Window の Run current File in interactive Window (対話型ウィンドウで現在のファイルを実行する) を実行
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556456/87e5d6b6-2e1c-5b1c-f6f3-f2ce1026caef.png)
1.  Interactive タブが生成されるので、Variables (変数) を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556456/71366c7c-5fe2-ac75-eddc-30a4db497b06.png)
1.  Valuable viewer タブが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556456/f2e681b8-6ecb-9e8c-86cd-27ffe14e52e3.png)

### そのほか
- 任意の変数をダブルクリックすると、変数の編集ができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556456/988f2f0d-0a8d-b0ca-30d9-08e5ab0ed9f0.png)

### 参考

https://stackoverflow.com/questions/69240557/does-vs-code-have-variable-explorer-object-like-we-have-it-in-spyder

https://devblogs.microsoft.com/python/python-in-visual-studio-code-april-2019-release/
非同期処理Promiseの解説で分からなかったことをコメントに追加して理解する

https://jsprimer.net/basic/async/#promise-instance

Javasctiptの勉強をしていて、非同期処理の所のサンプルコードの処理が理解できなかったので、コメントを追加しました。
```Javascript
function dummyFetch(path) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (path.startsWith("/success")) {
            /* ここでresolveの引数に渡されている値({body: `Response body of ${path}`})が
            .thenメソッドの第一引数にコールバック関数として定義されている関数の引数に渡される
            (ここではresponse)*/
                resolve({ body: `Response body of ${path}` });

            } else {
                reject(new Error("NOT FOUND"));
            /* ここでrejectの引数に渡されている値(new Error("NOT FOUND"})が
            .thenメソッドの第二引数にコールバック関数として定義されている関数の引数に渡される
            (ここではerror)*/

            }
        }, 1000 * Math.random());
    });
}
// `then`メソッドで成功時と失敗時に呼ばれるコールバック関数を登録
/* /success/data のリソースは存在するので成功しonFulfilledが呼ばれるというより、
第一引数に指定されているonFulfilled関数が呼び出されるという理解が正しい*/
dummyFetch("/success/data").then(function onFulfilled(response) {
    console.log(response); // => { body: "Response body of /success/data" }
}, function onRejected(error) {
    // この行は実行されません
});
// /failure/data のリソースは存在しないのでonRejectedが呼ばれる
dummyFetch("/failure/data").then(function onFulfilled(response) {
    // この行は実行されません
}, function onRejected(error) {
    console.error(error); // Error: "NOT FOUND"
});

```
DNS温泉8へ行った時に使用した乗車券

2023年9月9日(土)と2023年9月10日(日)に[DNS 温泉 8](https://dnsonsen.connpass.com/event/291770/ "DNS 温泉 8")に参加しました。勉強会自体の内容は[DNS 温泉 8のtogetter](https://togetter.com/li/2222335 "DNS 温泉 8のtogetter")をご覧頂くとして、それ以外の事について書きましょう。
今回は鉄道で移動しました。自宅の最寄駅はJR高崎線の上尾駅なので普通なら上尾⇔下呂の乗車券を使用するところでしょうが、長距離の乗車券の場合、区間を分割して購入すると安価に済む場合があります。[乗車券分割プログラム](http://bunkatsu.info/ "乗車券分割プログラム")でその計算ができます。結果は次の通りで、片道で220円、往復だと440円お得です。
<table>
  <caption>分割前の運賃</caption>
<thead>
    <tr>
      <th>分割前の発駅</th> <th>⇒</th> <th>分割前の着駅</th> <th>運賃</th> <th>キロ数</th> <th>備考</th>
    </tr>
  </thead>
  <tr>
   <td>上尾</td> <td>⇒</td> <td>高山</td> <td>8580 円</td> <td>524.0 キロ</td> <td>幹線</td>
  </tr>
</table>
<table>
  <caption>分割後の運賃と差額</caption>
<thead>
    <tr>
      <th>分割後の発駅</th> <th>⇒</th> <th>分割後の着駅</th> <th>運賃</th> <th>キロ数</th> <th>備考</th>
<thead>
    <tr>
      <td>上尾</td> <td>⇒</td> <td>浮間舟渡</td> <td>420 円</td> <td>23.1 キロ</td> <td>幹線 「東京近郊」</td>
    </tr>
    <tr>
      <td>東京都区内</td> <td>⇒</td> <td>焼石</td> <td>7700 円</td> <td>488.3 キロ</td> <td>特定都区市内発</td>
    </tr>
    <tr>
      <td>焼石</td> <td>⇒</td> <td>下呂</td> <td>240 円</td> <td>12.6 キロ</td> <td>地方交通線</td>
    </tr>
    <tr>
      <td colspan="3">3 枚運賃合計</td> <td>8360 円</td> <td colspan="2">（差額：220 円）</td>
  </tr>
</table>

実際の乗車券の写真は次の通りです。往復乗車券を購入しましたが、復路の分だけを載せています。みどりの窓口などで購入できます。
![帰りに使用した乗車券](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114856/0302c892-727e-50cc-b52f-78d5d14c6bae.png)
自動改札機を通らない場合は駅員のいる改札通路で確認してもらって使用します。

勉強会などでJRに乗車する時は上記の技は便利です。自費で長距離移動する時は重宝する技です。
サーバーサイドのデザインパターン[Strategy Patternの章]

# はじめに

プログラマーになって１年経ってプログラミング言語はハックできたのでデザインパターンを学びます。

ひとまずChatGPTに聞いてみた

Strategy Patternについて詳しく教えて
# GPTの答え
> もちろん、Strategy Patternについて詳しく説明します。
>
>Strategy Patternとは
Strategy Patternは、アルゴリズムや振る舞いを定義する方法の一つです。このパターンを使用すると、アルゴリズムの家族を定義し、それぞれをカプセル化して、交換可能にします。Strategy Patternを使用すると、アルゴリズムを使用するクライアントから独立してアルゴリズムを変更できるようになります。
>
>主な要素
Strategy (ストラテジ): すべての具体的な戦略が実装するインターフェースや抽象クラス。
ConcreteStrategy (具体的なストラテジ): Strategyのインターフェースを実装するクラス。異なるアルゴリズムや振る舞いがここで定義されます。
Context (コンテキスト): Strategyを使用するクラス。コンテキストは、Strategyインターフェースを通じてConcreteStrategyを実行します。
利点
変更に柔軟: Strategy Patternを使用すると、アルゴリズムの変更や追加が容易になります。
再利用性: 同じアルゴリズムや振る舞いを持つ複数のクラス間でストラテジを再利用できます。
コードの整理: 似たような条件分岐が多数存在する場合、それをStrategy Patternで整理して、コードを簡潔にすることができます。
実装例 (Pythonを使用)
```python

from abc import ABC, abstractmethod

# Strategy
class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount: float) -> None:
        pass

# ConcreteStrategy 1
class CreditCardStrategy(PaymentStrategy):
    def pay(self, amount: float) -> None:
        print(f"Paying {amount} using Credit Card.")

# ConcreteStrategy 2
class PayPalStrategy(PaymentStrategy):
    def pay(self, amount: float) -> None:
        print(f"Paying {amount} using PayPal.")

# Context
class ShoppingCart:
    def __init__(self, payment_strategy: PaymentStrategy):
        self._payment_strategy = payment_strategy

    def checkout(self, amount: float) -> None:
        self._payment_strategy.pay(amount)

# 実行
cart1 = ShoppingCart(CreditCardStrategy())
cart1.checkout(100)

cart2 = ShoppingCart(PayPalStrategy())
cart2.checkout(100)
```
>このサンプルでは、2つの異なる支払い方法（CreditCardとPayPal）をStrategy Patternを使って実装しています。ShoppingCartクラスはContextとして機能し、具体的な支払いストラテジを受け取り、それを使用してcheckoutを行います。
>
>Strategy Patternは、アルゴリズムや振る舞いが変更される可能性がある場面や、異なる種類のアルゴリズムを簡単に切り替える必要がある場面で非常に役立ちます。

![dia](https://kroki.io/plantuml/svg/eNqdkE0KwjAQhfdzillWpBfoQmo9gicI6VMCSSqZqVTEu_uDaQqCiy7n_XwDrxU1ScfgiVxUpJOx4KMmozjf-E7MW0ywo6LaNHwdXE8PIuuNCB-GaBMUOb5nFy4eAVFlLaNbx1BM-knV8u00c_vdFWg-KylWRhX6nFp8yfx6V5gL7WeGf2ZH1CL2r8GfyceCkw==)

全部説明してくれた。
図も出力していただきました。
リッチなのでGPT-4を使っています。

Strategyが実際の処理を呼び出すインターフェースの役割だがこいつのおかげで継承よりもオブジェクトの結合が緩くなって改修がしやすいらしい
中身に脳のリソース取られたくない時も実際の処理部分がカプセル化されてることで楽だね

# パターンを使う時

1. アルゴリズムの変更や交換が予想される場合: もしアプリケーションの特定の部分において、使用するアルゴリズムや振る舞いを容易に変更したいと考える場面。

2. 多数の条件分岐: 一つの操作に対して多くの実装方法や条件分岐が存在する場合、それぞれの分岐を独立したストラテジとして切り分けることで、コードが読みやすく、メンテナンスしやすくなります。

3. 類似のクラスが多い場合: 類似の振る舞いを持つが、いくつかのアルゴリズムの部分だけが異なるクラス群が存在する場合、共通のストラテジインターフェースを使用することでコードの重複を避けることができます。

4. クライアントが知識を持たずにアルゴリズムを選択したい場合: クライアントが特定のストラテジの具体的な実装に依存せずに、動的にアルゴリズムを選択・交換できる柔軟性を持たせたいときに利用します。

5. テストのしやすさを保ちたい場合: 独立したストラテジを持っていると、それぞれのストラテジを独立してテストすることが容易になります。MockやStubを利用して、特定のストラテジをテスト時に置き換えることも簡単です。

４がStrategy Patternの１番のメリットじゃない？簡単に実装者が動的に処理変えれるのはユーザーももちろんだけど賢い人に処理部分書いてもらったらこちとら呼び出すだけでインデント揃えることに集中できるじゃん

# 終わり


Strategy Patternは、アルゴリズムや振る舞いの変更・追加を容易にし、システム全体の柔軟性と拡張性を向上させるデザインパターン。

最初がんばろ！あとから楽しよって話