OmniAICreator/Qiita-1.07M huggingface dataset:
【WSL2セットアップ】WSL2のインストール関連のコマンド

※2024年3月3日時点の情報になります。修正あったら適宜直します。

# はじめに
WSL2のインストール関連のコマンドについてまとめます。

# wsl --install
以下に説明があります。

https://learn.microsoft.com/ja-jp/windows/wsl/install

何者か考えましたが、Microsoft StoreにあるWindows Subsystem for Linuxをインストールしてると考えてます。

![MicrosoftStore の Windows Subsystem for Linux](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/5e03bb3a-187e-ee19-bdf0-27264df586f7.png)

1回でも実行し、wslをインストールすると、このコマンド使えなくなる認識です。

以下のエラーが発生した場合は、このMicrosoftStore の Windows Subsystem for Linuxをアンインストールとインストールしてから、wsl --install -d Ubuntuなどを実行すると成功する認識です。

https://qiita.com/Anchovy-s3/items/eeff0d5a81dc364c533c

# wsl -l -v
wsl --list --verboseとやってること同じです。
インストールしているディストリビューション一覧が確認できます。

![wsl -l -v の実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/a69fa75c-c813-74d7-0d65-f13f57c5e206.png)

# wsl -l -o
wsl --list --onlineとやってること同じです。
インストールできるディストリビューションの一覧が表示されます。

![wsl -l -o の実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/b4fc181b-c978-4f0a-8591-9b00650a45b3.png)

# wsl --install -d ubuntu
MicrosoftStoreのUbuntu(無印)をインストールします。
隣のUbuntu 22.04.3 LTSをインストールするわけではありません。

![MicrosoftStore の Ubuntu](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/1dc2cc50-a871-5723-a804-dd2f6c97f930.png)

# wsl --install ubuntu-22.04
-dオプションを指定しなくても-dありと同じ実行になる認識です。
wsl --install ubuntu-22.04を指定すると、Ubuntu 22.04.3 LTSがインストールされます。

![MicrosoftStore の Ubuntu 22.04.3 LTS](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/9aa04267-0e1d-64df-74e6-250f6163e337.png)

# 終わりに
以上です。
他のWSL2の基本的なコマンドに関しては以下に記載あります。

https://learn.microsoft.com/ja-jp/windows/wsl/basic-commands

Windowsの機能の有効化の設定については以下にまとめています。

https://qiita.com/fujinninja/items/8882e179270b144076df
【VSCode】Visual Studio Codeのインストール（Windows）

# はじめに
VSCodeのインストール手順をメモとして残しておきます。
[公式サイト](https://code.visualstudio.com/docs/setup/windows)にインストール手順があるのでこれを参考に進めていきます。
# インストーラのダウンロード
自身の環境に合ったインストーラを選択します。

https://code.visualstudio.com/download

今回は画面左の方にある「Windows User Installer x64」を選択しました。
System InstallerはPC上のすべてのアカウントにインストールされ、User Installerは現在使用しているアカウントにのみインストールされます。よくわからない人はUser Installerを選択するといいと思います。
![インストーラ選択の公式サイト画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/ac11301d-b6e8-ee9b-db7e-b5fb45b6915f.png)

ダウンロードが完了したら、インストーラを起動します。

# インストールの実行
同意をしないと先に進めないので「同意する」を選択します。
![インストーラ画面1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/4b83dcbb-4546-9e09-4810-45cec2cb8c88.png)

インストール先やスタートメニューフォルダーの指定、追加タスクの選択などは特にこだわりがなければデフォルトのままで問題ありません。
自身で理解した上で変更したい箇所がある場合は変更しましょう。

「インストール」ボタンを押したらインストールが始まります。

以下のような画面が表示されたらインストール完了です。今回は30秒程度で完了しました。
![インストーラ画面2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/f0426f62-7944-ca55-27dc-b994f0ec22e4.png)

完了ボタンを押してVSCodeを起動してみましょう。

![VSCode初起動](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/ed472e79-1a6f-5a64-19e5-50fe4aaa3189.png)

無事にインストールできたことが確認できました。

ただ、このままの状態だと表示言語が英語になっています。
英語が中学生レベルの私には扱いにくいので、表示言語を日本語に変更します。

# 表示言語の日本語化
①のExtensions(拡張機能)を押し、②の検索ボックスに「japanese」と入力します。
![日本語化1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/19f3d0a0-e718-6034-a2da-a06b4e543551.png)

おそらく一番上に表示される「Japanese Language Pack for Visual Studio Code」（Unique Identifier：	MS-CEINTL.vscode-language-pack-ja）をインストールします。
![日本語化2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/145cc530-ecde-35bf-fbb6-41e4aac53639.png)

インストールが完了すると、画面右下に「Would you like to change Visual Studio Code's display language to Japanese and restart?」（Visual Studio Codeの表示言語を日本語に変更して再起動しますか？）というメッセージが表示されるので、青いボタン（Change Language and Restart）を押します。
![日本語化3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/c0258cdd-eb25-fc5a-09a8-20670fe6d089.png)

表示が日本語になりました。これで安心して開発ができます…
![日本語化完了](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712912/7b8a8a61-8c05-1452-2efe-8241a5e50065.png)

# おわりに
以上でインストール（＋α）は完了です。お疲れさまでした！
Pythonメモ

# 概要

Pythonでなにかしらを書いているときに、よく調べたりしていたちょっとした処理をまとめます。

# ファイル処理

ファイルの読み込み、書き込みについてまとめます。

## ファイル書き込み

```python
# ファイルに書き込む文字列
s = 'test string'
# ファイル名
path = 'test_write.txt'

# ファイルに書き込む処理
with open(path, mode='w') as f:
    f.write(s)
```

## ファイル読み込み

```python
# ファイル名
path = 'test_write.txt'

# ファイルから読み込む処理
with open(path) as f:
    s_read = f.read()

    # 読み込んだ内容を表示
    print(s_read)
```
【TypeScript】ユニオン型から指定した値を除外したユニオン型を作成する方法

以下のように記述するとユニオン型から指定した値のみ除外したユニオン型を作成できます。

```ts
type T1 = "A" | "B" | "C" | "D" | "E"
type T2 = Exclude<T1, "E">

// T2 = "A" | "B" | "C" | "D"
```

https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers
定型のメールの送信（600回／月）をGAS（GoogleAppsScript）で自動化

## 定型のメールの送信をGAS（GoogleAppsScript）で自動化した様子

https://twitter.com/MitsuhiroM82423/status/1764280129352818909

みなさん、こんにちは。
紙、印鑑、手作業に埋もれて業務をしている昭和男子の会社員です。

毎月、**請求書を大量に発行**し、メール送信している業務を行っています。
前回、Power Automate Desktop で請求書のExcelファイルをメールに添付し間違えないように取引先ごとに**Excelファイルを仕分け**したり、**フォルダを圧縮**したりして、自動メール送信まで、あと一歩まできました。

[前回の記事はこちら](https://qiita.com/miyabe-mitsuhiro/items/e20a0846cd06e49ef53d)

https://qiita.com/miyabe-mitsuhiro/items/e20a0846cd06e49ef53d

しかし、Power Automate Desktopで複数ファイルの添付の方法がわからず、また、フォルダを圧縮し添付すると文字化けしたり、まだまだ課題がありました。

そんな時、同僚からこんな一言が・・・
**「Gmailを使っているんだから、GASの方が相性がいいかも」**
ということで、GASで自動メール送信に取り組みました。

## 使用するもの
・ChatGPT
・Google Apps Script
・Google Spread Sheet
・Google Drive
・Gmail

## ChatGPTにGASのコードを聞く
GASのコードなんて書けないので、ChatGPTにとにかく聞いてみました。

:::note warn
Google Apps Scriptを使って、メール送信前の下書きメールを自動作成したい。コードを教えて!
:::
:::note warn
Google Spreadsheetsにrecipient、subject、bodyの各変数に対応する項目をつくりました。紐づけるコードを教えてください。
:::
:::note warn
スプレッドシートの空白行まで繰り返し下書きメールを作成するにはどうしたらよいですか？
:::
:::note warn
ファイルを添付したいのですが、どうしたらよいですか？
:::
:::note warn
下記のコードにさらにファイルを添付したい。
どのように修正すればよいでしょうか？
(コードを貼り付ける）
:::
:::note warn
データの4列目に添付ファイルを指定したい。
どうしたらよいですか?
:::
:::note warn
指定したフォルダにあるファイルを複数すべて添付したい。
どうすればよいですか？
:::
:::note warn
フォルダIDは、データの4列目に明記し、変数とします。
コードを修正してください
:::
こんな感じで聞きまくり、出来たコードがこちらです。

**GASのスクリプト**
```ruby:GASメール下書き　複数添付ファイル
function createDraftEmail() {
  var spreadsheetId = "スプレッドシートのID"; // スプレッドシートのIDを指定してください
  var sheetName = "sheet1"; // データがあるシートの名前を指定してください
  var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
  var dataRange = sheet.getDataRange(); // データがある範囲を指定してください
  var data = dataRange.getValues();


  for (var i = 1; i < data.length; i++) {
    var recipient = data[i][0];
    var subject = data[i][1];
    var body = data[i][2];
    var folderId = data[i][3]; // 4列目に添付したいファイルが格納されているフォルダのIDがあると仮定しています
    
    var folder = DriveApp.getFolderById(folderId);
    var files = folder.getFiles();
    var attachments = [];
    while (files.hasNext()) {
      var file = files.next();
      attachments.push(file.getBlob());
    }

    var draftEmail = GmailApp.createDraft(recipient, subject, body, {
      attachments: attachments // フォルダ内のすべてのファイルを添付します
    });

    Logger.log("下書きメールが作成されました。ドラフトメールのID: " + draftEmail.getId());
  }
}
```
## 複数のファイルを添付することが可能に
**メールの自動送信**をしたくて、添付ファイルをフォルダ毎にまとめることにし、**フォルダを圧縮**したのですが、「**文字化け**」の課題が解決できず、複数ファイルを添付することに再度**GASで挑戦**し、見事、成功しました。
ほんと、**ChatGPT**はすごいですね。

でも、こちらでも課題があり、通常使用している**エクスプローラーのフォルダ**のファイルは、添付できない仕様になっているとの事。
**GASで自動メール送信**をするには、エクスプローラーのフォルダから、Google Driveのフォルダへのアップロードの手間が必要になりました。
ひとつ課題をクリアすれば、またひとつ課題が・・・

なかなか思い通りには、ならないですね～
でも、また一歩自動化に近づいた気はします。
コメントを収集するライブラリChatDownloaderを使ってみた

# コメントを収集するライブラリChatDownloaderの紹介
徐々に寒さが増し、単位の結果が気になる季節ですね。皆さんは単位をしっかり取得できましたか？私は残念ながらいくつか落としてしまいました。

さて、今回はちょっと面白いライブラリ、ChatDownloaderについて紹介します。Pythonの環境構築などはまた別の機会に触れるとして…

ChatDownloaderを使う理由
近頃、ライブ配信の動画の長さに疑問を感じ始めました。コメントを収集して解析することで、見どころを抽出できないかと思い至りました。しかし、YouTube APIの使用は少し敷居が高いため、代わりにChatDownloaderを見つけました。

# 導入と使用例
ということで、四の五の言わずにpip install
使用環境はPython3.8です。

```Python:コマンド
pip install chat-downloader
```
ダウンロードするコメント付きの動画は
[LIVE: Bahrain Grand Prix Build-Up and Drivers Parade](https://www.youtube.com/watch?v=fdUL1wzSC1g "LIVE: Bahrain Grand Prix Build-Up and Drivers Parade")
という海外のレーシングの選手インタビューの動画をしようしました。ここで好きな配信者（Vtuber）の動画でも良かったのですが、起業部として記事を発信しているため皆さんに布教できないのが残念です。

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

```Python:chat_downloader.py
from chat_downloader import ChatDownloader

url = 'https://www.youtube.com/watch?v=fdUL1wzSC1g'
chat = ChatDownloader().get_chat(url)  # create a generator
for message in chat:  # iterate over messages
    chat.print_formatted(message)  # print the formatted message
```
結果は以下のようになります。
マイナスからスタートしているのは待機中のコメントであるためです。
```Python:結果
-1:45 | Solomon: Dont gamble burn rubber 
-1:42 | Proliwier: Max Verstappen 
-1:41 | flavi3nse: than than than
-1:36 | Shivam: AND ITS LIGHTS OU- ...(skips)..max wins the bahrain gp
-1:35 | Qylus: Haas 1-2 coming
-1:33 | kstfsy: Max
-1:33 | Nekkusu: @Kylian Mbappé Yeah thats what i'm talking about (We about to 3-peat the Champions league again)
-1:29 | Cakeplays21 : landoooooo 

以下同様に続く
```

スタートを0:00からしたいのであれば
```diff_python
- chat = ChatDownloader().get_chat(url)
+ chat = ChatDownloader().get_chat(url, start_time='0:00')
```
とすると0:00からスタートできます。
 # 終わりに
 いかがでしたでしょうか。
このライブラリの魅力は、YouTube、Twitch、Zoomなどのプラットフォームから認証なしでチャットメッセージを取得できる点にあります。

公式ドキュメントはこちらから参照できます。

 https://chat-downloader.readthedocs.io/en/latest/index.html

それでは、岐阜大学起業部からお送りしました。また次回お会いしましょう。
PythonでExcelの列幅を変更する時のサイズ感

Pythonのopenpyx|ではExcelの列幅を変更できます。
使ってみると、サイズが指定よりも若干小さくなるようです。
例えば、サイズを8にしようとすると7.42になりました。

指定したサイズに特定の倍率をかけることで指定したサイズになります。
お困りの方は下記の倍率を使っていただければと思います。
また、環境として、Excelは2021、Pythonは3.9を使用しています。


```
import openpyx|
from openpyxl import load_workbook

size = 指定のサイズを入力
bairitsu = 下記の倍率を入力

wb = openpyxl.load_workbook('対象ファイルパス')
ws = wb.active

ws. column_dimensions ['A’]. width = size * bairitsu #A列のサイズを変更しています
```


◆各サイズと倍率◆
8 * 1.0725
9 * 1.0644
10 * 1.058
11 * 1.05272
12 * 1.04833
13 * 1.04461
14 * 1.04142
15 * 1.03866
16 * 1.03625
17 * 1.03411
18 * 1.0322
19 * 1.03052
20 * 1.029
21 * 1.02761
22 * 1.02636
23 * 1.02521
24 * 1.02416
25 * 1.0232
26 * 1.0223
27 * 1.02148
28 * 1.02071
29 * 1.02
30 * 1.01933
【Rails】Bootstrap4から最新版(ver.5.3)に移行する方法

こんばんは！
今日Bootstrap4から最新版へと移行したので、方法を載せておきます。
実際方法は公式に載っていますし、とても簡単なのですぐ導入できます！
ですが、今回は自分の備忘録として載せます笑

## 過去のバージョンからの移行
今回古いバージョンからの移行となりましたが、特に古いバージョンの記述があっても残しておいて問題ありませんでした。
移行するメリットは最新版でjavascript主体のBootstrapが適用できるということです(Ver.4ではjQueryも使われていましたが、Ver.5以降はjavascriptのみになったそうです。)。オフキャンバスやその他多くの新機能も実装できるようになります。ただ一つデメリットとして挙げられるのは、もともとBootstrap4に対応していた記述が一部使えなくなる場合があることです。おそらくjQueryを使っていた部分やclass変更があった部分かと思います。私の場合は特に移行後も動作に問題ありませんでしたが、部分的にはそのような問題が起きうるかもしれないです。

## 早速導入してみる
まずはじめに、以下の記述をlayouts/application.html.erbのheadタグ内に追記します。
```erb:app/views/layouts/application.html.erb
<head>
<!--略。以下の1行を追記してください。-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
```

次に、以下の記述をlayouts/application.html.erbのbodyタグ内の**最終行**に追記します。
```erb: app/views/layouts/application.html.erb
<body>
<!--略。以下の1行を追記してください。-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>
```

これで導入は終了です。Ver.4も導入手順としては少ないですが、Ver.5はたったの2行を追記するだけで本当に驚きました:flushed:
皆さんもこの機に移行してみてはいかがでしょうか！
今日もお疲れ様でした！
IDEやテキストエディターで複数のフォントを使う

# 複数のフォントの活用

IDE（統合開発環境）やテキストエディターのなかには、複数のフォントを使えるものがあります。この機能によって、問題を解決したり快適な環境を作ったりできます。その活用事例を紹介します。

# Xcodeでのフォントの設定

[Xcode](https://developer.apple.com/xcode/)は、iOSアプリやmacOSアプリを開発するための、macOS用のIDEです。

Xcodeはエディターで日本語を使うと少し問題が起きます。日本語に対応していないフォントを使っていると、日本語が含まれない行と含まれる行で行の高さが異なってしまうのです。実際、デフォルトの設定では日本語に対応していないフォントになっており、次のようになります。

![](https://raw.githubusercontent.com/usami-k/qiita-contents/main/images/2024-use-multi-font/xcode-before.png)

日本語が含まれる箇所だけ行の高さが変わるため、行によって高さが変わってしまっています。これを避けるためには、日本語に対応したフォントを使う必要があります。

では、日本語に対応していないフォントを使いたい場合はこの問題には対処できないのでしょうか。実は対処法があります。

Xcodeはシンタックスハイライトの設定で、単に色やスタイルを変更するだけでなく、フォント自体を変更できます。実際デフォルトの設定では、Plain Textのフォントには「SF Mono」、Documentation Markupには「Helvetica Neue」と異なるフォントが設定されています。

![](https://raw.githubusercontent.com/usami-k/qiita-contents/main/images/2024-use-multi-font/xcode-font.png)

この機能を利用して、日本語がよく使われる箇所だけ日本語に対応したフォントを使うように設定できます。

日本語がよく使われる箇所は、Comments、Documentation Markup、Stringsなどが考えられます。ここでは、Plain Textなどの箇所のフォントは日本語非対応の「0xProto」、Commentsなどの箇所のフォントは日本語対応の「UDEV Gothic 35JPDOC」を使うことにします。その設定をすると、次のようになります。

![](https://raw.githubusercontent.com/usami-k/qiita-contents/main/images/2024-use-multi-font/xcode-after.png)

どの行もほとんど同じ高さになりました。この対処法で、好きなフォントを使いながら、日本語の表示も改善できます。

# CotEditorでのフォントの設定

[CotEditor](https://coteditor.com)はmacOS用のプレーンテキストエディターです。

CotEditorでは、ファイルの種類によって使うフォントを変える設定ができます。この機能を活用するとテキスト編集がより快適になります。

![](https://raw.githubusercontent.com/usami-k/qiita-contents/main/images/2024-use-multi-font/coteditor-font.png)

「優先するフォント」の設定を「自動」にすると、文書のシンタックスの種類が「標準」の場合（Markdownなど）は標準フォントが使われ、種類が「コード」の場合は等幅フォントが使われます。

この機能を利用して、Markdownなどの文書を開く場合は日本語が読みやすいフォントを使い、設定ファイルやソースコードを開く場合はコードが読みやすいフォントを使うように設定できます。

なお、CotEditorでは、Xcodeのような行の高さの問題は起こりません。そのため、日本語に対応していないフォントを使って日本語を表示しても問題は起こりません。

# 参考：フォントの紹介

この記事で使用したフォント「0xProto」「UDEV Gothic」については、次の記事に紹介があります。

https://qiita.com/usamik26/items/2ab0c4b88bf7c00845dd

https://qiita.com/macneko/items/c2e0400f537af83ca4a9

# 情報募集

この記事では、次のIDEやテキストエディターを取り上げました。

* [Xcode](https://developer.apple.com/xcode/) : シンタックスハイライトの設定で複数のフォントが使える
* [CotEditor](https://coteditor.com) : ファイルの種類によって異なるフォントが使える

ほかに複数のフォントが使えるIDEやテキストエディターがあれば、ぜひ教えてください。
WearOSでRustからHello World

# 前置き
`TicWatch E2`というスマートウォッチ（WearOS）を手に入れたので、この前作ったクロスプラットフォームライブラリの[Nickname](https://github.com/oligamiq/nickname)[^1]を対応させようとした結果、そもそもRustでWearOS向けにビルドする方法が出なかったので、行き当たりばったりで試したら一応うまくいった。
リポは[ここ](https://github.com/oligamiq/wearos_rust_example)

# 技術的な話
なんかないかと調べたのだが、FlutterでWearOS向けに作れるという話や、Android向けとほとんど同じように作れるという話から、バイナリ的にはAndroidと同じだろうと予想していた。

# やってみたこと
まずはadbで接続した（WiFi経由）。
次に、コードを用意

```rust:src/main.rs
fn main() {
    println!("Hello, world!");
}
```
最後に、デバイスを確認してGO!!
```bash
$ adb devices
List of devices attached
192.168.11.32:5555      device

$ cargo dinghy -d 192.168.11.32:5555 run
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/83aef904-0816-a30f-17e3-80e4dfc84b19.png)

なんか出てますがうまく行きました！！

最後に、確認のためライブラリを試しに使ってみます。
`getrandom`と`reqwest`の`rustls`+`blocking`を使って、こんな複雑でネットを使うライブラリなどでも行けるのか試しましょう。

コードはこんな感じ
```rust
use reqwest::blocking::*;

fn main() {
    println!("Hello, world!");

    let mut buff = [0; 8];
    getrandom::getrandom(&mut buff).unwrap();
    println!("{:?}", buff);

    let body = get("https://www.rust-lang.org").unwrap().text().unwrap();

    #[cfg(debug_assertions)]
    println!("Debug mode");

    #[cfg(not(debug_assertions))]
    println!("Release mode");

    println!("body = {:#?}", body.lines().collect::<Vec<_>>()[0..10].to_vec());

    println!("Goodbye, world!")
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/df3dd22d-4c0c-1b25-0f13-623a54859527.png)

上手く動きましたね。
つまりAndroid互換ということ。
ということで、`cargo-apk`の後継の`xbuild`君には、是非WearOS向けのビルドを実装してほしいところですね。

[^1]: ユーザ名を取得したりするライブラリ
GitHubにコミットするユーザー名を変える

## 仕事用のアカウントから、私用のアカウントに変更したい


以下のコマンドで変更できる。

`git config user.name "名前"`
`git config user.email GitHubアカウントのアドレス`

※ユーザー名はダブルクォーテーションで囲み、メールは囲まない 
```
git config user.name "shiyou"
git config user.email shiyou@email.com
```



### 適当な名前・メールに変更してコミットしたらどうなる？

問題なくコミットできる。

以下スクショのように、GitHub画面上には `user.email` に紐づくGitHubアカウントのユーザー名が表示される。
GitHubアカウントに紐づかないメールアドレスを指定していた場合は `user.name` で指定した名前がそのまま表示された。

![shot240303-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733749/139ed7b8-e4a9-b1bd-c999-3d30589d6867.png)
for文で分からなくなりそうな部分をまとめます　言語：python

 <font color = #D3E173>※このQiitaで記事を書くことに慣れていない為、誤字・脱字や読みづらい部分もあるかと思いますが、ご理解ください。</font>

閲覧いただき、ありがとうございます！
私は、現在医療業界で働く医療従事者になります。
とある経緯からpythonを勉強中です。
ここでは自分が勉強した事を復習したり、忘れないようにするため記載いたしますので、もしもっとこうした方が良いよ、とかこれはちょっと。。。というものがあれば教えていただけますと幸いです。
※記事内容は随時更新します



## 辞書型でのfor文について
```py:記述内容
animals = { "one" : "cat", "two" : "dog", "three" : "bird" }   #index : value

for a in animals:
    print(a) #キーが取得される
    print(animals[a]) #バリューを出力したい場合はこう書く
```


出力結果

:::note
one
cat
two
dog
three
bird
:::

### items() メソッドを使うとキー、バリューも取り出せる
【Rails】異なるアクションが読み込まれるエラー(＋その他エラー)

今日は新しい機能を実装している際にルーティングを追加し、エラーが出てしまったのでそのエラー解決方法について備忘録として載せたいと思います！
他にもいくつかエラーが出てしまったので、その対処法も書いてみます！
以下紹介するエラー内容です。

::: note alert
エラー1: パスを指定したが遷移時に異なるアクションが読み込まれるエラー
エラー2: ActionTextが正常に表示されない(エラー文は出ていない)
エラー3: app/javascript/packs/application.jsが読み込まれない(コンソール上のエラー)
:::

## エラー1: パスを指定したが遷移時に異なるアクションが読み込まれるエラー
今回はパス自体の記述はあっているのに、遷移した際に違うアクションのページが読み込まれている場合です。ズバリ！ルーティングに問題がありました...というのも、そもそもなぜそのようになってしまっているのかまず説明しますね。
ルーティングをする際にroutes.rbを書きますよね。Railsはパスを読み込むと記述したルーティング順にどのアクションをすればいいか探していきます。その際に、URLが
```
user/:id(users#show)
user/check(users#check)
```
という順番になるようにルーティングを指定されていた場合(実際のルーティングの書き方をしていないのでかえって分かりづらかったらすみません。rails routesをしたときの表示に寄せています。)、user/:idはうまく読み込まれますが、user/checkは読み込まれません。この場合、パスを指定しているとid="check"と読み込まれて、users#showが読み込まれてしまいます。この問題の解決方法は

:::note info
ルーティングの記述順を入れ替える
:::

です。今回の場合だと

```
user/check(users#check)
user/:id(users#show)
```
このような順番で読み込まれるようにルーティングを書き換えれば問題解決します！
実際のルーティングはこのようになります。
```ruby:routes.rb
'user/check' => 'users#check'
'user/show' => 'users#show'
```
ちなみにルーティングの順番を入れ変えるほかに、idを数字しか読み込めなくするという解決方法もあるそうです。

## エラー2: ActionTextが正常に表示されない(エラー文は出ていない)
今回はエラーではありませんが、ActionTextをせっかく導入したのに、うまく読み込まれず形が崩れていました。
本来であればこのように表示されるはずです。
![スクリーンショット 2024-03-03 222759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677302/d1bb3025-a80d-3cf2-8413-52651c8b0f38.png)
しかし、解決前はBやIなどの部分がBold, Italicなどと表示され、入力フォームも中途半端に表示されていました。(写真無くてすみません:sweat_drops:)
解決方法としては、

::: note info
app/views/layouts/application.html.erbのhead内にstylesheet_link_tagを追記する
:::

でした。当時、stylesheet_pack_tagはあったものの、stylesheet_link_tagは消している状態でした。もし同じ状況の方がいらっしゃったらこちらを追記してください。
```erb: app/views/layouts/application.html.erb
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
```

## エラー3: app/javascript/packs/application.jsが読み込まれない(コンソール上のエラー)
webpackerを使用している際に、読み込む場所を正しく設定できていなかったようです。いろいろ記事を読んでみましたが、ビルドできていない状態で、jsファイルに変更があっても読み込まれていない状態でした。
解決方法は、

::: note info
ターミナルでbin/webpackというコマンドを実行する
:::

でした！これでファイルに変更があった際にも自動で読み込んで、コンパイルしてくれるそうです！以下の記事を参考にさせていただきました。

https://qiita.com/chimame/items/8d3d6f4afea675cffa7d

https://zenn.dev/yuma_ito_bd/scraps/c404fb04469a1c

これでも解決しない場合は、ファイルの場所や階層、読み込むための記述が間違っている可能性があるので、そのあたりを試してみてください。

## 最後に
最近PF作成で新しいことに挑戦する代わりに様々なエラーと出会う機会が増えました。頻繁に出会えるものではないので、出会ってから忘れないように書き留めておきたいなと思います。解決できる選択肢もいくつかあったりするので、いろんな方法をいつかパッと思い浮かぶようになりたいなぁと、メンターさんに質問していて感じました。
様々なエラーを日々解決している現役エンジニアの皆さんには本当に頭が上がりません...いつかそうなれますように！ちょっとした日記でした。
今日もお疲れ様でした！！
Docker × Django 開発環境作成

## はじめに
自分用の個人開発のメモ/備忘録として記録していきます。

## 環境
docker desktop
windows 11

## やりたいこと
Django開発環境をdocker上に作成したい。
最小限の構成とし、必要に応じて修正していく。


## ディレクトリ
プロジェクトディレクトリを任意の場所に作成。
docker関連のファイルとその配下にsrcディレクトリを作ることにした。
```
project directory
│  .env
│  docker-compose.yml
│  Dockerfile
│  requirements.txt
└─ src
```


## 必要ファイルを準備

### envファイルを作成
envファイルにてホスト側のディレクトリやポートを指定。
ポートは他コンテナと重複しないものを設定する。
``` :.env
# Directory
HOST_WORKDIR=./src

# Python version
PYTHON_VER=3.12-slim-bullseye

# Port
APP_HOST_PORT=8888

# Mode
ENV_STATE=local   #'local' / 'staging' / 'production'
```


### requirements.txtファイルを作成
とりあえずdjangoのみ。
必要に応じて追加する。
```
Django==5.0
```


### docker-compose.ymlファイルを作成
コンテナ側のポートは8000番に指定。
commandとportsのポート番号を合わせれば他のポートでもOK。

``` yml:docker-compose.yml
version: '3'

services:
  app:
    build:
      args:
        - WORKDIR=/var/www/src
        - PYTHON_VER={PYTHON_VER:-3.12-slim-bullseye}
      context: .
      dockerfile: Dockerfile
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - ${HOST_WORKDIR:-./src}:/var/www/src
    ports:
      - "${APP_HOST_PORT:-8000}:8000"
    environment:
      - ENV_STATE=${ENV_STATE:-local}
```


### Dockerfileファイルを作成
``` dockerfile:Dockerfile
#ベースイメージ作成
ARG PYTHON_VER
FROM python:${PYTHON_VER}
ENV PYTHONUNBUFFERED 1

#ディレクトリ作成、ワーキングディレクトリ指定
ARG WORKDIR
RUN mkdir -p ${WORKDIR}
WORKDIR ${WORKDIR}

#requirements.txtからパッケージインストール
COPY requirements.txt "${WORKDIR}/"
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
```

## プロジェクト/コンテナ作成

### イメージ作成
``` docker compose build ```

### プロジェクト作成
プロジェクトの共通設定を行うことが多いので名前をconfigとした。
src直下へ作成するため「.」としておく。

``` docker compose run app django-admin startproject config . ```

### コンテナ作成

``` docker compose up -d ```

## アクセスしてみる
ブラウザから```http://localhost:8888```へアクセスしてみる。
下記画面が出れば作成成功:congratulations:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680973/3e2f5c7e-073a-9197-3644-ae52a0bd8f1e.png)



## settings.pyを修正

### 環境によるDEBUGやALLOWED_HOSTSを切り替える。
``` python:settings.py
 envstate = os.environ.get('ENV_STATE','local')
if envstate=='production':
    DEBUG = False
    ALLOWED_HOSTS = []
elif envstate=='staging':
    DEBUG = True
    ALLOWED_HOSTS = []
else:
    DEBUG = True
    ALLOWED_HOSTS = [
        'localhost',
        'www.localhost',
        'host.docker.internal',
        'gateway.docker.internal',
    ]
``` 

### タイムゾーン等も変えておく。
``` python:settings.py
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```


## スーパーユーザー作成

### コンテナに入る
``` docker compose exec -it app sh ```

### マイグレートする
``` python manage.py migrate ```

### スーパーユーザー作成
``` python manage.py createsuperuser --email admin@example.com --username admin ```
パスワードを聞かれるので任意のものを設定する。


## admin画面にアクセスしてみる
ブラウザから```http://localhost:8888/admin```へアクセスしてみる。
作成したスーパーユーザーでログインしてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680973/7a358fb4-1fd2-1e91-a52d-01e516193a9c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680973/00c881c6-a4b6-ceaa-53ea-eb25f09b5c17.png)
【WSL2セットアップ】Windowsの機能の有効化または無効化

※2024年3月3日時点の情報になります。修正あったら適宜直します。

# はじめに

WindowsでWSL2の環境構築をしてると以下の画面に出くわすと思います。
この画面の内容についてまとめます。

![Windowsの機能の有効化または無効化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/ee609d4c-268c-78d5-24e7-8f50dcfce609.png)

# Hyper-V

この項目が出てない人もいると思います。以下、Microsoft Learnのリンクです。

https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v

> Hyper-V ロールは、Windows 10 Home にはインストールできません。

このように記載があるので、WindowsのHomeを使用している人は出てきません。
WSL2の要件を見たら以下のように記載があるだけなので、設定不要な認識です。
（記載が明確にないため、初心者は混乱するかもしれません。）

https://learn.microsoft.com/ja-jp/windows/wsl/install

> Windows 10 バージョン 2004 以上 (ビルド 19041 以上) または Windows 11 を実行している必要があります。

![Hyper-v](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/ccb5ad67-65b9-1f4d-72c9-a17a13f253e1.png)

# Linux 用 Windowsサブシステム

WSLの正体ともいえるのでチェックつけてください。

![Linux 用 Windowsサブシステム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/e8586d65-df27-b8ff-f9f3-9806c3515664.png)

# Windows ハイパーバイザー プラットフォーム

調べたところ、他の仮想マシンと同時併用したいならチェックすべき項目らしいですが、WSL2を使用するだけならチェックをしなくても良いと思います。

https://forest.watch.impress.co.jp/docs/news/1255681.html

ちなみにAndroidStudioを使用してる人はここをチェックすることで躓くかもしれないので注意です。
Androidの設定をするわけではないので、今回は詳細を省きます。
（HAXM のサポートを段階的に廃止してるので、今後はチェックついていても問題ないかもしれません。）

https://qiita.com/rice_rice_rice/items/c00f1338b173a149fb28

https://support.google.com/googleplaygamesonpc/answer/11913190?hl=ja

![Windows ハイパーバイザー プラットフォーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/94782599-cea9-de4b-1e31-1e1f61395eb1.png)

# 仮想マシンプラットフォーム

これも初心者トラップですが、仮想マシンプラットフォームは仮想化機能を有効化する場合にチェックつけないといけないみたいです。
ので、チェックつけてください。

https://support.microsoft.com/ja-jp/windows/windows-11-pc-%E3%81%A7%E4%BB%AE%E6%83%B3%E5%8C%96%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B-c5578302-6e43-4b4b-a449-8ced115f58e1

![仮想マシンプラットフォーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733770/899d16f3-28e1-8373-fd85-169659b58c2d.png)

# おわりに

以上です。
基本的には、上記の設定をして、公式の記載通りの手順で実行したらWSL2のインストールはできると考えています。

https://learn.microsoft.com/ja-jp/windows/wsl/install

WSL2のインストール関連のコマンドについては以下にまとめています。

https://qiita.com/fujinninja/items/fbe65f4309a646b10fe7
LINEでiPhoneの録音ファイルが破壊した時の対処法

こんにちは。ともまるです。
私はとある音楽系の団体に所属しておりまして、そこで自団体の練習の録音をLINEで共有することが多くあります。しかしながら、まれにそのファイルが再生できない、開けないという現象に出くわすことがあります。今回はその対処法がわかった（ような気がしたので）自分のためにも備忘録として残します。
大事なことは最後にinfoで書いたのでそこまで飛んでください。

# 事象
- LINE（グループトーク）で録音ファイル（拡張子は```.m4a```）を送信した際に、本来ならばiPhone上でそのまま再生可能なはずだが、以下のような表示になる
- 具体例（再生不可時はタイトルが表示される）
![image.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665880/0c451cfa-0adb-d478-35b8-71555e3d9844.jpeg)
- （参考）正常動作時
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665880/927d730c-0417-31ec-1b85-447061c20353.jpeg)

このままでは音声ファイルがiPhone上で再生できない。

# 原因の切り分け
- ファイルに起因するエラーを疑った 
    - ファイル名に```.```（ドット）を含むことが原因かと考えたが、他の```.```を含むファイルは生きていたので法則は見いだせなかった（でも正直これが原因である可能性が高いと推察した）
    - ファイル名から```.```（ドット）を削除した（効果なし）
    - ファイル名が長かったので単純なものに変えた（効果なし）
    - ファイルのメタデータが破壊しているかを調べた（特に問題はなく、録音した日時や時間は正確に記録されていた）
    - ファイル自体の容量はあった（正常）
- 同じ端末で録音した他のファイルは正常に再生されたので、録音時の端末に依存するエラーではなさそうだと考えた
- 再生環境のエラーを疑った
    - iPhoneではなくPC版LINEから該当データファイルをダウンロードして再生を試みたが、以下のエラーが表示された
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665880/ebdde455-487f-ccf4-4ae5-11b1b7159b91.jpeg)
    - エラーの言うことを聞いて、しばらく待っても状況は変わらなかった
    - エラーコードの意味も調べたが、復元ソフト的なものを使うしかなさそうだった
    - VLC media player で開けるみたいなことが書いてあったのでダメ元でやってみた

# VLC media player で開く
- プログラムから開く→VLCメディアプレイヤー で開いたら、再生された（驚いた）
- ただ、メディア情報を確認するとタイトルが「新規録音2」のままで、LINE上で表示されるタイトルと不一致だった（違和感を覚えた）、やはりメタデータが壊れているのかな？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665880/37f6f2fc-40a0-6241-c867-b1afe57bd446.png)

# VLC media player の変換機能で形式を変える
- 自分の手元の環境では開けるが、これをLINEグループ内の全員聴くことができる形にして共有したい
- このファイルを直接共有しても他のグループメンバーは聴くことができなかった、つまりVLCで開く場合のみ聴けるようだ（のちに分かったのだが、iPhone、Androidを問わずこの録音は聴けないらしい）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665880/6f21d3ed-0c86-7ab5-a737-85934b681500.png)
- とりあえず```.mp3```形式に変換し、変換後のファイルを送ったところ、機種を問わず聴けるようになった

# 原因を考察する（これ一番大切だと思う）
- ファイル名に```.```（ドット）を含んだこと
    - 他の```.```（ドット）を含んだファイルは問題なく再生できたので断言はできない
    - （参考：Yahoo!知恵袋,ファイル名に「.」ドットをいくつ入れても構わないのでしょうか？）https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1023826520
    - （参考：VIT-SHOP,Windowsで使わない方がいい文字？）https://vit-shop-toyama.jp/knowledge14/ 
:::note info 
これらを参照する限りでは、基本的にPC（スマホも然り）等デジタル機器でファイルを管理する際に、ファイル名に```.```（ドット）を含むのはあまりよくないと思います。```.```（ドット）はWindows上でファイルの種類を判別する際に使われるため、Windowsがファイルの種類を正常に判断できなくなる可能性があります。絵文字も含まない方が良い（機種によって表示できない場合にエラーを引き起こす可能性がある）と思います。
:::
- iPhone のボイスメモアプリで収録した後、タイトルを変更して速攻でLINEに送信したこと
    - 内部でタイトルを書き換える処理が完了していない状態で、LINE側に送信された可能性がある 

# おわりに
過去何回か同じような現象に遭遇しましたが、VLC media player で開くという手をなぜか思いつきませんでした。私の場合は過去に同じ事象が起こったファイルに対しても同様の方法で修復（変換）できました。

結局のところ何が悪さしちゃってるのかは断定できませんが、

:::note info
とにかく、ファイルのタイトルに ***「絵文字」*** と ***「```.```（ドット）」*** を ***使わないこと***が大事だと思います！
:::

おしまい！

# 実行環境
- Windows 11
- VLC media player 3.0.20
Python学んでみた　第５回（numpy,Matplotlib）

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
前回の続きです。

https://qiita.com/mr_noppo/items/638136de0dc835e5d561

# 使用したものや事前準備
・Macbook Pro
・Python
・Anaconda
・jupyter notebook


# Python
## numpy
行列操作をおこうなことができるサードパーティのライブラリ。ソースコード内にnpといたらnumpyを指していると思っていい。600を超える関数を揃えている。
特徴は行列操作が速い。行列の入れ替えやスライス、フィルタリングによる抽出もできたりやれることは豊富。
ただ、一回で理解し切れる量ではなかったので省略しています。:sob:
```python
import numpy as np
digits = np.array(range(10))
digits # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```
### 計算
ループ文を使用しなくても全ての値を計算できる
```python
digits # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
digits + 10 # array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
digits + digits # array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
np.sin(digits) # array([ 1. ,  0.54030231, -0.41614684, -0.9899925 , -0.65364362, 0.28366219,  0.96017029,  0.75390225, -0.14550003, -0.91113026])
```

### 配列生成
二次元配列が作成可能。
np.eyeは主対角線（indexが同じ）を1とした二次元配列を生成します。
```python
np.arange(3) # array([0, 1, 2])
np.ones(3) # array([1., 1., 1.])
np.eye(3 ,5)
#array([[1., 0., 0., 0., 0.],
#       [0., 1., 0., 0., 0.],
#       [0., 0., 1., 0., 0.]])
```

### 乱数生成
```python
np.random.random(3) # array([0.30741411, 0.20918913, 0.26900705])
```

## Matplotlib
Pythonでグラフ（折れ線グラフ、散布図、ヒストグラム、棒グラフなど）を描画するためのライブラリ
こちらも省略しています。

```python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.cos(x)
fig = plt.figure() # 描画
ax = fig.add_subplot(221) # 左上
ax2 = fig.add_subplot(222) # 右上
ax.plot(x, y) # 折れ線グラフ生成
ax2.plot(x, y) # 折れ線グラフ生成

plt.savefig('test.png', dpi=300)
```
![スクリーンショット 2024-03-03 22.04.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/741dcced-2d56-a822-c637-65e487681096.png)

![スクリーンショット 2024-03-03 22.05.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/43a6e259-67d8-6a32-7366-f67c2ee7e6ed.png)

![スクリーンショット 2024-03-03 22.06.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/bc36d8a0-3e54-719d-6122-66fb8562b20f.png)


# 最後に
最低限の内容は抑えられたと思いますが、勉強のしがいがあるプログラミング言語だと思いました。ついてけるかは別として、これで仕事できたら楽しそう。:thinking:
ここに書いてあることは感想の部分が多いので興味がある方はぜひ下記のリンクで学んでみてください！

https://opencv.org/university/python-for-beginners/?utm_source=opcv&utm_medium=fcpage&utm_campaign=obc
DrupalのPHPUnit実行方法メモ

コアのUnitテスト実行方法。

```shell-session
$ cd path/to/project_root
$ ./vendor/bin/phpunit -c web/core web/core/modules/system/tests/src/Unit
```

```shell-session:実行結果
PHPUnit 9.6.17 by Sebastian Bergmann and contributors.

Testing /Users/hikarumaruyama/src/github.com/hmaruyama/drupal-exercise-q12024/web/core/modules/system/tests/src/Unit
...............................................................  63 / 113 ( 55%)
..................................................              113 / 113 (100%)

Time: 00:00.423, Memory: 22.00 MB

OK (113 tests, 380 assertions)

Legacy deprecation notices (12)
```


さらに、ddevで実行する方法。

```shell-session
$ ddev exec ./vendor/bin/phpunit -c web/core web/core/modules/system/tests/src/Unit
```

ddevコンテナ内でKernelテストを実行する方法。
まずは web/core/phpunit.xml.dist の内容を web/core/phpunit.xml にコピーする。

```shell-session
$ cp web/core/phpunit.xml.dist web/core/phpunit.xml
```

phpunit.xmlの中身を、`SIMPLETEST_BASE_URL` と `SIMPLETEST_DB` の2箇所書き換える。

```xml:phpunit.xml
    <env name="SIMPLETEST_BASE_URL" value="http://drupal-exercise-q12024.ddev.site"/>
    <env name="SIMPLETEST_DB" value="mysql://db:db@db/db"/>
```

プロジェクトルート直下で、 `ddev exec` を頭につけて実行する。

```shell-session
$ ddev exec ./vendor/bin/phpunit -c web/core web/core/modules/system/tests/src/Kernel
```

実行結果

```shell-session
PHPUnit 9.6.17 by Sebastian Bergmann and contributors.

Testing /var/www/html/web/core/modules/system/tests/src/Kernel
...............................................................  63 / 264 ( 23%)
............................................................... 126 / 264 ( 47%)
............................................................... 189 / 264 ( 71%)
............................................................... 252 / 264 ( 95%)
............                                                    264 / 264 (100%)

Time: 03:36.452, Memory: 16.00 MB

OK (264 tests, 2179 assertions)
```

コントリビュートモジュールも同じ方法でKernelテストを実行できた。

```shell-session
$ ddev exec ./vendor/bin/phpunit -c web/core web/modules/contrib/devel/tests/src/Kernel/
```
AWSにおけるアウトバウンド通信の制御方法

# はじめに
AWSにおけるアウトバウンド通信の制御について、選択肢がどのようなものがあるのかを語っていきます。

# 想定するケース
以下のようなケースを想定します。
IntenetGatewayがVPCにアタッチされており、NATGW経由でインスタンスがインターネット方向にアウトバウンド通信をおこなうケースです。
![スクリーンショット 2023-10-29 21.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/8663896f-b89d-5bae-f0ed-2c57654c0848.png)

# 想定するリスク
このケースに置いて想定するリスクは以下です。
・インスタンスがマルウェア等に感染し、攻撃の踏み台にされる。
・利用者が不特定多数の接続先に接続可能であり、情報漏洩やウイルス感染のリスクがある

# 想定される対策
## SG、NACLによる制御
これは言わずもがなの対策ですが、SG、NACLにより、接続可能なIPアドレスを明示的に許可、拒否すべきものをNACLにて遮断しておく対策です。とはいえ、IPアドレスベースで制御不可能なケースが多く、根本的な対策となるかは状況次第です。
![スクリーンショット 2023-10-29 22.01.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/787a72e1-e657-7eab-5143-56142fba0273.png)

## ホスト型セキュリティ対策ソフトの導入
こちらは説明するまでもないかもしれませんが、接続元となるホスト側にセキュリティ対策ソフトを導入し、アウトバウンド通信の検査を行うパターンです。割りとオーソドックスな方法かもしれませんね。

## プロキシの導入
プロキシサーバを中継として導入し、接続先を管理する方法です。FQDNベースで接続先をコントロールできますし、接続先もログとして残すことができるので、アウトバウンド通信を厳格に管理したい場合によいでしょう。とはいえ、EC2が増えるので、管理コストや拡張性が課題となります。
![スクリーンショット 2023-10-29 22.04.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/cbab160f-328f-40c9-5bad-bc273d8faffe.png)

## DNSFirewallの導入
Route53DNSFirewallを利用するケースです。
通常VPC上で名前解決を実施する場合、Route53Resolverに対して問い合わせが行われますが、そこで、特定のドメインについて許可、拒否などのルールを設定することで名前解決による通信制御を行う事が可能です。また、既知のマルウェアやC&Cサーバの通信先のマネージドルールも用意されており、該当の名前解決をブロックすることが可能です。ただし、IPアドレスが明示的に指定されている場合は、本対策では防ぎようがありません。
![スクリーンショット 2023-10-29 22.09.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/f23422c6-2846-ffc3-d17b-aed1a8ad2790.png)

## NetworkFirewallの導入
NetworkFirewallを導入するケースです。IPS、IDS等の機能やシグニチャベースの評価、IPアドレスの制御、送信先ドメインの制御など多数の機能を持ち合わせています。とはいえ他の対策に比べて費用は高くつきます。
![スクリーンショット 2023-10-29 22.17.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/f6895205-95f9-6e37-295d-867ea2b8af07.png)

# 比較
選択肢を比較してみる以下の通りになります。

| # | 導入サービス | メリット | デメリット |
|---|---|---|---|
| 1 | SG、NACL | 追加のコストがかからない、IPアドレスベースであれば、確実に制御可能 | IPアドレスで制御できない場合意味をなさない |
| 2 | ホスト型セキュリティ対策ソフトの導入  | 比較的簡単に導入可能、マルウェア対策にもなる | 追加のコストがかかる、製品によって制御できる範囲がバラバラ、管理が手間　|
| 3 | プロキシの導入  | URLベースでの制御が可能 | OSの管理コストがかかる、拡張性や可用性を担保する必要がある、インスタンスタイプによってはコストが高い　|
| 4 | DNS Firewall  | 比較的簡単に導入可能、マルウェア対策にもなる、URLベースでの制御が可能、コストが安い | IPアドレスには対応していない　|
| 5 | Network Firewall  | IDS機能や、IPアドレス、ドメインでの制御も可能で高機能 | コストが比較的高い |

# まとめ、結局どれを選べばよいか
まず考えるべきは、どこまでのリスクが発生しうるかかと思います。
例えば、マルウェアに感染するようなケースが想定されるのかというところです。
送信元がコンテナであれば、ReadOnlyとすることで、コンテナの書き込みを拒否することで対策が可能かもしれません。また、EC2であれば、マルウェアが混入しないような使い方（特定の宛先に送信しかしていないなど）をしているケースもあるかもしれません。厳格な権限制御をOS側で導入することも手段の一つです。
このケースにおいては、SGや、NACLなどの標準的な対策でも良いのではないかと思います。
必要に応じてホスト型のセキュリティ対策ソフトと組み合わせるのがよいでしょう。
その他、FQDNのみで制御可能なのであれば、安価なDNSFirewallがおすすめです。
このサービスの利用料は非常に安く、かつマネージドルールにおいて、既知のマルウェア等の通信先をブロックする機能も有しているため、利用を検討するのが良いでしょう。
NetoworkFirewallは非常に高機能ですが、同時に効果なので、IDS等の導入が本当に必要なのか、リスクと費用を考慮し、リスクが許容できないものであれ場導入すべきです。
様々な対策がAWS上では可能ですが、かならず、コストがつきまといます。過剰な対策となっていないかを考慮し、必要な対策を見極めましょう。
OpenShift LocalをベアメタルのRHEL 9.3にインストールする

# OpenShift LocalをベアメタルのRHEL 9.3にインストールする

アプリケーション開発の環境としてOpenShift Localを検証する目的で、まずはベアメタルにインストールしているRHEL 9.3にOpenShift Localをインストールしました。その際の備忘となります。

## 目的
- OpenShift Localを構築する
- リモートのPC/MacからOpenShift Localにアクセスできるようにする

## インストール環境
- ベアメタルのサーバにRHEL 9.3をインストール
    - ベース環境；最小限のインストール
    - 選択した環境用のその他ソフトウェア：標準
- セットアップ時期：2024年2月
- インストール時の注意点
    - パーティションの構成に注意すること。OpenShift LocalはユーザのHomeディレクトリにKVMイメージなどをインストールするため、Homeディレクトリは60GB程度は空けておく必要があります。
- OpenShift Localのバージョン：2.32

## インストール手順
基本はRed Hatのマニュアルで十分です。まずは目を通しましょう。
以下では要点だけ記載します。

https://access.redhat.com/documentation/ja-jp/red_hat_openshift_local/2.32/html/getting_started_guide/installing_red_hat_openshift_local


1. OpenShift Localの最新版をダウンロードする
    ダウンロード先はマニュアル内に記載されていますが、こちら[OpenShift Local](https://console.redhat.com/openshift/create/local)です。

2. ダウンロードしたファイルを展開し所定の場所に設置する
    私の場合は面倒でしたので、既にパスが通っている `/usr/local/bin` にファイルを展開しました。

1. 使用状況データ収集の設定はとりあえず"yes"を選択する
    YesでもNoでもどちらでも良いようです。

1. セットアップコマンドを実行する

    ```
    crc setup
    ```

    マニュアル内ではオプションのプリセットについて解説がありますが、デフォルトで問題ありません。Podmanプリセットは[非推奨](https://access.redhat.com/documentation/ja-jp/red_hat_openshift_local/2.32/html/release_notes_and_known_issues/notable_changes)となりましたので注意してください。

5. OpenShift Localを起動する
起動時に各種ファイルがダウンロードされるので、そこそこ時間がかかります。のんびり待ちます。なお初回起動時はダウンロードしたPull Secretを聞かれるので、オプションで指定しておくとスムーズに進みます。

    ```
    crc start -p pull-secret.txt
    ```

    余談ですが、初期設定では9GBのメモリサイズでインスタンスが起動します。メモリサイズを変更して起動することもできますので、リソースに余裕があれば増やしてみましょう。下記は20GBの例です。

    ```
    crc start --memory 20480
    ```

    CPU、メモリサイズの変更方法はマニュアルでも解説されてますので、参考にしてみてください。

https://access.redhat.com/documentation/ja-jp/red_hat_openshift_local/2.32/html/getting_started_guide/configuring_the_instance

以上で初期インストールはここで完了です。

## リモートからアクセスするためのセットアップ
OpenShift Localはローカル環境で使用することが大前提なので、リモートからアクセスにはちょっとした手間が必要となります。こちらもマニュアルとRed Hatのブログを参考にセットアップしていきます。

### リモートサーバでのOoenSfhit Localの設定
まずはマニュアルに従ってHA ProxyとFirewallの設定を行います。

https://access.redhat.com/documentation/ja-jp/red_hat_openshift_local/2.32/html/getting_started_guide/setting_up_red_hat_openshift_local_on_a_remote_server

### DNSの設定
リモートからアクセスする際にDNSで名前解決できると便利です。
Red Hatのブログが参考になりますので、こちらと同じ対応を行います。
ブログで解説された時期は少し前になりますが、2024年2月時点でも問題ありませんでした。

https://rheb.hatenablog.com/entry/crc_remote_connecting

以上。
これからはOpenShift Localを使ってアプリの開発や各種Operatorの導入とか解説していきたいと思います。
AWS JAM参加のススメ

# はじめに
直近所属企業内でAWS JAMが開催され、参加者の方からの評判が非常に良かったので、今までの自身のAWS JAM参加経験(パブリックな場: 2回, 社内: 1回(運営として))と合わせてAWS JAMの良さについてまとめてみたいと思います。

# そもそもAWS JAMって何？
AWSの公式ブログから抜粋すると、下記のような説明になります。
> AWS のユースケースに沿って用意された様々なテーマの課題 (チャレンジと我々は呼んでいます) を解決していく実践型のイベントで、「AWS を楽しく学ぶ」ことができます。 

引用: [2023 年 AWS Summit Tokyo で実施する AWS Jamのご案内](https://aws.amazon.com/jp/blogs/news/aws-summit-tokyo-2023-aws-jam-intro/)

AWSの学習においては、
+ AWS資格試験の合格を目指す
+ AWSやサードパーティから提供されるトレーニングを受講する

などの方法がありますが、**「楽しく」** 学ぶという観点でいえば、AWS JAMは非常に優れていると感じていますので、次の章で詳しく記載します。

# AWS JAMの楽しい点

私は約3年間AWSの学習を続けてきたのですが、一番楽しいと感じてきたのはAWS JAMでした。
主な楽しいポイントとしては、

### 1\. 謎解きゲームのように楽しめる 
先日社内AWS JAMに参加くださった参加者の方の感想がわかりやすかったので拝借してしまいましたが、与えられた課題に対して、試行錯誤しながら時にはヒントを使って解いていくという感覚を言い表すのに、まさにその通りだなと感じました。
資格試験の勉強やトレーニング受講はインプットとアウトプットという観点だと、どうしてもインプットが多く受動的になりがちだと思うのですが、AWS JAMについてはイベントの性質上アウトプットが多くなり、能動的に学ぶことができるのではないかと感じました。
また、AWS JAMは問題が解けた際にポイントが得られ、そのポイント数の多いチームが優勝というシステムであるため、純粋に一つの勝負として燃える方もいらっしゃるのではないでしょうか。
(イベントによっては、優勝者〜3位までに商品が贈られることもあるため、それ目当てで頑張るという人も多いかと思います!)

### 2\. 同じチームのメンバーとのコミュニケーション
AWS JAMはおおよそ3~4人組でチームを組んで参加することが多いです。チームに対して複数の共通の課題が割り当てられるため、誰がどの問題を解くか、またはメンバーで同じ問題に取り組むかなど、チーム内で戦略を立てる必要があります。
戦略を立てる際、チームでのプログラミングと同様に、下記のような方法を参考にすることができます。
+ ソロ型: チームメンバーがそれぞれ異なる問題に取り組む
+ ペア型: 2人1組で同じ問題に取り組む(4人チームの場合、2組のペアがそれぞれ問題に取り組むイメージ)
+ モブ型: 3人以上が1組になって問題に取り組む（そのうちの一人がAWSコンソール上での作業に取り組む）

ソロ型の場合は、必ずしもコミュニケーションが活発化するわけではないのですが、ペア型・モブ型については必然的にコミュニケーションが発生します。特に、技術的なレベルに差異があるメンバーの組み合わせや、普段関わらないような方（パブリックイベントなど)との組み合わせについては、より多くの学びを得ることができるのではないかと思います。
私が、[AWS re:Invent 2023](https://aws.amazon.com/jp/events/reinvent-2023/)でJAMイベントに参加した際には、私以外のチームメンバーは全員母国語が英語でした。
そんな中でも、AWSを一つの共通言語として一緒の課題に取り組み、問題が解けた時には喜び合うという経験ができたのは非常に貴重な経験でした。
こういった機会が得られたのも、AWS JAMというイベントあってのことだと考えています。

### 3.JAM運営側も学びがある
どちらかといえばパブリックで開催されるイメージの強いAWS JAMですが、実は特定の組織内などでホストすることが可能です。ホストする際にもいくつかのプランがあり、
+ AWSが開催にあたっての司会といった仕切りをやってくれるプラン
+ ライセンスを購入し、自分達で仕切りを行うプラン

などがあります。今回自社で開催されたのは後者のプランだったのですが、私は問題選定やJAM終了後の問題解説などを担当させていただきました。
問題選定するにあたり、参加者の技術や関心に沿った内容としたいと思いつつ、私自身が紹介したいと思っているサービスも取り上げたいといったこともあり、問題選定は正直大変でした。
ただ、実際にJAMを開催してみて参加者の方から、
+ クイズ形式で楽しくAWSを学ぶことができた
+ 知らないサービスに初めて触ることができて良かった

といった感想をいただき、嬉しいと思うとともにもっとAWS技術者を増やす活動をしていきたいという想いを持つことができました。

# まとめ
長々と語ってきましたが、結論としてはAWS JAMはAWSに興味がある人にとって参加して間違いなく損のないイベントです！
パブリックな場でのAWS JAMは非常に人気が高くすぐに席が埋まってしまいますので、興味のある方は開催情報へのアンテナを張り巡らせておいてください。
もし、パブリックな場でのJAMに参加するのはちょっと・・・という方には、[AWS Skill Builder](https://aws.amazon.com/jp/training/digital/)の個人サブスクリプションを利用するのも一つの手です。
AWS Skill Builderには様々な学習コンテンツがありますが、その中に**AWS Jam Journey**というコンテンツがあります。これは個人でJAMを体験することができ、JAMのイメージを掴むのはもちろんのこと、純粋な学習コンテンツとしても使えます。
様々な形でAWS JAMを楽しんでいただき、より良いAWSライフに繋げていっていただければ幸いです。
npx expo start で 開発サーバー起動してもQRコード表示されないんだけど！？と嘆いてる貴方へ【ReactNativeExpo】

# 問題
コマンド実行してもURLしかでないし
アクセスしてもアプリ動かない...

# 解決方法
非対話モードのシェル(バッシュ)を使っていませんか？
対話モードのシェル(バッシュ)を使用することで解決すると思いますよ！


# 終わりに
vscodeでコマンド打ってたら発生しえない問題だったなぁ。。
gitbashでコマンド打つ癖あったから矯正しようと思いました
Lightsail のデータベースにおける MySQL 5.7 のサポート期限


## 前提
[**公式ドキュメント**](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/extended-support.html)によると、RDS for MySQL 5.7 のサポートは`2024 年 2 月 29 日`に終了しています。


## 解決したいこと
Lightsail のデータベースのおける MySQL 5.7 のサポートの期限を知りたい。


## 調査結果

Lightsail のデータベース作成時の画面に`2024 年 6 月 30 日`と表示されていました。

![recommend-menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/d01c7540-995e-9350-72d2-07c3e84d4093.png)

:::note info
2024年3月6日 追記
公式ドキュメントのリンクを追加しました。[2]
:::

### 英語部分
>Starting June 30, 2024, Lightsail will no longer support MySQL 5.7, and you will not be able to create new databases with this blueprint. For more information about this change—and to learn how you can upgrade major versions, see Choose a Lightsail database .


### 英語部分を一部抜粋し日本語化
>2024年6月30日以降、LightsailはMySQL 5.7をサポートしなくなり、このブループリントで新しいデータベースを作成できなくなります。

## 参考資料
- [1] [Amazon RDS 延長サポートの使用 - Amazon Relational Database Service](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/extended-support.html)
- [2] [Lightsail データベースを選択する - Amazon Lightsail](https://docs.aws.amazon.com/ja_jp/lightsail/latest/userguide/amazon-lightsail-choosing-a-database.html)
【小ネタ】p5.js（バージョン 1.9.1）で createCapture() を使う際に左右反転を簡単に適用する方法： { flipped:true }

p5.js公式の以下のページを見ていたときに、ふと見かけてきになった内容を記事にしてみました。

●reference | createCapture()
　https://p5js.org/reference/#/p5/createCapture

具体的には、以下の `createCapture(VIDEO, { flipped: true })` という部分です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/80183480-5e17-281f-3a6f-afc913ed9e8a.png)

上記の公式サンプルのページに書かれていた内容を、p5.js Web Editor で以下の内容にして実行してみたら、左右反転が適用されたのを確認できました。

```javascript
let capture;

function setup() {
  createCanvas(640, 480);
  capture = createCapture(VIDEO, { flipped: true }); // 左右反転の指定が簡単に
  capture.hide();
}

function draw() {
  image(capture, 0, 0);
}
```

詳細は以下に書いていきますが、どうやら記事執筆時点での最新バージョン「1.9.1」で実装された新機能のようでした。
※ 記事執筆時点で、p5.js Web Editor においてスケッチの新規作成を行うと、「{ flipped:true }」に対応した最新版の 1.9.1 が使われるようになっていました

## これまでのやり方の 1つ
p5.js のバージョン 1.9.0 までで、createCapture() で得られた画像を左右反転させる場合、それを実現する方法の　1つは、以下がありました。

```javascript
  push();
  translate(width, 0);
  scale(-1, 1);
  image(capture, 0, 0);
  pop();
```

コードの見た目的には、少しトリッキーな感じがするかな、とも思うものです。
そういったトリッキーさはありつつも便利に使えるものだったので、自分も活用していました。

## 今回の内容が実装された流れ
今回の `{ flipped:true }` を指定する方法は、これまで見かけなかった気がするので、いつから使えるようになったものか検索して調べてみました。

そうすると、具体的に以下でやりとりが行われていたのを発見できました。

●Support mirrored video for createCapture · Issue #6441 · processing/p5.js
　https://github.com/processing/p5.js/issues/6441

### 実装要望の部分
2023/9/29 に、簡単に左右反転を指定できるようなやり方を追加できないか、という要望が出されたようでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e38ded2e-e23e-b0fd-5e7d-3aa1dc2ba990.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b69dd334-e340-7c69-5e57-04166b3b359d.png)

### 実装完了という話
そして、上記のやりとりの最後の部分を見てみると、記事執筆時点から 2日前のタイムスタンプの投稿で、1.9.1 でリリースしたという話が書いてありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/aac27d12-bbbb-ac28-2bc1-e8978d1c07b3.png)
初学者向け、JWTの基本構造

# はじめに
今回は数ある認証の中でも広く使用されているJWT認証について、初学者が学習した内容をまとめました。

間違いなどもあるかもしれませんので、もしお気づきの点がありましたらご指摘頂ければ幸いです。

# JWT認証とは
ログイン機能として必須な機能、***システムがユーザーの身元を確認するプロセス***。
それが***認証***です。

具体的には
1.  ユーザーがログイン
2.  サーバーでの照合、認証
3.  認証後、JWTが生成され、***ユーザーのブラウザに保存***
4.  その後、ユーザーが保護されたリソースへのアクセスを要求するたびに、クライアントはリクエストと共にJWTをサーバーに送信し、JWTの検証を行います。

JWT（JSON Web Token）とは、JSONオブジェクトを用いて、二者間で情報を安全に伝達するためのコンパクトで自己完結型の方法です。

認証や情報交換によく使用され、署名されているため、内容が信頼できることが保証されます。

JWTは ' . ' (コンマ)で区切られた3つの部分から構成されており、それぞれ
* ***ヘッダー(Header)***
* ***ペイロード (Payload)***
* ***シグネチャー(Signature)***

の3部分から構成されています。

これら3つの部分をコンマで連結したものが、完全なJWTです。
以下のようになります。

```json
xxxxx.yyyyy.zzzzz
```
xはヘッダー、yはペイロード、zはシグネチャーをBase64Urlエンコードされた値です。

JWTを使用することで、安全に情報を交換することができ、特にWebアプリケーションやAPI間での認証情報のやり取りに有効です。
# 各部分の目的と役割

## ヘッダー(Header)
ヘッダーは、JWTのどの形式を使用してトークンをエンコードするかを指定する部分です。
ヘッダーは、
* ***トークンのタイプ（typ）、通常はJWT***
* ***使用される署名アルゴリズム（alg）、例えばHMAC SHA256やRSAなど***

上記の2つの部分から構成されます。

## ペイロード(Payload)
ペイロード(荷物)部分には、トークンに関する「クレーム」(主張)が含まれます。
クレームは、エンティティ（例えば、ユーザー情報）や追加のデータに関するステートメントです。

クレームには、

* ***登録済みClaims***
事前に定義されたクレームで、JWTの処理方法を提供します。
例えば、iss（発行者）、exp（有効期限）、sub（主題）、などがあります。
* ***公開Claims***
衝突を避けるためにIANA JSON Web Token Registryに登録されるか、URI形式で名前空間を持つクレームです。
これらは、共有情報を伝達するために公開的に使用されます。
* ***プライベートClaims***
トークンの作成者と消費者の間で合意されたクレームです。
特定のアプリケーション固有の情報を伝達するために使用され、他のどのトークンとも衝突しないために一意な名前を持つべきクレームです。

## シグネチャー(Signature)
シグネチャー部分は、メッセージが途中で改ざんされていないことを保証するためのものです。

ヘッダーのエンコードされた値、ペイロードのエンコードされた値、秘密鍵（または公開鍵/秘密鍵ペアの場合は秘密鍵）、およびヘッダーで指定されたアルゴリズムを使用して生成されます。
トークンの最後の部分を形成し、トークンの改ざんを防ぎます。

# JWT認証のメリット、デメリット
## メリット
1. ***ステートレス認証***
JWTは自己完結型で、トークン自体が必要なすべての情報を持っています。
これにより、サーバー側でユーザーの状態を保持する必要がなくなり、拡張性が向上します。

2. ***分散システムでの利便性***
分散システムやマイクロサービスアーキテクチャでは、異なるサービス間でユーザー認証情報を共有する必要があります。
JWTは簡単に他のサービスと共有でき、各サービスで個別にユーザーを認証する必要をなくします。

3. ***クロスオリジン認証が容易***
JWTはクロスオリジンリクエストに適しており、異なるドメイン間で安全に認証情報を交換できます。

4. ***パフォーマンスの向上***
セッションベースの認証と比較して、JWTはサーバーのリソースを節約でき、より良いパフォーマンスを提供します。

## デメリット
1. ***トークンの盗難リスク***
JWTが盗まれると、有効期限が切れるまで攻撃者によって悪用される可能性があります。
これを防ぐために、HTTPSを使用して通信を暗号化する、トークンの有効期限を短くするなどの対策が必要です。
2. ***トークンのサイズ***
JWTはセッションIDよりも大きくなることが多く、特に多くのクレームを含む場合は、ネットワークのオーバーヘッドが増加します。
3. ***トークンの失効管理***
一度発行されたJWTは、有効期限が切れるまで有効です。
即時に無効化する標準的な方法がないため、トークンの悪用を防ぐためには追加の仕組みが必要になることがあります。
# まとめ
メリットとして書いたように、JWTの利点はその自己完結性にあり、その汎用性と拡張性から広く利用されています。

しかしその分、悪意ある他者にトークンを利用された場合は容易になりすます事が可能です。
安全性に注意し、対策を講じる必要があります。



JWTの「なりすまし」攻撃対策として、トークンのデコード方法について理解することも重要です。

個人的に　***[JWT.io](https://jwt.io/)***　というサイトがJWT認証の理解を深める手助けになると思います。

JWT.ioでは、エンコードされたJWTを入力することで、そのヘッダー、ペイロード、および署名を可視化することができます。

もしJWT認証に興味を持たれたら、ぜひ触ってみてください。
jotaiを使ってみたメモ1【基本の使い方・SWRとの連携】

Recoilからjotaiに移行してしばらく経ったのでメモとして残しておきます。

## 基本的な使用方法

```ts
// 元となるatomの宣言。このままexportはしないほうがいい？
const counterState = atom(0);

// get専用のatom
export const getCounterState = atom((get) => {
    return get(counterState);
});

// 使う時 
cosnt counter = useAtomValue(getCounterState);

// set専用のatom
export const incrementAtom = atom(null, (get, set) => {
    const current = get(counterState);
    set(counterState, current + 1);
});

// 使う時 
const increment = useSetAtom(incrementAtom); 

// getとset両方を使うatom
export const counterAtom = atom(
    (get) => {
        return get(counterState);
    },
    (_, set, newValue: number) => {
        set(counterState, newValue);
    }
);

// 使う時 
const [counter, setCounter] = useAtom(counterAtom);

```

## SWRとの連携、urlのStateをjotaiに持たせる

```ts

const swrFetcher = async (url: string) => {
    return axois.get(url).then((response) => {
        return response.data;
    });
};

// 
export const urlAtom = atom((get) => {
    // 元となるurl
    const baseUrl = get(baseUrl);
    const parameter = get(parameterAtom);

    const newUrl = `${baseUrl}?parameter=${parameter}`
    return newUrl;
});

const useFetch = () => {
    const url = useAtomValue(urlAtom);

    useEffect(() => {
        mutate("fecthUrl");
    }, [url]);

    const { isLoading, error } = useSWR(
        "fecthUrl",
        () => {
            return swrFetcher(url);
        },
        {
            onSuccess: (data) => {
                console.log(data)
            },
        }
    );

    return {
        data,
        isLoading,
        error
     };
};
```

このように書けば、`parameter`の値が変更された時、`parameterAtom`に依存している`urlAtom`が自動で再計算され、`mutate（）`が発火することによりSWRの再検証が行われる、という流れが実現できる。

このような処理はRecoilではselectorを用いるのが普通？だったが、jotaiにはそのような機能がない(selectAtomという機能はあるが基本的には非推奨)のでこのような形で処理を書く。

まだまだ使いこなせてない感があるので、また新しい知見が得られれば記事として残します。