OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon RDS

## はじめに

この記事はAWS SAA試験勉強のための、Amazon RDSに関する知識のまとめです。


## Amazon RDSとは

Amazon RDS(Amazon Relational Database Service)はAWS上で提供しているリレーショナルデータベースです。オンプレミスでデータベースサーバを構築する際に必要となるサーバの購入・設定、OSのインストールなどの煩雑な作業をすることなく、利用契約後すぐにデータベース構築が可能です。


## DBインスタンス

DBインスタンスとはRDSで作成するデータベースサーバーのことです。
リレーショナルデータベースのセットアップ、 運用、拡張を**容易にします**。
パッチ当てはAWS側が実施します。







## セキュリティ

### 暗号化
Amazon RDSの暗号化はオプション設定となっており、DBインスタンスを起動する際にユーザー側で暗号化を有効化する必要があります。

暗号化されているデータベースから生成される**スナップショットは自動的に暗号化**されています。

### アクセス制御

- EC２インスタンスなどのAWSリソースはIAM ユーザーまたはIAMロールの認証情報と認証トークンを使用して、RDS DB インスタンスまたはクラスターに接続することができます。


- RDSではインスタンスにSSHすることができません。その代わりにパラメータグループという機能を利用してチューニングを行います。

- **RDSはファイルシステムへのアクセスがサポートされていない**ため、ファイルシステムへのアクセスに基づく設定や自社管理を実現するためには、EC2インスタンスにデータベースをインストールしてデータベースサーバーをカスタムで構築する必要があります。



## Amazon RDSリードレプリカ
Amazon RDS <font color="red">**Read**</font> Replicaであり、Lead Replicaではありません。 
すなわちリードレプリカとは読み取り専用のDBのことです。 アクセス数が多くDBに読み取り負荷が起きている場合などは、リードレプリカを構築することでプライマリデータベースへの負荷を分散することができます。 

マルチAZ構成との違いは、リードレプリカへのデータ更新は非同期で行われる点です。リードレプリカは非同期的にレプリケートされる個別のデータベースインスタンスであるため、 レプリケーションデータが遅れることがあり、最新のトランザクションのいくつかが表示できない可能性があります。これを**レプリケーションラグ**といいます。

別リージョンに起動可能なRDSの唯一のグローバル機能です。

リードレプリカはRDS for MySQL, MariaDB, PostgreSQL, Oracle, Auroraで利用できます。

### AWS CLIを使用してRDSのリードレプリカを読み取る

```
aws rds describe-db-instances --db-instance-identifier <リードレプリカの識別子>
```

## [インスタンスタイプ](https://aws.amazon.com/jp/rds/instance-types/)

EC2のインスタンスタイプの前にdb2をつけます。

### db.m5d
db.m5d は高性能なデータベースアプリケーションに適したインスタンスタイプであり、メモリとストレージが重視されるワークロードに最適です。
低レイテンシー、非常に高いランダム I/O パフォーマンス、高いシーケンシャル読み取りスループットに向けて最適化された汎用インスタンスクラスで、このDBインスタンスにこのクラスを利用することで**ランダムI/O遅延が発生しない**パフォーマンスを発揮できます。





## マルチAZ配置機能

RDSのプライマリデータベースが応答しない場合に自動フェールオーバーを実行する機能。
フェイルオーバーが実行されると、Amazon RDSはDBインスタンスのCNAMEレコードをプライマリーからセカンダリーに切り替え、セカンダリーを新しいプライマリに昇格させます。
RDSのマルチAZ構成はバックアップからRDSを複製する必要はありません。

Amazon RDS MySQLをマルチAZ配置にしても、セカンダリーDBはアクティブに利用できないため、**読み取りトラフィックと書き込みトラフィックを分離することができません。**

RDSにオラクルデータベースタイプのインスタンスを起動して、マルチAZを構成すると、データベースサーバーに障害が発生した場合でもWebサイトの可用性を高めることが可能です。


## マルチAZ DBクラスター

Amazon RDSのマルチAZ DBクラスターは、マルチAZ構成の新しい高可用性オプションです。従来のマルチAZ構成とは異なり、3つのアベイラビリティゾーンにまたがって配置されるため、可用性がさらに強化されています。


## 拡張モニタリング

Amazon RDSのDBインスタンス上のさまざまなプロセスまたはスレッドにおけるメモリ状況を**常時モニタリングする**ためには、RDSの拡張モニタリングを有効化することが必要です。

## RDS Proxy

アプリケーションとRDSデータベースの間の仲介役として機能します。
Lambda関数とRDS Proxyを連携させると、LambdaはDBインスタンスのエンドポイントに直接接続するのではなく、RDS Proxyを介してデータベースとの接続を実施し、<font color="red">**コネクション過負荷の課題を軽減**</font>できます。

## DBインスタンスの停止
DBインスタンスの停止には、次のような制約事項があります。
- リードレプリカが含まれているか、リードレプリカであるDBインスタンスは停止できません。
- マルチAZ設定のAmazon RDS for SQL Server DBインスタンスは停止できません。
- 停止されたDBインスタンスを変更することはできません。

## シャーディング

シャーディングはデータベース内の複数のテーブルにデータを分割するための一般的な概念です。リクエスト増加などで単一のマスターDBの運用で限界がある場合に、 一定のルールに従いデータを複数のDBに振り分けることでアクセスを分散させることができます。 

## パラメータグループとオプショングループ

Amazon RDSにおいてタイムゾーンや最大接続数、監査ログの有効化などデータベースの設定を変更したい場合は、「DBパラメータグループ（DBクラスターパラメータグループ）」または「オプショングループ」で定義します。
xcodeからGit連携時に"Failed to load repository owners"エラーが出る

# やりたいこと
以下画像のエラーを解決する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645607/6d4b9d40-bf74-e1d4-791e-f3ff72ed42c8.png)

IOS開発時にXcodeからGithubへリモートリポジトリ作成などをしていた。
その際に発生したエラーの対応をしていく。

# 対応策
以下記事を参考にすると良い。
>https://zenn.dev/umas/articles/09dff47d5be757
【RubyOnRails】モーダル実装時の考えをなぞる #初心者向け

# 概要
モーダル実装時に考えたことをなぞり、思考回路を文章化しました。

# 対象者
- モーダルを見たことがあり、モーダルのイメージが湧く。
- ボタンをクリックした後に表示するモーダルを作成したいと思っている。
- 実際の実装方法がわからない。

# 作りたいモーダル
1. ボタンをクリックした後に、モーダルが表示される。
2. 表示されたモーダルには、説明文がある。

## 1. 導線

モーダル作成を考えるときに、まず初めに思い浮かべることは【導線】です。

モーダルはページ遷移を伴いませんが、新しいViewが必要になることが予測されます。

また、Viewを表示するためには **アレ** を準備する必要があります。

:::note
route.rb の中にルート（導線）を書きましょう。
:::


## 2. アクション
ルート（導線）が準備できたら  **アレ** を準備する必要があります。

controllerの中にアクションを書きましょう。

アクション名はモーダル内容によって命名してください。

またルート（導線）とアクションを作成した後は、```binding.pry``` で動作確認しましょう。

:::note
XXXX_controller.rb の中にアクションを書きましょう。
:::

## 3. 表示
ルート（導線）とアクションの準備できたら、次に **アレ** を準備する必要があります。

ユーザーが目にすることになるHTML（Viewファイル）です。

ボタンをクリックして、表示されるべき内容を書きます。

内部的には、ルート（導線）とアクションを経由して、表示されるべき内容を書きます。


:::note
_modal.html.slim を作成して説明文を書きましょう。
:::

## 4. モーダル特有
モーダル特有の動きは **ページ遷移を伴わない** ことです。

実現するには、JS（javascript）の P（Power）が不可欠です。



:::note
アクション名.js.erb を作成して render しましょう。
:::

# 一言
人類（Rails）は **MVCモデル** に支配されていることを忘れない。
書籍『Pythonでスラスラわかる ベイズ推論「超」入門』潜在変数モデル補足

## はじめに
書籍『Pythonでスラスラわかる ベイズ推論「超」入門』著者です。
読者からいただいた質問のうち、実装コード付きで示した方がいいものがあったので、この場で解説をしたいと思います。
なお、当記事は、書籍で説明している概念については、すべてわかっている前提で記載しています。わからない部分はすべて書籍内に説明がありますので、関心を持たれた読者は是非、本編の書籍もお買い求めいただけるとありがたいです。
書籍サポートサイトのリンクは下記になります。
https://bit.ly/3uV4i3R

## いただいた質問と直接の回答
いただいた質問は、5.4節　潜在変数モデルの実習コードに対するものです。
以下のコードはサポートサイト上にもアップしておきました。
https://bit.ly/3vjwY6M

潜在変数モデルでは、特別な工夫をしないと「ラベルスイッチ」と呼ばれる事象が発生します。
その対策として、書籍内の実習コードではサンプリング関数呼び出し時に``chains=1``のパラメータを付け、ラベルスイッチが起きない工夫をしています。

```
with model1:
    idata1 = pm.sample(chains=1, draws=2000, target_accept=0.99,
      random_seed=42)
```

読者からいただいた質問の内容としては、下記のようにchainsとdrawsのパラメータを落としてサンプリングをしたが(この呼び出し方をするとchains=2, draws=1000を指定するのと同じになります)、ラベルスイッチは特に起きていないように見える。これはどうしてかというものでした。

```
with model1:
    idata1_1 = pm.sample(target_accept=0.99, random_seed=42)
```

```
az.plot_trace(idata1_2, var_names=['p', 'mus', 'sigmas'], compact=False)
plt.tight_layout();
```

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/f7fef38d-8848-c5e1-be5d-075caf16fd77.png' width=800>

質問に直接答えると、ここで起きている事象は読者の指摘のとおりで、このパラメータの組み合わせの場合、ラベルスイッチは起きていません。
２つのchainでラベルスイッチが起きるかどうかは、ほぼ確率1/2です。このパラメータの場合、たまたまラベルスイッチが起きないパラメータの組み合わせだったということができます。

## 発展的な実験

質問への回答という意味では以上で終わっているのですが、この話はより発展的な話をいろいろと含んでいます。
それを試すために次のようなパラメータでサンプリングをしてみます。

```
with model1:
    idata1_2 = pm.sample(target_accept=0.99, chains=5, random_seed=42)
```

上のサンプリングと比較すると、chainsの値だけ2から5に変更し、残りのパラメータはまったく同一です。

5つのchainのグラフを同時に表示するとわかりにくいので、chainの値でフィルターをかけて、[0, 1], [2], [3, 4]の３つのグループで分けてグラフ表示してみます。

### [0, 1]のグループ
chainでフィルターをかけたい場合、``coords={"chain": [0, 1]}``のようなパラメータを追加します。
結果は、一つ上のグラフとまったく同一になります。

```
# 最初の２つのchainのみ抽出
az.plot_trace(idata1_2, var_names=['p', 'mus', 'sigmas'], 
 coords={"chain": [0, 1]}, compact=False)
plt.tight_layout();
```

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/f7fef38d-8848-c5e1-be5d-075caf16fd77.png' width=800>


### [2]のグループ
では、その次のchainはどのようなことになっているでしょうか。

```
3番目のchainのみ抽出
az.plot_trace(idata1_2, var_names=['p', 'mus', 'sigmas'], coords={"chain": [2]}, compact=False)
plt.tight_layout();
```

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/27d8883b-af54-5650-6860-d34e6943280e.png' width=800>

面白い結果になりました。右下のmus1のグラフが一番わかりやすいので、それを使って解説すると、繰り返し回数200までは、おおよそ1.5程度の値だったのが、400回以降では2.0程度の値に変わっています。
つまり、このchainでは１回のchain内でラベルスイッチが発生したということになります。

### [3, 4]のグループ

最後は[3, 4]のグループです。前と同様に実装コードと結果グラフを示します。

```
# 最後の２つのchainのみ抽出
az.plot_trace(idata1_2, var_names=['p', 'mus', 'sigmas'], 
　　coords={"chain": [3, 4]}, compact=False)
plt.tight_layout();
```
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/938d5ea3-7719-4e3a-11dc-7a0f06c57a49.png' width=800>

この２回分だけ見るとラベルスイッチはないのですが、２つ前のグラフを比較するとmus0とmus1の値の傾向がまったく逆になっていることがわかります。
これがラベルスイッチの事象ということになります。
【Unity】ChatGPTでは解決しないエラー "you have switched active Input handling to Input System package in Player Settings" 

## まえがき

スクリプトとエラーメッセージを見せれば、大抵の問題は解決できるChatGPTだが、たまに壁に当たることがある。

今回がそのパターンで、以下のエラーメッセージに対して、ChatGPTは歯が立たなかった。

:::note alert
コンソール
InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System package in Player Settings.
UnityEngine.Input.GetKeyDown (UnityEngine.KeyCode key) (略)
yyy.Update () (at Assets/Scripts/xxxScene/yyy.cs:104)
:::

これは、UnityでOpenXR開発をしていて、キーボード入力を追加しようとしたときに吐いたエラー。

## 解決方法

入力に使うInput ManagerとInput System Packageが混在していると起きるようだ。

理想は新しいInput System Packageで全て書くことかもしれないが、面倒なので、以下の設定をして、両方対応させた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638306/fd363bc4-7fc3-9e48-48c8-4493dc18580a.png)

プロジェクトセッティング→プレイヤー→Active Input Handingを選択。

ここをBoth（両方）に変更すると、どちらも使えるようになる。尚、この時にプロジェクトが再起動するので注意。
raspberrypiでapt updateしたときErr:6 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic Release 404 Not Found となる場合


# はじめに
raspberry pi (debian)でupdateを行おうとしたときに，
```Err:6 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic Release 404 Not Found```
と出たので，解決方法を備忘録として上げておきます．debian,ubuntuなら同様の方法で解決出来ると思われます．

# 環境
- raspberry pi 4 
- NAME="Debian GNU/Linux"
- VERSION_ID="11"
- VERSION="11 (bullseye)"

# エラー
```zsh
Hit:1 http://security.debian.org/debian-security bullseye-security InRelease
Hit:2 http://deb.debian.org/debian bullseye InRelease
Hit:3 http://deb.debian.org/debian bullseye-updates InRelease
Ign:4 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic InRelease
Hit:5 http://archive.raspberrypi.org/debian bullseye InRelease
Err:6 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic Release
  404  Not Found [IP: 2620:2d:4000:1::81 80]
Reading package lists... Done
E: The repository 'http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
```

# 対策
```/etc/apt/sources.list.d/```内にある```deadsnakes-ubuntu-ppa-mantic.list```の```deadsnakes-ubuntu-ppa-mantic.list```をコメントアウトしてあげれば，これを無視してupdateが行われる.
- 好きなエディタでファイルを開く(例はnanoを使用)
```zsh
sudo nano /etc/apt/sources.list.d/deadsnakes-ubuntu-ppa-mantic.list
```
- 開いたファイルの以下の行をコメントアウト

```zsh
deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic main
```
↓
```zsh
# deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu mantic main
```
- もう一度アップデートコマンドを入力
```zsh
sudo apt update
```

# 終わりに
同様に困っている方がいたら参考にしてください．間違えなどありましたら，教えていただけるとありがたいです．
【C#】配列の初期化


# 概要

C#での配列（一部 List）の初期化方法や要素アクセス等に関するメモ書き
出来るだけ分かりやすい方法

# 0. new でのデフォルト値による方法

"new 型[要素数]"で空の配列を作成すると
オブジェクト型 → デフォルト値に変数が初期化される

```cs:test.cs
int[] array1 = new int[5];
float[,] array2 = new float[3,8];

// これはエラー．初期化時に要素数を指定する必要がある．
int[] array3 = new int[]; // CS1586
float[,] array4 = new float[,]; // CS1586
```

# 1. 要素を代入する方法 (手書き)

```cs
// 1次元配列
int[] array1 = new int[] { 2, 4, 6, 8, 10, };
// 2次元配列
int[,] array2 = new int[,] { { 1, 2 },{ 3, 4 },{ 5, 6 }, };

// new式と型は省略可能 ．
int[] array3 = { 2, 4, 6, 8, 10 };
```

# 2. for 文で回す方法 (力技)

初心者にも分かりやすく代入値も簡単に編集可能だが，いちいち for 文を書くのはめんどくさい

```cs
int[] array = new int[5];
for(i=0; i<intArray.Length; ++i) {
    array[i] = 1; // 同じ値で初期化
    array[i] = i; // 連続した値で初期化
}
```

# 3. LINQ による方法

```cs
int[] array1 = Enumerable.Repeat(1,5).ToArray(); // 同じ値で初期化
int[] array2 = Enumerable.Range(1,5).ToArray();  // 連続した値で初期化

float[] array3 = Enumerable.Range(1,5)
                .Select(x => x*0.1f)  // 任意の値に変更
                .ToArray();
```
学校配布端末でYoutubeみる方法(2024年1月7日時点)

皆さん、学校から配布されてる端末(Chromebook、iPad等)でYoutubeを見たいと思ったこと、ありますよね？(問答無用)なので、今回は、そんな少年少女(お前が言うか)のために、Youtubeを見る方法を教えていきたいと思います！！
ちなみに、筆者の環境は以下のとおりです。

・ASUS Chromebook Flip C214MA
・ロイロWebフィルター
・ドメイン管理済み(Gmailなどはブロックされる。)

ではでは早速Youtubeに飛んでいきます！

①ブラウザを開く
②https://www.croxyproxy.com/_ja#google_vignette に飛ぶ
(ここの時点でプロキシ回避と言われブロックされてしまった勇者よ、、、南無南無)
③Youtubeのリンクをコピペし、「飛ぶ！」をクリック

そうすると、フランスのIPアドレスに飛ばされ、Youtubeが見れるようになります！
ここでの注意点は以下のとおりです！

・前述した通り、フランスに飛ばされるため、Youtubeの初期候補はフランスの動画
・Googleアカウントにはログインできない(メアド、パスワードが盗まれない保証はない)
・課金しないと、リンクを踏んだときによくわからん広告に飛ばされる

です！文章だけでは分かりにくかったと思うので、以下のリンクから動画見てってください！
https://drive.google.com/file/d/1nOoEfyBVlEtB6RfitUKQfeLfneQw54fP/view?usp=sharing
mindの研究 その66

# 概要
mindが、謎なので調べてみた。
vbsの力を借りて、mdbを叩いてみた。

# 環境
- windows11
- mind 8.07
- office 2007


# サンプルコード

```

出力ファイルは　ファイル。
エラー検査は
　エラー？　ならば
　　エラー文字列で　重大エラー
　つぎに
　。

メインとは
　「db.vbs」で　出力ファイルを　新規オープンし　エラー検査し
　「Set db = CreateObject("ADODB.Connection")」で　出力ファイルに　一行書き込み　エラー検査し
　「db.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\pmind\db1.mdb"」で　出力ファイルに　一行書き込み　エラー検査し
　「sql = "SELECT * FROM blog_data"」で　出力ファイルに　一行書き込み　エラー検査し
　「Set rs = db.Execute(sql)」で　出力ファイルに　一行書き込み　エラー検査し
　「Do Until rs.EOF」で　出力ファイルに　一行書き込み　エラー検査し
　「    WScript.Echo "id: " && rs(0) && " title: " && rs(1) && " body: " && rs(2) && " modified: " && rs(3)」で　出力ファイルに　一行書き込み　エラー検査し
　「    rs.MoveNext」で　出力ファイルに　一行書き込み　エラー検査し
　「Loop」で　出力ファイルに　一行書き込み　エラー検査し
　出力ファイルを　クローズし　エラー検査し
　「C:\Windows\SysWOW64\CScript.exe db.vbs」を　プログラム実行
。


```

# 実行結果

```
>mdb0
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

id: 1 title: test body: test modified: 2024/01/07 9:00:08

```


以上。
JWTってなんぞ?

先日、[「世界最悪のログイン処理コード」を解説してみた](https://qiita.com/YSRKEN/items/0095cf75be3f607b0f98) という記事を読んだのですが、そこに次のようなことが書いてありました。

> ちなみに真っ当なログイン処理の場合、書き込む情報をランダムなログインIDにしたりJSON Web Token(JWT)にしたりします。
> 

自分もちょうどログイン処理を作成していて、JWTは初見だったので調べたことを備忘録としてまとめておきます。

# JWT とは

JavaScript Object Notation Web Token ⇒ JSON Web Token ⇒ JWT で「ジョット」と読む。

IT用語辞典には、以下のようにまとめられている。

> JWT（JSON Web Token）とは、JSON形式で表現された認証情報などをURL文字列などとして安全に送受信できるよう、符号化やデジタル署名の仕組みを規定した標準規格。IETFによってRFC 7519として標準化されている。
> 

# JWT の構造

構造についてIT用語辞典では、次のように説明されています。

> ヘッダー（header）、ペイロード（payload）、署名（signature）の3つの部分に分かれており、これらをそれぞれBase64URL（Base64をURLパラメータ仕様に適合させたもの）方式で符号化して「.」（ピリオド）で連結したものがトークンとなる。
> 

そこで、JWTのデバッグができるサイト ([jwt.io](https://jwt.io/)) で作成したデータを基に、その構造を見てみます。

```jsx
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

```

たしかに、3つの文がピリオド「.」で結合された構造になっています。3つの文章は上から順に「ヘッダー」、「ペイロード」、「署名」となっています。

## ヘッダー部分

ヘッダーは、署名のハッシュ値を計算するアルゴリズム `alg` とトークンタイプ `typ` を設定します。

```jsx
{
	"alg": "HS256",
	"typ": "JWT"
}

```

上記の場合は、ハッシュ値計算にHMAC SHA-256を使用、トークンタイプはJWTに設定されている。

ハッシュ値計算は、HS256以外にもHS512, RS256などが使用できる。

## ペイロード部分

やり取りするデータ本体を入れる場所。クレームデータとも呼ばれ、規格上で意味が定められている「登録済みクレーム」以外に自分で任意のプロパティを含ませることもできる。

```jsx
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}

```

name, admin は自分で追加したプロパティ。

登録済みクレームの名前と意味は以下の通りです (詳細は[こちら](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1)) 。

| クレーム |  | 概要 | 型 |
| --- | --- | --- | --- |
| iss | Issuer | JWT発行者の識別子 | String or URI |
| sub | SubJect | 主体に関する記述 | String or URI |
| aud | Audience | JWT受信者の識別子 | String or URI |
| exp | Expiration Time | トークンの有効期限 | 1970-01-01 00:00:00Zからの秒数を数値(IntDate)で指定 |
| nbf | Not Before | このプロパティで設定した日時以降にJWT処理が可能になる | 1970-01-01 00:00:00Zからの秒数を数値(IntDate)で指定 |
| iat | Issued At | JWT発行日時。 | 1970-01-01 00:00:00Zからの秒数を数値(IntDate)で指定 |
| jti | JWT ID | JWTのための一意(ユニーク)な識別子。重複が起きないように割り当てる必要がある。 | 大文字と小文字を区別する文字列 |

## 署名

```jsx
data = Base64URLEncode( header ) + ‘.’ + Base64URLEncode( payload )
signature = Hash( data, secret )

```

Base64URLEncode( header ) は、ヘッダー部分をBase64URLを使って変換した文字列

Base64URLEncode( payload ) は、ペイロード部分をBase64URLを使って変換した文字列

### 補足: Base64 エンコードとBase64URLエンコード

Base64URLエンコードについては[こちらの記事](https://qiita.com/kunihiros/items/2722d690b1525813c45e)が詳細に説明してくださっていました。

> Base64 は、データを 64 種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式。
> 

Base64URLエンコードとは

> URL に使用できる Base64 Encode のことを指します。
> 
> 
> まず、Base64 Encoding をしたあと、に各記号を置き換えるようです。
> 
> - `+`を`-`に置換
> - `/` を `_` に置換
Chromeでメモを取ることに特化した拡張機能を作った話

## はじめに

エンジニアとして、業務をしていて一番使うアプリは、Chromeです。
Web会議、テスト、プロジェクト管理、コミュニケーションツールなど、一日の大半をChromeで作業しています。

がっつりメモを取るときは、Notionを使っていますが、
ちょっとしたメモを取るときは、いちいちNotionを開くのが面倒だなと思っていまいました。

Chromeでメモを取ることに特化した拡張機能を作りました。

## 作った拡張機能

![chrome-app-handy-memo-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631803/8f0f2de4-102f-cb27-4adb-eb29e1bc0ba5.png)

Chrome拡張機能「Handy Memo」は、Chromeでメモを残すことができる拡張機能です。

ポップアップで表示されるメモのエリアに、タイトルとメモの内容を入力できます。

https://chromewebstore.google.com/detail/handy-memo/gebjcpnknlagmidhnhajcknjcphpnnid

### ツールバー

アイコンをクリックすることで特定の文字を入力できます。

- `#` アイコンをクリックすると、`#`を入力します。
- `##` アイコンをクリックすると、`##`を入力します。
- `###` アイコンをクリックすると、`###`を入力します。
- `■` アイコンをクリックすると、`■`を入力します。
- `DATE` アイコンをクリックすると、`YYYY/MM/DD`を入力します。
- `TIME` アイコンをクリックすると、`HH:MM:SS`を入力します。
- `URL` アイコンをクリックすると、現在開いているタブのURLを入力します。

### 各種ボタン

- コピーボタンをクリックすると、メモの内容をクリップボードにコピーします。
- リセットボタンをクリックすると、タイトルとメモの内容をリセットします。
- ダウンロードボタンをクリックすると、メモの内容を`md`ファイルとしてダウンロードします。
  - タイトルが入力されていない場合は、`YYYY-MM-DD-HH-MM-SS`の形式でファイル名が付与されます。

## 開発プロセス

### 使用した言語

- TypeScript
- HTML
- CSS（Bootstrap）

この拡張機能を開発するにあたり、私はTypeScript、HTML、そしてCSS（Bootstrap）を選択しました。
TypeScriptを採用した理由としては、TypeScriptを使ってなにか開発したかったからです。
動画や書籍だけで学ぶのは難しいので実際に手を動かしたかったというのもあります。

### 開発環境の設定

https://developer.chrome.com/

開発において、環境構築がかなり面倒ですが、Chromeの拡張機能は`manifest.json`を用意するだけで環境構築ができるのでかなり便利です。

簡単に環境構築ができるので、開発着手までの期間がかなり短くなります。

https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world

## まとめ

TypeScriptでコーディングする際には、型の重要性を再認識しました。
また、Webpackを使用することで、よりスマートな開発が可能であることを発見しました。
CSSとBootstrapのおかげで、デザインの重要性を完全に理解しました。新しい技術を使うことは最初は挑戦でしたが、その価値をしっかりと実感しました。

新しいことを始めるには時間がかかること、継続的に改善することの重要性を学びました。
AndroidStudioで接続している端末の画面サイズ、OSバージョンを簡単に知る方法

AndroidStudioで接続している端末の画面サイズ、OSバージョンを簡単に知る方法を紹介致します。

Androidは端末によって様々な画面サイズがあるので、画面サイズが小さい物だけ表示しきれていない事があると思います。
自分が使用している端末が、どの画面サイズなのか知っておくと良いと思います。



まずはDeviceManagerを開きます。

![スクリーンショット 2024-01-07 9.52.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/9a5f2c68-53e3-37c4-f731-a86ae8d6fb90.png)

画像のようにPhysicalを選択します。
そうすると接続した事のある端末が表示されます。
接続している端末の名称をクリックすると表示されます。

![スクリーンショット 2024-01-07 9.54.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/156ca44c-588f-07b7-36a0-4e942c680341.png)

以上の操作で確認する事ができました。
Pythonで「辞書に指定したキーの要素が含まれているか確認する」の動作を確認してみた

# 概要

Pythonで「辞書に指定したキーの要素が含まれているか確認する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/dictionary/index7.html

# 実装

以下のファイルを作成しました。
```sample.py
mydict = {"L":"Lemon", "O":"Orage", "G":"Grapes"}
print("O" in mydict)
print("P" in mydict)

mydict = {"L":"Lemon", "O":"Orage", "G":"Grapes"}
print("O" not in mydict)
print("P" not in mydict)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
True
False
False
True
```

# まとめ

何かの役に立てばと。
マルチステージビルドとDistrolessでDockerイメージを最適化する

Node.js(Express)ベースのアプリケーションをGoに移行した際、Dockerイメージのサイズを2.8 GBから400 MBまで大幅に削減できて一旦満足したのですが、リソースの効率的な利用やデプロイの速度向上を目指す中で、さらなるイメージサイズの削減ができることがわかったので、新たな試みをしてみることにしました。

DevOps経験のあるエンジニアには既知の内容だと思いますが、初心者の方々への参考として、改善内容を共有します。

# 元のDockerfile
元のDockerfileでは、`golang:1.21.0`ベースのイメージを使用し、Goのモジュールのダウンロード、アプリケーションのビルド、実行のためのステップを含んでいます。しかし、この方法では開発環境に必要な全てのファイルがイメージに含まれるため、最終的なイメージサイズが大きくなってしまいます。

```dockerfile
# Goの公式イメージをベースにする
FROM golang:1.21.0

# アプリケーションディレクトリを作成する
WORKDIR /app

# Goのモジュールを有効にする
ENV GO111MODULE=on

# 依存関係をコピーし、ダウンロードする
COPY go.mod .
COPY go.sum .
RUN go mod download

# アプリケーションのソースをコピーする
COPY . .

# アプリケーションをビルドする
RUN go build -o main .

# ポート待ち受け
EXPOSE 8081

# アプリケーションの起動コマンド実行
CMD ["./main"]
```

# 改良したDockerfile
改良したDockerfileでは、マルチステージビルドを導入しました。
マルチステージビルドは、一つのDockerfileで複数のビルドステージを定義し、最終的なイメージに必要なファイルだけを含める手法です。
最初のステージでアプリケーションをビルドし、次のステージでビルドした実行可能ファイルのみを軽量な`alpine`イメージにコピーします。これにより、最終的なイメージには必要最小限のファイルのみが含まれるため、イメージサイズが大幅に削減されます。

```dockerfile
# Goの公式イメージをベースにする
FROM golang:1.21.0-alpine as builder

# アプリケーションディレクトリを作成する
WORKDIR /app

# Goのモジュールを有効にする
ENV GO111MODULE=on

# 依存関係をコピーし、ダウンロードする
COPY go.mod .
COPY go.sum .
RUN go mod download

# アプリケーションのソースをコピーする
COPY . .

# アプリケーションをビルドする
RUN go build -o main .

# 実行用のステージ
FROM alpine:3.19

WORKDIR /root/

# ビルドしたバイナリをコピー
COPY --from=builder /app/main .

# ポート待ち受け
EXPOSE 8081

# アプリケーションの起動コマンド実行
CMD ["./main"]
```

# 結果の比較
元のDockerfileを使用した場合、イメージサイズは約400 MBでした。しかし、マルチステージビルドを適用した後、イメージサイズはわずか10 MBにまで削減されました。なお、マルチステージビルドを行わずにベースイメージに`golang:1.21.0-alpine`を使った場合は約160 MBでした。

# Distrolessイメージについて
今回はデバッグのためにシェルを含むAlpineイメージを選択したのですが、Googleが提供するDistrolessイメージの使用も検討しました。Distrolessイメージはセキュリティが強化された非常に軽量な環境で、最小限のファイルしか含まれておらず、シェルや不要なパッケージが削除されています。

Distrolessイメージを使用する場合、Goで書かれたアプリケーションは、外部のC言語ライブラリに依存しないスタティックリンクされたバイナリを必要とします。これは、Distrolessが最小限の環境のため、外部ライブラリやシェルが含まれていないからです。そのため、`CGO_ENABLED=0`を設定してCGO(C言語とGo言語のインターフェース)を無効にし、全ての依存関係を含む独立したバイナリを生成する必要があります。

Distrolessを使った場合のDockerfileは以下のようになります。

```dockerfile
# ビルドステージ
FROM golang:1.21.0 as builder

# アプリケーションディレクトリを設定
WORKDIR /app

# Goモジュールを有効にする
ENV GO111MODULE=on

# 依存関係をコピーし、ダウンロードする
COPY go.mod .
COPY go.sum .
RUN go mod download

# アプリケーションのソースをコピー
COPY . .

# アプリケーションをビルド
RUN CGO_ENABLED=0 go build -o main .

# 実行ステージ
FROM gcr.io/distroless/base-debian10

# ビルドしたバイナリをコピー
COPY --from=builder /app/main /

# アプリケーションの実行
CMD ["/main"]
```
市区町村データファイルをマージする場合

市区町村データファイルをマージする場合，市町村名をキーとしてマージしてはいけない。

漢字表記された市町村名が同じ市町村が複数個あるからである。
有名なのは東京都府中市と広島県府中市。

団体コード（市区町村コード）をキーとしてマージすべきである。

2022年度時点で，漢字表記が同じ市町村一覧
「市」，「町」，「村」がつく場合。つかない場合はもっと多くの重複がある。
「ちょう/まち」，「そん/むら」の区別はしない。読みがながついている場合は区別できる場合もある。

団体名|都道府県名
:---|:---
池田町|北海道, 岐阜県, 福井県, 長野県 
朝日町|三重県, 富山県|山形県 
南部町|山梨県, 青森県, 鳥取県 
美浜町|和歌山県 愛知県, 福井県 
美郷町|宮崎県, 島根県, 秋田県 
美里町|埼玉県, 宮城県, 熊本県 
伊達市|北海道, 福島県
金山町|山形県, 福島県
広川町|和歌山県, 福岡県
高山村|群馬県, 長野県
高森町|熊本県, 長野県
小国町|山形県, 熊本県
昭和村|福島県, 群馬県
松前町|北海道, 愛媛県
森町　|北海道, 静岡県
清水町|北海道, 静岡県
川崎町|宮城県, 福岡県
川上村|奈良県, 長野県
川西町|奈良県, 山形県
太子町|兵庫県, 大阪府
南牧村|群馬県, 長野県
日高町|北海道, 和歌山県
日野町|滋賀県, 鳥取県
府中市|広島県, 東京都
明和町|三重県, 群馬県
【個人開発】シェアハウスでの生活を快適にする管理アプリを作ってみた


はじめまして。
私は現在、都内のITベンチャー企業でエンジニアとして働いています。
今回はシェアハウス生活を管理できるWEBアプリを個人開発したので機能と構成について記事にしました。
また、勉強ために開発をしたのでシステム構成などは初心者目線の寛大な心で見ていただけると幸いです。

制作期間：約3ヶ月（2023/01~2023/04）

ポートフォリオとして以下を1月末頃（AWS無料期間）まで公開しています。

## ポートフォリオ
### ゲストユーザー
・ユーザーID：guest1
・パスワード：guestpassword

### ゲストルーム
・ルームID　：guestRoom
・パスワード：guestpassword

### アプリ画面
https://main.dsv8p23lrjk0t.amplifyapp.com/

### API画面
https://31uz4c2c0l.execute-api.ap-northeast-1.amazonaws.com/portfolio/docs/

## 作ろうと思ったきっかけ
友達と3人でシェアハウスをしていた経験があり、共同生活をする上で共有や管理する内容が色々とありました。
・チャット
・カケイボ
・スケジュール
・ToDoリスト
以上などが挙げられます。

当時は機能それぞれの別アプリ複数を利用していました。
別々の機能のアプリをひとつにできればシェアハウス生活の管理を快適にできたのではないか...
また、エンジニアとしての経験も浅いため勉強としても個人開発を始めることにしました。

## アプリ画面構成
![スクリーンショット 2024-01-07 6.48.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470136/1b179240-6b18-08f6-8eb8-b14311b92cb7.png)

![スクリーンショット 2024-01-07 6.49.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470136/f16b11a7-d789-47e5-7aa8-237c548094b4.png)

## システム構成
![スクリーンショット 2024-01-07 6.53.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470136/deb72a31-73ac-0812-b18e-986a6703e913.png)

![スクリーンショット 2024-01-07 6.54.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470136/e8646c7d-5d7e-5a9a-5395-8bd35d38db7f.png)

## 機能一覧
### ユーザー
・ログイン
・登録
・更新
・削除
・画像変更

### ルーム
・ログイン
・登録
・更新
・削除

### チャット
・確認
・追加
・削除

### カケイボ / カレンダー / ToDoリスト
・確認
・登録
・更新
・削除

## 使用言語およびサービス
### フロントエンド
・React
→ AntDesign / MaterialUI / FullCalendar / ReduxToolkit ...

### バックエンド
・Python
→ FastAPI / MySQLClient / Pillow / Alembic ...

### データベース
・MySQL

### AWS
・S3
・EC2
・RDS
・Amplify
・API Gateway

## まとめ
実装したい機能はまだまだありますがAWS無料期間が1月末に終えるため、ポートフォリオは一度停止します。
個人開発を得てアプリケーション全体の開発手順やフロントエンド・バックエンド・AWSなどの幅広い知識を理解することができました。
それぞれの詳細に関しては別の記事で紹介していきますのでそちらもみていただけると嬉しいです。
今後はFlutterかReactNativeでスマホアプリ版を作ってみたいと考えています。

ここまで記事を読んでいただきありがとうございました。
Qiita初投稿でしたが、業務や個人開発で得た知識を少しでも共有していければと思います。
　　
　　
　　
おわり。
Spark　RDDについてより深く調べてみた

# 0.初めに

分散処理システムは、利用者はあまり分散処理のアルゴリズムをわかっていないくても、また意識しなくても
うまい具合にデータを処理してくれるので、利用する分には詳しくわかっていないくてもいいかもしれません
が、データの動きというのは分散処理には欠かせない技術なので
これがわかっておくだけでも、コードの記述なども理解しやすいと思います。

今回は、２つの資料を参考にしています。

１つめは、couseraでIBMが公開している講義になります。Sparkを中心として説明しています。
あまりこれにフォーカスした資料が意外とないもので、日本語訳もある程度機能しているので
是非！

https://www.coursera.org/learn/introduction-to-big-data-with-spark-hadoop

2つ目は、NTTデータの土橋さんという方が公開しているSparkの資料になります。
これはとてもわかりやすく、実際の講義ではHands-onでSpark UIで説明していたりしているのでしょうか。参加してみたかった。。

https://www.scsk.jp/lib/product/oss/pdf/Spark.pdf

# 1.RDDとは
Spark内のクラスターのノード間で分割された耐障害性のある要素の集まりのこと

そもそもクラスターとは、
同時に連携して、タスクを実行するコンピューターの集まりを指します。
分散処理には欠かせません。

#  2.RDDはSparkでどのように耐障害性を実現するのか？

不変性とキャッシュによってSparkのレジリエンス(回復性)を実現する
データが不変であるため、RDDは常に回復可能。
Sparkのもう一つの重要な機能は、操作を重ねてもデータセットをメモリに永続化またはキャッシュすること

キャッシュ自体は耐障害性があり、いつでも回復可能

## 2.1 例　PythonでのRDD作成
```python
data = [1,2,3,4,5]
distData = sc.parallekize(data)
```

RDDは、部分故障への耐性を考慮した分散コレクションに対し、
典型的なデータ処理を繰り返して目的の結果を得ます。

入力⇨RDD⇨グルーピング⇨RDD⇨フィルター⇨RDD⇨集計

```python
rdd.filter(...).resuceByKey(...)
```
このようにコレクション操作のように記述します。

これらの部分的な処理は、中間処理を都度出力する必要がないため、HDFSなどの外部分散ストレージへのI/Oが抑えられます

# 3.キャッシュの重要性

例えば、HDFSからジョブAがあって、データAを読み込むとします。
読み込んだ中間データはメモリにキャッシュされます。

別の処理ジョブBでデータAを使いたい場合、すでにキャッシュがあるので
それを利用すればよい。

同じデータを活用するシーンにおいて、ディスクI/Oが生じないので、処理が効率的というわけですね。
SDRAMの張り替え

以前FON2100などのSDRAMを張り替えてうまく使えるようにできたのですが、もう一度調べてみます。

M12L128168A(16M)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/7d10591c-3e1a-a5d6-bdcf-6760f7740be8.png)

M12L2561616A(32M)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/da1406bb-0fd0-0f8f-986b-cdd8cb74de24.png)

20,21,36ピンが違うようです。

36ピンの回路があれば16Mから32Mに張り替えて認識されるものと思われます。

基板設計の時には16Mでも32Mでも使用できるようにしてある事があります。

16M SDRAMで36ピンがプルダウンされてる場合はCPUに接続されてます。

FON2100の時はRedBootをビルドして焼直しました。

16Mを二枚で32Mにする場合はSOCで2個のSDRAMサポートがあれば、それを使い、16BitのSDRAMでCPUが32Bit busをサポートしていれば上下で一つに見せる事が出来ます。
バッチファイルでiniファイルを読み込む（セクション対応）

バッチファイルでいい感じにINIファイルを読めたのでメモ。
```batch
SETLOCAL ENABLEDELAYEDEXPANSION
SET SET_COMMAND=
SET PREFIX=
FOR /F "usebackq tokens=*" %%I IN (config.ini) DO (
    SET LINE=%%I
    ECHO !LINE! | FINDSTR /B [ >NUL
    IF ERRORLEVEL 1 (
        SET SET_COMMAND=!SET_COMMAND!^^^&SET !PREFIX!%%I
    ) ELSE (
        SET PREFIX=!LINE:~1,-1!_
    )
)
REM ERRORLEVELを元に戻す
DIR >NUL
ENDLOCAL %SET_COMMAND%
```

こんな ```config.ini``` を用意してると、
```ini
[SECTION1]
ENTRY1=valu1-1
ENTRY2=valu1-2
ENTRY3=valu1-3

[SECTION2]
ENTRY1=value2-1
ENTRY2=value2-2
```

こんな風に読み込める。
```batch
>set
...
SECTION1_ENTRY1=valu1-1
SECTION1_ENTRY2=valu1-2
SECTION1_ENTRY3=valu1-3
SECTION2_ENTRY1=value2-1
SECTION2_ENTRY2=value2-2
...
```

ポイントは２つ。

ポイント１つ目。
このコード、最後に ```FINDSTR``` が失敗して終わるので、コード実行後に ```ERRORLEVEL``` が ```1``` になり、バッチファイル呼び出し元でエラー判定しちゃうってことになってしまった。
そこで、最後に ```DIR >NUL``` で ```ERRORLEVEL``` を戻してあげている。

ポイント２つ目。
環境変数の遅延展開を使いたいけど、そうすると```endlocal```以降に環境変数を持ち出せなくなってしまう。
最初は呼び出し元で ```setlocal enabledelayedexpansion``` を呼び出さないといけない縛りを付ける方向でかんがえてたんだけど、実は[endlocal以降に変数を持ち出す裏技](https://iijimas.hatenadiary.org/entry/20101023/1287772847 "バッチファイルで、setlocal〜endlocal内での変数の値を外部に引き継ぎたい！ - IIJIMASの日記")があるらしい。
リンク先の技そのままだと、環境変数名がわかってる必要があるけれど、今回はINIファイル次第で変数名も数も変わるのでそのままでは書きづらい。
ということで、
```batch
&SET SECTION1_ENTRY1=value1-1&SET SECTION1_ENTRY2=value1-2...
```
みたいな文字列を作って ```endlocal``` の後ろに置いてみたらいい感じにエクスポートできた。

ただし、この変数を組み立てるときに
```batch
SET SET_COMMAND=!SET_COMMAND!&SET !PREFIX!%%I
```
としたところ、```SET SET_COMMAND=!SET_COMMAND!``` と ```SET !PREFIX!%%I``` が別コマンドとみなされて玉砕。
```batch
SET SET_COMMAND=!SET_COMMAND!^&SET !PREFIX!%%I
```
これでもうまくいかなくて（```!SET_COMMAND!```の展開時にコマンド分割された？）、
```batch
SET SET_COMMAND=!SET_COMMAND!^^^&SET !PREFIX!%%I
```
で最初のハットもエスケープしてあげたらうまくいった。

まあなんだかんだいい感じにできてよかったｗ
モジュール凝集度・結合度の個人的まとめ

## モジュール強度・凝集度
暗合的強度(coincidental strength)
プログラムをモジュール化しようとする際に、まったくのランダムなところで機能を分割してモジュールを作る。そのモジュールは暗合強度を持つ。

論理的強度(logical strength)
1つのモジュールに複数の機能が含まれていて呼び出すときに引数で機能を選択するモジュールは論理的強度を持つ。
新しい機能を作るとするときに引数を増やしたりすると、他の機能すべてで追加された引数を考慮するように作り直さなければならない。

時間的強度(classical strength)
初期化処理、終了処理など特定のタイミングで必要な処理をまとめたモジュール

手順的強度(procedural strength)
手順通りに実行される複数の機能があるモジュール

連絡的強度(communicatonal strength)
手順的強度モジュールと同じだが、扱うデータが機能間で関係していなければならない。
例えば、機能１の戻り値が機能２の引数になる。または機能１，２が共通の入出力データを参照する。

機能的強度(functional strength)
１つの固有の機能を実行するモジュール
１組の機能が集約的機能として１つの固有の機能としてまとめて記述できるときはそのモジュールは機能的強度を持つ。
例えば文章を英語に翻訳するモジュールというのは内部では様々な機能に分割できるが集約的機能としてみなせる。

情報的強度(informational strength)
・多重入口点を持つ
・各入口点は単一の固有の機能を行う
・これらの全ての機能は、同じデータ構造のデータを参照し、データ構造に関係のあるものである
情報的強度モジュールは、いくつかの関連した機能的強度モジュールを一緒にパッケージしたものと見ることができる

## モジュール結合度
内容結合(content coupling)
モジュールが他のモジュールの中のデータを直接参照している状態

共通結合(common coupling)
グローバル変数を参照するモジュールグループの間で起こる状態

外部結合(external coupling)
共通結合と同じ。ただし参照するグローバル変数は同種のデータ構造を持つ

制御結合(control coupling)
１つのモジュールが他のモジュールへ引数のような形で機能コード、制御スイッチを渡すとき、これらのモジュールは制御結合している。

スタンプ結合(stamp coupling)
２つのモジュールが同じ非グローバル的データ構造を参照しているとき、これら２つのモジュールはスタンプ結合している。

データ結合(data coupling)
複数のモジュール間で必要なデータだけを引数で渡す。データ構造を参照するのではなく、データ構造の中から必要なデータだけを取り出して引数に指定する。このときこれらのモジュールはデータ結合している。
<hr>
参考
https://www.momoyama-usagi.com/entry/info-software09#i-7
https://zenn.dev/yuyu_hf/articles/355e3ce854ba96#%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%97%E7%B5%90%E5%90%88
【UE5】GASを使用せず連続攻撃を実装してみる

今日は連続攻撃を実装してみます

「あれ？連続攻撃ならGASを使うだろ？」
とUEをある程度触った人でしたら思いますが
今回はGASが使えない人用の記事になります

# 今回実装すること
![無題の動画-‐-Clipchampで作成-_5_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/84929827-55f4-b3de-7e24-3caa97327565.gif)



# 使用アセットについて
今回は以下のアセットを使用します

https://www.unrealengine.com/marketplace/ja/product/paragon-kwang

# 実装する関数
**OnPlayComboAnime**　　　　攻撃アニメーションを再生する
![スクリーンショット 2024-01-07 050818.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/f2c69825-c0e6-0af9-237a-60a98dcf0019.png)

**OnTriggerAttackCombo**　攻撃ボタンを押下した時にコール
![スクリーンショット 2024-01-07 050734.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/11e7711c-6489-7ec5-1d5c-20d2dc0cb182.png)


**OnCheckSavedAttack**　　　　攻撃ボタンの押下情報から次再生するアニメーション決める
![スクリーンショット 2024-01-07 050746.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/8483b6fb-b2fe-4263-d4f4-aded292735ca.png)


**OnResetAttackCommbo**　　攻撃に関する全てのパラメータを初期状態へ戻す
![スクリーンショット 2024-01-07 050758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/4cf2c286-5afe-528d-fe35-a84ee2e017fd.png)

各アニメーションモンタージュの以下のNotifiesを設定
「攻撃終了後」　**SaveAttack**
「モンタージュの最後」　**ResetAttack**
![スクリーンショット 2024-01-07 051231.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/dd826d07-ef31-f795-0072-3b5f3a344090.png)

AnimationBlueprintから以下を設定

SaveAttack  →　「OnCheckSavedAttack」
ResetAttack →　「OnResetAttackCommbo」
![スクリーンショット 2024-01-07 051457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/2d440d13-e624-1ef7-9815-602100a20d15.png)



# 流れを解説
アニメーションモンタージュは再生中に別のモンタージュを再生すると上書きされます

1 「OnTriggerAttackCombo」を再生

2 「IsAttacking」がFalseなので最初のアニメーションが再生



◯ 次の攻撃ボタンを押下してない時
3　各アニメーションモンタージュの最後に仕込んだ「ResetAttack」がコール
4　正常に終了し1へ戻る


◯ アニメーションが再生中に次の攻撃ボタンを押下時

3 「Save Attack」をTureに更新
　次のアニメーションで現在のアニメーションを上書き
　(再生中の最後に仕込んだ「ResetAttack」はコールされません)

4　アニメーションモンタージュに仕込んだ「ResetAttack」がコールされるまでループ

# 最後
いつかGASを使って実装してみたいですね
repetition_penaltyってなんしよーと？

transformersの`generate`メソッドを使っていて気になったのでメモ。

参考文献1を確認したところ論文を見てねとのことだったので、参考文献2の論文を拝見しました。
すごくわかりやすい論文やんって思いました！

## repetition penaltyを導入する動機
言語生成をする際、はじめに次トークンとしてふさわしいものを予測し、それらを確率分布の形で出力します。つぎにtop-kやtop-pといった確率を利用した操作によって次トークンを決定するわけですが、時として貪欲に最大の尤度のトークンを選択したほうが良い場合が存在します。この論文の例だと首都を当てるクイズが挙げられてますね。こうしたケースに合わせるならば貪欲に最大尤度のトークンを選択するのが良いと思ってしまうのですが、そうしてしまうと同じ文章や言い回しを繰り返し出力することが知られているので、これを回避したいというのが動機です。

## どうやって実現しよーと？
アイディアはシンプルで予測した次トークンの確率分布の確率をいじってやればいいわけですね。形はSoftmax関数ですね。
$$p_i=\frac{\exp(x_i/(T・I(i\in g)))}{\Sigma_j \exp(x_j/(T・I(j\in g)))}$$

ここで、$g$は生成されたトークンのリスト、$T$はTemperatureで、$I(c)$は$c$という条件が真の場合に$\theta$をかえし、そうでない場合は1を返す関数です。

なので一度トークンが生成されればTemperatureがさらに強まるイメージですね！

## 蛇足: Temperatureは？
式の形はrepetition penaltyの項がない分簡潔に表せます。
$$p_i=\frac{\exp(x_i/T)}{\Sigma_j \exp(x_j/T)}$$

Temperatureが何をやってるかというと、実際にTに値を代入するとわかりやすいです。
まず、$y=e^x$の場合
![Screenshot 2024-01-07 045907.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627854/a24a931d-c7d7-9268-c03a-06acf225a35d.png)
次に、$y=e^{x/10}$の場合
![Screenshot 2024-01-07 045919.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627854/8804be49-91e0-987f-3f68-579f043feede.png)

$T$が大きくなるほどに値の上昇が緩やかになってるのがわかりますね。$T$を大きくすると大きな値は小さく、小さな値は大きくなるように調整されるわけです。

なので、論文内では$T\rightarrow0$とすると最大の値を増幅した貪欲な確率分布に近づき、$T\rightarrow\infty$とすれば一様分布に近くなるって書いてあります。納得ですね。


## 参考文献
1. https://huggingface.co/docs/transformers/internal/generation_utils#transformers.TFRepetitionPenaltyLogitsProcessor
2. https://arxiv.org/abs/1909.05858
離乳食のレシピを提案するツール

# 概要
離乳食のレシピを提案してくれるツールを作ったので公開します。タンパク質1種類、野菜をN種類、味付けを1種類をランダムに選択します。

https://github.com/hsmtta/babyrecipe

# 使い方
使いたい野菜の数と、生成するレシピの数を指定して実行するだけです。

```bash
$ python recipe.py -h
usage: recipe.py [-h] [-v N] [-n N]

options:
  -h, --help           show this help message and exit
  -v N, --vegetable N  # of vegetable to use
  -n N, --number N     # of recipe to generate
```

# 動作概要
* タンパク質は6種類から1つ選びます。魚を選んだ場合は、魚の種類を10種類から1つ選びます
* 野菜は24種類からN個選びます（自分は2～3種類を使うことが多いです）
* 出汁は鰹か野菜の2種類から選びます（素材の味が出ていれば使わなくても良いと思います）

```python

protein = ["鶏肉", "豚肉", "牛肉", "魚", "卵", "豆腐"]
fishes = ["さば", "あじ", "いわし", "さけ", "まぐろ", "かつお", "たい", "たら", 
          "ぶり", "かれい"]
vegetables = ["人参", "玉ねぎ", "ほうれん草", "かぼちゃ", "大根", "キャベツ", "ブロッコリー",
              "トマト", "ピーマン", "なす", "かぶ", "れんこん", "さつまいも", "ごぼう", 
              "しいたけ", "しめじ", "えのき", "まいたけ", "マッシュルーム", "パプリカ", 
              "ズッキーニ", "白菜", "さといも", "ネギ"]
soup = ["鰹", "野菜"]
```

# 使用例
さっそく使ってみたところ次のような結果でした。野菜を3つ使って、20個のレシピを生成してみます。
```
$ python recipe.py -n 20 -v 3
豚肉と ピーマンキャベツ玉ねぎの 野菜風味
卵と かぶピーマンブロッコリーの 野菜風味
牛肉と 白菜ブロッコリーキャベツの 野菜風味
豆腐と 人参トマトしめじの 野菜風味
卵と しめじまいたけトマトの 鰹風味
さばと ピーマンブロッコリーえのきの 野菜風味
豆腐と パプリカ玉ねぎマッシュルームの 野菜風味
牛肉と キャベツしいたけかぼちゃの 鰹風味
いわしと マッシュルームキャベツ玉ねぎの 野菜風味
さばと えのきかぶピーマンの 野菜風味
牛肉と かぶさといもブロッコリーの 野菜風味
豚肉と 白菜さつまいもえのきの 野菜風味
鶏肉と まいたけブロッコリーピーマンの 野菜風味
豚肉と さといもしいたけなすの 野菜風味
あじと なすブロッコリー人参の 野菜風味
豆腐と マッシュルームえのきかぼちゃの 野菜風味
豆腐と えのきほうれん草れんこんの 鰹風味
卵と キャベツかぼちゃ人参の 鰹風味
さけと 玉ねぎかぶほうれん草の 野菜風味
卵と なすブロッコリーしめじの 野菜風味
```

生成される組み合わせの総数は、`(5 + 10) * combination(24, 3) * 2 = 15 * 2024 * 2 = 60720` になります。組み合わせがこれだけあれば、献立に困ることはなさそうです。

# まとめ
離乳食のレシピをランダムに作成するCLIツールを作りました。離乳食づくりの参考になれば嬉しいです。大人の献立のアイデアも浮かんでくるかもしれませんね。
スプレッド演算子を用いてオブジェクトの更新操作を行う方法

```javascript

const updateLikability = { ...someoneSpecial,
                           likability: {...someoneSpecial.likability, funnyRating:increaseLikabilityByFunnyJoke }

```
気になるあの子の好感度を更新してゆきたいと思います。




まず、気になるあの子(someoneSpecial)の現在の状態を
スプレッド演算子を用いてコピーします。





このコピーは表面的なもので、内部のlikabilityオブジェクトは元のsomeoneSpecialからの参照として保持されています。

次に好感度オブジェクト(someoneSpecial.likability)もコピーしておいて、その中の面白さプロパティを新しい値(increaseLikabilityByFunnyJoke)で更新しています。

以上で「ノリの良い軽口であの子を笑わせて自分の好感度を上げる」オブジェクトを作ることができました。

現実世界で実行可能なオブジェクトであればいいのに。
AndroidStudioでADVが起動しない ADV Pixel_2_API_28 has terminated

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253995/abfaf020-00ab-ae33-579d-8c346038409f.png" width=60%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253995/ac18fd1d-8f2d-6537-65b0-4df34da79b6d.png" width=80%>

Android エミュレーターの起動に失敗します。
The emulator process for ADV Pixel_2_API_28 has terminated

# 原因

ディスク容量が足りない
→足りている

WindowsでNVIDIAの設定を変更
→私は MacBook M

ADVの画面で Emulated Performance を変更
→Pixel2 は変更できない（Pixel6 は変更できるしそもそも動く）

# 対処法

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253995/0ebc5048-a0e9-5c9f-7eeb-44fa5e97ab99.png" width=80%>

APIは28がダメで29か30にすると起動しました。

# なぜ Pixel2 API28

Google Play ストアに公開しようと aab をアプロードすると、Pixel2 API28 で起動できないエラー出て、リリースできなくなりました。
エミュレータが起動できず再現テストできないので、強引にAPIを上げました。

↓ app/build.gradle の minSdkVersion を23から29に変更
```
  defaultConfig {
    minSdkVersion 29
    targetSdkVersion 34
  }
```

# 結果

aab を再アップロードするとエラーが消えて無事に審査できました。
いやー二年ぶりに審査に出したのですが自動的にテストするのですね。自分でテストするより開発段階でガンガンGoogleにチェックさせた方がいいですね。
初心者向け unity みやすいコードの書き方


# はじめに
昔の自分がかいたコードを見てすごく見づらくて途中で見るのが嫌になったので
なるべく見やすく早く見返せるコードの書き方について書いていこうと思います！
僕の好みもあるのでもし見にくかったらすみません

## 変数の種類で分ける
unityで使う変数の種類
1. [SerializaField]属性がついた変数
1. コンポーネント型の変数
1. 普通の型の変数(その他)

説明が難しいので実際の僕のコードを見ていきます


``` before1.cs
    float xTargetPosition;
    float yTargetPosition;
    float zTargetPosition;
    [SerializeField] float everyFewSeconds = 3;
    public GameObject TargetObject;
    float time;
    [SerializeField] float speed = 0.01f;
    Vector3 pursuers;
    Vector3 afterPosition;
``` 
``` after1.cs
    [SerializeField] float everyFewSeconds = 3;
    [SerializeField] float speed = 0.01f;

    public GameObject TargetObject;

    float xTargetPosition;
    float yTargetPosition;
    float zTargetPosition;
    float time;
    Vector3 pursuers;
    Vector3 afterPosition;
```
一目瞭然ですよね　beforeを見てみると
まだそこまで変数の数が多いわけではないのに見通すのに時間がかかってしまいます
変数の名前についてはしっかり考えているけど、配置に関しては適当な人もいると思うので
この機に見直してみてください

### 　メソッドの配置
さっきの話と似ているのですがStart や Update などのunity側で初めから用意されてるメソッ
ドを上に、自分で作ったメソッドを下に分けて置いておくのも見やすくていいです

## いらないものは捨てる
不必要なコメントやテスト用の変数やメソッドなど本番環境に必要ないものは適時消して
読みやすくするための必要最低限のコードにしたほうがいいです

unityでエディターを開くと最初から Start と Update メソッドが置いてありますが開いたとき
に使わないなら消したほうが邪魔になりにくいと思います

## 中括弧｛ ｝の位置
if文やメソッドを作る際に中括弧 { } で囲む位置についてです

``` before2.cs
    public void OnCollisionEnter(Collision collision){
    
        if (collision.gameObject.tag == "Guardian"){
        
            invisibleObject.SetActive(false);
        }
        else if (collision.gameObject.tag == "Player"){
        
            invisibleObject.SetActive(false);
        }
    }
```

``` after2.cs
    public void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Guardian")
        {
            invisibleObject.SetActive(false);
        }
        else if (collision.gameObject.tag == "Player")
        {
            invisibleObject.SetActive(false);
        }
    }
```
エディターが初期設定だったら visual studio だと下 visual studio code だと上だと思います
ここは好みが分かれると思います。僕は下のほうが何がどこに入ってるのかわかりやすいの
で好きです

## さいごに
読みやすいコードを書くために必要そうなことを他の人が触れてなさそうで僕が案外大事だ
なって思ったことを書いてみました

ほかにも気を付けたほうがいいことや間違いなどあったら教えてください。
Deno FFI で文字列の配列を外部関数に渡す方法（execvp(3) の呼び出しを例に）

[Deno FFI のドキュメント](https://docs.deno.com/runtime/manual/runtime/ffi_api)には文字列や配列を外部関数に渡す方法の解説がない。手探りで調べて動くコードにまとめてみた。

なお、このコードは Deno 1.39.1 で動作確認した。このバージョンで FFI は unstable なため、今後挙動が変わったり動かなくなったりする可能性がある点に注意すること。

```ts
// 以下、 deno run で実行するには --unstable --allow-ffi --allowr-read フラグが必要

// libc の関数 int execvp(const char *file, char *const argv[]) の呼び出しを例に取る
function execvp(program: string, args: string[]) {
  const libName = Deno.build.os === "linux" ? "libc.so.6" : "libc.dylib";

  const lib = Deno.dlopen(libName, {
    // 文字列の配列のポインタを取る引数（第2引数）の型は buffer とする
    execvp: { parameters: ["buffer", "buffer"], result: "isize" },
  });

  // JS の文字列を UTF-8 バイト列のバッファに変換する
  const programCString = stringToCString(program);
  const argCStrings = args.map((arg) => stringToCString(arg));

  // バッファのポインタを取得する
  const argPointers = argCStrings.map((arg) => arrayBufferToRawPointer(arg));

  // execvp() に渡す配列は NULL ポインタで終端する必要がある
  argPointers.push(0n);

  // 配列を TypedArray (BigUint64Array) に変換する
  const argPointersArray = BigUint64Array.from(argPointers);

  // execvp() を呼ぶ
  lib.symbols.execvp(programCString, argPointersArray);
}

function stringToCString(s: string): ArrayBuffer {
  // C 文字列は末尾に \0 を置く必要がある
  return new TextEncoder().encode(`${s}\0`).buffer;
}

function arrayBufferToRawPointer(buffer: ArrayBuffer): bigint {
  // Deno.UnsafePointer.of() は opaque なポインタオブジェクトを返す
  // それを 生のメモリアドレスに変換する
  return BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(buffer)));
}
```

Deno FFI におけるポインタの扱いは以下のページが参考になった。

https://denonomicon.deno.dev/types/pointers
【プロトアウト生向け】参考記事の読み方

# はじめに
本記事ではプロトアウト生（特に授業が始まったばかりの人）に向けて、参考記事のどういうところを見たらいいのか？をかる〜く解説していきます！

（手前味噌で恐縮ですが）この記事を題材に、みていきましょう

https://qiita.com/cog1t0/items/23e0950da0fa52419bdf

# サッと見る
## アウトラインでだいたいわかる？
![スクリーンショット 2024-01-07 1.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/ded47c4d-8e73-67d5-e9e2-c083d602e37b.png)
画面右側に記事の概略が載っているので、まずはそちらで記事のアウトラインを確認しましょう。
「アウトラインがわかりやすい」というのは以下のバロメーターでもあります
-  「記事の内容が整理されている」
- 「読む人のことを考えられている」


## ファーストビューには何が表示されている？
![スクリーンショット 2024-01-07 1.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/33059520-cebf-76df-1679-b38569963a82.png)
記事を開いて、スクロールなしで最初に表示される画面のことを「ファーストビュー」と呼びます。
ファーストビューが文字ばっかりだと読む気がなくなってしまうので、図やTwitterの動画など、興味を強く惹くものが詰め込まれているようなものを目指しましょう

## タグはどんなのを使ってる？
![スクリーンショット 2024-01-07 1.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/82ddff6d-7121-24e0-787e-5c5f476233cc.png)
タグは、「どういう人に興味を持ってもらいたいか」ということを表しています。
そのタグのついた新着記事を

# じっくり見る
記事の概要をサクッと掴んだら、スクロールしてじっくり読んでみましょう

## 図でどんなことを説明してる？
![スクリーンショット 2024-01-07 1.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/4f3a3248-c936-b49f-f5d9-f6838216616a.png)

これから作るものを、一発で伝えるには図を載せると効果抜群です。
図にするとこんな効果があります
- 登場人物が整理される
- 「いつ、どういうときに使うのか？」のシチュエーションが伝わる
- 何を使って作るのかがすぐ分かる
- データの流れがすぐ分かる

図の作成は、パワーポイントでもいいですが、[Canva](https://www.canva.com/)は使いやすくて時短になります。

## 記事を読んだら真似して作れそうだな！と思わせるにはどのくらい丁寧に書いたらいいのか
![スクリーンショット 2024-01-07 1.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/32373f3e-e1a5-cdcb-f7ce-4c2224dc83b1.png)
記事を読んで、「真似して作れそうだな！」と思わせるには、どのくらいの粒度で解説をしたらいいかを掴んでみましょう。
ただ、事前準備などの解説は「詳細はこちらの記事を参考にしてください」で逃げることも可能です。（全部書いちゃうと長くなりますし）

## この書き方どうやるんだろう？
![スクリーンショット 2024-01-07 1.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/5ab1cc6d-f9ce-39c3-c64a-36639a097505.png)
![スクリーンショット 2024-01-07 1.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/762726c2-282e-d8c9-f907-fcebdf7f8594.png)

記事を読んで、この書き方はどうやるんだろ？と思ったら、マークダウン記法でどう書かれているか直接確認してみましょう

マークダウン記法を体系的に学ぶには[こちら](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)を参照

## 「作ってみた」を超えてるか
![スクリーンショット 2024-01-07 1.49.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/29fad24a-4049-e0e2-9783-cb6f88ea9897.png)

だいたいの人が、初めて記事を書くことになると思うので、「作ってみた」的な記事を書くのに精一杯になっちゃうと思いますが、作ってみてどう思ったか？なにがわかったか？何がわからなかったのか？など、一歩踏み込んで分析してみることが大切です。

# 最後に
他の人の記事を読んでみる、というのはとても大切なことですが、ざっくりと指針があれば便利かなと思って今回作ってみました！
非常にざっくりとした解説だったので、随時内容を追加していきたいと思います！
**まずは、手を動かす！**
**レビュー前に誰かに見てもらう**というのもとても有効です！

がんばっていきましょう！

余力があればQiita公式のガイドラインもチェックしてみましょう
[良い記事を書くためのガイドライン](https://help.qiita.com/ja/articles/qiita-article-guideline)
MusicGenを使用して自然言語から音楽を生成する方法

![スクリーンショット 2024-01-07 015308.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/8c33fa06-05e2-69e4-4e8d-7158324039f0.png)

## はじめに
この記事では、Metaの音楽生成ツールであるAudio CraftのMusicGenを使用して、テキストから音楽を生成する方法を紹介します。MusicGenは学習済みモデルを活用して、テキスト記述に基づいてオリジナルの音楽を生成することができます。この記事では、ステップごとに手順を提供し、読者が独自の音楽を生成するための知識を提供します。

## ステップ1: 環境のセットアップ
まず、必要なライブラリとモデルをセットアップします。以下の手順に従って、環境を整えて音楽生成の準備をします。

1.1. Audio Craftのリポジトリをクローンします。
```
!git clone https://github.com/facebookresearch/audiocraft/
%cd audiocraft
```
1.2. MusicGenをインストールします。
```
!pip install -e .

from audiocraft.models import MusicGen
model = MusicGen.get_pretrained('facebook/musicgen-small')
model.set_generation_params(
    use_sampling=True,
    top_k=250,
    duration=30)
```
## ステップ2: テキストから音楽の生成と再生
次に、指定したテキスト記述に基づいて音楽を生成し、再生する方法を説明します。

2.1. テキストを指定して音楽を生成します。今回は「雅楽とJ-POPの融合」をテーマにしてみましょう。
```
from audiocraft.utils.notebook import display_audio
output = model.generate(
    descriptions=['Fusion of Gagaku and J-pop'],
    progress=True, return_tokens=True)
```
2.2. 生成した音楽を再生して確認します。
```
display_audio(output[0], sample_rate=32000)
```
## ステップ3: 音楽の保存
次に、生成した音楽をファイルに保存する方法を説明します。以下の手順に従って、音楽を保存します。

3.1. 保存先のファイルパスを指定します。
```
import soundfile as sf
import torch

output_file_path = "generated_music.wav"  # 保存先のパスを指定してください
```
3.2. 音楽データをホストメモリにコピーします。
```
output_cpu = output[0].cpu().numpy()
```
3.3. 音楽データの形状を修正します。
```
output_cpu = output_cpu.squeeze()  # 余分な次元を削除
```
3.4. 音楽を指定したファイルパスに保存します。
```
sf.write(output_file_path, output_cpu, sample_rate)
print("音楽を保存しました:", output_file_path)
```
今回は保存した曲をhttps://me-qr.com/ja/music/19768879
でQRコードにしてみました！雅楽とJ-POPは表現できてますかね、、、😅
![Fusion of Gagaku and J-pop (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/074fb431-d37e-276a-9296-8d2caf874ed3.png)
## 最後に
この記事ではMusicGenを使用してテキストから音楽を生成し、保存する方法を詳細に説明しました。皆さんもMusicGenを使ってオリジナルで創造的な音楽を生成してみてください！
Next.jsでMSWを導入しようとしたら苦戦した

# MSW(Mock Service Worker)とは
APIモッキングライブラリ
Service Workerを使ってリクエストをインターセプトし、事前にモック化したレスポンスを返す。

# Next.jsで導入
https://mswjs.io/docs/getting-started
こちらの手順に沿って一通り設定を終え、
いざローカルを立ち上げようとするとエラーが出る。
```
Module not found: Package path ./browser is not exported from package /xxxxxx/node_modules/msw (see exports field in /xxxxxx/node_modules/msw/package.json)
```
対象のファイルを見にいってもちゃんとexportされている:thinking:

# 調査
色々調べていたらissue発見
https://github.com/mswjs/msw/issues/1801

原因
> The error happens during build time (not runtime). None of nodeHelpers are never called in browser and they are not even included in browser bundle thanks to tree-shaking. Webpack though still needs to go through them during build and because of ./node being blocked in browser it errors as it can't find the entry point.

mswでこれを解決することはなさそうで、closeされてた。
> I'm fairly confident our exports are correctly written. We forbid msw/node imports in the browser and msw/browser imports in Node.js. In the end, it's your framework's compiler that evaluates those, and so it must be configured correctly by the framework to understand what modules should use what export condition.


# 解決
next.config.jsにwebpackの設定を書き加えて解決した。
```javascript: next.config.js
const nextConfig = {
	...
	webpack: (config, { isServer }) => {
		if (isServer) {
			// next server build => ignore msw/browser
			if (Array.isArray(config.resolve.alias)) {
				config.resolve.alias.push({
					name: 'msw/browser',
					alias: false,
				});
			} else {
				config.resolve.alias['msw/browser'] = false;
			}
		} else {
			// browser => ignore msw/node
			if (Array.isArray(config.resolve.alias)) {
				config.resolve.alias.push({ name: 'msw/node', alias: false });
			} else {
				config.resolve.alias['msw/node'] = false;
			}
		}
		return config;
	},
    ....
};

module.exports = nextConfig;

```
ABC335の記録

# はじめに
今年もABCやっていきます。

https://atcoder.jp/contests/abc335

成績：ABC3完(550)

# A
$S$の-2文字目までを出力して末尾に4を足す。
```python:A
s = input()
print(s[0:-1]+'4')
```

# B
3重ループにすれば勝手に辞書順になってくれる。
$N \le 21$なので3重ループでも余裕。
```python:B
n = int(input())
for i in range(n+1):
    for j in range(n+1):
        for k in range(n+1):
            if i + j + k <= n:
                print(i, j, k)
```

# C
典型90で見たことある形式で、すべての座標を毎回計算していたらTLEだろうなと直感した。
（ちょっと形式は違うけど……）

https://atcoder.jp/contests/typical90/tasks/typical90_ar

で、頭の座標を毎回メモしておいて2種類目のクエリが来たら計算する、で対処できそうと考えて観察していると、パーツ$i$の挙動は

・頭が$i-1$回移動するまでは$(i,0)$から$(1,0)$まで動く
・頭が$i$回移動した後は、頭が$i-1$回前にいた座標に位置する
（移動回数を$m$とするとパーツ$i$の座標 = 移動回数$m-i+1$の時の頭の座標）

となることを発見した。
ということで、座標$(x,y)$と移動回数cntを管理すれば計算できる。

```python:C
n , q = map(int,input().split())
loc = []
cnt = 0
x = 1
y = 0
loc.append([x,y])
for _ in range(q):
  num, query = map(str, input().split())
  if num == '1':
        cnt += 1
        if query == 'R':
            x += 1
        if query == 'L':
            x -= 1
        if query == 'U':
            y += 1
        if query == 'D':
            y -= 1
        loc.append([x,y])
  if num == '2':
        query = int(query)
        if cnt <= query - 1:
            print(query - cnt, 0)
        if cnt >= query:
            print(loc[cnt - query + 1][0], loc[cnt - query + 1][1])
```

# D
配置は何でもいいわけなので、渦巻き状にするのが最も考えることが少なそうと感じた。
まず全部ゼロの$n \times n$の二次元配列を作成する。
左上からスタートして、壁に当たるかすでに数字が書かれているマスに当たったら方向を90度変えればいいな、と考えていたが実装が間に合わずタイムアップ。

公式解説を見るとこのやり方で問題なさそうなので進めてみる。
```python:D
n = int(input())
ls = [[0 for i in range (n)] for j in range(n)]
ls[(n-1)//2][(n-1)//2] = 'T'
num = 1
cnt = 0
x = 0
y = 0
while True:
    if ls [x][y] == 'T':
        break
    if ls[x][y] == 0:
        ls[x][y] = num
        num += 1
        if cnt%4 == 0:
            y += 1
        if cnt%4 == 1:
            x += 1
        if cnt%4 == 2:
            y -= 1
        if cnt%4 == 3:
            x -= 1
    if x == n or y == n or ls[x][y] != 0:
        if cnt%4 == 0:
            x += 1
            y -= 1
        if cnt%4 == 1:
            x -= 1
            y -= 1
        if cnt%4 == 2:
            x -= 1
            y += 1
        if cnt%4 == 3:
            x += 1
            y += 1
        cnt += 1

for i in range(n):
    print(*ls[i])
```
進んでいって壁か既に値が入力されていた場合は戻って方向を変える、という挙動になっている。
二次元配列のどの領域がどの座標に当たるかを丁寧に考えれば問題なかった。
このくらい時間内に実装できるようになりたいところ。