OmniAICreator/Qiita-1.07M huggingface dataset:
【xarray】cftime型時間座標を持つ時系列のプロット

vscodeのinteractive windowにおける話です。他の環境ではそもそも同じような問題が生じるのか、この方法で問題が解決するのかわかりません。
# 概要
時間座標のデータ型がcftime.datetimeである1次元xarray.DataArrayのプロットがしたい場合を想定しています。この時、 **はじめに1度、`xarray.DataArray.plot()`でプロットを行う** ことで、それ以降、`plt.plot(x,y)`や`ax.plot(x,y)`でのプロットも可能になります。
【Android】Google I/O '23 で発表された Material 3 の新機能

## 新しいカルーセルコンポーネントが登場

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/0acacdbd-351a-b54b-d2ea-a4d5fb1bb3e9.png)

* MDC と Figma Design Kit で使用可能。
* Jetpack Compose は開発中、Flutter 及び Web は計画中とのことです。

https://m3.material.io/components/carousel/overview

## Bottom sheet が Predictive Back gesture に対応

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/fa6ae56e-d3fe-4d47-5b9c-5af5d2e66ded.png)

* Bottom sheet の他に、Side sheet と Search が Predictive back gesture に対応します。

https://m3.material.io/components/bottom-sheets/guidelines#3d7735e2-73ea-4f3e-bd42-e70161fc1085

https://m3.material.io/components/side-sheets/guidelines#c72aa3ea-9b57-4b0d-8194-d6251d1343d5

https://m3.material.io/components/search/guidelines#3f2d4e47-2cf5-4c33-b6e1-5368ceaade55

## 新しい color contrast schemes

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/61721e3d-d57b-99be-07ef-25855c855527.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/2ce36fe5-eafe-b414-3692-c1160fb70563.png)

## Monochrome schemes

![スクリーンショット 2023-05-11 8.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/59febd84-51f6-e4ea-9093-ef1cb3f90fba.png)

## 動画

https://www.youtube.com/watch?v=vnDhq8W98O4
ケースステータスに基づくオムニチャネルルーティング

+ [アイデア](https://ideas.salesforce.com/s/idea/a0B8W00000Gdkq2UAB/omni-channel-routing-based-off-case-status)


オムニチャネルは現在、作業をルーティングする際にケースのステータスに注意を払っていません。つまり、解決済みのクローズ済みケースは、必要のない場合でもエージェントにルーティングされます。オムニ チャネルはステータスに注意を払う必要があり、ステータスがクローズ済みとしてマークされている場合、オムニ チャネルは作業のルーティングを試みるべきではありません。オムニチャネルがクローズ済みのケースをルーティングすると、エージェントはすでに解決済みで割り当てられた作業を再度クローズするという二重作業が発生します。  

:::note
これは、ステータス ベースの容量を介した OOB でサポートされています。ケースが非動作状態に移行すると、保留中の作業項目はすべて削除されます。

 それでもタブベースのキャパシティーを使用したい場合は、ケースをクローズするときに、独自の自動設定を通じて同時に所有者も更新する必要があります。ケースをクローズするために使用しているアクションを更新するか、レコードをトリガーするかのいずれかです。ケースのステータスがクローズに更新されたことを検出し、所有者を更新するフロー。これにより、キューまたはスキルから作業が削除され、エージェントにルーティングされなくなります。
:::

しかし、うまくいってない？

この機能は同じではないようですか？この機能を使用すると、エージェントのキャパシティに対してどのステータスをカウントするかを選択できますが、ステータスベースのキャパシティに「クローズ済み」を追加しないと、ルーティング キュー内でクローズ済みステータスのケースはルーティングされません。それともルーティングされますか?

これは、ここで必要な機能と同じではありません。
提供された機能により、エージェントはケースをクローズするまで忙しくなります。
要件は、エージェントにクローズ済みのケースを割り当てないことです。


+ [元の質問：終了したケースはオムニチャネルにルーティングされます](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Plyhz)

ケースのステータスがクローズに等しくない場合はカスタマー サポート キューに割り当てるというケース割り当てルールを実装しようとしましたが、同じことがまだ発生しています


+ [オムニチャネルのルーティングをテストする単元を実施しているのですが、キューをケースに割り当てることができない](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cm9fM)

:::note
以下のように Hightと入力すると表示できると思います。
何も入力しないと表示されませんね。不親切なUIです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b0f0b4e1-bce4-0b7b-2089-d5f129add013.png)
:::
Github Copilotを活用する上でのおさえておくべき特徴とTips

## 目的
個人の学習メモです。以下3点を目的にします。
1. Github Copilotを利用するにあたって現状で認識しておくべきであることを整理しておく。
2. Github Copilotを感覚ではなくコントロールして使用できるようになる。
3. 知らないTipsをインプットする。

## 参考

https://www.ai-native.dev/docs/v/ja/

こちらのサイトからのアウトプットです。Githubで公開されていて、Github Copilotを中心にまとめられています。

## 知識

### Github Copilotに利用されているモデル

codexというモデルが利用されている。
GPT-3ベースで自然言語の理解が可能。
codexモデルに渡せるトークン数は限られていることをしっておくべき。

### Github Copilotの補完のしくみ

詳しいロジックは公開されていないようですが、エディタで開いているファイルを読んで現在開発しているファイルに関連の深いものを参考にしている。

## Tips

### GitHub Copilot の参照優先度

GitHub Copilot は直近開いたいくつかの同じ言語のファイルを参照し、類似性を計算してプロンプトに含めるファイルを決定します。

### コメントからコードを生成

コメントで条件を指定することでCopilotはコードを生成する。ある程度複雑に条件を定義することも可能。

### 逆にコードからコメントを生成することも可能

コメントで関数の意味を説明することでコメントを自動生成することができる。
PHPDocなどコメントが書かれていない理解しにくいコードの理解を助けることができる。

### リファクタリング

```python
リファクタリングされた calculate_sum()を以下に書いてください
```

上記のように関数を指定するとリファクタリングの案を提示してくれる。ただし、意味が変わる可能性がある点には要注意。

リファクタリングに関してはテストが書かれているとより効率的。

## Copilotを活用するうえで意識するべきこと

### コードの中にコメントを意識的に残すこと

ビジネス要件にかかわることや実装するうえでの前提となる知識を優先的に書く。Copilotが読んで以降の開発効率の向上につながる。ただし、過剰なコメントアウトは逆に精度を低める可能性がある。

### AIにも理解しやすい命名規則の採用

シンプルに読みにくいコードはGithub Copilotの精度にも影響します。チームであらかじめ共通の命名規則を決めておくことが重要です。例えば「ローワーケースを使用するのか、キャメルケースを採用するのか」など

### 網羅的なテストコードの開発（ChatGPTの活用が前提）

活用が認められる場合に限りますが、ChatGPTを活用して網羅的なテストケースを作成します。

作成したテストケースをコメントアウトとして張り付けてテストコードをCopilotに記述させる。

完璧なテストであるとは保証できないが、プログラムの品質を保証することは確実なのでできれば採用したい。

### 関連ファイルを隣接タブに開いておく

Copilotが認識できるのはエディタで開いているファイルの隣接するタブのみ。関連ファイルをタブに開いたままにしておくことでより正確な提案を行うことが可能になる。このとき、同一拡張子のファイルである必要がある。

また、そもそもCopilotが認識できる文字数には限りがあるため、タブに開くファイルはおおすぎてもダメ。

### コードを生成するためのTipやプロンプトをチームで共有する

コードを生成するためのコメントアウトなどはいらなくなるのでリポジトリには共有せれることがありません。各エンジニアが学習するために共有しておくことでチーム開発がより効率的になり、かつ個人の育成が可能になります。

### 車輪の再発明

ライブラリへの依存を低減する。という意味で車輪の再発明を推奨する。利用するライブラリがシンプルなものだったり、スコープが限定的なら内部に実装するほうがいい場合がある。
「デカ文字」「ドット文字(64x128)」をST7735で作る2(頑張ってパターンを作る)




上側0-9

![o_cop510.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/48fcf1c3-2f2b-3bfa-2049-1ff8b342bdd8.jpeg)



下側0-9

![o_cop511.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a405d085-39d6-6bd3-f518-ef07a79c6e95.jpeg)
複数の同一形式で吐き出されたCSVファイルをWindowsPowerShellで１つにまとめるコマンドレット

# 概要
大したことはないけれど、複数の同一形式で吐き出されたCSVファイルを１つにまとめるコマンドレットを作成したので備忘です。最近は自分というよりはメンバーの十徳ナイフ的に使えたらいいなという気持ちで公開していますね。

# スクリプト

```shell
$sourceDirectory = "（指定のディレクトリ）"
$outputFile = "（作成後のファイル名）"
$encoding = 'UTF8'

$csvFiles = Get-ChildItem -Path $sourceDirectory -Filter *.csv -File
if ($csvFiles.Count -gt 0) {
    $firstCsv = $csvFiles[0]
    $header = Get-Content $firstCsv.FullName -First 1 -Encoding $encoding
    $header | Set-Content $outputFile -Encoding $encoding

    foreach ($csvFile in $csvFiles) {
        $content = Get-Content $csvFile.FullName -Encoding $encoding | Select-Object -Skip 1
        $content | Add-Content $outputFile -Encoding $encoding
    }
}
```

# おわり
いずれPowershell芸人ニでもなってみたいですね（ジョーク）
はじめてのGolang

## はじめに
この記事ではGolangの知識が0の状態からどのようにキャッチアップして、REST APIを作成していったかをまとめています。
これからGolangを学習しようと思っている人の参考になれば幸いです。

## 出会い
「何か新しいことしたいな〜」という一年で数回来る謎のモチベーションがことの発端でした。
これまでにRailsやLaravelちょこっと、React, Next.jsなどを触ってきました。
それを踏まえて別の言語でhotなものをやりたいなと思っていた矢先にGolangと出会ってしまったのです。

## 動機
Golangと言う言葉すらも正直しらず、はじめはGo言語って美味しいの状態でした。
まずは手始めにGolangでできることを調べてみたり、既存のGolangで実装されているサービスを調査してみたり、YoutubeでGolangについて語っている人の動画を見たりしながら調査していきました。

そのうち、「Golangはどうやらhotらしいぞ」と判断する自分がいました。
だったらやってみようかなと興味を持ったことが学習の動機になりました。

## 何を作るか
Golangに限らず、新しいことを学ぶときは「何を作るか」というゴール設定がないと続きません。
そこで以前、Next.js × mongoDBで作成していたバイカー用のアプリがあったのでBE側のAPIをGolangに置き換えることをゴール設定にしました。（実はバイクで日本一周をしながらこのアプリも作っていた）

## どう学ぶか
GolangでAPIを作成することは決まったがGolangの知識は0のままです。
本題のどのような手順で学習していったかを列挙していきます。

**1. 公式のチュートリアルをやってみる(3days)**
まずは公式チュートリアルでGolangがどんなものか触れる。

https://go-tour-jp.appspot.com/welcome/1

この動画を参考にしていました。

https://youtu.be/YS4e4q9oBaU


**2. Echoを触ってみる(2days)**
APIを作成するにあたり、GolangのAPIフレームワークを見ていると`Gin`と`Echo`が良く出てきました。
両方の公式ドキュメントを見比べた上で`Echo`の方がとっつきやすかったので`Echo`を選択しました。

https://echo.labstack.com/guide/

**3. Echoでミニアプリを作ってみる(1week)**
`Echo`の公式を参照しながら簡単なAPIを作り、ディレクトリの構成やテストの書き方などを色々と試してみました。

**4. GolangでREST APIを作成(4weeks)**
目標に設定していたAPIの作成に着手。
詳しくは以下の記事から5つに分けて実装しています。

https://qiita.com/rorrou25/items/935ba8c09c74b2ada629

**repo**

https://github.com/tatsuro1997/bike_noritai_api

## おわりに
トータル6週間くらいでGolangのキャッチアップからREST APIの作成までの過程を振り返ってみました。
やっぱり**新しいことを学ぶことは面白いということに気づけたことが一番の収穫**でした。
まだまだGolangの一部分しか触れられていないので色々な使い方を試してみて実務でも使えるようになりたいなと思いました。
miniscriptの作法 その3

# 概要
miniscript見つけたので、やってみた。
ライントレース、やってみた。
ゴールしてみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/deb5c0b4-e33d-fdc0-1e71-01d60aa32ceb.png)


# サンプルコード

```
for i in range(0, 100000)
   ref = ev3_color_sensor_get_reflect
   p = ref - 18
   ev3_motor_set_power_left (20 - p)
   ev3_motor_set_power_right (20 + p)
   yield
end for
```


以上。
miniscriptの作法 その2

# 概要
miniscript見つけたので、やってみた。
ライントレース、やってみた。

# 参考にしたページ。

https://qiita.com/YoshitakaAtarashi/items/ee2144c4c8349a54da70

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/41379aff-9556-5edf-3aa2-08900cc10a53.png)


# サンプルコード

```
for i in range(0, 100000)
   ref = ev3_color_sensor_get_reflect
   if ref < 18 then
      ev3_motor_set_power_left 30
      ev3_motor_set_power_right 10
   else
      ev3_motor_set_power_left 10
      ev3_motor_set_power_right 30
   end if
   yield
end for
```

以上。
miniscriptの作法

# 概要
miniscript見つけたので、やってみた。

# 参考にしたページ。

https://qiita.com/YoshitakaAtarashi/items/877d1a0cc5ba94a39755

# Hello World

```
print "Hello Word!"
```

# fizzbuzz

```
for i in range(1, 100)
   if i % 15 == 0 then
      print "FizzBuzz"
   else if i % 5 == 0 then
      print "Buzz"
   else if i % 3 == 0 then
      print "Fizz"
   else
      print i
   end if
end for
```

# zundoko

```
i = 0
while i < 4
   if rnd < 0.5 then
      print "zun"
      i = i + 1
   else
      print "doko"
      i = 0
   end if
end while
print "doko"
print "kiyosi"
```

# 九九

```
for j in range(1, 9)
   a = ""
   for i in range(1, 9)
      a = a + i * j + " "
   end for
   print a
end for
```

以上。
MAC「Terminalが予期しない理由で終了しました」のポップが出てターミナルが起動できない

MACユーザーの皆さん、ターミナルを使っていて次のエラーを見たことはありませんか？

**「Terminalが予期しない理由で終了しました」**
![terminal_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342142/51310b1f-ee3e-24a0-c620-dc08d8563f63.png)
最初は[再度開く]を押していたらターミナルが起動するのですが、ある日[再度開く]を押しても上記エラーを繰り返し全く開かなっくなってしまいました。今回は私の備忘録も兼ねて対処法を綴ります。

## システム環境
Macbook Air (M1,2020)
macOS ver.12.6
チップ：Apple M1

## 試したこと
>1.セーフモード（セーフブート）
2.新規アカウント作成しターミナル起動
3.ライブラリから問題となるファイルの退避・削除

対処については以下の記事を参考にさせていただきました。
[[ターミナル]"Terminalが予期しない理由で終了しました"となり、使えなくなった時の対処記録](https://note.com/nakagawa_2424/n/nede5f295df3f)

## 1. セーフモード（セーフブート）

| **[セーフモードの実行方法]** ※Appleシリコンの場合  |
|:--|
|1. [システム終了]で電源OFF<br>2. 電源ボタン長押し（オプション画面が表示されるまで）<br>3. 起動ディスクの選択<br>→「Macintosh HD」を一度クリックし選択された状態にする<br>4. shiftキーを押したまま、Enterキーで決定<br>→shiftキーを押し「続ける」が「セーフモードで続ける」に変わったらEnterキーを押下<br>5. 画面が切り替わり右上に「セーフブート」と表示されていることを確認|

セーフブートを実行して、MACが起動した時点で、メンテナンス作業は終了しています。
システム終了後、再起動してターミナルを確認してみます。私の場合解決しませんでした。

## 2. 新規アカウント作成しターミナル起動

この方法で以下、どちらが問題となっているかを確認します。
>・ユーザーアカウント依存で問題が起きているのか
・PC依存で問題が起きているのか

| [新規アカウント作成手順] |
|:--|
|①アップルメニュー（左上のりんごマーク）　＞　システム設定　をクリック<br>②[ユーザーとグループ]をクリック<br>③[アカウントを追加]をクリック<br>④表示されているアカウントにログインする時のPWを入力　＞　[ロック解除]をクリック<br>⑤フルネーム（日本語可） / アカウント名（半角英数字） / パスワード / を決めて作成(※すぐに削除予定なので適当なアカウント名で大丈夫です！)<br>⑥[ユーザーを作成]をクリック|

以上でアカウントの作成が完了です。
アカウント作成が完了したら **新規アカウントでログインしターミナルを起動** してみましょう！
ターミナルを起動させ冒頭のエラーが表示されるか確認を行います。（※ここでの動作で以下が確認できます。）
>正常に動作する場合　：ユーザーアカウント依存で問題が起きている
正常に動作しない場合：PC依存で問題が起きている

私はこの方法で正常に動作したため「ユーザーアカウント依存で問題が起きている」ことが分かりました。

## 3.ライブラリから問題となるファイルの退避・削除

**1.2.** を実施しユーザーアカウント依存で問題が起きている事から、ユーザー設定から格納されているライブラリの中に問題が発生していると判別ができたため、問題になりそうなファイルを1つずつ退避or削除していきます。

[【トラブルシューティング】[2]新しいユーザアカウントでは改善するがセーフモードでは改善しない場合](
https://discussionsjapan.apple.com/docs/DOC-1032)　を参照

▼ライブラリを表示
　ファインダー選択下で画面上部バーの「移動」を選択　> 「Optionキーの長押しで表示される「ライブラリをクリック」
![liberary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342142/e67f2ec9-206b-6e35-ae47-43832b3216d5.png)

▼問題となっている可能性のファイルを退避・削除

以下はセーフモード❌新規アカウント⭕️の場合に確認するファイルです。

>・/ユーザ/[ユーザ名]/ライブラリ/Application Support
・/ユーザ/[ユーザ名]/ライブラリ/Autosave Information
・/ユーザ/[ユーザ名]/ライブラリ/Containers
・/ユーザ/[ユーザ名]/ライブラリ/Preferences
・/ユーザ/[ユーザ名]/ライブラリ/Saved Application State


私はライブラリに退避フォルダを作り、一度ファイルを退避させて確認しました。

## 結果

私の場合原因になっていたのは、
>/ユーザ/[ユーザ名]/ライブラリ/Saved Application State/

の中に含まれている

>com.apple.Terminal.savedState

こちらのファイルでした。
中身を退避させ、ターミナルを起動してみると、問題なくターミナルが起動しました！🎉

## まとめ

たくさんの記事を参考にしましたが、想像以上に時間がかかりました。すぐに解決するための備忘録として記事にしてみました。
個人的に原因だと考えたのが、症状が発生する1週間くらい前に
Macのターミナルをカスタマイズしたくて背景色や文字色を変更して遊んでいました。
その後すぐのエラーが現れたため、恐らくここでの設定が原因ではないかと思いました。
今回技術的な話ではありませんでしたが、誰か1人でも参考になる記事となっていたら嬉しいです。


参考サイト一覧
■[ターミナル]"Terminalが予期しない理由で終了しました"となり、使えなくなった時の対処記録
https://note.com/nakagawa_2424/n/nede5f295df3f
■キャッシュについて
https://koneta.nifty.com/koneta_detail/1141008005077_1.htm
■セーフモード実行手順
https://bamka.info/safemode-m1-mac/
■Macで新規アカウントを作成する
https://www.too.com/support/faq/mac/22842.html
■トラブルシューティング for Mac (ソフトウェア編)
https://discussionsjapan.apple.com/docs/DOC-1032
「デカ文字」「ドット文字(64x128)」をST7735で作る1(仕様)

目的
温度計等で使用かる　どでか　デカ文字を作り表示する
圧縮形式または、方法は、沢山あるが上下分離のパターン式とする
4ドット×8ドットする
上下分離でおかしくなるところは、デザインでごまかす
下側が真円、上側が余白
線の太さは、1ドット


完成図

![o_cop505.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e93cd27d-1dd8-ebf4-f1ed-2ec507a3f0f5.jpeg)

パターン等

![o_cop506.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a978680a-455e-7558-7f56-ce3fd2b37c65.jpeg)


![o_cop498.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/82969c57-daa9-caab-978b-cf0e89b88c7d.jpeg)


![o_cop499.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2c46c864-f65e-f223-fe36-ec5dc1785339.jpeg)


![o_cop507.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/246d4acc-2d1c-66f5-ba75-72dea312e48f.jpeg)

![o_cop508.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d90cff92-0229-c21d-3de5-c59e493df968.jpeg)

![o_cop509.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/edffb625-e094-77e4-2fd6-6b0294cef22f.jpeg)
ベルヌーイ試行の平均が従う分布

 ## はじめに
A/Bテストについての書籍で気になる点があったので確認するためのメモです。  
以下が気になった点です。 

> あくまで経験則ではあるが、メトリクスの平均値が正規分布に従うために必要なサンプルサイズは、メトリクスYの歪度（skewness）sの2乗の355倍程度である(Kohavi,DengandLongbotham,etal.2014)。歪度とは分布の非対称性を表す値の1つで下記の式で定義される。(17.5)  
Ron Kohavi,Diane Tang,Ya Xu,大杉 直也. A/Bテスト実践ガイド　真のデータドリブンへ至る信用できる実験とは (Japanese Edition) (p.315). Kindle 版. 


## メモ
1000人のうち、1名が商品を購入する時、0.1%の購入率だと表現することができます.  
ここで、1000人のそれぞれが同一の確率で購入するという仮定を置く. 
すると、成功確率pのベルヌーイ試行に従う確率変数を1000回抽出した標本平均はざっくりいってpである確率が最も高いということになります.  
この抽出作業をp=0.001とした上で、1000回繰り返しヒストグラムにしたのが下図です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1276668/4832cf3c-a4ca-dd70-a3bd-f29a4e78e882.png)

この分布は、n(この場合1000人の1000)が非常に大きい場合、正規分布に近似されることが中心極限定理により示されることを統計検定２級のテキストや大学の一般教養として学びました. 
しかし、今のところ上図は正規分布に近似できているとは思えません.  
色々と似ていないところがありますが、例えばこのケースでは0未満の標本平均は実現しないので、著書からの引用を借りると、歪んでいると言えます.  
また、数値がそもそも離散的で、今回のケースでは1000人の購入割合を計算しているので、上図のとおり最小でも0.001刻みになります. 

累積度数にして再表示させると下図のようになるので、正規分布を仮定できない場合でも、1000人のうち3人以上が購入する結果を得た場合は、稀だということができます.  
その場合、何か施策の効果があったなど、この標本の1000人はこれまで仮定していた標本とは異なる成功確率pを持つと考えるか、あるいは1000人の購買行動をそれぞれ購入率pのベルヌーイ試行だという仮定そのものが誤りであることを疑うことになります. 私はどちらかといえば後者です.  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1276668/78b2d821-f3ed-873a-d210-ac0e8e019c34.png)

さて、再度引用文です.  

> あくまで経験則ではあるが、メトリクスの平均値が正規分布に従うために必要なサンプルサイズは、メトリクスYの歪度（skewness）sの2乗の355倍程度である(Kohavi,DengandLongbotham,etal.2014)。歪度とは分布の非対称性を表す値の1つで下記の式で定義される。(17.5)  
Ron Kohavi,Diane Tang,Ya Xu,大杉 直也. A/Bテスト実践ガイド　真のデータドリブンへ至る信用できる実験とは (Japanese Edition) (p.315). Kindle 版. 

### 歪度とは  
Bingにチャットしてみると以下のようです.  
$$\frac{\frac{1}{n}\sum_{i=1}^{n}(x_i-\bar{x})^3}{\left(\frac{1}{n}\sum_{i=1}^{n}(x_i-\bar{x})^2\right)^{\frac{3}{2}}}$$

分散や標準偏差の考え方を修正して、平均からプラスとマイナスいずれにばらついているか表現できるようにしたものだと理解しました.(3乗してプラマイが現れるようになっているので...)  

pythonで計算する場合は以下のようなので数式を覚える必要はなさそうです.  
歪度を計算すると1近傍の数値となり、著書で言及されている歪度（skewness）sの2乗の355倍を計算すると305.9928486457792となり、私の直感とは異なる結果となりました.  
```python
import numpy as np
from scipy.stats import skew

p = 0.001 # 確率
n = 1000 # 試行回数
sample = np.random.binomial(n, p, 1000) / n # 標本平均を1000回取得
skewness = skew(sample) # 歪度を計算

print(skewness ** 2 * 355)
```

著書内によると、正規分布に従うかどうかの検定が存在するみたいですが、まだそこまで追いついていないのでメモはここまでです. 



### 2023年5月12日追記
よくよく引用部分を見ていると上述の歪度計算に使う数値に誤りがあることに気づいたので追記です.  
> あくまで経験則ではあるが、メトリクスの平均値が正規分布に従うために必要なサンプルサイズは、メトリクスYの歪度（skewness）sの2乗の355倍程度である(Kohavi,DengandLongbotham,etal.2014)。歪度とは分布の非対称性を表す値の1つで下記の式で定義される。(17.5)  
Ron Kohavi,Diane Tang,Ya Xu,大杉 直也. A/Bテスト実践ガイド　真のデータドリブンへ至る信用できる実験とは (Japanese Edition) (p.315). Kindle 版. 

メトリクスYの歪度を求めるべきなのに、メトリクスYの標本平均の歪度を計算していました.  
図で表すと私が表現すべきなのは下図のような形状のベルヌーイ分布の歪度です.  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1276668/f2139387-7b22-ccfd-d693-f89cb483a180.png)

Bingに聞いて、計算してみたところ約35万という数値が得られました.  
```python
import numpy as np
from scipy.stats import bernoulli

p = 0.001 # 成功確率
n = 1000 # 試行回数

x = bernoulli.rvs(p, size=n) # ベルヌーイ試行

skewness = bernoulli.stats(p, moments='s') # 歪度の計算

print(f'skewness: {skewness}')
print(f'skewness ** 2 * 355: {skewness ** 2 * 355}')
'''
skewness: 31.575322658699797
skewness ** 2 * 355: 353935.35535535525
'''
```
【Tableau】DATASaber:HandsOn - Fundamental(Ord1) Q2 解説

tableau datasaberになるための技術力に関する問題を解いていきたいと思います。
こちらの問題はtableauを始める方にぴったりだと思いますので、ぜひチャレンジしてみてください！
使用するデータは、「サンプル - スーパーストア.xls」を使用する。:arrow_down:
https://drive.google.com/drive/u/0/folders/1kXSb3fqPTt3VcPjGUSgOmrztlRfvvpMH

:white_check_mark:ord1-Q2
・割引率が最も大きい地域はどこですか？
　また、そこでの割引率は何%でしたか？

地域ごとに割引率を出します。
そのまま割引率をビューに入れると、下記のように合計になってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/3b7f8d55-1450-67ea-25c9-658554b9b0a6.png)

よって先に合計から平均に変えていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/ddf1bc0a-6270-06a1-0b5b-13ab6b359942.png)

次に、割引率は何%でしたか？と聞かれているので、数値形式より、パーセンテージに変更していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/7202d666-1767-3831-453e-44e204c32363.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/a94b39f2-9e60-0466-e011-fa2eca711ba4.png)

変更後、ord1-Q1で紹介した降順に変更し、マークラベルを表示することで、割引率が最も大きい地域とその地域の割引率を求めることができます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/1224a648-65ce-6634-fc46-a8d6581fecb0.png)
【Linux】diffコマンドの差分比較を見やすくする

・差分比較をするためのファイルを作成

``` file1.txt
apple
banana
Orange
peech
```

``` file2.txt
orange
banana
peech
lemon
```

・差分比較をしてみる

```
[root@localhost 20230510]# diff -y file1.txt file2.txt
apple                                                         | orange
banana                                                          banana
Orange                                                        <
peech                                                           peech
                                                              > lemon
```

記号の意味は下記の通り

```
| 一部異なる
< 左記にのみ存在する
> 右記にのみ存在する
```

・ソートするとより見やすくなる

```
[root@localhost 20230510]# diff -y <(sort file1.txt) <(sort file2.txt)
apple                                                         <
banana                                                          banana
Orange                                                        | lemon
                                                              > orange
peech                                                           peech
```

・大文字a-zと小文字a-zもソートしてみる

```
[root@localhost 20230510]# diff -y <(LC_COLLATE=C sort file1.txt) <(LC_COLLATE=C sort file2.txt)
Orange                                                        <
apple                                                         <
banana                                                          banana
                                                              > lemon
                                                              > orange
peech                                                           peech
```

でけたー。個人的な最適解。
Orangeとorangeは「|」で表記されたほうが良いのかな？
競技プログラミングの鉄則 A12 - Printer

# 記事概要
競技プログラミングの鉄則 演習問題集のA12のとりあえず動くコードと説明．
問題 -> https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_l

# 注意
アルゴリズム初心者が書いてます．時間内の動作は確認してますが、必ずしも最適解ではないです．

# とりあえずコード
~~~C++:A12_main.cpp
/////////////////
// A12-Printer //
/////////////////

// 問題解決に使う技法
// ・二分探索

#include <iostream>
#include <vector>

using std::vector;

int main(void)
{
	//============================= 入力 =============================//
	long long N, K;
	std::cin >> N >> K;

	vector<long long> printer(N + 1);
	for (auto i = 1; i <= N; ++i) {
		std::cin >> printer[i];
	}

	//============================= 計算 =============================//
	long long inf = 1'000'000'000;						// 求める答えの最大値

	// 計算の方針
	// 1～10^9の範囲の内、K枚のチラシをプリントできる時間の最小値を二分探索で求める．
	long long left = 1, right = inf;
	while (right > left) {
		long long mid = (left + right) / 2;
		
		// 時間midまでにプリント可能なチラシの枚数と求める
		long long print_sum = 0;						// 時間midまでにプリント可能なチラシ数．
		for (auto i = 1; i <= N; ++i) {
			print_sum += mid / printer[i];				// printer[i]が時間midの間にプリント可能なチラシの枚数をprint_sumに加える．
		}
		
		if (print_sum >= K) {
			right = mid;
		} else {
			left = mid + 1;
		}
	}

	//============================= 出力 =============================//
	std::cout << right << std::endl;
}
~~~

# コード説明
この問題の特徴は、ある時間tの間に全プリンタがプリントできる枚数kを求めることは簡単であるのに対し、ちょうどk枚プリントすることができる時間tを直接求めることは困難であることである．つまり、必然的に前者のアプローチで問題をとる必要がある．

ある時間tの間にプリント可能な枚数kはしたの式で求まる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305871/0ea6feed-5e04-9f69-048d-653521094806.png)

さて、問題の前提条件より、ちょうどk毎プリントする時間tは1~1'000'000'000の範囲に存在することが分かっている．この範囲で二分探索を行う．
探索を行う範囲の左端leftと右端right、その中間のmidを見る．ある時間tをmidでおく．この時、時間midの間にプリントできた枚数を k_mid でおく．k > k_midであれば、求めるtはmidからrightの範囲に存在し、k < k_mid であれば求めるtはleftからmidの間に存在することがわかる．これをright == leftとなるまで繰り返すことで、tを求めている．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305871/76da07b6-f0c8-0e98-bf69-09027887b839.png)
MUIのMenuとhoverを組み合わせるアレ

たいしたコンポーネントではないですが、ググっても検索上位に出てこなかったので、備忘録として。

## 最小構成環境
@mui/material: 5.11.5
react: 18.2.0

## 実現したもの
メニューにホバーしたらメニューが展開されるやつ(よく見ますね)
![preview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/4bb39fcd-65d8-9ef7-6310-0caae89b9528.gif)

# CodeSandbox
実装はCodeSandboxを参照してください

https://codesandbox.io/embed/mui-menu-with-hover-clo8yg?fontsize=14&hidenavigation=1&theme=dark
chatgptが正規表現の訓練に付き合ってくれた話

## はじめに

今日はフロントのバリデーションで正規表現に触れる機会がありましたが、行いたい振る舞いを実装するのに時間がかかってしまったため、おさらいしてみました。

まず、以下を入力しました

> 正規表現を何もみずにかけるようなエンジニアはつよいとだれかがいってた。
正規表現のインストラクターとしてふるまって下さい。
いくつか問題を出して、添削や解説を行ってください。
> 

会話をした後に、最後に「これまでの会話をマークダウン形式でまとめてください」と入力しました。

## **正規表現についての会話**

### **問題の提示**

- メールアドレスの正規表現を作成してください。([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+)
- 郵便番号の正規表現を作成してください。(\d{3}-\d{4})
- 電話番号の正規表現を作成してください。([0|+81][0-9]{3,5}[0-9]{1,4},[0-9]{4})
- URLの正規表現を作成してください。((http | https)://[a-zA-Z0-9.-]+(/[a-zA-Z0-9_./-]+)*)
- 身分証明書番号の正規表現を作成してください。([a-zA-Z]\d{12})

### **正規表現についての解説**

- 正規表現は、文字列のパターンを表すための言語です。
- 正規表現を使うことで、文字列の検索や置換などを柔軟かつ効率的に行うことができます。
- 正規表現は、様々なプログラミング言語やツールでサポートされています。

### **正規表現の解説**

- **`^\d{3}-\d{4}$`**は、3桁の数字、ハイフン、4桁の数字のパターンにマッチする正規表現です。(例: 123-4567)
- **`^\d{3}-\d{4}-\d{4}$`**は、3桁の数字、ハイフン、4桁の数字、ハイフン、4桁の数字のパターンにマッチする正規表現です。(例: 123-4567-8901)
- **`^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$`**は、メールアドレスのパターンにマッチする正規表現です。([username]@[domain].[tld]) 例: **[john.doe@example.com](mailto:john.doe@example.com)**
- **`^(http | https)://[a-zA-Z0-9.-]+(/[a-zA-Z0-9_./-]+)*$`**は、URLのパターンにマッチする正規表現です。([protocol]://[hostname]/[path]) 例: **[https://www.example.com/index.html](https://www.example.com/index.html)**
- **`[a-zA-Z]\d{12}`**は、アルファベット1文字に続いて12桁の数字のパターンにマッチする正規表現です。(例: A123456789012)

### 正規表現の詳しい解説

かなり詳しい解説をしてくれました。

例えば、メールアドレスのパターンについて以下のような解説をしてくれました

**`^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$`**

- この正規表現は、**[XXX@YYY.ZZZ](mailto:XXX@YYY.ZZZ)**形式の電子メールアドレスを検証するために使用されます。
- **`^`** は文字列の先頭を表します。
- **`[a-zA-Z0-9_.+-]+`** は、1つ以上の文字（大文字、小文字、数字、ピリオド、アンダースコア、プラス、ハイフン）を表します。
- **`@`** は@記号を表します。
- **`[a-zA-Z0-9-]+`** は、1つ以上の文字（大文字、小文字、数字、ハイフン）を表します。
- **`\.`** はピリオド文字をエスケープして表します。
- **`[a-zA-Z0-9-.]+`** は、1つ以上の文字（大文字、小文字、数字、ピリオド、ハイフン）を表します。
- **`$`** は文字列の末尾を表します。

### 予約された正規表現一覧

- **`.`** : 任意の1文字にマッチ
- **`^`** : 文字列の先頭にマッチ
- **`$`** : 文字列の末尾にマッチ
- `*` : 直前の表現に0回以上マッチ
- **`+`** : 直前の表現に1回以上マッチ
- **`?`** : 直前の表現に0回か1回マッチ
- **`{n}`** : 直前の表現にn回マッチ
- **`{n,}`** : 直前の表現にn回以上マッチ
- **`{n,m}`** : 直前の表現にn回以上、m回以下マッチ
- **`[]`** : キャラクタークラス。括弧内のいずれかの文字にマッチ
- **`()`** : グループ化。後述の量指定子や論理演算子でグループ化できる
- **`|`** : 論理和。AまたはBにマッチ
- **`\`** : エスケープ文字。特殊文字をエスケープする
- **`\d`** : 数字にマッチ。[0-9]と同じ
- **`\D`** : 数字以外にマッチ。[^0-9]と同じ
- **`\w`** : 単語構成文字にマッチ。[a-zA-Z0-9_]と同じ
- **`\W`** : 単語構成文字以外にマッチ。[^a-zA-Z0-9_]と同じ
- **`\s`** : 空白文字にマッチ。[ \t\n\r\f\v]と同じ
- **`\S`** : 空白文字以外にマッチ。[^ \t\n\r\f\v]と同じ




すごいっす。

あれ、これ俺正規表現の文法身に着ける必要ある...?と思ってしまった僕でした。

文法自体というよりも、**「物事を構造化して整理する力」** が求められている気がします。


## おわりに

作るアプリのテーマが決まったので、次回は設計とかしようかなと思います。

ではまた。
【Python】パスカルのトライアングル（実装）

# はじめに
パスカルのトライアングルをPythonで実装しました。

### 参考図（パスカルのトライアングル）　Wikipediaより引用
![スクリーンショット 2023-05-10 23.56.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/a73aef97-2fe4-56d9-9d81-0737cf8d65e5.png)


# 実装
```python:pascal_triangle.py
from typing import List

# 値を足し合わせる部分のアルゴリズム（出力はリストに入ったままの状態）
def pascal_triangle(depth: int) -> List[List[int]]:
    # 各深さ毎のリストを作成する（深くなる毎に1が追加されていく）
    data = [[1] * (i + 1) for i in range(depth)]
    # 和を計算できるようになるのは、深さが２以降
    for line in range(2, depth):
        # １つ上の層の値を足したものに置き換える。
        for i in range(1, line):
            data[line][i] = data[line-1][i-1] + data[line-1][i]
    return data

# トライアングル形式で表示させる関数
def print_pascal(data: List[int]) -> None:
    width = 6
    for index, line in enumerate(data):
        # リスト内の数字のみを取り出す
        numbers = "".join([str(i).center(width, " ") for i in line])
        # 深さに応じてインデントを変える
        print((" " * int(width/2)) * (len(data) - index), numbers)

# テスト
if __name__ == "__main__":
    # 改行して表示させる
    print_pascal(pascal_triangle(11))
```

# 参考
https://www.udemy.com/course/python-algo
GASで便利なスクリプト集

# スプレッドシートをPDF化するスクリプト
```
// 関数を実行するタブをメニューバーに追加
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('効率化');
  menu.addItem('アクティブなスプレッドシートのPDF化', 'createPdf');
  menu.addToUi();
}

/**
 * 現在開いているシートよりPDFを出力
 */
function createPdf() {

  // アクティブなスプレッドシートIDを取得
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const spreadsheetId = spreadsheet.getId();

  // アクティブなシートID
  const gid = spreadsheet.getActiveSheet().getSheetId();

  // スプレッドシートのあるフォルダ
  const folder = DriveApp.getFileById(spreadsheetId).getParents().next();

  // シート名を取得
  const name = spreadsheet.getName().replace('.xlsm', '');

  // 出力するPDFファイル名
  const fileName = `${name}_${Utilities.formatDate(new Date(), 'JST', 'yyyyMMdd')}.pdf`;
  
  // 出力オプション
  var opts = {
    'exportFormat' : 'pdf',    // ファイル形式の指定 （pdf / csv / xls / xlsx）
    'format'       : 'pdf',    // ファイル形式の指定 （pdf / csv / xls / xlsx）
    'size'         : 'A4',     // 用紙サイズの指定 （legal / letter / A4）
    'portrait'     : 'true',   // 用紙の向き （true : 縦向き / false : 横向き）
    'fitw'         : 'true',   // 幅を用紙に合わせるか （true : 合わせる / false : 合わせない）
    'sheetnames'   : 'false',  // シート名をPDF上部に表示するか （true : 表示する / false : 表示しない）
    'printtitle'   : 'false',  // スプレッドシート名をPDF上部に表示するか （true : 表示する / false : 表示しない）
    'pagenumbers'  : 'false',  // ページ番号の有無 （true : 表示する / false : 表示しない）
    'gridlines'    : 'false',  // グリッドラインの表示有無 （true : 表示する / false : 表示しない）
    'fzr'          : 'true',   // 固定行の表示有無 （true : 表示する / false : 表示しない）
    'top_margin'   : 0.8,
    'bottom_margin': 0.8,
    'left_margin'  : 0.7,
    'right_margin' : 0.7,
  };

  let urlExt = [];
  
  // オプション名と値を「=」で繋げて配列に格納
  for( optName in opts ){
    urlExt.push( optName + '=' + opts[optName] );
  }

  // 各要素を「&」で繋げる
  const options = urlExt.join('&');

  // API使用のためのOAuth認証用トークン
  var token = ScriptApp.getOAuthToken();

  // URLの組み立て
  const url = `https://docs.google.com/spreadsheets/d/${spreadsheetId}/export?gid=${gid}&${options}`;

  // PDF作成
  var response = UrlFetchApp.fetch(
    url, {
      headers: {'Authorization': 'Bearer ' +  token}
    }
  );

  // Blob を作成する
  var blob = response.getBlob().setName(fileName);

  //　PDFを指定したフォルダに保存
  folder.createFile(blob);
}
```
# スプレッドシートにデータを書き込む関数
```
/*
 * sheet:スプレッドシート
 * data:連想配列データ(項目名:回答)
 **/
function setDataToSheet(sheet, data) {
  let lastrow = sheet.getLastRow();
  if (lastrow == 0) {
    //記入先シートにデータが無い場合は、1行目の項目(key)をセット
    sheet.appendRow(Object.keys(data));
    lastrow++;
  }
  const firstRowDatas = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
  let entries = Object.entries(data);

  //データのエントリーを1つずつ精査
  for (entrie of entries) {
    //A1からデータがある最終列までの値を取得
    for (firstRowDataPos in firstRowDatas) {
      const itemName = removespace(firstRowDatas[firstRowDataPos]);
      //項目名と一致するエントリーの回答をセットする。
      if (itemName == entrie[0]) {
        //入力先のセルを文字列表示させる。
        sheet.getRange(lastrow + 1, parseInt(firstRowDataPos) + 1).setNumberFormat('@');
        //回答をセルにセット
        sheet.getRange(lastrow + 1, parseInt(firstRowDataPos) + 1).setValue(entrie[1]);
        break;
      }
    }
  }
}
```
[cloudflare]DNS_PROBE_FINISHED_NXDOMAIN

cloudflareで管理しているwebサイトが見れなくなるバグに見舞われました。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/52aa99a4-748e-ce0a-7438-136aa3bed6a3.png)

```
DNS_PROBE_FINISHED_NXDOMAIN
```

NXDOMAIN: ドメインが見つからない

そんなぁぁ何もしてないのにぃ。。


# 何もしてないなんてことはない
search consoleでサイトの所有権の確認とかしてませんか？
ちゃんと注意書きを読みましょう、ルートのcnameが消されるみたいです。。。。
cnameを登録しなおせば復帰します。

# 詳しくは
https://zenn.dev/xbit/articles/014c27a4c6bbe2
laravel8以降におけるテスト実行時の環境変数について

# 概要

- laravel8以降でのテスト実行時の環境変数の読み込まれ方についてまとめておく。

# 注意

- 一部情報で確証が得られていない物があるので誤りがありましたら何なりとコメントいただけますと幸いです。

# laravelでテストクラスのテストメソッドを実行する方法

- laravelでテストを実行する方法は大きく分けて2通り存在する。
- `$ ./vendor/bin/phpunit`コマンドを実行するパターン（以降、「phpunitコマンドでテスト実行」と呼称）と、`$ php artisan test`コマンドを実行するパターン（以降、「artisanコマンドでテスト実行」と呼称）である。
- どうやらこの２つの方法ごとに環境変数の読まれ方が若干違うようなのでまとめてみる。

# phpunitコマンドでテスト実行

- laravelのプロジェクトディレクトリで下記のように実行することでテストを実行する。

    ```shell
    ./vendor/bin/phpunit
    ```

- この方法だとphpunit.xmlに記載されている環境変数が読み込まれ、テストが実行される。
- そのため、テスト用DBへの接続情報などはphpunit.xmlのenvに記載する必要がある。（下記のvalue=の部分をテスト用DBへの接続情報で埋めてゆく）

    ```phpunit.xml
    <env name="DB_CONNECTION" value=""/>
    <env name="DB_HOST" value=""/>
    <env name="DB_DATABASE" value=""/>
    <env name="DB_USERNAME" value=""/>
    <env name="DB_PASSWORD" value=""/>
    ```

- phpunitコマンドでテストを実行するとたとえ.env.testingにテスト用の環境変数情報を記載しても読み込まれない（おそらく）

# artisanコマンドでテスト実行

- 下記のartisanコマンドを実行することでテストを実行する事ができる。

    ```shell
    php artisan test
    ```

- 上記の状態だと特に.envが指定されていないのでデフォルトの.env（各環境で動作するときに使われる.env）の内容が読み込まれてテストが実行される。
- .env.testingを用意している場合、下記のように`--env=testing`のオプションをつけることで.env.testingの環境変数を使ってテストを実行してくれるっぽい。

    ```shell
    php artisan test --env=testing
    ```

- .env.testingの情報を使ってテストを実行してほしいならこっちを実行する。
- ただ、PHPUnitが実行されるときにphpunit.xmlはartisanコマンドを使ったテスト実行でも読み込まれているはずである。phpunit.xmlの記載で上書きされたら嫌なので、.env.testingに記載してartisanコマンドでテスト実行するならphpunit.xmlのテスト用DBの接続情報のタグはコメントアウトするか削除したほうがいいかも。（`<env name="DB_CONNECTION" value=""/>`のまま記載されておくと空文字で環境設定がオーバラップされそう、、！ちょっとこの辺は調査不足です。ごめんなさい。）

# まとめ

### phpunit.xmlにテスト時の環境変数を記載したい人

- 下記コマンドを使ってテストを実行する。

    ```shell
    ./vendor/bin/phpunit
    ```

- .env.testingを用意して、情報記載しても別に構わないがphpunitコマンドでテスト実行すると.env.testingは読まれない（はず）

### .env.testingにテスト時の環境変数を記載したい人

 - 下記コマンドを使ってテストを実行する。

    ```shell
    php artisan test --env=testing
    ```

- phpunit.xmlも読まれているはずなのでオーバーラップされたくない環境変数のタグはphpunit.xmlから削除かコメントアウトしておいたほうがいいかも。（ただ、artisanコマンドを使って--env=testingを指定してテスト実行すると.env.testingの環境変数が優先されると何処かで読んだ気もするので、削除やコメントアウトの必要はないかも知れない。）
【Dependabot】特定の依存関係を無視する方法


## 設定方法

`.github/dependabot.yml`に以下のように記述することで特定のバージョンを無視できます。  

```yml:.github/dependabot.yml
version: 2
updates:
  - package-ecosystem: 'docker'
    directory: '/'
    schedule:
      interval: 'daily'
    ignore:
      - dependency-name: 'node'
        versions: ['~>19.0']
```
【Swift】ActiveLabelを使ったハッシュタグをクリックした後の処理

# はじめに
マークアップと比較して、iOSではテキストの中からURLを検知し、それをリンクとして処理するのに工数がかかる。

`ActiveLabel`を使って、UILabelの中の`#`をクリックしたときにTwitterのURLに飛ばす処理を備忘録として記録。

# 実装
::: note warn
「ハッシュタグをクリックしてURLを開く処理」に対するエラーハンドリングは実装してないので、参考までに。
:::
``` swift:ViewController.swift
import UIKit
import ActiveLabel

final class ViewController: UIViewController {
    @IBOutlet private var label: ActiveLabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.handleHashtagTap { hashtag in
            let appURL = URL(string: String.twitterURL)!
            UIApplication.shared.open(appURL, options: [:], completionHandler: nil)
        }
    }
}
```

# プレビュー
**アプリの画面**
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802393/feeae7b6-2a7f-bd3d-1301-21f2278c9c8d.png">

**ハッシュタグをクリックした後の画面**
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802393/8cef9220-8d92-620c-1e28-8a854a1edd61.png">


# 終わりに
UILabelの文字の中から正規表現を使わずに`#`を認識してもらえるのは助かる

`ActiveLabel`はURL, メールアドレスにも活用できるので、今後有効活用したい

# 参考リンク
[ActiveLabel - Github](https://github.com/optonaut/ActiveLabel.swift)
[UIを作る際にライブラリにする？それともDIYする？の切り分けと実装のアイデア帳 (@Swift Tweets 2018 Spring)](https://qiita.com/fumiyasac@github/items/144aec1e1726500d9d5a)
音声対話チャットボットフレームワークChatdollKitでChatGPT Streamを試してみる

ChatdollKitでChatGPTのStream対応したサンプルコードが公開されたので検証しました。今までのサンプルコードはStreamに対応してなかったのでBotが会話するまでに若干のラグがありました。

https://twitter.com/uezochan/status/1655614155943215107?s=20

## ChatdollKitの説明 

> ChatdollKitは、お好みの3Dモデルを使って音声対話可能なチャットボットを作るためのフレームワークです。

公式から引用

## 検証環境

- Unity Version 2021.3.24f1
- ChatdollKit.unitypackage v0.6

# ChatdollKitの導入

こちらの記事を参考にChatdollKitを導入します
[ChatGPT＋3Dモデルの音声対話エージェントを15分で開発する方法](https://qiita.com/uezo/items/7ff1566f05c0a1c74a46)

## 躓いたポイント
### JSON.NET For Unityのインポート
JSON.NETの公式をドキュメントを参考にパッケージマネージャー経由でインストールします。

https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Install-official-via-UPM

# ChatGPTStreamSkillを試してみる

## ChatGPTStreamSkill.csのインポート
https://github.com/uezo/ChatdollKit/blob/master/Examples/ChatGPT/ChatGPTStreamSkill.cs からChatGPTStreamSkill.csをダウンロードしてUnityのエディタの画面からChatdollKit/Example/ChatGPT/ChatGPTSkillのフォルダに追加します。

## DemoChatシーンを編集

### ChatGPTStreamSkillをAdd Component

ChatdollKit/Demoフォルダの中のDemoChatを開いて、ChatdollLKitVRMにChatGPTStreamSkillをAdd Componentします。追加したらApi Keyの欄にChatGPTのAPI Keyを記載しておきます。
![スクリーンショット 2023-05-10 23.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89131/f9eb6005-387d-8251-2ee5-04b6c412e7f9.png)
既存のChatGPTSKillはRemoveしておきましょう。

### TTSの設定
自分が試した際はVoiceVox TTS Loaderではうまく動作しなかったので、Google TTS Loaderを使ってます。

## 躓いたポイント
### NullReferenceException: Object reference not set to an instance of an object

> NullReferenceException: Object reference not set to an instance of an object
ChatdollKit.UI.MicrophoneVolumeController.LateUpdate () (at Assets/ChatdollKit/Scripts/UI/MicrophoneVolumeController.cs:31)

シーンを再生すると上記のエラーが起きたので、下記のスクリプトをChatdollKitVRMのオブジェクトに追加して解決しました。

- GoogleVoiceRequestProvider
- GoogleWakeWordListener

![スクリーンショット 2023-05-18 20.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89131/a2900093-7232-b1c7-94ee-6698e99b10d2.png)


# 検証
シーンを再生して話しかけてみましょう！


https://twitter.com/yoshikai_/status/1656306533658161152?s=20

かなりはやい！！

## 検証に使ったモデル
https://booth.pm/ja/items/4038641
AWS Certified Machine Learning – Specialty＿勉強メモ（３日目）

# はじめに
標記の試験に向けた勉強メモ（３日目）です。

# 勉強メモ
・kinesis Data Firehoseは、ストリーミングデータをデータストアや分析ツールにロードする最も簡単な方法。データをキャプチャして、S3、Redshift（データウェアハウス）、Elasticsearch serviceなどにロードするために必要となるインフラやストレージなどをすべて管理する。

・QuickSightは、S3から直接データを読み取ることが可能。

・Glueは、分析、機械学習、アプリケーション開発のためのデータの検出、準備、結合を容易にするサーバーレスデータ統合サービス。（数分で使用開始可能。）

・Glue ETLジョブでは、データを書き込むのに15分の遅延が発生する。

・Object2Vecを使用すると、意味的に類似するオブジェクトを検索できる。（重複する質問を特定したい時などに使用）

・BlazingText Word2Vecでは、意味的に類似した単語のみを検索できる。

・Elastic File System (EFS) は、サーバーレスで完全に伸縮自在なファイルストレージを提供するように設計されており、ストレージ容量やパフォーマンスのプロビジョニングまたは管理なしでファイルデータを共有することを可能にします

・Kinesis Data Analyticsは受信ストリームデータを直接取り込むことができない。（Kinesis Data Streamsなどを介すことが必要）

・Kinesis Data AnalyticsはデータをEFSに直接書き込むことができない。

・EMRは、AWS上でのApache HadoopやApache Sparkなどのビッグデータフレームワークの実行を簡素化し、膨大な量のデータを処理および分析するマネージドクラスタープラットフォーム。（用途に合わせて、Apache HiveやApache Pigの使用も検討する）

・バッチサイズは、1回の反復で使用されるトレーニングサンプルの数のこと。

・転移学習モードでは、ネットワークは事前にトレーニングされた重みで初期化され、最上位の完全に接続された層だけがランダムな重みで初期化される。

・増分（インクリメンタル）トレーニングは、前回のトレーニングでは考慮されていなかった、モデルのパフォーマンスが低下した基礎となるパターンを含む拡張されたデータセットを使用して、新しいモデルをトレーニングする際などに用いる手法。（単純に定期的に生成される新しいデータで、モデルをアップデートしたい場合にも使用）

・MICE（Multiple Imputation by Chained Equations）は、欠損値を補完するための統計的手法の一つ。欠損値のないレコードを学習データとして使用し、モデルを作成する。作成したモデルを欠損値を含む行に適応させ、出力された値を補完値とする。
実装例：https://www.kaggle.com/code/residentmario/simple-techniques-for-missing-data-imputation/notebook

# 参考
https://www.udemy.com/course/aws-certified-machine-learning-specialty-full-practice-exams
超かみ砕いてWebの基本概念を説明してみた

# 超かみ砕いてWebの基本概念を説明してみた

クッキー・セッションって何ですか？

この質問にすぐに答えられなかった方は見てくださいねー。(すぐ読めます)

Webに関わる方には最低限知っておいて頂きたいWebの基本概念を超絶簡単にイメージできるようにするための記事です。

何かWeb系の本を読む前にざーっとここに書いてある内容を読んでおくと理解が進むと思います。

※以下の書籍を参考にかみ砕いて説明しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3350234/4f1bb260-f222-5788-b98c-758999891904.png)

# 用語説明



## クライアントサーバー

クライアント？サーバー？全然っ難しくないです。

**クライアントは何かのサービスを受け取る人**

今回でいえばサービス(Webページ)を受け取るブラウザのこと

**サーバーとはサービスを提供する人**

今回でいえばWebページを配信するコンピューターのこと



クライアントサーバーは現実世界で例えると簡単です。

マックを例にします。
- 商品を提供する店員さんがサーバー
- 商品を受け取るお客さんがクライアント

|用語|マック|Web|
|--|--|--|
|クライアント|お客さん|ブラウザ|
|サーバー|店員さん|Webページを配信するコンピューター|

## リクエストとレスポンス

マックに行ったら商品を注文しますよねー。

WebではWebページを注文することを**リクエスト**と呼びます。

商品を注文したら商品を受け取りますよねー。

Webでは注文して受け取ったWebページを**レスポンス**と呼びます。



### HTTPプロトコル

ところで、マックでの注文の仕方って決まってますよね。

列に並んで、メニュー表からメニューを選んで、お金を払う。

お金払わないと注文できないですよね。

Webの世界にもリクエストの仕方に決まりごとがあり、

***通信プロトコル***(通信する際の決まりごと)と呼びます。

特にWebページの受け渡しをやり取りする際の決まり事を

***HTTPプロトコル***というんです。

qiitaのホーム画面を表示したいときはブラウザに下記のURLを打ち込むと思います。
https://qiita.com

このURLの先頭の https(http)がHTTPプロトコルで通信しますよということを表しています。


### ステートレスとステートフル
ステートというのは状態という意味なんですけどこれも現実にたとえていきましょう。

散髪屋さんに行ったとします。

高級な散髪屋さんはサービスが充実しているので、あなたが前に来たことを覚えてくれています。

２回目以降あなたが高級な散髪屋さんに行くと店員さんは、前回と同じ髪型にしますか？と聞いてくれます。


1000円カットの散髪屋さんはいちいちあなたが来たことを覚えてくれていません。

2回目以降来店しても毎回どんな髪型にしますか？と聞かれます。


状態を持つ→前回来店したお客さんを覚えている(高級散髪屋)
状態を持たない→前回来店したお役さんを覚えていない(1000円カット)

Webの世界に戻ります。

***結論を先に言うとHttpプロトコルでの通信(Webページのやり取り)は状態を持ちません(ステートレス)***。


つまり、Webページを提供しているサーバーがこのクライアントからのリクエストは前回も来たなー　

とは覚えておらず、毎回始めてきたお客さんのようにふるまうということです。

覚えておいてくれた方がリッチじゃんと思うかもしれないですが処理層度を上げるためにHttp通信では

ステートレスが採用されているのです。



### クッキー

するどい方はこういう疑問を持つかもしれません。

アマゾンで買い物する時ログインしている間は、商品ページ画面や商品購入ページなどに移動しても

自分がこの商品を見て、自分がこの商品を買おうとしているということが分かっているじゃないか！

***HTTPって本当にステートレスなの？***　と。

はい、HTTPはステートレスです。それは変わりません。

しかし、***HTTPを拡張してステートを持たせることを可能にした技術がクッキーなのです。***


***クッキーとはブラウザがあなたのPCに保存するただのテキストファイルです。***

クッキーにはどんな情報が保存されているのでしょうか？

それはあなたが特定のサーバーに対してリクエストを送った際に、サーバー側で発行される識別子です。


識別子って言っても全然難しくなくて、他の人とかぶってしまわないくらい長い適当な文字列です。


もう一度あなたが同じサーバーに対してリクエストを送る際に、クッキーも添えて送るんです。

サーバーはクッキーに保存されているあなたのリクエストだと判別できる文字列を見て

これは前にリクエストしてきてくれたあなたのリクエストだと判定しています。

HTTP通信でステートを持てる理由が分かったと思います。

ちなみにログアウトするとクッキーは削除されるので、ログアウト後はステートレスになります。


### セッション
Webページ(アマゾンなど)にログイン
　　　　　　　↓
　　　　　商品を選択
　　　　　　　↓
　　　　　商品を購入
　　　　　　　↓
　　　　　ログアウト

このように
***クッキーを使用してサーバーと通信する一連の流れをセッションといいます。***

# 最後に

超かみ砕いてWebの用語を説明してみました（笑）。

Webってなんかエンジニアとかしかわからない難しいものみたいに思われがちですが、

ほんとに誰でも理解できます。

というかWebってこんなにシンプルに実装されていたんだと逆に感動すると思います。

皆さんのWebへの架け橋になるような記事になることを願っています😊。
【基本情報技術者試験】BNF記法（バッカス記法）

### 学習前
過去問道場での解説があまり理解できなかった。

***
### 参考にしたYoutube動画

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

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

***
### 感想

やるかやられるかチャンネルさんわかりやすい。
コンパイル時の構文解析で利用されているらしい。
再帰的とやらが分かった
Flutterでプロジェクト生成時にそれをGitHubリポジトリ化する手順

いつも忘れるのでメモ。
既存ディレクトリをGitHubにプッシュする流れ。

# 1. Githubリポジトリを作成する

Flutterプロジェクト作成時に `README.md` も生成されるので、README.mdは無しで良い

# 2. Flutterプロジェクトを作成する

こんなのができる
```shell
% ls -l
total 64
drwxr-xr-x  19 kentaro  staff   608  5 10 20:25 ./
drwxr-xr-x  10 kentaro  staff   320  5 10 20:25 ../
drwxr-xr-x   6 kentaro  staff   192  5 10 20:25 .dart_tool/
-rw-r--r--   1 kentaro  staff   701  5 10 20:25 .gitignore
drwxr-xr-x   6 kentaro  staff   192  5 10 20:25 .idea/
-rw-r--r--   1 kentaro  staff  1668  5 10 20:25 .metadata
-rw-r--r--   1 kentaro  staff   551  5 10 20:25 README.md
-rw-r--r--   1 kentaro  staff  1453  5 10 20:25 analysis_options.yaml
drwxr-xr-x  12 kentaro  staff   384  5 10 20:25 android/
-rw-r--r--   1 kentaro  staff   842  5 10 20:25 hogehoge.iml
drwxr-xr-x   7 kentaro  staff   224  5 10 20:25 ios/
drwxr-xr-x   3 kentaro  staff    96  5 10 20:25 lib/
drwxr-xr-x   8 kentaro  staff   256  5 10 20:25 linux/
drwxr-xr-x   7 kentaro  staff   224  5 10 20:25 macos/
-rw-r--r--   1 kentaro  staff  5262  5 10 20:25 pubspec.lock
-rw-r--r--   1 kentaro  staff  3872  5 10 20:25 pubspec.yaml
drwxr-xr-x   3 kentaro  staff    96  5 10 20:25 test/
drwxr-xr-x   6 kentaro  staff   192  5 10 20:25 web/
drwxr-xr-x   6 kentaro  staff   192  5 10 20:25 windows/
```

# 3. Gitリポジトリ化してコミット

```shell
git init
git remote add origin git@github.com:ユーザ名/リポジトリ名.git
git add *
git commit -m 'first commit'
git push origin main
```

以上
RubyでAtCoder ABC263(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC263のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Full House
https://atcoder.jp/contests/abc263/tasks/abc263_a
```ruby:a-263.rb
a = gets.split.sort
puts (a[0] == a[2] && a[3] == a[4]) || (a[0] == a[1] && a[2] == a[4])  ? "Yes" : "No"
```
## 解説
ソートを使うことで、３枚の部分は真ん中のカードの探索を省略することができます。

# B - Ancestor
https://atcoder.jp/contests/abc263/tasks/abc263_b
```ruby:b-263.rb
n = gets.to_i
m = gets.split.map(&:to_i)
ans, i = 1, n - 2
while m[i] != 1
  i = m[i] - 2
  ans += 1
end
puts ans
```
## 解説
人Nから人１になるまで探索していくことで実装することができます。

# C - Monotonically Increasing
https://atcoder.jp/contests/abc263/tasks/abc263_c
```diff_ruby:c-263.rb
n, m = gets.split.map(&:to_i)
- (1..m).to_a.combination(n).each do |array|
+ (1..m).to_a.combination(n) do |array|
    puts array.join(" ")
  end
```
## 解説
N, Mともに10以下と小さいため、combinationメソッドを使った全探索により実装することができます。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
マイナンバーカードを利用した住民票の誤交付はどうして起こったのか

# 概要
2023年5月2日、マイナンバーカードを利用したコンビニの住民票発行システムで誤発行が発生した。
https://news.yahoo.co.jp/articles/548e659b98b68bce1a9bc54e6ba1433f598e66b9

偶然、AさんとBさんは同時に住民票の発行を行い、どちらもBさんの住民票が発行される事態となった。

# 注意書き
これ以降はすべて**私の妄想**です。ただし、現実世界のシステム開発で起こりそうな事象を想定します。

本記事は、同様の不具合を起こさないようにするための注意喚起であり、妄想記事であり、**マイナンバーカード及びマイナンバーカードに関連するシステムに対する批判や政治的な意図は一切ありません。**


# 想像図

コンビニのプリンタ機があって、
プリンタ機からアクセスできる住民票発行用サーバがあって
住民票の記載情報が入ってるデータベースがあるっていう図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330109/11cb68a9-ade2-3863-1f3c-fdd444036a4f.png)

# 処理の流れの想像

1. プリンタ機がマイナンバーカードを読み取って、サーバにマイナンバーカードの情報を送る
2. サーバはデータベースにアクセスして、住民票に記載する情報を記したpdfファイルを生成する
3. 生成したpdfファイルをタイムスタンプで保存する
例：2023年5月2日 19時20分34秒なら「20230509192034.pdf」を保存する
4. プリンタ機に「20230502192034.pdf」を印刷させる
同時に発行依頼があると上書きされてしまう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330109/8d95ee21-8f0b-9ba9-abf8-cac863e39af6.png)

こうして、秒単位で同時に住民票の発行をしたであろうAさんとBさんに、Bさんの住民票が発行された(かもしれない)

この不具合が今になって起きた背景として、マイナンバーカードの普及率の上昇とそれに伴う利用者の増加が考えられる。正直、こんな感じの潜んでる系のバグが一番怖いめう🥺

# 対策

PDFを生成して印刷する場合、どのようなファイル名を付ければよいだろう？

- そもそもタイムスタンプではなく、UUID(ULID)のようなユニークキーを利用する。UUIDなら一応重複チェックを入れたほうがよさそう
- ユーザIDがデータベースにあるなら、それをファイル名に含ませても良いかも
- 面倒だが、同じタイミングで印刷されたファイルが存在しないかチェックして、存在する場合にはファイル名の末尾に連番を加える
- プリンタ機の識別子みたいなのがあるような気がするので、それをファイル名に付け加えることができるかもしれない。知らんけど

他にもいい方法はあるかもしれない。何かしら対策をしていれば、このようなことは起こらなかっただろう


（ただ、記事には通信連携プログラムの不具合と書いてある…ジョブキュー処理で、同時の発行申請があった場合にタイミングをずらす処理の箇所で不具合があったのかもしれない。だとしても後勝ちになるのはちょっと……）
[AWS Q&A 365][Step Function]AWSのよくある問題の毎日5選 #53

# 1. AWS Step FunctionsのWorkflow Studioとは何ですか？
回答：Workflow Studioは、ドラッグアンドドロップのインターフェースを使用してステートマシンを設計および管理するためのAWS Step Functionsの視覚的なインターフェースです。

# 2. Workflow Studioの主な機能は何ですか？
回答：Workflow Studioは、視覚的なインターフェースを使用してステートマシンを作成、編集、および実行することができます。また、ステートブラウザ、キャンバス、およびインスペクタを提供して、ユーザーがワークフローを設計および管理するのを支援します。

# 3. Workflow Studioは動的リソースIDをサポートしていますか？
回答：いいえ、Workflow Studioは動的リソースIDをサポートしていません。

# 4. Workflow Studioはワークフローを自動的に保存できますか？
回答：いいえ、Workflow Studioはワークフローを自動的に保存しません。

# 5. Workflow Studioの既知の制限は何ですか？
回答：Workflow Studioの既知の制限の1つは、Internet Explorer 11をサポートしていないことです。
[AWS Q&A 365][Step Function]Daily Five Common Questions #53

# 1. What is Workflow Studio in AWS Step Functions? 
Answer: Workflow Studio is a visual interface in AWS Step Functions that allows users to design and manage state machines using a drag-and-drop interface. 

# 2. What are the key features of Workflow Studio? 
Answer: Workflow Studio allows users to create, edit, and run state machines using a visual interface. It also provides a state browser, canvas, and inspector to help users design and manage their workflows. 

# 3. Does Workflow Studio support dynamic resource IDs? 
Answer: No, Workflow Studio does not support dynamic resource IDs. 

# 4. Can Workflow Studio automatically save workflows? 
Answer: No, Workflow Studio does not automatically save workflows. 

# 5. What is the known limitation of Workflow Studio? 
Answer: One of the known limitations of Workflow Studio is that it does not support Internet Explorer 11.
【AxiosError:401】apiにアクセスできない

参考記事

https://qiita.com/RYA234/items/1585418b978a12d0fbdb

### 環境

Laravel9
Inertia
Vue3

# エラー

以下のエラーが出てapiにアクセスできませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/fbe990a0-ce98-b589-ebc0-af78e3c63802.png)


# 原因

パスの書き方を間違えていました。

# 修正前

```js:index.vue
onMounted(() => {
    axios.get('/api/user')
    .then( res => {
        console.log(res)
    })
})
```

# 修正後

アドレス表記を修正したら、無事に操作できるようになりました。

```js:index.vue
onMounted(() => {
    axios.get('http://127.0.0.1:8000/admin/purchases/create')
    .then( res => {
        console.log(res)
    })
})
```
zabbixのセットアップ中にserver.sql.gzが見つからないエラー

# はじめに
zabbixを公式の手順通りにセットアップしていると以下のような項目があります。
```bash:bash
zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -uzabbix -p zabbix
```
すると出力は
```bash:bash
gzip: /usr/share/doc/zabbix-sql-scripts/mysql/server.sql.gz: No such file or directory
```

????????

# 結論
dpkgの設定が悪さをしていました。
``/etc/dpkg/dpkg.cfg.d/excludes``というファイルを開き
```:excludes
path-exclude=/usr/share/doc/pollinate/copyright
path-exclude=/usr/lib/nagios/plugins/check_pollen
```
これの一番上の項目をコメントアウトして、もう一度パッケージを``apt install ...``すれば解決しました。

この項目のせいでホワイトリストに登録されてインストールから外される？ようです。
<br>  
別サーバーで同様の作業をしていたらこの``excludes``ファイルが存在せずにエラーを吐くという事態になりました
このときは``excludes``ファイルを作成し、一番上の行を書けば解決しました。謎…
2023/05/12　追記

# 参考文献

https://support.zabbix.com/browse/ZBX-20451
円ドル為替レートの推移

# はじめに

今回は、FRED（Federal Reserve Economic Data）からライブラリー（fredapi）を使って円ドル為替レートを取得し、インタラクティブなグラフを描くことにした。

# 事前準備
取得してあるAPIキーは’FRED_api_key.txt’というファイル名にしてGoogleドライブに保存してあるので、まずは、Googleドライブのマウント。

```python
# Colaboratory 上で Google Drive をマウント
from google.colab import drive
drive.mount('/content/drive')
```

Google Colabにfredapiはインストールされていないのでインストール。
```python
! pip install fredapi
```

# コード
FREDにおける円ドル為替レートの系列IDがDEXJPUSであることを確認して、以下のコードを実行して描画。

```python
import pandas as pd
import plotly.graph_objects as go
from fredapi import Fred

# APIキーファイルのパス
api_key_file_path = '/content/drive/MyDrive/FRED_api_key.txt'

# APIキーを読み込む
with open(api_key_file_path, 'r') as file:
    api_key = file.read().strip()

# FREDオブジェクトを作成
fred = Fred(api_key=api_key)

# FREDから為替レートのデータをダウンロード
data = fred.get_series('DEXJPUS')

# データをPandasデータフレームに変換
df = pd.DataFrame(data, columns=['Rate'])

# インデックスを日付に変換
df.index = pd.to_datetime(df.index)

# 1990年代、2010年代、2020年代の最小値および最大値を見つける
min_1990s = df['1990':'1999']['Rate'].idxmin()
min_rate_1990s = df.loc[min_1990s, 'Rate']

min_2010s = df['2010':'2019']['Rate'].idxmin()
min_rate_2010s = df.loc[min_2010s, 'Rate']

max_2020s = df['2020':'2029']['Rate'].idxmax()
max_rate_2020s  = df.loc[max_2020s, 'Rate']

# グラフを作成
fig = go.Figure()

fig.add_trace(go.Scatter(x=df.index, y=df['Rate'], mode='lines', name='JPY/USD Rate'))

# ホバーテキストを設定
hovertext_min_1990s = f"Date: {min_1990s.strftime('%Y-%m-%d')}<br>Rate: {min_rate_1990s}"
hovertext_min_2010s = f"Date: {min_2010s.strftime('%Y-%m-%d')}<br>Rate: {min_rate_2010s}"
hovertext_max_2020s = f"Date: {max_2020s.strftime('%Y-%m-%d')}<br>Rate: {max_rate_2020s}"

fig.add_trace(go.Scatter(x=[min_1990s, min_2010s], y=[min_rate_1990s, min_rate_2010s], mode='markers', marker=dict(color='red', size=10), name='Min Rate', text=[hovertext_min_1990s, hovertext_min_2010s], hoverinfo='text'))
fig.add_trace(go.Scatter(x=[max_2020s ], y=[max_rate_2020s ], mode='markers', marker=dict(color='red', size=10), name='Max Rate', text=[hovertext_max_2020s], hoverinfo='text'))

fig.update_layout(
    title='JPY/USD Spot Exchange Rate(1971/1/4-)',
    xaxis_title='Date',
    yaxis_title='Japanese Yen to One U.S. Dollar',
    hovermode='x',
    showlegend=False
)

fig.show()

```

# おわりに
出力結果をここにアップすることができないが、昨年（2022年）の円安局面で1ドル=150円を突破した（みずほ銀行から公表されているデータhttps://www.mizuhobank.co.jp/market/csv/quote.csv では、10月21日に1ドル=150.26円）はずだったが、このグラフでは突破してないことが分かった（10月20日の1ドル=149.82円がこの時期の最円安）。
コードがおかしいのかと疑ったが、そこは問題なさそう。為替レートなのでどういうレートかもキチンと見る必要はあるが、東京市場とニューヨーク市場の違いなのだろう。
これには、可視化の効果はやはり大きいと気づかされたところ。次は、みずほ銀行のデータか日銀のデータを使って、試してみたい。