OmniAICreator/Qiita-1.07M huggingface dataset:
UnityEditorでEditor実行時にErrorPauseを強制的に解除する

作業環境
Unity2022.1.9f1

以下のスクリプトをEditorフォルダ以下に入れてください

```
using UnityEditor;

public class ForceDisableEditorErrorPause
{
    [InitializeOnEnterPlayMode]
    static void RunOnEnterPlayMode()
    {
        var assembly = typeof(Editor).Assembly;
        var type = assembly.GetType("UnityEditor.ConsoleWindow");
        var consoleWindow = EditorWindow.GetWindow(type);
        var methodInfo = type.GetMethod("SetConsoleErrorPause");

        methodInfo.Invoke(consoleWindow, new object[] {false});
    }
}
```

実行時にConsoleウィンドウが前面に出てきちゃうので、GetConsoleErrorPauseがtrueだったら。という風にしてもよさそうです
プログラミングスクールに通ってよかった話

<h1>この記事について</h1>
<p>この記事では、実際にプログラミングスクールに通っていた経験から、そのメリットとデメリットをまとめています。</p>
<h1>利用していたプログラミングスクール</h1>
<dl>
<dt>スクール名</dt>
<dd>テックアカデミー</dd>
<dt>受講期間</dt>
<dd>８週間</dd>
<dt>料金</dt>
<dd>２０万円ちょっと</dd>
<dt>コース</dt>
<dd>フロントエンド（HTML/CSS/JavaScript）</dd>
</dl>
<h1>受講概要</h1>
<p>
私が受講したフロントエンドコースでは、HTML、CSS、JavaScriptをみっちり学習できるといったコースでした。基礎学習には、カリキュラムに沿って、学校教育のように基本から学んでいくといった形でここまでは無料のプログラミング勉強サイト（Progateなど）で学べるようなことと全く同じです。違うところはというと、週に一回メンターと呼ばれる現役エンジニアの先生と面談し、わからないことなどを直接質問できる点です。</p>
<p>基礎学習が終わるとメンターさんから課題を言い渡され、毎週その課題に励むといった流れで、最後の１週間は、自分が作りたいサイトを作ってそのレビューをいただくといった流れでした。</p>
<h1>メリット</h1>
<ul>
<li>現役エンジニアであるメンターと直接話すことができる</li>
<li>やる気がぶちあがる</li>
<li>受講後に転職支援してもらえる</li>
</ul>
<p>個人的には、一つ目のメンターさんと直接話すことができるということに一番価値を感じました。学んでいるプログラミング言語の技術面はもちろんですが、どんな言語を触るにしても覚えておかないといけない心構えを学ぶことができました。<br><br>
また、受講料を払うため、払ったらやるしかない！といった具合にやる気にならざるを得ないですｗ<br><br>
コース受講後には、転職の支援を行ってくれるサービスを受けることができます。</p>
<h1>デメリット</h1>
<ul>
<li>料金が高額である</li>
<li>無料の教材でもある程度学べる内容</li>
<li>メンターにあたりはずれがある</li>
</ul>
<p>
まずは受講料金、、金銭的には痛い出費でしたが、私のような意志の弱い人間には踏み出すきっかけになったかなと思いますのでメリットともデメリットとも取れますｗ
<br><br>
学べる技術については、私の場合は、無料で学べる教材でもいいかなってレベルしか学ぶことができませんでしたが、これはその人の進捗次第です。私は、かなり理解に苦しんだので進捗は遅かったと思います。
<br><br>
メンターにあたりはずれがある、これはあるでしょう。私は、厳しめのメンターさんが担当してくださり、最初こそ説教に近いような感じで話されたこともありましたが、甘やかされるより断然いいなと感じていました。
</p>
<h1>さいごに</h1>
私の意見としては、プログラミングスクールを最初の手段にするのは賛成はしません。現在では、無料の学習サイトが数多くありますのでそちらを利用してみるのが第一の手段としてはいいと思います。その中でわからないことは調べるなど、ある程度自分で走ってみようとすることが必要ですし、その中で得た知識の方が記憶に残ります。
プログラミングスクールでは技術面以外での恩恵を受けることができますので、ご自身の求めるものに合っていれば受講してみてはいかかでしょうか。
公務員からSESに転職した話（未経験転職）

<h1>この記事について</h1>
<p>本記事は、公務員からSES会社へ転職する際に行っていたことに関する記事です。<br>これから未経験での転職を考えている方の参考となれば幸いです。</p>
<h1>経歴</h1>
<p>地方国立大学理系学部を卒業し、新卒から５年間公務員として勤務。</p>
<p>2022年6月に転職活動、2023年1月からSES会社に勤務し、現在は研修中。</p>
<h1>転職のきっかけ</h1>
<p>このまま公務員で働いていることへの不安や自分自身の挑戦のために転職を決意しました。主に以下の不安と思いがありました。</p>
<ul>
<li>挑戦したい</li>
<li>他業界の同年代に対する引け目</li>
</ul>
<p>これまでの人生、自身で思い切った決断をしてこなかったと感じていた私は、自分で決めた道であがいてみたいという思いが強くありました。また、公務員という安定の職について、親族は喜んでくれましたが、給与面の低さや自身のスキル向上を感じられていないことに対する不安、そしてなによりも、定年まで働いたときの自分の人生がリアルに想像でき、<b>このままでは後悔する</b>と感じたことが転職のきっかけです。</p>
<h1>転職までにやっていたこと</h1>
2022年6月に転職の内定をいただくまでに行っていたことについてまとめます。
<ul>
<li>2019年10月　HP制作に興味を持ち、スクールに入校</li>
<li>2020年 2月　第1次転職活動、転職断念</li>
<li>2020年 3月　java学習開始。挫折...</li>
<li>2022年 1月　ITパスポート学習開始</li>
<li>2022年 4月　ITパスポート取得</li>
<li>2022年 5月　転職活動開始</li>
<li>2022年 6月　SES会社内定</li>
</ul>
<p>はじめにプログラミングに興味を持ったのは、HP制作でした。プログラミングスクールに入校し、２カ月間HTML、CSS、JavaScriptの学習を行いました。プログラミングスクールに関する記事も後日まとめます。</p>
<p>こうしてHP制作に熱中した私は、自作のHP３作品と自身のポートフォリオサイトを作成し、初めての転職活動に挑みました:fire:<br>この時の転職のターゲットは、WEB制作系の会社２社、システム開発（自社）を２社受けました。なんとか面接に進めた会社では、未経験でエンジニアとして採用するよりも営業として採用がしたいとの話になり、自身の思いとマッチしていなかったこともあり、この時は転職を断念しました。</p>
<p>この転職活動で気づいたのですが、私の住むエリア（東海圏）は、<b>WEB制作系の会社の求人は少なく、システム開発系の会社の求人が多い</b>ということです。</p>
    <p>当時は転職を断念したものの、プログラミング自体は面白いと感じていた私は、システム開発系の言語に学習をシフトしようと考えました。<br>そこで、書類選考で落ちたシステム会社さんに何からできるようになったらエンジニアになれるか聞いたところ、<b>「未経験ならJavaシルバーをまず取得してみるところから初めてみてください。」</b>とアドバイスをいただき、早速、javaの学習に取り組みました。<br>しかし、挫折しました。:sob:</p>
<p>この後、２年間は、コロナの流行もあり、現職に打ち込みました。</p>
<p>２年ぶりに発起し、ITパスポートを取得、javaの学習も再開。無事にSES会社に就職しました:fireworks:</p>
<h1>面接で意識したこと</h1>
<p>特に意識したことは、１つだけ、<b>やる気を見せる</b>ことです。やる気は最低限必要なものでありながらも、業界未経験者にはこれをアピールするしかないと思っています。<br>私の場合はそのアピール手段が「資格取得」でした。資格取得の目的と取得までの過程、そして今後も取得する資格を面接で話したときには好印象を持っていただけた実感があります。面接の際、私は「基本情報を取得します。」と宣言し、その後、宣言どおり取得いたしました。</p>
<p>私の場合は、資格という形でやる気を見せましたが、手段は人それぞれだと思います。「現職でITを活用した業務改善の実例」や実際に「自身でサービスをリリースする」など、自分が自信を持ってやる気をアピールする手段を選ぶのがいいと思います。</p>
<p></p>
<h1>これから転職活動をする人に向けて</h1>
<p>私の経験から感じたことです。</p>
<dl>
<dt>第一に転職市場を把握する</dt>
<dd>学習したものの、転職を考えていたエリアでは求人がないといった事態になったら泣けます。</dd>
<br>
<dt>資格取得をする</dt>
    <dd>未経験の人がやる気を見せるには、資格取得か制作物を作成し、熱意を見せるしかないと思います。現場で資格は役に立たないと思いますが、知識は得ることができます。何もしないよりマシです。</dd>
<br>
<dt>転職の相談はしても、最後は自分の意志を貫く</dt>
<dd>相談しても止められることの方が多いと思います。しかし、いざ転職が決まれば引き止めてくれた人も応援してくれます。自分のために自分で選びましょう。</dd>
</dl>
GitHubとの接続時にWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!と出てきた際の対処法

# TL; DR

次のコマンドで対処できると思います。

```sh:対処方法コマンド
ssh-keygen -R github.com
# ssh -T git@github.com  # 無くてもよさそう（後述）
ssh-keygen -R 20.27.177.113  # github.comのIPアドレス
ssh -T git@github.com
```


# 概要

`git pull` する際、次のようなWarningメッセージが出るようになりました。
残しておくのも気になるので、消す方法を調べました。

```txt:Warningメッセージ
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Please contact your system administrator.
Add correct host key in ~/.ssh/known_hosts to get rid of this message.
Offending RSA key in ~/.ssh/known_hosts:1
Password authentication is disabled to avoid man-in-the-middle attacks.
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
```


# 対処方法

他記事にもある通り、GitHub側でhost-keyが変更されたことが原因のようです。

対処方法ですが、おそらく環境位により微妙に異なるかと思うので、上記Warningメッセージが出ている場合での方法を提示します。
対処方法コマンドを、以下に記します。

```sh:対処方法コマンド
ssh-keygen -R github.com
ssh -T git@github.com  # 無くてもいいかも？（後述）
ssh-keygen -R 20.27.177.113  # github.comのIPアドレス
ssh -T git@github.com
```

https://zenn.dev/tfutada/articles/1abfe7a87e7c00

https://qiita.com/making111/items/5b482df89acbdd68d2e2

https://superuser.com/questions/421004/how-to-fix-warning-about-ecdsa-host-key


## 詳細説明

### 1回目対処時

1回目の `ssh-keygen -R github.com` で、次のWarningメッセージに変化しました。

```txt:2回目のWarningメッセージ
Warning: Permanently added 'github.com' (ECDSA) to the list of known hosts.
Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '20.27.177.113'
Offending key for IP in ~/.ssh/known_hosts:40
```

### 2回目対処時

2回目の `ssh -T git@github.com` で、次のWarningメッセージに変化しました。
おそらくですが、2回目と4回目のコマンドに違いはないため、4回目のコマンドだけ実行しても解決できるかもしれません。

```txt:3回目のWarningメッセージ
Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '20.27.177.113'
Offending key for IP in ~/.ssh/known_hosts:40
Matching host key in ~/.ssh/known_hosts:55
```

### 3回目対処時

3回目の `ssh-keygen -R 20.27.177.113` で、次のWarningメッセージに変化しました。

```txt:4回目のWarningメッセージ
Warning: Permanently added the ECDSA host key for IP address '20.27.177.113' to the list of known hosts.
```

### 4回目対処時

4回目の `ssh -T git@github.com` で、全てのWarningメッセージが無くなりました。
Node.jsからngrokを使ってみた。(JavaScriptライブラリのサポート)

# はじめに

2023年3月31日にngrokからニュースレター(メール)を受信しました。

![スクリーンショット 2023-03-31 9.37.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5705d844-bace-5ef8-7ff6-8c8fcb22c7fc.png)

Goプログラム、Rustプログラムからngrokを使えるようになったようです。

GitHubを除いたところ、Node.js版もリリースされていたので試してみました。

https://github.com/ngrok/ngrok-js

# 手順

npmモジュールをインストールします。

```bash
$ npm install @ngrok/ngrok
```

サンプルコードを試します。

```javascript:app.js
const http = require('http');
http.createServer(
  function(req,res){res.writeHead(200);
  res.write('Hello');
  res.end();
} ).listen(8081); 

var ngrok = require('@ngrok/ngrok');
new ngrok.NgrokSessionBuilder().authtokenFromEnv().connect().then((session) => {
  session.httpEndpoint().listen().then((tunnel) => {
    console.log('tunnel at: ' + tunnel.url());
    tunnel.forwardTcp('localhost:8081');
  })
});
```

nodeプログラムを実行します。

```bash
$ node app.js 
$ tunnel at: https://2005-2400-2410-d461-3100-7833-cafd-f216-5fb.jp.ngrok.io
```

表示されたURLへブラウザでアクセスするとエラーが表示されました。

![スクリーンショット 2023-03-31 9.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/83a46bf1-b533-dc5f-d3ef-6b10fd0081c7.png)

アクセストークンが設定されていないという内容です。
ドキュメントには記載されていませんが、コードの内容を確認して、環境変数(NGROK_AUTHTOKEN)にアクセストークンを設定する必要があります。

ngrok.ioのダッシュボードへアクセスして、アクセストークンの情報を取得します。

![token_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/384ac5b9-7867-44d1-0cc9-84d44fb354ab.png)

環境変数(NGROK_AUTHTOKEN)を設定して、再度nodeプログラムを実行します。

```bash
$ NGROK_AUTHTOKEN=XXXXXXXXXXXXXXXXXXXX node app.js 
$ tunnel at: https://f832-2400-2410-d461-3100-7833-cafd-f216-5fb.jp.ngrok.io
```

無事にアクセスできました。

![スクリーンショット 2023-03-31 9.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/313bfd57-f0d6-bbf1-764c-cde3b9c05ace.png)
NAPT(IPマスカレード)について

## NATとは
- Network Address Transitionの略
- LAN内の機器からインターネットへ接続する場合、プライベートアドレスからグローバルアドレスへ変換する必要がある。この変換を自動的に行う機能をNATという
### NATの図
![NAT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092613/44b4df31-dbc5-e694-bde1-6bc22bb0cace.png)

## 問題点
LAN内に複数のPCが接続されている場合でも一つのグローバルアドレスに変換される
👇
パケットが宛先から帰ってくる時、グローバルアドレスをもったルーターに返ってくる
👇
NATテーブルを見てもどのLAN内の端末にパケットを送信するべきかわからない

## NAPT
- NAT＋ポート番号を変換する
- ポート番号と通信端末を紐づけることで、LAN内の端末を識別可能にする
NAT : プライベートIP↔グローバルIP
ポート番号変更 : LAN内の端末の識別
<table class="confluenceTable"><colgroup><col /><col /><col /><col /></colgroup><tbody><tr><th class="confluenceTh">変換前ポート番号</th><th class="confluenceTh">変換前IPアドレス</th><th class="confluenceTh">変換後ポート番号</th><th class="confluenceTh" colspan="1" width="">変換後IPアドレス</th></tr><tr><td class="confluenceTd">10000</td><td class="confluenceTd">192.168.1.2</td><td class="confluenceTd">20000</td><td class="confluenceTd" colspan="1" width="">1.1.1.1</td></tr><tr><td class="confluenceTd">10001</td><td class="confluenceTd">192.168.1.3</td><td class="confluenceTd">20001</td><td class="confluenceTd" colspan="1" width="">1.1.1.1</td></tr></tbody></table>


![NAPT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092613/f7c00244-9553-7983-a0a1-4cf3582c5738.png)
----
参考記事
<a href="https://www.itbook.info/study/nat4.html">NAPT(IPマスカレード)</a>
GitHubに接続できなくなった！

# はじめに

GitHubを使おうとしたらワーニングメッセージが表示されて接続できなくなったので、その時の対応メモを残しておきます。
環境はAWSのEC2でしたが、Macでも同じ現象が起きました。

# 状況

GitHubでpullしようとしたら次のようなメッセージが表示された。

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
```

これまで問題なく使えていたのに突然このような状態になった。

# 原因

GitHubがセキュリティ対策のために公開鍵情報を変更したため
詳細は[こちら](https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/)

# 対応

```
$ ssh git@github.com

# 同じエラーが出ることを確認する

$ ssh-keygen -R github.com

# Host github.com found: line XX といった表示される

$ ssh git@github.com
 
:
:
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
# このようなメッセージが表示されるのでyesと入力する

$ ssh git@github.com

# 確認する

PTY allocation request failed on channel 0
Hi xxx! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

# このように表示されればOK
```

# 他のやり方

known_hostsに他のホスト情報が書かれていなければ、known_hosts情報を丸ごと消してしまって良いかもしれません。

```
$ mv ~/.ssh/known_hosts ~/.ssh/known_hosts.old

$ ssh git@github.com
```


# 最後に

GitHubの公開鍵が変更になったことでこのような対応を行いましたが、他のホストでも同様のことが起きる可能性がありますので、参考になればと思います。

最後に対応にあたって情報提供してくれた、M氏、K氏、ご協力ありがとうございました。
備忘録： watch コマンド

## いっけなーい、仕事を会社の端末でやりっぱだった！

こんな時 "screen" かけておけば大丈夫？？
いや screen って detach されてないと取れないよ？
orz...

## Bingで検索してみた（徒労）

あれはやっぱり一般事務向けです（偏見）

## Google で探す（いまでも使える？）

watch コマンド出してきました。おー、忘れてたあこれだ。

## watch こまんどのつかいかた

* w します。
<pre>USER       TTY      FROM                                LOGIN@  IDLE WHAT
strnh       pts/0    192.168.1.5                      Thu02PM     7 /usr/bin/
strnh       pts/1    192.168.1.5                       Thu04PM 15:15 -sh (sh)
strnh       pts/2    smtp.example.com                   9:16AM     - w
strnh       pts/3    smtp.example.com                   9:29AM     9 -sh (sh)
b

</pre>

* 乗っ取りたいセッション TTY を確認出来たら、おもむろに
<pre>
$ sudo watch -iW pts/1
</pre>

とかやります。　-i はインタラクティブ、-W は入力オーバライド。

## 悪用厳禁

* 自組織、自宅サーバ以外で使うのは控えたほうがいいと思います。 
* linux には "chvt" というコマンドがあります。
*
ChatGPTに英語をカタカナにしてもらう

# どういう記事？
- VOICEVOXのような読み上げソフトは便利ですが、英語をアルファベットのまま読んでしまうので聞き取りづらい場合があります。
- よく挙げられる対策は辞書ベースなので専門性が高い論文などに効果がありません。
- なのでZero-shot性能の高いChatGPTに英語をカタカナにしてもらおうという記事です。

# プロンプト
以下がプロンプトになります。

```
あなたは優秀なアシスタントです。

以下の疑似スクリプトを実行して結果を出力してください。

疑似スクリプト：
for word in ['英単語1', '英単語2', ...]:
    word = カタカナにする(word)
    print(word)

出力：
```

プログラムで使用しやすいように出力のフォーマットが一定になりやすいようにしました。

# 入出力例
入力1：
```
あなたは優秀なアシスタントです。

以下の疑似スクリプトを実行して結果を出力してください。

疑似スクリプト：
for word in ['Xavier', 'ImageNet', 'CHARACTERIZING']:
    word = カタカナにする(word)
    print(word)

出力：
```

出力1：
```
ザビエル
イメージネット
チャラクタライジング
```

入力2：
```
あなたは優秀なアシスタントです。

以下の疑似スクリプトを実行して結果を出力してください。

疑似スクリプト：
for word in ['ARCHITECTURAL', 'SpectralNorm', 'orthogonal', 'GAN', 'BigGAN', 'Wang']:
    word = カタカナにする(word)
    print(word)

出力：
```

出力2：
```
アーキテクチャル
スペクトラルノルム
オーソゴナル
ジーエーエヌ
ビッグジーエーエヌ
ワン
```

入力3：
```
あなたは優秀なアシスタントです。

以下の疑似スクリプトを実行して結果を出力してください。

疑似スクリプト：
for word in ['RepVGG', 'ConvNeXt', 'ConvNet', 'Lion', 'SwinV2']:
    word = カタカナにする(word)
    print(word)

出力：
```

出力3：
```
レプブイジージー
コンブネクスト
コンブネット
ライオン
スウィンブイツー
```

# 総評
固有名詞を含め良くカタカナ化できていると思います。こういうときに便利ですねChatGPT
この出力形式ならデータが利用しやすいのもグッド！

# 追記
APIのRate Limitが大丈夫なら、1単語ごとに以下のプロンプトでカタカナ化する方が経済的っぽいです。

```
English: <word>
Japanese Katakana Only:
```
Stylelintがv15からPrettierと書式フォーマットルールがごっつんこしなくなったゾ

## はじめに

リンターとフォーマッターはそれぞれが担う役割が異なります。
リンターは構文チェック、フォーマッタは書式のチェックを行うものです。

CSSに関して、前まではリンターであるStylelintとフォーマッタであるPrettierを併用すると、書式ルールについて競合するという問題がありましたが、これが解消されたようなので、これをまとめていきます。

※Stylelintの具体的な導入やその他変更点については↓の記事で書いています。

https://qiita.com/heeroo_ymsw/items/3fca90ba41986ebf6cc5

## Stylelint v15で76の書式ルールが非推奨に

v15から`color-hex-case`や`property-case`など、76個の**書式ルールが非推奨**になりました。
非推奨となったルールについては以下をご参照ください。

https://stylelint.io/user-guide/rules/#deprecated

非推奨となった理由は、現在はPrettierなどのフォーマッタが存在するため、書式のフォーマットについてはそれらのフォーマッタに任せ、Stylelintではエラー回避のための書式以外のルール策定と維持に重きを置いていく方針にしたためであると説明されています。

v15では非推奨とするに留まっていますが、次回のメジャーリリースでは削除も辞さないとのことですので、本リリースから**該当のルールは使わない**ようにするのが良さそうです。

## Prettierとの併用

さて、書式ルールをStylelintに任せていた場合、Prettierとの併用が必要になったということですが、そもそも、前のバージョンだとPrettierと併用すると問題がありました。

その問題とは、Prettierで整形したものを、Stylelintが書式エラーとして検出してしまうという問題です。
この対策として、競合する可能性のあるStylelintのルールをオフにする`stylelint-config-prettier`を利用する必要がありました。

しかし、v15のリリースによってこの拡張ツールを利用しなくてもよくなったようです。

> you may no longer need to extend Prettier's Stylelint config as there should be no conflicting rules[^1]
[^1]: https://stylelint.io/migration-guide/to-15/#deprecated-stylistic-rules

「may」と言われるといささか不安ですが、stylelint-config-prettierのREADMEを参照すると、

> If you are using v15 or higher and are not making use of these deprecated rules, this plugin is no longer necessary.[^2]
v15以降を使っている方で、これらの非推奨ルールを利用していない場合は、このプラグインは**もう必要ありません**。
[^2]: https://github.com/prettier/stylelint-config-prettier

と記載がありました。

ということで、素のStylelintとPrettierをそのまま併用できるようになったようです。どんどはれ。

## まとめ

早速Stylelint v15とPrettierを併用していますが、今のところルールの競合の問題は無さそうなので、この運用で今後も進めていきたいと思います。

Prettierはあまり自由が効かない印象ですが、それが逆にフォーマッタとしては書式の「統一」に適しているのかもしれませんね。
PythonでAPIkeyを用いたGCPの使用法

# APIkeyを使うのは多分非推奨です
```
client_gcp = texttospeech.TextToSpeechClient(client_options={"api_key":os.environ.get("API_KEY_GCP"),"quota_project_id":"プロジェクト名"})
#たぶんjsonとかでやってるやつにclient宣言してるところがあるのでそこに
```
PythonでTTS(Text-to-Speech)を使うときに少し迷ったので備忘録です(Qiita書いたことないので記法は適当です)
RubyでAtCoder ABC293(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC293のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。
# A - Swap Odd and Even
https://atcoder.jp/contests/abc293/tasks/abc293_a
```ruby:a-293.rb
s = gets.chomp
(s.size / 2).times do|i|
    s[2 * i], s[2 * i + 1] = s[2 * i + 1], s[2 * i]
end
puts s
```
<追記>
コメントでいただいた別解になります。sliceメソッドを使うことで隣り合う要素のswapを実現しています。
```ruby:別解
s = gets.chomp.each_char
puts s.each_slice(2).map { |a, b| b + a }.join
```
## 解説
問題文の通りに2iと2i+1の文字をswapして、swap後の文字列を出力すればOKです。

# B - Call the ID Number
```ruby:b-293.rb
# 修正前
n = gets.to_i
a = gets.split.map(&:to_i)

hash = {}
n.times do|i|
    next if hash[i + 1]
    hash[a[i]] = true
end

ans = []
for i in 1..n
    next if hash[i]
    ans << i
end
puts ans.size
puts ans.join(" ")
```
```ruby:b-293.rb
# 修正後
n = gets.to_i
a = gets.split.map(&:to_i)

hash = {}
a.each_with_index do|i, j|
    hash[i] = true unless hash[j + 1]
end

ans = *(1..n).select{ |i| !hash[i]}
puts ans.size
puts ans.join(" ")
```
## 解説
まず、呼ばれた人を連想配列hashに記録します。そして、1からnの番号の人で呼ばれなかった人をans配列にもたせます。最後に呼ばれなかった人数と番号を出力します。

# C - Make Takahashi Happy
```ruby:c-293.rb
# 修正前
h, w = gets.split.map(&:to_i)
a = Array.new(h){ gets.split.map(&:to_i)}

ans = 0
[*(0...h + w - 2)].combination(h - 1) do|arr|
    route = Array.new(h + w - 2, 1)
    arr.map{ |factor| route[factor] = 0 }

    i, j = 0, 0
    temp = [a[i][j]]
    route.each do|factor|
        factor == 0 ? i += 1 : j += 1
        temp << a[i][j]
    end
    ans +=1 if temp.uniq.size == temp.size
end
puts ans
```
```ruby:c-293.rb
# 修正後
h, w = gets.split.map(&:to_i)
a = Array.new(h){ gets.split.map(&:to_i)}

ans = 0
[*(0...h + w - 2)].combination(h - 1) do|arr|
    route = Array.new(h + w - 2, 1)
    arr.each{ |factor| route[factor] = 0 }

    i, j = 0, 0
    hash = {a[i][j]=>true}
    route.each do|factor|
        factor == 0 ? i += 1 : j += 1
        break if hash[a[i][j]]
        hash[a[i][j]] = true
    end
    ans += 1 if hash.size == h + w - 1
end
puts ans
```
<追記>
コメントでいただいた別解になります。私はスタックを使って解きましたが、このように再帰を使って解くこともできます。
```ruby:別解
h, w = gets.split.map(&:to_i)
field = Array.new(h) { gets.split.map(&:to_i) }

count = 0

define_method(:go) do |x, y, visited|
  return if x == w || y == h
  a = field[y][x]
  return if visited.include?(a)
  visited += [a]
  if x == w - 1 && y == h - 1
    count += 1
    return
  end
  go(x + 1, y, visited)
  go(x, y + 1, visited)
end

go(0, 0, [])
puts count
```
## 解説
（他の方の提出結果を参考にしました）

オフセットで考えて、(0, 0)から(h-1, w-1)に移動するので移動回数はh+w-1となります。ここで、下に移動する回数はh-1回となります。なので、combinationメソッドを使って下に移動する場合はroute配列の要素を0としています。そして、要素がすべて異なればansをインクリメントするようにしています。

メモ
・mapメソッドは新たに配列を生成して、それを返している。

# 終わりに
今回のC問題は少し難しめの全探索系でした。「より簡素なコードにするにはどうしたらよいのか」を考えながらコードを書くようになり、それを自然に行えるようになればコーディングスピードも上がりそうですね！

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166

# 参考
・[【Ruby】 mapメソッドの基礎から応用の使い方まとめ](https://pikawaka.com/ruby/map)
非エンジニアがIT業界の用語に翻弄されながら培った知識

# これは何?
- 自分がQiitaに勤めてから覚えた基本的なIT関連の知識を記載
    - 自分の状況
        - 文系
        - 会話する時に専門用語の読み方が合っているかドキドキする
            - redashを「レッドアッシュ」と読んでいた
        - 知らない専門用語を調べると、別の専門用語で解説されており何度も詰んだ
- 備忘録も含め、これからIT関連に関わる人に少しでも役立てれば幸いです

# この記事の目的
- 非エンジニアの方がIT関連の用語に対してざっくりなイメージを持ってもらう

# 自分的によく聞く単語
### Java（ジャバ）とJavascript（ジャバスクリプト）
- 似ている言葉だが別の言語
    - 「ハム」と「ハムスター」ぐらい違うなど、ネットでどれ位違うか例えを出すサイトまである。
        - 参考サイトは[こちら](https://togetter.com/li/1919395#h20_0) 
- Javaとは?
    - Googleが開発に用いている三大言語の1つ（Java、C++、Python）
    - システム、Web、アプリケーションなど様々な開発に利用されている
- Javascriptとは?
    - Webサイトを構成しているHTMLやCSSを操作する。
    - サイトの画像に触れると色が変わったり、別の画面が出たりするのはJavascriptのお陰
### Ruby（ルビー）とRails（レイルズ）
- Ruby
    - 日本人が作ったプログラミング言語
    - コードがシンプルで初心者でも勉強がしやすい
- Rails
    - 正式名称はRuby on Rails（ルビーオンレイルズ）
    - Rubyのフレームワーク
        - フレームワークとは?
            - 毎回ゼロからコードを書くのは大変なので予め用意された枠組みのこと（料理で言うとレシピみたいなイメージ）
    - QiitaもRuby on Railsで作られています
### Python（パイソン）
- プログラミング言語
- シンプルな構造の為、書くのが短くて済む
- YouTubeやInstagramなど様々なサービスが開発されている

### Query（クエリ）
- 「昨年の月別の売上」など知りたい情報をパソコンに命令して出してもらう事
- イメージは、グーグル等で調べる時の『検索キーワードへ入力する文字』みたいな感じ

### AWS（エーダブリューエス）,Azure（アジュール）,GCP（ジーシーピー）
- パブリッククラウドサービス
    - たくさんのデータを保存できるサーバーを個人や企業に貸してくれるサービスのこと
- アマゾンはAWS (Amazon Web Services)
- マイクロソフトはAzure (Microsoft Azure)
- グーグルはGCP (Google Cloud Platform)
    - 上記3つが有名
### 機械学習
- 開発者が用意した大量のデータを用いてAI（ユーザーの質問にそれっぽい答えを返せるプログラム）を作ること
    - 下記は投稿時に認識していた自分の誤った知識
        - ~~ユーザーの質問に対して違う答えを出した場合などに適切な回答（データ）を用意し、意図通りの答えを出せるようにしていく~~
        - ~~どんどん出来るようになるのが人間の学習みたいだから機械学習。~~
        - ~~AIが自ら試行錯誤を繰り返し、最適な行動・答えを見つけ出していくこと~~
        - ~~身近なもので言うと~~
            - ~~通販サイトのチャットなどで質問を入力すると、予測して答えを出してくれる等~~
### デプロイ
- 作成したプログラムを動かせる（使える）状態にする。という意味
- 例文
    - 「テストが終わったので本番環境でデプロイしよう」

### Github（ギットハブ）
- プログラムコードなどを保存、公開できるウェブサービス
- 基本機能はほとんど無料で使える!
### マージ
- 何かと何かを「合体する」みたいなイメージ
- 例文
    - 「売上と顧客をマージする（=売上と顧客データを紐付ける）」
### マージリクエスト（マジリク）
- 機能追加などの仕様変更を他のエンジニアがレビューして本体に取り込むこと
- エンジニアの会話で「マジリクお願い」と聞いた時は「これだけは本当（マジで）にやってもらいたい作業（リクエスト）だから、よろしく!」の略だと勘違いしていた。



# 最後に
- 他にも知らない単語はたくさんありました。
- また備忘録を含め書こうと思います
WireSharkの仕組み

## WireShark
- Wiresharkは多くのプロトコル（L7であればhttp, ssh, telnet, etc...）に対応したパケット取得・プロトコル解析ソフト
- ネットワークに流れるパケット情報をリアルタイムで調査可能
- ネットワークインターフェースを流れるパケットがリアルタイムでリスト表示される

## パケットキャプチャドライバ
- Wireshark単体ではパケットキャプチャは行うことができない。windowsはWinPcap(Linuxの場合はlibpcap)
- WinPcapやlibpcapは<b>パケットキャプチャドライバ</b>と呼ばれるもの
- 通常のアプリケーションはソケットを経由してデータを送受信する。
　※ソケット：アプリケーションがデータを送受信するための仕組みを提供するAPI
- ソケット経由では自身のアプリケーション向けのパケットのみ取得できるが、パケットキャプチャドライバを使用することでネットワークを流れる全てのパケットを取得することが可能になる

## プロミスキャスモード
- 標準モード：NICは自分宛てのパケットを受信したときのみ、上位のレイヤーにそのデータを受け渡す
- プロミスキャスモード：パケットの宛先に関わらず、全てのパケットを上位レイヤーに受け渡す



----
参考文献
- <a href="https://forest.watch.impress.co.jp/library/software/wireshark/">Wiresharkダウンロードサイト 
- <a href="https://pcap.it-mem.info/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AEwireshark/%E3%83%91%E3%82%B1%E3%83%83%E3%83%88%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%97%E3%83%AD%E3%83%9F%E3%82%B9%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%A2%E3%83%BC/">パケットキャプチャの仕組み</a>
Googleデジタルマーケティング＆Eコマース：ヒートマップ

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/05f6fefc-adb6-1242-4eb1-528a10511727.png" width="800">

# ヒートマップとは

ヒートマップツールの多くは、虹色（または熱色）スケールを使用しています。ほとんどのヒートマップツールは、虹色（または熱）スケールを使用して、ページのさまざまな部分にわたるユーザーの行動パターンを示しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/9a6e6a96-94f4-8c1b-02bf-151d6171821d.png" width="600">

- エンゲージメントが高い領域は「ホット」とみなされ、スケールの暖かい方の色（例：赤、オレンジ）で示されます。クリック率やタップ率が高い要素がホットスポットと呼ばれるのは、このためです。
- エンゲージメントが低いエリアは「冷たい」状態となり、冷たい色（例：青）で表現されます。

ヒートマップは、単に指標を追跡するだけでなく、有用なツールです。ヒートマップは、ページの特定の部分に対して訪問者がどのように反応しているかという詳細なデータを提供します。ヒートマップは、訪問者が何を読み、どこをクリックし、何を完全に見逃しているのかを知ることができます。このデータから得られる洞察は、訪問者の体験を改善し、パフォーマンス目標を達成するために、各ページをテストまたは調整する方法を決定するのに役立ちます。

# ヒートマップの種類

### <font color="MediumBlue">スクロール・ヒートマップ</font>

スクロールマップは、訪問者の何パーセントがWebページの特定のポイントにスクロールダウンしたかを追跡します。スクロールマップは、訪問者が個々の要素にどのように反応するかではなく、ページのどの部分を見る可能性が高いかを教えてくれます。多くの場合、「最もホット」なエリアは、フォールド（スクロールする前に表示されるエリア）の上にあり、訪問者がクリックするにつれて、マップはより下に冷たくなります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/426cca6a-7f45-bb78-0c4f-357462e59b8a.png" width="600">

スクロールマップから得られるインサイトにより、以下のことが可能になります。

- 重要なコンテンツを最も注目される場所に配置する。
- 偽の底（ページが終わったと思い、訪問者が早々にスクロールを止めてしまう場所）を特定する。
- スクロールを促進するための変更を提案する（追加スクロールが目的である場合）。
- ウェブとモバイルの両方に対応したページを最適化する。

### <font color="MediumBlue">クリック・ヒートマップ</font>

クリックマップ（モバイル端末ではタッチマップ）は、訪問者がWebページをクリックしたりタップしたりした場所を追跡します。下の図に示すように、アクティビティの集団が、ページ全体に色のついた塊（スポット）として表示されます。このデータから、訪問者の行動のパターンと傾向を特定し、将来のクリック率向上に役立てることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/df85a4b1-0b79-9328-dc9e-d7bb7770d846.png" width="600">

クリックマップは、訪問者が特定のリンクやコールトゥアクション（CTA）をクリックしているかどうか（またはタップしているかどうか）を知ることができます。リンクのエンゲージメントが十分でない場合、または訪問者がクリックできない要素をクリックしている場合、ページが過密状態であるか、わかりにくい状態である可能性があります。

クリックマップデータも役に立ちます。

- 訪問者がどのページ要素に反応しているかを確認する。
- CTAの有効性を評価する。
- 特定の要素でA/Bテストを実行するかどうかを決定する。
- ページのコンテンツや構造を明確にする。

### <font color="MediumBlue">ホバー・ヒートマップ</font>

特に文章やビジュアルコンテンツの場合、エンゲージメントは必ずしもクリック数で測れるわけではありません。ホバーマップ（マウスマップ、ムーブメントマップとも呼ばれる）は、ページ上でのマウスの動きを追跡することで、訪問者の注意のパターンを捉えることができます。マウスの動きは注意の完全な指標ではありませんが、訪問者がどこに注目しているかを知ることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3d0b5315-4e01-f558-d144-537614488cec.png" width="600">

特定の要素にどれだけの注意を払うのが最適かは、そのページの目標によって異なります。訪問者が特定の段落に注目している場合、その段落が興味深い、あるいは役に立つと判断している可能性があります。しかし、そのテキストがわかりにくい、あるいは読みにくいということも考えられます。

ホバーマップは、訪問者が次のような状態であるかどうかを判断するのに役立ちます。

- 正しい（または間違った）要素に注意を払う
- 重要でないページの細部に気を取られる
- ページのコンテンツに苦労している
すぐに使えて効果が大きいAWS Configルール

# なぜ我々は苦しんでいるのか
日々たくさんのAWSリソースを作成し運用する我々はAWSリソースに様々な設定を施します。
その中で以下のような苦しみを抱えています。

## 多数のAWSリソースに共通する設定があることを担保したい！
* 「多数のVPCでVPCフローログの設定を統一できてたっけ・・・・・・？」  
* 「rootユーザーのMFA設定を忘れてないか心配・・・・・・」  

我々はたくさんのAWSリソースに対して共通の設定を入れるようにします。  
それらの共通設定を維持するには作成時の設定だけでなく定期的な抜け漏れのチェックする運用が必要になります。

## セキュリティ上危ない設定をAWSリソースに入れられないようにしたい！
* 「セキュリティグループに許可ルールを足すとき大は小を兼ねるで広すぎるIPレンジに許可しちゃう人がいないか怖い・・・・・・」
* 「TLSが下位バージョンの通信を受け入れてしまう箇所がうっかりできていないか心配で眠れない・・・・・・」

共通する設定を「入れる」仕組みはCloudformationが提供されています。  
しかし共通する設定を「入れない」仕組みは意外と思いつきません。

## 結局IaCなんて絵空事なのか
Cloudformationなどで綺麗に同じ設定のリソースを作っても、均一さが維持されないかもしれません。  
例外的な対応の中でセキュリティグループルールを足してしまったり、手動で間違った設定をしてしまったり。

# Configルールは我々に何をもたらすのか
簡単に言ってしまうと、「我々が常に入れたい/入れたくない設定があるかチェック」してくれる機能です。

`AWS Config を使用して AWS リソースの設定内容を評価します。`

https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/evaluate-config.html

## ルール違反リソースを見つける
Config マネージドルールを使うと以下のような状態を検知できます。

* 「ELBがルールで定められたS3バケットにアクセスログを出力していない」  
* 「セキュリティグループが0.0.0.0/0に対してSSHポートを開放している」

### すぐ使えるマネージドルールたち

以下がAWSマネージドルールの一覧です。  
これらのルールについてはパラメータを渡すだけでアカウント内のリソース設定の監視が実現できます。

https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/managed-rules-by-aws-config.html

以下のルールならパラメータすら渡す必要がなく、入れるだけお得なルールになっています。
* セキュリティグループがsshポートを0.0.0.0/0に開放しているか（INCOMING_SSH_DISABLED）
* rootユーザーのMFAチェック（ROOT_ACCOUNT_MFA_ENABLED）

# でもお高いんでしょう？
賢明な参加者のみなさんは機能の便利さだけに目を奪われず、ここでコストのことが気になっていることでしょう。  
結論だけ言うと、マネージドルールは日次のチェックであれば1ルール月々3円程度でご利用いただけます。

1つのConfigルールの評価(日次チェック) 
0.001USD * 30 = 0.03USD
≒ 3円

https://aws.amazon.com/jp/config/pricing/

価格はルールでリソースをスキャンした「回数」によって決まります。  
スキャン対象のリソースの数は無関係です。  
なのでたくさんのリソースがある環境でも安心して利用できます。  
Configの設定履歴の料金は別途かかります。
Kubernetes+IstioでBlue/Grennのルーティングを確認するアクセスがうまくいかない

# はじめに

Kubernetesのパイプラインを作ることが最近多く、そこでBlue/GreenをIstioで初めてやったのでそのときに起きた問題についてまとめます。
内容としてはKubernetesの話になります

# 問題

Webアプリのコンテナにアクセスするためのゲートウェイであるポッドから、`curl`を叩いてBlue/Greenの切り替えができるかを検証しました

```
$ kubectl -n dev exec -it gateway-blue-7d7899777-188xc -- bash

# blueのポッドにアクセス
$ curl test-app-svc.dev.svc.cluster.local:10302 -H "x-idle:true" (複数回実行)
```

しかしポッドのアクセスログを確認するとBlueとGreenランダムにアクセスが行われていました

```
test-app-blue-c48659849-pbqpr test-app 127.0.0.6 - - [30/Mar/2023:23:43:54 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.81.0" "-"
test-app-green-c48659849-pbqpr test-app 127.0.0.6 127.0.0.6 - - [30/Mar/2023:23:43:55 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.81.0" "-"
test-app-green-c48659849-pbqpr test-app 127.0.0.6 127.0.0.6 - - [30/Mar/2023:23:43:56 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.81.0" "-"
test-app-blue-c48659849-pbqpr test-app 127.0.0.6 127.0.0.6 - - [30/Mar/2023:23:43:56 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.81.0" "-"
test-app-green-c48659849-pbqpr test-app 127.0.0.6 127.0.0.6 - - [30/Mar/2023:23:43:57 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.81.0" "-"
```

# 解決方法

なぜBlue/Greenの切り替えができていなかったかというと、ちゃんとしたゲートウェイのコンテナに`exec`で入れていなかったのが原因でした

`gateway`ポッドは`istio-proxy`と`webアプリ`の`サイドカー`になっており、`exec -it gateway-blue-7d...`で入ると、どちらのコンテナに入ればよいかわからず、`istio-proxy`の方に入ってしまいました

istioからアクセスすることはないはずなので、ちゃんとしたBlue/Greenのルーティングが行われなかったのが原因でした

そこで、入るコンテナを指定して検証しました

```
$ kubectl -n dev exec -it -c gateway gateway-blue-7d7899777-188xc -- bash

# Blueアクセス
$ curl test-app-svc.dev.svc.cluster.local:10302 -H "x-idle:true"

# Greenアクセス
$ curl test-app-svc.dev.svc.cluster.local:10302
```

これでBlue/Greenの検証ができました

# おわりに

サイドカーの話が完全に頭から抜けていました
サイドカーになっているのはその前に気づいてはいたのですが、、
Blue/Greenが比較的簡単に再現できるのはとてもよかったです
Configurable Bundles in Salesforce CPQ

[CPQ関連のトレイルヘッドに戻る](https://qiita.com/Keiji_otsubo/items/db0e341fd6e3a938b01f)


+ [Learn About Configuration in the Sales Process での問題[言語設定がNull]](https://qiita.com/Keiji_otsubo/items/02c48be0180feec3eba0)


+ [Configurable Bundles in Salesforce CPQ](https://trailhead.salesforce.com/ja/content/learn/modules/cpq-product-configuration)

処理が遅いみたい。

+ [Change the Feature User Experience: Recalculating... Queued](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000OsJs2SAF)

:::note alert
Recalculating... Queued
:::


# Use Features to Organize Options

+ [このチャレンジでは機能にオプションを追加できないようです。機能を作成した後、レーザー プリンターのトレイ オプションの 1 つを開き、「機能」フィールドをクリックして「トレイ」を検索しても何も表示されません。すでにトレイという名前の機能を作成し、同じレーザー プリンター構成の SKU に関連付けているにもかかわらずです。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erADf)

:::note
Please check this article.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Kg5g6SAB

製品レベルの「機能」オプションにバグがある可能性があります

実際の結果: フィールドは空です。

追加情報:

オプション レベルでこの新しい製品機能を使用して新しい機能を作成すると、製品レベルの機能リストに追加されますが、他のオプションでは再度選択できなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/363db716-7691-6672-888f-7cd750f8533e.png)

:::
JestでJest encountered an unexpected tokenエラーがでる

# はじめに

Jestを導入して、テストを実行したところエラーがでたのでまとめます

# 問題

以下のコマンドでテストを実行するとエラーがでました

```shell
$ npm run test
```

```
● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    SyntaxError: /home/watanabejin/workspace/Presenter.spec.ts: Missing semicolon. (11:22)

       9 |   describe("display", () => {
      10 |     test("表示できる", () => {
    > 11 |       const state = {} as Arttate;
         |                       ^
```

Jestを使うために、`npm install jest`を行った状態です

# 解決方法

[こちら](https://typescript-jp.gitbook.io/deep-dive/intro-1/jest)をみたところ、設定ファイルが必要なのを思い出しました。

しかし、この設定ファイルはCommonJSになっているので、ESModuleに変えて以下のようにしました

```js:jest.config.js
const config = {
  "roots": [
    "<rootDir>/src"
  ],
  "testMatch": [
    "**/__tests__/**/*.+(ts|tsx|js)",
    "**/?(*.)+(spec|test).+(ts|tsx|js)"
  ],
  "transform": {
    "^.+\\.(ts|tsx)$": "ts-jest"
  },
};

export default config;
```

テストを実行したところ以下のエラーに変わりました

```
  ● Test suite failed to run

    Unable to load the module "typescript". Using "ts-jest" requires this package to be installed. To fix it:
        ↳ install "typescript": `npm i -D typescript` (or `yarn add --dev typescript`)
```

TypeScriptを入れろと言われているので以下のコマンドを実行しました

```
$ npm i -D typescript
```

すると問題なくJestが実行できるようになりました

# おわりに

久しぶりにJestを導入したので思ったより時間がかかりました
CommonJSとESModuleのところは注意が必要です

# 参考

https://typescript-jp.gitbook.io/deep-dive/intro-1/jest
【ドラゴンボール風解説】RDSについて

# はじめに
この記事はAWSの説明は今ひとつよくわからないのでドラゴンボールに例えて説明してほしい。
というAWS初学者向けの記事です。
※投稿記事作成にはchatGPTを使用しております

# RDS
オス、オラ悟空！おっ、次はAmazon RDSか！ドラゴンボールで例えると、神龍（シェンロン）に似ているかな？

神龍は、ドラゴンボールを7つ集めることで、願いを叶えることができる存在だ。Amazon RDSも同じように、**データベースの管理を簡単にしてくれる存在**なんだ！

Amazon RDSは、ドラゴンボールの神龍が集まることでパワーアップするように、**MySQLやOracleなど、複数のデータベースエンジンをサポートしている**ぞ！また、神龍が召喚されたときに、ドラゴンボールが光り輝くように、Amazon RDSも**データベースにアクセスするためのエンドポイントが自動的に作成される**んだ！

さらに、神龍は召喚されるたびに消えるように、Amazon RDSも必要に応じてインスタンスを作成し、**処理が終わったら削除することができる**んだ！また、神龍が召喚されるまでに7つのドラゴンボールを集める必要があるように、Amazon RDSも**データベースインスタンスを作成するために必要なリソースを確保する必要がある**んだ！

ただし、神龍が召喚されると願いを叶える代わりに、Amazon RDSはAWSのリソースを使用するため、使用料が発生するぞ！また、**データベースの容量やパフォーマンスに応じて課金される**ため、使用する際には注意が必要だぞ！

オラも、神龍に願いを叶えてもらった経験を活かして、Amazon RDSを使ってデータベースを管理していくんだ！どんな願いでも叶えてやる！ワクワクしてきたぞ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304054/bbef3a9e-7f13-6d11-0b12-c74160e76015.png)
【Windows利用者必見】PowerToysで作業効率化

# PowerToysって何？
Microsoft公式から提供されている便利機能の詰め合わせソフトです。
Windows10、Windows11のどちらでも使用できます。

https://learn.microsoft.com/ja-jp/windows/powertoys/

以下のいずれかの方法でインストールできます。  
ちなみに私はMicrosoft Storeからインストールしました。

* GitHubからインストーラーをダウンロード
* Microsoft Store
* コマンドライン または PowerShellからコマンド実行

# PowerToysで何ができる？

2023年3月末時点で18個の便利機能が利用できます。
* 指定したウィンドウを常に手前に表示
* OSの電源設定を変更することなくPCを起動を維持
* カラーピッカー
* 複雑なウィンドウレイアウトの作成
* 指定したファイルを使用しているプロセスの確認
* エクスプローラーのプレビュー表示拡張
* hostsファイル専用エディタ
* エクスプローラーから画像サイズ変更
* 独自のキーボードショートカット作成
* マウスの機能拡張
* プレーンテキストとして貼り付け
* エクスプローラーからファイル名の一括変更
* Alt + Space でアプリケーションのクイック起動
* アクセント付き文字の入力
* 画面上のピクセル測定
* 使用可能なショートカット一覧の表示
* Snipping ToolのOCR版
* ビデオ会議のミュート操作

上記の中から個人的に便利と感じた機能を抜粋して紹介いたします。  

# Color Picker
Windowsキー + Shiftキー + C でカラーピッカーが起動します。  
デフォルトでは16進数表記（例：ffffff）の値がクリップボードにコピーされます。  

<img width="300" alt="color-picker-select" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339770/8fd6b9e9-c696-48b0-81e0-8f1b1ee804b8.png">

選択時にエディタを起動して、エディタから異なる形式の値や履歴から値を取得することが可能です。  

<img width="350" alt="color-picker-dialog" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339770/6be81b36-427f-7377-6b72-990cdcdab435.png">

# Hosts ファイル エディター
hostsファイルを編集できるエディタを使用できます。  
ボタンクリックで有効／無効（コメントアウト）を切り替え可能です。  

<img width="500" alt="hosts-file-editor" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339770/532e78dc-e14a-b1b4-3786-bd4d58a5d1ce.png">

# PowerToys Run
Altキー + Spaceキーで様々なアプリケーションの起動を迅速に行えます。

例1）アプリケーション全体から "qiita" を指定 

<img width="500" alt="run-qiita" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339770/f788bcf8-ff7b-3210-b7cc-e169a270c983.png">

例2）Visual Studio Code のワークスペースを指定

<img width="500" alt="run-vscode" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339770/8751edfb-76f9-4159-5f42-b30a54a59e96.png">

例3）切り替え先のウィンドウを指定（Alt + Tabと同じ操作）

<img width="500" alt="run-window" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339770/36fbda7a-a6e6-c9c6-0419-2b98fd379069.png">

# Text Extractor  
指定した領域の文字を読み取ってクリップボードにコピーすることが可能です。
Windowsキー + Shiftキー + T で起動します。    
使用感としてはSnipping ToolのOCR版です。  

# おわりに
ほんの数日前までこんなソフトがあることを知りませんでした。。。
会社のルールでフリーソフトを自由にインストールできない環境においても、Microsoftから提供されているソフトであれば許可が下りる場合もあると思います。
本記事で紹介できていない機能もぜひ使ってみて頂いて、日々の作業効率化に繋がれば幸いです。
AWS全12資格取得にチャレンジして、制覇してみた。

何故、目指したのか？
--
これまで、エンジニアとしてキャリアを積んできましたが、__「何の専門家ですか？」__ と問われた際に、場に合わせて相手に回答していました。突き詰めて言うと、__自分に対して明確な回答がありませんでした。__ そのため、自分自身を信じるための手がかりを求め続けました。結果として、たどり着いたのが、「AWS全12資格取得」するです。

『人を信じよ。しかし、その百倍も自らを信じよ。』手塚治虫
--

人を信じるのって、大変ですが、その前にやる事ってあります。自分を信じる事。自分を信じていないと、人を信じる事は、出来ないんじゃないかなと思います。__「AWS全12資格取得」の一番のメリットは、何回か落ちて、くじけず、やり遂げた事にによって、自分自身を信じられるようになった事です。__

自分を信じている人の行動パターン？
--

__目標設定と計画の立案__
自分を信じている人は、自分が達成したいと思う目標を設定し、それに向けて計画を立てる。

彼らは、自分が自分自身に課した目標を達成するために必要なステップを把握し、
それに向けた計画を立てることで、自信を持って行動する。

__行動の決意と継続力__
自分を信じている人は、目標達成のために必要な行動を実行するために必要な決意力や継続力を持っている。
彼らは、自分の能力や価値観に自信を持っており、その信念をもとに、行動を起こす。

__自己評価と反省__
自分を信じている人は、自分自身に対して正確な自己評価を行うことが出来る。
彼らは、自分の弱点や改善点を正直に見つめ、自分自身に対して建設的なフィードバックを与える。
失敗した場合でも、反省し、自分自身を客観的に再評価することで、より強い自信を持って次に進む。

__リスクを取ることへの積極性__
自分を信じている人は、リスクを取ることに積極的である。
彼らは、自分自身に自信を持っており、失敗した場合でもそれを乗り越える自信を持っている。
そのため、彼らは新しいことに挑戦し、自分自身をより高いレベルに引き上げるために積極的にリスクを取る。

凡人の私には、自分の技術力を信じるような基準が特にありませんでしたが、
--
振り返ると、__「自分を信じている人の行動パターンを地道に実行した」__ と思います。


一昨年末に、
「AWS Certified Solutions Architect - Professional (SAP)」に合格しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/d3d029a3-1cd5-c168-0876-a3393189d837.png)

__そしたら、少し、自分を信じる事が出来ました。__

次に立てた目標が、
全てのクラウドベンダーでプロフェッショナル(エキスパート)取得するというもので、
--
1月末に
「Microsoft Azure DevOps Engineer Expert」を取得。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/a6f9a6e8-f07f-8416-dd84-f2fe2e2b55aa.png)

３月末に
「Google Cloud Professional Cloud Architect」を取得。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/5749d64c-c53d-a29f-2d5e-9cb7122bb589.png)
4月末に
「Google Cloud Professional Data Engineer」を取得。

達成出来ました。
--

更に、「AWS12資格取得」という目標を立てて実行してみました。
--

結果
AWS Certified Solutions Architect Associate (取得済み)
AWS Certified Solutions Architect Professional (取得済み)
AWS Certified Data Analytics Specialty (5月取得)
AWS Certified Database Specialty (8月取得)
AWS Certified Machine Learning Specialty (8月取得)
AWS Certified DevOps Engineer  Professional (12月取得)
AWS Certified Developer  Associate (1月取得)
AWS Certified SAP on AWS Specialty(2月取得)
AWS Certified SysOps Administrator  Associate (3月取得)
AWS Certified Cloud Practitioner (3月取得)
AWS Certified Advanced Networking Specialty　(3月取得)

全ての資格に合格しました。
--



__『人を信じよ。しかし、その百倍も自らを信じよ。』・・・納得しました。__
=

__10個ぐらい取得した段階で、会社を経営している人達から、
社員を教育したいので「AWS教えてもらえるかな」とお声がけをもらえるようになりました。__


__たぶん、自分を信じて行動に移している姿を仲間に見せれば、
きっと、仲間から受け入れてもらう事も出来て、仲間達もやる気を出してくれると思います。__

AWSの12資格取得チャレンジは、なかなかやりがいがあります。宜しければ、チャレンジしてみて下さい。
CSS Selectors Level 4 前半

# CSS Selectors Level 4について
追加されたセレクタを解説

## :matches()

:matches()は指定された複数のセレクタのいずれかに一致する要素を選択
```css
p:matches(strong, em) {
  color: red;
}
```
この例では、:matches()擬似クラスを使用し、strong要素またはem要素を内包する全ての<p>要素に対して、テキストの色を赤に変更する

## :where()
:where()は内包するセレクターの詳細度を0に保つ
```css
:where(p:last-of-type) {
  color: red;
}

@media (max-width: 600px) {
  :where(p) {
    color: blue;
  }
}
```
このように記載することで従来では:last-of-typeで詳細度が上がってしまい、上書きするにはmedia queryの中で再度:last-of-typeを記載するなどの対応が必要であったが:where()で囲むことで詳細度を制御することが可能


## :not()
:not()は指定されたセレクターに合致しない要素を選択する
また、複数のセレクターをカンマ区切りで記載することが可能
```css
div:not(.foo,.bar) {
  /* fooクラスとbarクラスを持たないdiv要素にスタイルを適用 */
}
```

## :is()

:is()は複数のセレクタをまとめて指定することが可能

```css
.container .header,
.container .main,
.container .footer {
  font-size: 24px;
}

.container :is(.header, .main, .footer) {
  font-size: 24px;
}
```

:is()とnot()を組み合わせた例
```css
:is(:not(p),:not(div)) {
  font-size: 18px;
}
```

## :placeholder-shown
:placeholder-shownは、フォームのプレースホルダーテキストが表示されている場合にスタイルを適用するためのCSS疑似クラス
フォームの入力フィールドに何も入力されておらず、代わりにプレースホルダーテキストが表示されている場合にスタイルを適用が可能

```css
input[type="text"]:placeholder-shown {
  color: gray;
}
```

## :read-only
:read-onlyは、読み取り専用の要素に適用する擬似クラスセレクタ
このセレクタを使用することで、input、textarea、select要素などでreadonly属性がtrueのものに適用される
```css
input:read-only {
  background-color: #eee;
}
```

## :read-write
:read-onlyと反対に、読み書き可能な状態の時にスタイルを適用できる
disabled属性が入っている場合もスタイルが適応される


## :required

:requiredはformの入力必須の場合にスタイルを適用するための擬似クラス
required属性がある場合に適用される

```css
input:required {
  border: 2px solid red;
}
```

## :optional

:optionalはformの入力必須でない場合にスタイルを適用するための擬似クラス
required属性がない場合に適用される

```css
input:optional {
  border: 1px solid gray;
}
```

## :default
:defaultはユーザーによって入力値が変更されていない、デフォルトの値を持つ要素に対して適用される

```css
input:default {
  color: gray;
}
```

## :indeterminate
:indeterminateはチェックボックスやラジオボタンでチェック済みでも未チェックでもない中間の状態に対してスタイルを適用する
```html
<input type="checkbox" id="myCheckbox" />
<label for="myCheckbox">Check me!</label>
```

```css
#myCheckbox:indeterminate {
  background-color: gray;
}
#myCheckbox:checked {
  background-color: green;
}
#myCheckbox:not(:checked):not(:indeterminate) {
  background-color: red;
}
```

```javascript
const checkbox = document.querySelector('#myCheckbox');
checkbox.indeterminate = true;

checkbox.addEventListener('change', () => {
  checkbox.indeterminate = false;
  if (checkbox.checked) {
    console.log('Checkbox is checked');
  } else {
    console.log('Checkbox is unchecked');
  }
});
```
【エックスサーバー等の仕様】Outlook(365)からのSSL証明書の警告をバッチで自動回避させて運用してみる

# 独自MXレコードのメールサーバーを設定した時にSSL証明書の警告が毎回出てしまう課題
![principalerror.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667967/1192ca38-afaf-95ff-f6a1-71bbb4ce80a6.png)

エックスサーバーでメールをSSL/TLS通信で利用する場合、
Outlook（2013、365）のメールサーバー設定には、
「sv***.xserver.jp」等、エックスサーバー自身のホスト名を使わないと、
SSL証明書の警告が毎回発生してしまいます。
→これは証明書のインストールを選択しても回避できませんでした。

(Xserver)サポート
[メールソフトで「識別情報を確認できない」「証明書が不正」という旨のエラーが出る場合について](
https://www.xserver.ne.jp/information_detail.php?view_id=5134)

(Xserver)ホーム>マニュアル
[メールソフトの設定>Outlook 2019(Outlook 365)](https://www.xserver.ne.jp/manual/man_mail_setting_ol2019.php)


なおこの事象はエックスサーバーに限ったことでは無いようですね。
（例：ITの教科書様）[対象のプリンシパル名が間違っていますOutlook2016対処法](
https://josys-memo.com/outlook-principal/)


このSSL証明書の警告ダイアログを回避しようと思い、
グループポリシやレジストリ設定をネット検索して記載内容を試しましたが上手く動作せず。。
（chatGPTにも聞いたのですけどね、、できます！と言って書いてくれた設定が動作せず。。）
ならば警告ダイアログの「はい」ボタンを自動で押すバッチスクリプトを作るか。と。

# SSL証明書警告をバッチで自動回避させて運用してみる
```batchfile
rem sendkeys(ベクターダウンロードサイト）https://www.vector.co.jp/soft/win95/net/se250664.html

if not "%1" == "1" (
    start /min cmd /c call "%~f0" 1
    exit
)

chcp 65001
@echo off
cd %~dp0

:LOOP
cls
echo OUTLOOKの「インターネットセキュリティ警告」に自動で「はい」を選択しています。

tasklist | find "OUTLOOK.EXE"
if %ERRORLEVEL% == 0 (
 .\sendkeys\SendKeys.exe "インターネット セキュリティ警告" y
)
timeout /T 1 > nul

goto LOOP
```
# 動作の様子
- 動画の前半がバッチを起動させていない時、動画の後半がバッチを起動した時です。
  - これをスタートアップに置いていただけば自動でSSL証明書の警告に「はい」を押します。
![4_SSL証明書警告をバッチで自動回避させて運用_XServerの仕様__モザイク付き_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667967/24ac34aa-4a14-521b-9f83-c980eaef48e5.gif)

以上
gpt-3.5-turboを使ってチャットの異常を検知する

## 背景

****[「起きたら全て消えていた」　Discordで横行する“サーバー凍結荒らし”、1万人参加サーバーが一夜で消えたその手口](https://nlab.itmedia.co.jp/nl/articles/2112/07/news166.html)****

という記事を読んで、「gpt-3.5-turboに検知させたらいいんじゃなイカ！？」

って思ったのでやってみようと思います。

・・・

できました。

サーバーを開いてあるのでいろいろ試してみて下さい。

一応言っておきますが、シークレットトークンは送信しないでくださいね？

https://discord.gg/DnWFxRAU


## 実装のポイント

以下のような構成で作りました。
![](https://storage.googleapis.com/zenn-user-upload/8b7271b29b5d-20230331.png)

以下のようなプロンプトを使用して検知させてみました。

日本語にではなく英語を使用した理由は、いろいろ試した結果英語の方が精度が高いと感じたのと、日本語よりも英語の方がしっかりと意図を反映させた文章が書けると思ったからです。

やはり今話題のプログラミング言語である”English”なだけあって使いやすいですね。

```python
from OpenAIClient import request_openai


# ChatGPTを使ってメッセージを検証する
async def validate_massage_by_chatgpt(message: str) -> bool:
    prompt = f"Output 1 if the following text is part of a Japanese conversation\n" \
             f"\n" \
             f"{message}\n" \
             f"\n" \
             f"Output:"

    response = await request_openai(prompt)
    response_message = response['choices'][0]['message']['content']

    # レスポンスメッセージに'1'が含まれている場合はTrueを返す
    return '1' in response_message
```

このプロンプトではトークンを節約する意図もあって`Output:`で止めてあります。

こうすることで、日本語の会話の一部であると判断した場合に`1`だけを返信してくれる確率が上がります。

`そうではない場合は0を出力して下さい。`という文も入れていたのですが、返信に`1`が含まれていなければ、何かしらの理由で日本語の会話の一部ではないと判断したのだろうということで`0`を返信してもらう必要はないと思ったのと、指示が多いと精度が落ちると思ったのでプロンプトから削除しました。

完成したアプリを使ってDiscordを監視させている動画がこれです。
![](https://storage.googleapis.com/zenn-user-upload/997654dec5d8-20230331.gif)

トークンらしきものをしっかり削除してくれてます。

これを応用すれば酔っている時に調子に乗ってツイートしてしまったツイートも自分が寝ているうちにBotに削除してもらったりすることができますね。

（お酒を飲んだらツイッターは触らないようにしましょう。）



## リポジトリ

こちらに作成したコードを置いておくのでよかったら試してみて下さい。

https://github.com/edojidaipj/GPT-Discensor


プロンプト次第な気もしますが、たまにスルーしてしまうこともあるので


AIを使用せず、サーバー内で使用できるテキストのルールを決めて、それに反するメッセージは自動で削除する方がいいのかもしれないなーと思ったりもしました。

## AIなし版

ということで作りましたのでもしよかったらこちらも試してみて下さい。

https://github.com/edojidaipj/Discensor

## 告知

そういえば、「今北産業」って送信すると直近の会話を３行で要約してくれるサービス（無料です）も作りましたのでもしよかったら試してみて下さい。


サーバーレスで頑張ったのにマジで誰も使ってなくて寂しいので使って下さい！！！！！！！


https://twitter.com/EdoJidaiPJ/status/1637791528205828096?s=20
Viteで作ったサイトをGitHub Pagesでホストしてカスタム404ページを有効にする


## この記事の概要

タイトル通り、[Vite](https://ja.vitejs.dev/)でサイトを作成し、[GitHub Pages](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages)で公開する際、カスタム404ページを適用する方法を記事にしました。

## 環境

主だったものを記載します。

| パッケージ名 | バージョン |
| --- | --- |
| react | 18.2.0 |
| typescript | 4.9.3 |
| vite | 4.1.0 |

## 前提

公式サイトにあるように[GitHub Actionsを使ってGitHub Pagesへデプロイする](https://ja.vitejs.dev/guide/static-deploy.html#github-pages)とします。

もちろん手動でデプロイしても構いませんが、要は`vite build`をした結果生成される`dist/`を静的に配信する、ということです。

## 実施すること

要約すると以下を実行します。

1. `404.html`を用意する
2. `vite.config.js`を編集して、エントリーポイントを増やす

本来GitHub Pagesでは`404.html`を用意すればそれだけでカスタム404ページとして公開してくれます。
しかしViteはデフォルトではこのファイルを認識してくれないため、ビルドしたコードに含まれません。
そのため、`vite.config.js`を編集して明示的に`404.html`を含めるようにする必要があります。

```javascript:vite.config.js
import { resolve } from "path";
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        404: resolve(__dirname, '404.html'),
      }
    }
  }
});
```

この状態で`npm run build`などのコマンドが叩かれれば、`dist/`内に`404.html`が含まれて、カスタム404ページを配信できます。

より細かいことは、公式の[本番環境用のビルド - マルチページアプリ](https://ja.vitejs.dev/guide/build.html#%E3%83%9E%E3%83%AB%E3%83%81%E3%83%98%E3%82%9A%E3%83%BC%E3%82%B7%E3%82%99%E3%82%A2%E3%83%95%E3%82%9A%E3%83%AA)を参照してください。

## 試したけどダメだったこと

`public`の中に`404.html`を配置すればいける？と思いましたがダメでした。
よく考えれば当たり前ですね。

中身を何も書き換えないまま`dist/`内に配置されてしまうので、バンドル後のJavaScriptではなく開発用のファイルを呼び出そうとしてしまいました。

## 最後に

何も手を加えないでもできるものだと勘違いしていましたが、思ったよりは設定が必要でした。
今回はカスタム404ページを作るだけの話だったものの他でも使いそうな知識な気がして、記事にしています。

お役に立てれば幸いです。

---

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

[Devトーク](https://jobs.qiita.com/employers/qiita-inc/dev_talks/489)でお話してくださる方も募集中です！
zshのプロンプトにgitユーザー名を表示させてみた

# 概要
会社のPCで個人開発をしているのですが、時々gitのユーザーを間違えて作業してしまうことがありました。
そこで、プロンプトにgitユーザー名を表示するようにして、ミスを未然に防ごうと思います。

※ディレクトリ移動時にgitユーザーが切り替わっても、それに対応したgitユーザー名がプロンプトに表示されます

# やり方
```shell:.zshrc
# gitプロンプトを読み込む（今回のgitユーザー名とは関係ないです）
# https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh
source ~./path_to/git-prompt.sh

# gitのユーザー名を出力する
git_usr_name () {
	local repo_info git_usr_name
	repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
		--is-bare-repository --is-inside-work-tree \
		--short HEAD 2>/dev/null)"
	git_usr_name=`git config user.name`

	if [ -n "$repo_info" ]; then
		# gitディレクトリが存在する時
		echo "[$git_usr_name]"
	fi
}

PS1='%F{green}%n%f: %F{cyan}%~%f %F{red}$(__git_ps1 "(%s)")%f %F{11}$(git_usr_name)%f'"
\$ "

# プロンプトの出力例
pc_usr_name: cuurent_directory (branch_name) [git_usr_name]
```
# 開発までの軌跡
## ユーザー名が切り替わらない
異なるgitユーザーが設定されているディレクトリに移動しても、プロンプトに表示されているgitユーザー名が切り替わらなかったです。筆者は最初、変数にユーザー名を格納してそれをPS1内で展開してたので、ユーザー名が更新されなかったです。

## ユーザー名を読み込むトリガーの発見
何をトリガーでユーザー名を取得すればいいかを探していました。その過程で`fswatch`などの指定したファイル変更を監視するライブラリを使ったりもしましたが結局できなったです。`git-prompt.sh`にもそのような記述は無く、どこで毎度実行されているかが見つけることができなかったです。結局はPS1内に書けば毎度実行されることがわかりました。

## 結局`%s`がどこから来ているかわからなかった
今回の開発で`git-prompt.sh`を読みまくってたのですが、ブランチ名を表示している`%s`がどこで定義されているのかが結局発見できなかったです。わかる方はコメントで教えてください。

## PS1とは（GPT-4より）
ZshのPS1は、シェルのプロンプト文字列をカスタマイズする環境変数です。プロンプトは、コマンドを入力する前に表示されるテキストで、ユーザー名、ホスト名、カレントディレクトリなどの情報が含まれています。

# 参考
プロンプトカスタマイズ https://ryota2357.com/blog/2022/zsh-prompt-custom/
ディレクトリごとに GitHub アカウントを自動的に切り替える設定 https://zenn.dev/taichifukumoto/articles/how-to-use-multiple-github-accounts