OmniAICreator/Qiita-1.07M huggingface dataset:
DockerでつまづくLaravel Dusk何なのお前

# はじめに

色々事情があってブラウザテストすることになったんですよ。
そう言えばLaravelには「Dusk」っていうイカしたブラウザテストユニットがあったなとか思い出して、試しに使ってみました。
https://readouble.com/laravel/5.5/ja/dusk.html

↑のドキュメント通り、duskをインストールし、動かしてみたら

```
# php artisan dusk
Cannot load Xdebug - it was already loaded
Cannot load Xdebug - it was already loaded
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.

E                                                                   1 / 1 (100%)

Time: 1.29 seconds, Memory: 16.00MB

There was 1 error:


1) Tests\Browser\ExampleTest::testBasicExample
Facebook\WebDriver\Exception\UnknownServerException: unknown error: cannot find Chrome binary
  (Driver info: chromedriver=2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881),platform=Linux 4.19.76-linuxkit x86_64)

```

は？　chromeのバイナリがないだと？

# いい忘れてたけど、環境

|OS/ミドルウェア/FW|バージョン|
|---|---|
|CentOS|7.5|
|Apache|2.4.6|
|php|7.2.28|
|Laravel|5.5.46|

これをDockerで組んでます。

# chromeを入れてみる

んじゃ、素直に入れてみますかね。
CentOSはepel入れるとchromiumを入れることができるようになります。

```bash
$ yum install -y epel-release
$ yum install -y chromium 
```

よしよし、うごかしてみっかー。んー、なかなか応答が返ってこないなー、、、お、今度は `/session` がダメとか言ってくるなー。

```
1) Tests\Browser\AdminTest::testTop
Facebook\WebDriver\Exception\WebDriverCurlException: Curl error thrown for http POST to /session with params: {"desiredCapabilities":{"browserName":"chrome","platform":"ANY","chromeOptions":{"binary":"","args":["--disable-gpu","--headless"]}}}
```

# --no-sandbox を入れてみる

なんか調べども調べども `seleniumコンテナ入れろ` みたいなのばっかなんですよね。なんか負けたような気がするじゃないですか。気の所為でしょうけど。

んで、たどり着いたのはこちら。
[Laravel DuskをDockerコンテナ内で起動するまで](https://qiita.com/acro5piano/items/50aeb01e06f398bc0296)

なんと、 `--no-sandbox` フラグを付けるだけだと……！？

`DuskTestCase.php`に追記しましょ。

```php:DuskTestCase.php
    protected function driver()
    {
        $options = (new ChromeOptions)->addArguments([
            '--disable-gpu',
            '--headless',
            '--no-sandbox', //追記
        ]);

        return RemoteWebDriver::create(
            'http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
                ChromeOptions::CAPABILITY, $options
            )
        );
    }
```

よし、これで動いた！
props,emit備忘録

簡単なpropsはなんとなく分かっていましたが、親コンポーネント側の配列を子コンポーネント内でfor文で回した時の挙動が難しかったので、
[【Vue.js】子から親コンポーネントのデータを更新する方法｜たのしいWeb開発](https://dev83.com/vue-emit/)
を参考にさせていただき、少しまとめてみました。

<img width="1274" alt="93495604a3e649eb038e9a5ffbc255f3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/082fb9a3-e008-7d91-65e1-57f2fe8f3699.png">


1.親コンポーネント側で、配列fluitsを宣言。中には、2つのオブジェクトが入っている。

2.親コンポーネント側で子コンポーネントを表示した際に、for文で回して親コンポーネントの配列fluitsの中身を１つ１つ表示させている。
fluitの中のオブジェクトの要素数に応じて、表示する数は変動する。今回の表示は下記のようになる。

```

{{fluit.name}}={{subtotalCount}}
<button @click = "increment()">増やす</button>
<button @click = "reduce()">減らす</button>

{{fluit.name}}={{subtotalCount}}
<button @click = "increment()">増やす</button>
<button @click = "reduce()">減らす</button>
```

3.for文で親コンポーネントのオブジェクトを子コンポーネントに渡すときは、v-bind:【propsで渡す変数名】="配列データのキー"

4.子コンポーネント側で、clicked-increment-button,clicked-reduce-buttonが発火されたら、親コンポーネント側のincrementTotalCount,decrementTotalCount
  を呼び出す、ということ。
  この流れをemitと言い、子コンポーネントから親コンポーネントに値を渡すときに使用される。
  子コンポーネント側でsubtotalCountが増減するのに合わせて、親コンポーネント側のtotalCountも増減する。
JavaScriptで指定した文字全てを置換する方法


個人用にメモ
置換メソッドreplaceについて記述してみる

使い方はこんな感じらしい

```
[配列名].replace(/`変換対象の文字`/,` 変換後の文字`)
```



配列に入ってる`,`だけ取り除いてみる。

```
//配列生成
const str = "apple,banana,orange";
//　「,」を全て取り除く
const replaced = str.replace(/,/g, ' ')

//出力結果
console.log(replaced) 
apple banana orange

```

オンライン実行環境
https://paiza.io/projects/WIGdDzgEKj0Ctwf470BSBw
C言語で小数点以下のみを取得する方法

たまにド忘れするので備忘録。

## 方法1
小数から整数部分のみを引く。

#### float型をint型へキャスト変換

```c

#include <stdio.h>

int main(void){
    float num;
    float a;

    num = 1.5;
    // int型のキャスト変換で整数化
    a = num - (int)num;
    printf("%f",a);
}
```
実行結果

```
0.500000
```

### floor関数を用いる
```c

#include <stdio.h>

int main(void){
    float num;
    float a;

    num = 1.5;
    
    // floor関数の性質上、負の場合は分ける
    if(num >= 0){
        a = num - floor(num);
    } else {
        a = -num - floor(-num);
    }
    printf("%f",a);
}
```
実行結果

```
0.500000
```

### floor関数を用いる（fabs関数利用）
```c

#include <stdio.h>

int main(void){
    float num;
    float a;

    num = 1.5;
    
    // 浮動小数点の絶対値fabs関数を利用
    a = fabs(num) - floor(fabs(num));
    printf("%f",a);
}
```
実行結果

```
0.500000
```


## 方法2
### `math.h`のmodff関数を使う。

> float modff(float value, float *iptr);
> >modff関数は、valueを整数部と小数部に分ける。整数部及び小数部の符号は、xと同じとなる。iptrが指すオブジェクトに整数部を格納する。

```c

#include <stdio.h>
#include <math.h>

int main(void){
    float num;
    float a, b;

    num = 1.5;
    // aにnumの小数部、bにnum整数部が代入される
    a = modff(num,&b); 
    
    printf("%f %f",a,b);
}
```
実行結果

```
0.500000 1.000000
```

## 参考
https://masutaka.net/chalow/2004-12-10-1.html
http://www.c-lang.org/detail/function/modff.html
docker 削除系

# dockerのイメージ、コンテナ、ボリューム、ネットワークを全て消す
```
docker-compose down --rmi all --volumes
```
### --rmiオプション
削除するイメージの種類を指定
allはすべてのイメージ
省略すると、イメージは消されない

### --volumesオプション
docker-compose.ymlのvolumesの名前付きボリュームとコンテナにアタッチされたanonymous volumeが削除
VBAでフォルダにあるファイルの一覧を取得する

# やりたいこと
指定したフォルダにあるすべてのファイルの名称を取得して、リストで表示します。
フォルダのパスは、ダイアログボックスのポップアップ画面でフォルダを選択することで取得します。

VBAの基本的な操作については、以下の記事を参考にしてください。
[VBAでHello Worldを表示する](https://qiita.com/harufuji/items/2113fbcdaa4f6cdc1e42
)

# 前提条件
- フォルダの中にフォルダが入っている場合は、フォルダ名やフォルダの中身のファイル名は取得しません。
- フォルダにあるすべてのファイル形式のファイルの名称を取得します。.xlsxだけではなく、.jpgなども取得します。

# ソースコード

```vb
Sub GetFileName()

'FolderPath変数を宣言する
Dim FolderPath As String

'フォルダ選択のダイアログボックスのポップアップ画面を表示する
'選択したフォルダのパスを取得、変数FolderPathに代入する
If (Application.FileDialog(msoFileDialogFolderPicker).Show = True) Then
 FolderPath = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1)
End If

'カウントアップ用の変数FileCountを宣言し、1を代入する
Dim FileCount As Long
FileCount = 1

'ファイル名を格納する変数FileNameを宣言する
'Dir関数を使って、FolderPathに入っているファイル名を取得し、FileNameList変数に格納する
'Dir関数は引数に指定したファイルが存在したとき、そのファイル名を返す関数
Dim FileName As String
FileName = Dir(FolderPath)

'Do loopは、条件式を判定し、真の間だけステートメント（命令文）を繰り返し実行するステートメント
'FileNameが""（ブランク）になるまで実行し続ける
Do While FileName <> ""
 Worksheets("Sheet1").Cells(FileCount, 1).Value = FileName 'FileNameListを書き込むセルの位置を指定
 FileCount = FileCount + 1
 FileName = Dir() 'Dir関数は引数を省略すると前回の引数を引き継ぐ。Dir関数は一度戻り値として返したファイルは除外する。
Loop

End Sub

```
Linux環境でファイルから特定文言を抽出していきたい時

Linux環境でファイルから特定文言を抽出していくコマンドサンプル（巨大ファイルゆえエディタから開けないときとか）

```
sed -n       1,1000000p /usr/log/bigLog.log | grep TARGETSTR >> /home/test1.txt
sed -n 1000001,2000000p /usr/log/bigLog.log | grep TARGETSTR >> /home/test1.txt
sed -n 2000001,3000000p /usr/log/bigLog.log | grep TARGETSTR >> /home/test1.txt
```
UltraVNC環境でマウスカーソルを普通に表示したい

ショートカットに引数をセットしておくことでVNC画面でもノーマルカーソルにできる

`"C:\Program Files\uvnc bvba\UltraVNC\vncviewer.exe" -normalcursor`

ただ、これだけだと、マウスが変化してくれないので、
サーバー側でマウスキー機能（簡単操作）を有効にしておく
VSCodeの中、Vagrant に SSH-FS 接続よりいい方法があるかな？🤔

## SSH-FSの開発ユースケース、だるさポイント

毎朝こうになっちゃうね。

1. Vagrantを立って
2. VSCodeを起動
3. VSCodeで新しいターミナルを開いて、Vagrantのボックスファイルがあるところで、　`vagrant up`、 `vagrant ssh`を入れます。
4. また新しいターミナルは必要になったら、　また最初に`vagrant ssh`でターミナルを接続しなきゃ・・・
5. `git grep`したら、開きたいなら左にあるファイルエクスプローラーで手作業で正しいファイルを開いて、時間がかかる
6. ターミナルで　`vagrant reload` したら、SSH-FSに手作業でまた接続しなきゃいけない。
7. Git 管理はめちゃくちゃー

「だるくねえ？」と思ってるお友達に、Remote-SSHを使いましょう！！！

## Remote-SSHというエクステンションを使いましょう！！

👍ポイント：

* `git grep`でファイルリンクはリンク化。　`control-click`したら、ファイルをすぐに開けます！
* ターミナル開いたら、直接Vagrantの環境でターミナルを開きます！
* `vagrant reload`したら、VSCodeは文句が言って、いつでもVagrantの状態が分かります！
* VSCodeのGit管理ツールも使えます！！

👎ポイント：

* SSH-FSよりちょっとラムを食います。

## インストール手順  

* VagrantファイルでVagrant環境に専用RAMメモリーを上がりましょう。

```Ruby:Vagrantfile

Vagrant.configure("2") do |config|
  # ...
  # なんちゃらなんちゃら設定で、デフォルトでコメントアウトところでこのものもあります。コメントインしてね。
  config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    # vb.gui = true   (そのままコメントアウト、いらない)
  
    # Customize the amount of memory on the VM:
    vb.memory = "4096" # とりあえず2GB(2048)ぐらいは十分ですが、俺は石器時代のパソコンではないから、4ギガにします。
  end
  
  # なんちゃらなんちゃら他の設定
  # ...
end
```

* Vagrantfileの変更が終わったら、`vagrant up` か　`vagrant reload`してください。
* 歯車のアイコンを押して、エクステンションで　`Remote-SSH`をインストールしてください。
* コマンド　パレット（WindowsならF1）で　`Remote-SSH: Connect to Host`を選んでね。
* デフォルト設定なら、`vagrant@localhost:2222`に接続してください。
* 次の画面で、パスワード入れてください。　デフォルトは　`vagrant`
* 最後に、VSCodeファイルエクスプローラーでデフォルトのフォルダーを選んでください。これは`/home/vagrant/`で良さそうが、自分の環境によって設定してください。
* 次回パソコンのターミナルで`vagrant up`して、VSCodeの中で、最近開いたフォルダーを選んだら、パスワード入れた後でもうVagrantの選んだフォルダーから始まれます。

以上です！

これで`cd`で自分のプロジェクトフォルダーを開いて、git grepをやってみてください。全てのファイルリンクはもう、リンク化になってるでしょう。　ターミナル開いたら、もう直接Vagrantのターミナルを開ける！　これで開発は楽勝はずです！！

やってみましょう！
iOS,Android input type="date" JavaScriptイベント取得まとめ

##はじめに
Javascriptでinput="date"のイベント取得をiOS,Androidで調べたのでまとめ

##検証環境
iOS 13.3
ブラウザ　Safari

Android 8.0.0
ブラウザ　Chrome

##iOS
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113074/ade12b54-4713-7643-6574-d5c817bb9dcf.png">

|  操作  |  イベント  |
| ---- | ---- |
|  フォーカス  |  onchange  |
|  日付切り替え  |  onchange  |
|  消去  |  onchange  |
|  完了  |  onblur  |

完了を押下するとフォーカスが外れるため'onblur'が発火するっぽい

##Android
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113074/c9b234dc-5c81-b981-3102-76642d0fa42f.png">

|  操作  |  イベント  |
| ---- | ---- |
|  フォーカス  |  -  |
|  日付切り替え  |  -  |
|  削除  |  onchange (日付が入力済みの場合) |
|  キャンセル  | - |
|  設定  |  onchange  |


## 比較
| | ios | Android | 
| ---- | ---- |---- |
| フォーカス | onchange | - | 
| 日付切り替え | onchange | - |
| 消去・削除 | onchange | onchange |
| キャンセル | - | - |
| 完了・設定 | onblur | onchange |



## sample
alertだとダイアログを消した際に、blurが発生し続ける見たいだったので、HTML出力

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="shotaabe" data-slug-hash="YzzRLmq" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="sample date">
  <span>See the Pen <a href="https://codepen.io/shotaabe/pen/YzzRLmq">
  sample date</a> by shotaabe (<a href="https://codepen.io/shotaabe">@shotaabe</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Mac Terminalのコマンドチートシート ( 備忘録 )

Mac初心者なんで個人的な備忘録でここにチマチマ書いておく、他の人の参考には多分ならない


## ファイルの削除
``` rm -rf ファイル名 ```
削除対象がフォルダの場合は警告されるので引数 -r を付け足す
対象ディレクトリの中に読み込み専用ファイルがあると警告が出るので -rf 引数を付け足すと強制削除になる


## Macに接続したAndroid端末のストレージ容量の調べ方
```adb shell``` 
で端末に入った状態で

``` df -h ```
コマンドを事項することで端末のディスク情報を見ることができる
操作が終わったら

``` exit ```
コマンドでshellから出る

## ダミーファイルの作り方
需要は微妙だが容量チェックとかで偶に必要になったりする
``` mkfile 1g dummy.txt ```
コマンドで 1GB の dummy.text ファイルが生成される
WinBUGSによるMCMC資料を、R（rJAGS, rstan)で自習するときに注意すべきメモ

MCMCすることが多いですよね？ 参考書や記事には、歴史があるWinBUGSの資料を見かけることも多いハズ。
それをJAGSやSTANで試してみたりすることが多々あると思います。

その時、推定がうまくいかない・・・など問題に直面すると、①モデルの書き方が悪いのか？ ②コマンドの与え方が悪いのか？など迷うときが（私は）多々ありました。
それ以外にも③「データ表記法」がBUGS言語とR、Python等で異なることがあります。

これについて調べた結果のメモです。

## 結論

http://www.openbugs.net/Manuals/ModelSpecification.html#ArraysAndIndexing
に記載がある「Arrays and indexing」を理解すればOKでした。

```
OpenBUGS reads data into an array by filling the right-most index first, 
whereas the R/S-Plus program fills the left-most index first. 
```

### 二次元の場合

1. 参考書のデータを教科書のまま入力
2. matrixにしてdputするなどして.Dim=c(3,2)ならc(2,3)する
3. t()で転置行列にする。

ダメダメなケースは、１，３で転置だけすケース。インデックスが崩れるから、データが教科書と異なることになる。すなわち、①、②が正しくとも絶対に整合しない。

### 三次元の場合

```
 .Dim=c(4,2,3) to .Dim=c(3,2,4)
```

## なぜ気がついたか？

Agresiti先生の多名義尺度のロジスティック回帰( Modeling for multinomial Resonse）のワニの食餌データ。

"Alligators: multinomial - logistic"として古くから有名なモデル？らしいが、大先生Agresiti本の例題とはデータが異なる。

WinBUGSの「サンプルコードをコピペしたらなんとかなる」的なノリで試すと結果が異なるり、大怪我。
JAGS実装の例題があるので確認すると、結果はWinBUGSと整合している。

モデルは共通だから、データ配列の順序を疑う。よく見ると違っていた。
（モデルやキックするコードばかり見ていてデータを見ていなかった）

### 感想

JAGSやSTANを使いこなすには、「単にソフトウエアを使えるだけではなく、行列でモデルを表現できる」ことが必須と最近感じております。勉強せねば。

以上、2020年の在宅業務中にφ(..)メモメモ
[Kotlin] Map の withDefault

KotlinのMapにwithDefaultというメソッドが生えているらしい。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">On a map, use &#39;withDefault&#39; to get a wrapper that obtains a default value when using &#39;getValue&#39; on a key that is not present. Note that this does not change the behavior of the indexed access operator x[idx] / x.get(idx)! <a href="https://t.co/kldivSn4mI">https://t.co/kldivSn4mI</a> <a href="https://twitter.com/hashtag/KotlinTips?src=hash&amp;ref_src=twsrc%5Etfw">#KotlinTips</a> <a href="https://t.co/VM20ZtrWbi">pic.twitter.com/VM20ZtrWbi</a></p>&mdash; Kotlin (@kotlin) <a href="https://twitter.com/kotlin/status/1267750314024808450?ref_src=twsrc%5Etfw">June 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

試してみた。

```kotlin
val fruits = mapOf(
    "イチゴ" to "🍓",
    "バナナ" to "🍌",
    "ミカン" to "🍊"
).withDefault {
    "❓"
}

val s = fruits.getValue("イチゴ") // 🍓
val p = fruits.getValue("パイナップル") // ❓
val r = fruits["ラズベリー"] // null
```

ツイートの通りの結果になった。

デフォルト値を返したとしても、それが元の `Map` に詰められるわけではない。デフォルト値は毎回生成される。

```kotlin
fruits.getValue("マンゴー")
fruits.getValue("ブドウ")
val keys = fruits.keys // [イチゴ, バナナ, ミカン]
```

別の `Map` を作ったらもちろん `withDefault` の効果は消える。

```kotlin
val fruits2 = fruits + mapOf("モモ" to "🍑")
val p2 = fruits2.getValue("パイナップル") // NoSuchElementException
```



## 感想

`getValue` はデフォルト値を返すが、 `get` は `null` を返す、というのはどういうところが嬉しいんだろうか？ :thinking: 
`getValue` を使うつもりでうっかり `get` を使っていた、ということが起こりそう…。使いどころがよくわからない。
【Git】新しいブランチを作成する。

メモとして残します。


#■やり方
###0.作成前にカレントブランチを確認
```shell
git branch --contains=HEAD
```
注）分岐させたい場所にいなかったら、ブランチまたはコミットレベルで移動する。

###1.ローカルにブランチ作成
```shell
git branch <作成するブランチ名>
```

###2.リモートに作成したブランチを反映
```shell
git push -u origin <作成したブランチ名>
```
【第0回】話し相手を作りたい！　〜AgentCraftを使ってみる〜

#誰でも作れる!？自動音声対話アプリ

はじめまして、
カフェジローと申します。
コーヒーが好きなエンジニアでございます。

突然ですが、喫茶店を開くのが私の夢です。
・こたわりの生豆からのこだわりの手網焙煎
・抽出方法にあったメッシュの大きさで豆を挽く
・ペーパードリップで抽出し、お客様に提供する
・お客さんとゆっくり世間話や、コーヒーの話したりして楽しんでくつろいでいただく
・お勘定をする
![DSC_3388.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/1557c827-24be-204f-f5bc-0d38a0a71c02.jpeg)

以上の対応を全て手作業で真心を込めてご提供したいと思っておりました。
しかしながら現実的には、手作業にこだわると、時間的に、経営的に
難しいことを突きつけられます。
・焙煎からドリップまでの作業と会計は機械でできるということ
・ある程度機械化しないと作業工数的に赤字に陥ると言うこと
・手作業による価格上昇についてお客様がその価値に納得するか疑問がある

ましてや、自分自身体調が悪くなったりしたら、店を閉じなければいけない。
コロナの感染拡大も重なったりして不安も増えてしまった・・・・。

どうしたらお客様にコーヒーを
**・店内で
・安全に
・安く
・おいしく
・楽しんで
・くつろいで**
いただけるのであろうか・・・。

現実を見つめ、コストを突き詰めた結果、カフェのマスター自身も機械化したいという謎の発想にまで至りました。 
私の代わりになる対話可能なロボットは作れないだろうか。

そこでふと閃いた！
![DSC_3391.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/8078b3f6-781c-681e-8f2e-35cdac80fc9c.jpeg)

**喫茶店のマスターを機械化(対話AI化)したら
お客様の入店から退店まで、喫茶店の雰囲気を保ちつつ無人化できるのではないか！！**

と考えました。

例えばマスターを**対話可能なAIロボットに**すれば、
**本人が不在**でも対応できそう。
対話例　お客様「今日のブレンドの豆は何を使っているのですか？」
　　　　　↓
　　　　マスターAI「コロンビアスプレモとグアテマラを使ってますよ」

など。
こうしてしまえば**24時間営業**も可能かもしれない。
マスター本人がいるときは、オフラインイベントとしてもいけそうかもしれない。
(マスターを謎の人物化することで話題性を作れそう)
マスター不在時のお客さんとの会話ログを見れば、
**お客さんとの会話をシームレスに引き継ぎも可能になるはず！！**
AIが成長すれば私の会話パターンのコピーができることも夢ではない！！
コロナでも、３密を防ぎながら営業ができるかも。

と言うことで、喫茶店のマスターばりに対話ができるAIを作ってみたくなりました。

素人でも対話AIを作成するのは可能なのか・・・。

ネットを探って見た所、以下に紹介するサイトにたどり着きました。
対話AI作るための**対話エージェント作成ツール**です。


最近AIが発達してきて、人間じゃなく、機械ともおしゃべりできる様になってきましたね。
おしゃべりできるアプリを作成できるらしいので、
実際に喫茶店のマスターばりにお話し相手を作れるかどうか、
本記事で連載(全10回の予定)していきます。

さて、早速**ツール**ですが、↓(以下をクリック)
[AgentCraft™(エージェントクラフト)](https://agentcraft.sebastien.ai/)
です。
以下のが画像が出てくると思います。
<img width="1426" alt="Agentcraft登録.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/ad4715a1-d850-edf5-d94f-9f50998e47cc.png">
![無料で試せる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/4e787e87-cbd2-ec47-0129-a68d5d7e7d35.png)
サービス概要を見ると**無料**で試すことができるそうです。
**※商用目的でなく、試験環境環境として使う分には、申し込み不要でアカウントを登録/ログインするだけで使えるそうです。**
![無料で試せる2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/beff2e6a-56cf-546d-c4f1-0a1f20bd32b3.png)

まず、とにかく、触ってみましょう。
**ログイン**の方法は、
**・Googleアカウント**
**・dアカウント**
の２種類があるみたいです。
とりあえず、Googleアカウントを持っているので
こちらで**ログイン/登録ボタン**を**クリック**してみましょう。

<img width="595" alt="アカウント選択.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/d1d828e9-ee21-0cc9-56cc-637dc3763bf5.jpeg">

**アカウントの選択**画面が出てきたら、
登録したい**アカウント**を**クリック**してみましょう。
![利用規約同意.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/05b4ee49-2993-5c60-d8e0-e2f08dcb44c2.png)
**規約に同意する**を**クリック**し、**チェック**を入れて、
**同意する**をクリックします。

![AgentCraft初期画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/de3ca397-43af-c18c-6227-b3d4176d09d6.png)
↑のように、AgentCraftの編集画面が出てきます。
![AgentCraft発声.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640326/29a10dc4-e770-5a22-a615-d65944ede167.png)

声の近くのスピーカボタンを押してみましょう。
女性の声で**「こんにちは」**と発話してくれました！！

さて、一応ここまでで、対話の準備が整いました。
次回第一回は実際に、カフェジローにふさわしい声選びと、
対話を編集画面から設定していきたいと思います。
whereメソッドの統一感がない残念なお知らせ

numpyとpandasの`where`の挙動が反するように感じたので、共有します。

条件に応じて値を代入するメソッドに`where`と`mask`があります。
メソッドの詳細は[こちら](https://note.nkmk.me/python-pandas-where-mask/)にございます。
（いつもお世話になっております:pray:）
 

以下に適当な例を出してみます。

```py
import numpy as np
import pandas as py

test = np.array([1,2,3])
```

この`2`を`200`に置換したいとします。

`np.where`でやってみましょう。

```py
>>> pd.Series(np.where(test == 2, 200, test))
0      1
1    200
2      3
dtype: int64
```
目的の結果が得られます。

では、`pd.where`では？

```py
>>> pd.Series(test).where(test == 2, 200)
0    200
1      2
2    200
dtype: int64
```
残念です。目的とは逆の結果になりました…

`np.where`の代わりには`pd.mask`を使いましょう。

```py
>>> pd.Series(np.where(test == 2, 200, test))
0      1
1    200
2      3
dtype: int64
```

`np.where`との挙動を合わせてほしいですね…
vscodeの設定・ショートカットで悩んだ話

- [snippet](https://qiita.com/teradonburi/items/c4cbd7dd5b4810e1a3a9)

emacs使いが，vscodeの設定・ショートカットで悩んだ個人のメモです．
# ショートカット
## emacs
emacsのkeymapを入れると変なところでおかしくなります．

例えば，ctrl-c,vでcopy and pasteができなくなったり，
ctrl-aが消えたり．．．

## windowの切り替え
- ctrl-0
- ctrl-2 で2分割
- ctrl-1 でexplorerへ
- ctrl-b でexplorerの表示のon-off
- ctrl-w でclose the window

## editorとterminalの切り替え
### keybindings.json
消えた．今は，File->Preferences->KeyboardShortcutsを選んで，右上の斑点のようなボタンを押すとkeybindings.jsonがeditorで立ち上がります．そこへ加えていきます．

```json:keybindings.json
[
  {
    "key": "ctrl+;",    "command": "workbench.action.terminal.focus",
                           "when": "editorTextFocus"
  },
  {
    "key": "ctrl+;",    "command": "workbench.action.focusFirstEditorGroup",
                           "when": "terminalFocus"
  }
]
```
- [統合ターミナルウィンドウへフォーカスするショートカットキーを設定する](https://qiita.com/rai_suta/items/05e69f0b9065989b19c1)
- "ctrl+`"ではうまくいきませんでした．

# indent region
領域を選択してtabでできます．
逆はshift-tab

# terminalの切り替え
始めるdirectoryごとに設定が違うみたい．
- wslのrubyで始めるとfishが，
- Desktopのpythonで始めるとpowershellが立ち上がります．

ありがたいことです．でも．．．

# fishのフォントを直してみると．．．
【Laravel】Homestead環境のファイルアップロード上限サイズを変更する

# 環境
- Laravel Homestead 9.5.1
- nginx 1.15.8
- PHP 7.4.5

# Nginxが返す413エラーを解消する

```bash

sudo vi /etc/nginx/nginx.conf
```

追記

```conf:/etc/nginx/nginx.conf

...
http {
...
        ##
        # Other Configs
        ##
        client_max_body_size 200m;
}
...
```

適用

```bash

sudo service nginx restart
```

# Laravelが返す413エラーを解消する
Nginxの設定変更するとWhoopsって言われるようになるので、今度はPHPの設定を変更する

<font color="Red">※/etc/php/7.4/cli/php.iniは編集しても意味ないので注意</font>

```bash

sudo vi /etc/php/7.4/fpm/php.ini
```

変更

```conf:/etc/php/7.4/fpm/php.ini(編集前)

...
post_max_size = 100M
...
upload_max_filesize = 100M
...
```

↓

```conf:/etc/php/7.4/fpm/php.ini(編集後)

...
post_max_size = 200M
...
upload_max_filesize = 200M
...
```

適用

```bash

sudo service php7.4-fpm restart
```
学んだイディオム

###||=を使った自己代入
x ||= Aのコードを見たら、「変数Xがnilまたはfalseなら、AをXに代入」と解釈する

```ruby:
number = nil
number ||= 10
number #=> 10

number = 20
number ||= 10
number #=> 20
```
n += 1 がn=n+1と展開できるのと同じ要領で

```ruby:
number ||= 10
number = number || 10
#同じ意味になる。
```
###!!を使った真偽値の型変換
！は否定の演算子
例
　!Aと書いた場合
　Aが真  -> false
　false または　nil -> true

```
!true    #=> false
!!true   #=> true

!!7      #=> true
!!false  #=> false
!!nil    #=> false
```

使用例

```ruby:
def title_exists?
  #データベースなどからタイトルを探す（なければnil）
  title = find_title
  if title
    true
  else
    false
  end
end
```

```ruby:
def title_exists?
  !!find_title
end
```
参考文献
プロを目指す人のためのRuby入門
SchnorrのIdentificationプロトコル

### 使う記号

|記号|説明|
|---|---|
|$q$|$2^{140}\,$以上の素数|
|$p$|$p-1$が素因数$\,q\,$を含む、$2^{512}\,$以上の整数|
|$\alpha$|$a \neq 1\,$で、$\alpha^{q} \equiv 1 \bmod{p}$を満たす整数|
|$h$|ハッシュ関数 $\,\mathbb{Z}_{q} \times \mathbb{Z} \to \lbrace 0,..,2^{t-1} \rbrace$|
|$I$|名前、住所、ID番号等を含んだID文字列|
|$s$|秘密鍵 $\,\lbrace1,2,...,q\rbrace\,$|
|$v$|公開鍵 $\,\alpha^{-s}\bmod{p}\,$|

### ユーザーの登録
各ユーザーが、自分の$(I,v)$に、自分の秘密鍵で署名したものを登録。

### Identification
$A\,$が自分のIdentityを、検証者$\,B\,$に証明する
1. $A\,$が$\,B\,$に、$(I,v)$を送って、$\,B\,$は、登録されている署名に対して$v$が正しいことを確認。
2. $A\,$が、$r \in \lbrace 1,..,q-1\rbrace\,$をランダムに選んで、$x=\alpha^{r} \bmod{p}$を計算して$\,B$に送る。
3. $B\,$が、$e \in \lbrace 0,..,2^{t-1}\rbrace\,$をランダムに選んで、$A\,$に送る。
4. $A\,$が、$y = r + se \bmod{q}\,$を計算して$\,B\,$に送る。
5. $B\,$は、$x\,$が、$\alpha^y v^e=\alpha^r\alpha^{se}=\alpha^r(\alpha^s)^e=\alpha^y v^e,$と一致するかどうかを確認する。(※pdfでは公開鍵は$\,\alpha^{-s}\bmod{p}\,$となっているが、ここは$\,\alpha^{s}\bmod{p}\,$の前提で)

### 参考文献
https://link.springer.com/content/pdf/10.1007%2F0-387-34805-0_22.pdf
【Day77】積み上げ日記

##学習内容
■例外処理
■イベントドリブンモデル

##学習ポイント
■エラー処理の方法
・try-catch-finally
■イベントの種類
・onChange
■エラーの種類（別記事にて）

##参考文献
■フォーカスについて
https://hakuhin.jp/js/focus.html

■エラー内容
https://developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps/What_went_wrong

■エラーリファレンス
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Errors
wordpressの立ち上げ

##概要
wordpressのプロジェクトをクローンして立ち上げるまでの備忘録

##やり方
①データベースを作成する
②wordpressのプロジェクトのリポジトリをgithubからクローンする
③このURLからhttps://ja.wordpress.org/download/  wordpressインストールする
④クローンしたディレクトリをwordpressのテーマの配下に移動させる
⑤データベースの情報を登録する

##１. データベースを作成する
localにデータベースを作成する
https://qiita.com/ibarakishiminn/items/ddfc8018b69246cbcbb8

##2. wordpressのプロジェクトのリポジトリをgithubからクローンする
プロジェクトをwordpressのテーマとして設定することで、開発していきたいので、まずはgithubからクローンする。
クローンしたら、そのディレクトリを、後ほどインストールしたwordpressのテーマに持っていく。
作業後wordpressで外観を確認してOKなら、gitで上書きして管理するイメージ。

##3. wordpressのインストール
以下のURLからインストール。wordpressは更新が頻繁に行われるので、プロジェクトごとにインストールし直す必要がある。
https://ja.wordpress.org/download/ 

##4. クローンしたディレクトリをwordpressのテーマの配下に移動させる
wordpressのテーマの配下にディレクトリを移動させることで、wordpressでテーマとして選ぶことができるようになる
配置先は/wordpress/wp-content/themes/の下

<img width="817" alt="スクリーンショット 2020-06-03 9.35.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/1a9cab55-1790-3aa4-09fd-7e29effdf42e.png">



##5. wordpressにデータベース情報を登録していく
ターミナルでインストールしたwordpressのディレクトリに移動する。
ここで以下のコマンドを走らせる。

```terminal
php -S 0.0.0.0:80
```

起動したらリンクが表示されるのでそれを踏んで以下のような画面に移る。`さぁ、始めましょう！`をクリック

![スクリーンショット 2020-06-02 15.52.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/a7676c80-d200-b2c5-14a2-942a23cad84e.png)


ローカルで作成したデータベースの情報を登録していく。
データベース名・ユーザー名・パスワード・データベースのホスト名を入力する
テーブル接頭辞はデフォルトでOK
`送信`をクリック

![スクリーンショット 2020-06-02 16.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/381c94c3-0941-d440-f2f8-16390b4487a1.png)

データベースの情報が間違っていると以下のようなエラーが返ってくる。

![スクリーンショット 2020-06-02 16.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/cfe485de-f910-4756-bed7-a196f358dad1.png)

データベースの登録が上手くいくと必要な情報を入力する画面に移動する。
サブタイトルからメールアドレスまでを入力する。
この時のユーザー名やパスワードはどこかで保管しておく。
`WordPressをインストール`をクリック

![スクリーンショット 2020-06-02 16.28.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/ef7a430e-9e17-5498-f2c0-d083a5fa0252.png)

インストールが終わると以下の画面が表示されてインストールに成功する
![スクリーンショット 2020-06-02 16.29.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/80980a5a-56d5-f58c-1771-c85a3be9831d.png)



※参考（丁寧な解説あり）
https://www.alpha-mail.jp/support/tool/wp/step_04.htm
日付の期間判定・過去未来判定について

# 結論

ミリ秒にして大小判定するのマジおすすめ  
※Javaを例にしていますが、どの言語でも同じ話です

※良い子のみんなは、java.util.Dateなんて使わずに[Joda-Time](https://www.joda.org/joda-time/)つかうか、Java 1.8以降ならTime APIを使おうネ）  

**※ただの参考コードです。Dateクラスの非推奨コンストラクタ使うのやめようね**

```java
Date nowDate= new Date();
// 2020/4/1 00:00:00 ～2020/4/30 23:59:59 の場合に「キャンペーン期間中だよ」と出力
if (nowDate.getTime() >= new Date(2020, 3, 1, 0, 0, 0).getTime()
    && nowDate.getTime() < new Date(2020, 4, 1, 0, 0, 0).getTime()) {
    System.out.println("キャンペーン期間中だよ");
}
```

# 言い訳

皆さんは、Javaの日付の判定、どうされていますか？  
java.util.Dateクラスを利用する場合、afterメソッドやbeforeメソッドを使っていますか？  
Joda-TimeやTime APIでも、似たようなメソッドありますよね？

でも、正直私はそのメソッドを見ただけでは「引数が未来なんだっけ？過去なんだっけ？指定された日付は含むんだっけ？含まないんだっけ？」というのを即時に判断出来ません。（アホですね）

JavaDocを見るとそれぞれこう書かれています。  
（[Java 1.8のJavaDoc](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Date.html)から引用）

* after

> この日付が、指定された日付より後にあるかどうかを判定します。

* before

> この日付が、指定された日付より前にあるかどうかを判定します。

つまり、どちらも「指定された日そのもの」は含まないわけです。  
英語が得意な方は、afterやbeforeが「含まない」という意味だと理解しているかもしれないですが、  
僕は知りませんでした。
  
よくやるポカとして、  
「2020年4月1日の00:00:00～2020年4月30日の23:59:59までをキャンペーンの申し込み期間としよう！」とした場合に

```java
Date nowDate = new Date();

if (nowDate.after(new Date(2020, 3, 1, 0, 0, 0)) 
    && nowDate.before(new Date(2020, 4, 1, 0, 0))) {
    System.out.println("キャンペーン期間中だよ");
}
```

こんな風にしちゃって、「日付変わった瞬間は申し込み出来ねーじゃん！！！！！」っていうバグを作り込んじゃいます。  
（まあ、その1秒を良しとするかどうかはプロジェクト次第ですが）

だから、数値型にしちゃって大小比較したほうが間違いが無いよね。っていう話でした。
【5分で理解】JavaScriptのユーザー定義関数について

こんにちは！
本日はユーザー定義関数について解説していきたいと思います。
JavaScriptの基本を学びたい初学者の方は是非読んでいってください！

## 📗 関数のイメージ
関数ってよく聞くけど数学苦手マンだからよくわからん！というような私みたいな方もいると思うので、
最初に関数のイメージについてお話します。

関数を英語にすると　function　となります。
functionだけだとピンときませんが、意味を調べると関数の他に***機能***などの意味があります。

関数のフローは自動販売機によく例えられます。

　　　　　　　　　　　***ジュースのボタンを押す***
お金を入れる→![自販機.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545998/ab2529fc-e624-1b2c-9f4b-6cd93a89929e.png)→選んだジュースが出てくる

コレを関数に比喩すると
お金を入れる　　＝　引数
ボタンを押す　　＝　処理の実行
ジュースが出る　＝　戻り値

というような形になります。
とりあえず、関数は自動販売機みたいな流れで動くというイメージだけ掴んでいただければOKです。

## 📗 ユーザー定義関数って何？
関数は主に２種類あります。

- 組み込み関数　→　既にプログラムで準備されている関数
- ユーザー定義関数 →　自身で自由に作れる関数

その名の通り、ユーザーが定義した関数のことをユーザー定義関数と呼びます。

基本的な形としては

 ```JavaScript:
function test(引数){
　//処理

 
return　戻り値; //戻り値
}
```
testという自販機に対して、引数を入れて処理を行い、戻り値(return)が帰ってきます。
実際には引数がなかったり、引数が複数あったりするパターンもありますので、そちらを解説していこうと思います。

## 📗 関数のパターン
上記で書いたとおり関数の記載には複数のパターンが存在します。
何パターンか紹介していこうかと思います。

###パターン１　引数なし、戻り値なし

```JavaScript:
function test(){         //引数は無いので（）の中には何も書かない
 console.log('test');    //戻り地も無いのでreturnを書かない
}

test();
```

コレで実行すると、コンソール上に test と表示されます。
シンプルにconsole.logだけが動いている状態です

###パターン2　引数あり、戻り値なし

```JavaScript:
const text = '春日部防衛隊ファイヤー！！！'
const text_2 = '救いのヒーローぶりぶりざえもん参上'
 
function getText(string){    //stringを引数に
 console.log(string);        //ここの（）の中身は必ず引数と同じ名前にする必要がある。
}

getText(text);             //勘違いしやすいですが、ここの（）の中身は引数と同じにする必要がありません。
```
コレを実行すると、春日部防衛隊ファイヤー！！！と出力されます。
このように、変数を代入して使うことが多いです。
またgetText(text_2);とすることで、救いのヒーローぶりぶりざえもん参上と出力されます。
###パターン3　引数なし、戻り値あり
このパターンは少し複雑になります。
下記のパターンで処理を実行した場合、どうなるでしょうか？

```JavaScript:
function textNumber(){
 return 5 ;
}
textNumber();
```
一見するとreturnの5が、コンソール上に反ってきそうにも見えますが、
このコードに出力する処理が書かれていないので、何も表示はされません。
しかし、処理自体は行われているのでtextNumberに５という数字自体は入っています。

```JavaScript:
function textNumber(){
 return 5 ;
}
console.log(textNumber());
```
このようにconsole.logでかこってあげると５と出力できます。
あるいは

```JavaScript:
function textNumber(){
 return 5 ;
}
textNumber();                     //この段階で５がtextNumberに入ってる。

const TextNumber = textNumber();   //textNumberを変数TextNumberに代入する

console.log(TextNumber)           //変数を出力する
```

このように変数化して出力することも可能です！
これでも５が出力されます。

###パターン4　インプット２つ、戻り値あり
今回は足し算の合計を出力するコードを作ります。

```JavaScript:
function sumNumber(int1,int2){   //int1=4,int2=6が代入される。下記の第一引数、第二引数がそれぞれint1,int2似自動で振り分けられる。
 let int3 = int1 + int2;         
 return int3;
}
const total = sumNumber(4,6);  //第一引数に4を第二引数に6を入れる

console.log(total);
```
この出力は、10となるのがわかるかと思います。
ポイントは引数と処理の中の文字をあわせることに注意するくらいだと思います。

非常に簡単でしたが、ユーザー定義関数について簡単にパターンと使い方について解説していきました。
今回は以上となります！
## 📗 次回予告
次回は、組み込み関数についても解説できたらなと思います。

私事ですが、今後はAWS認定ソリューションアーキテクト　アソシエイトに挑戦する予定ですので更新頻度が下がるか、備忘録的にそちらの記事を書いていくかと思われます。

***記事を読んでいただきありがとうございました。
間違えている部分などありましたらご指摘のほどお願い致します***
Xplenty入門 Part5: パッケージのチェックとジョブ結果確認

今回はXplentyでパッケージを作成後、パッケージが正しく作成されているかのチェックとジョブを実行した際の実行結果の確認方法について解説します。

#パッケージのチェック
パッケージを保存する前にパッケージが正しい定義に基づいて作成されているかをValidate機能を使ってチェックすることが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/b5718039-6946-0ceb-64df-b71331bcf8ff.png)

もし、問題がある場合は、以下のようにどのコンポーネントで問題が発生しているかをエラーメッセージで教えてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/8d2209db-eb18-5446-e115-37643d4969d8.png)
この場合は「Select1」というコンポーネントで無効なフィールドが設定されている旨のエラー内容が表示されています。エラーメッセージをクリックすると、エラーが発生しているのコンポーネントの設定画面に遷移します。

#ジョブ実行画面
ジョブ実行時の進捗状況（進捗度をパーセンテージで表示）の確認や実行中のジョブのキャンセルをジョブ画面で行う可能です。また、実行された結果をジョブ画面で確認し、書き込んだレコード数を確認することも可能です。（ストレージの場合Outputのプレビューを参照することもできます。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/ab3556d9-0434-9cba-d98d-6cfbc026bdbf.png)
エラーが発生した場合、詳細画面で詳細なログが表示されるので、それを参照しエラー原因を特定することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/e767a1c0-3856-087e-b07e-00ab6984bb05.png)

ログによって横スクロールしないといけない場合があり、少々分かりづらいのですが、注意深くエラー箇所を追っていくと、以下のようなエラー原因を特定するメッセージを発見できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/a2d38778-8192-8854-5415-9ae749f6ff61.png)
GAS:リストをもとに、テンプレートシートを複製し、シート名をリネームする

```javascript:qiita&nbsp;arrayPractice.js
const ThisSpread = SpreadsheetApp.getActiveSpreadsheet();

function createSheet(){
  const name_list = createNameList();
  Logger.log(name_list);
  const TemplateSheet = ThisSpread.getSheetByName('template');
  for (let name of name_list){
  const create_sheet = TemplateSheet.copyTo(ThisSpread);
  create_sheet.setName(name);
  }
}
function createNameList() {
  const name_list = [];
  const NamesSheet = ThisSpread.getSheetByName('names');
  for (row = 1; row <= 5; row ++){
  name_list.push(NamesSheet.getRange(row, 1).getValue());
  }
  //Logger.log(name_list);
  return name_list;
}
```
Nuxt.js で npm モジュールをプラグイン化するサンプル(IMI コンポーネントツール)

# 概要
- Nuxt.js で npm モジュールをプラグイン化して使う例をメモとして残す
- ついでに最近リリースされた IMI コンポーネントツールを使ってみる

# 手順

## npm モジュール追加
```shell
yarn add https://info.gbiz.go.jp/tools/imi_tools/resource/imi-enrichment-contact/imi-enrichment-contact-1.0.0.tgz
```

## プラグイン作成
- plugins 以下に javascript ファイルを作成
- モジュールを import してコンテキストと Vue コンポーネントにインジェクトする

```javascript:plugins/contact.js
import contact from 'imi-enrichment-contact';

export default (ctx, inject) => {
  ctx.$contact = contact;
  inject('contact', contact);
};
```

## nuxt.config.js を修正してロード
```javascript:nuxt.config.js
 plugins: ['@/plugins/contact'],
```

## .vue ファイルから使用する
```javascript:xxx.vue
  asyncData({ $contact }) {
    console.log($contact('117'));
  },
  methods: {
    normalize() {
      this.normalized = JSON.stringify(this.$contact(this.tel), null, 4);
    }
  }
```

# 動作サンプル
- https://yoshihiro-hirose.github.io/nuxt-vuetify-sample/samples/contact
- https://github.com/Yoshihiro-Hirose/nuxt-vuetify-sample

# 補足
- IMI コンポーネントツールはブラウザで動かないものもある(住所とか)
- プラグインを TypeScript から使う場合は型定義なども別途必要

# 参考リンク
- Nuxt.js プラグイン
  - https://ja.nuxtjs.org/guide/plugins/
- IMI コンポーネントツール
  - https://info.gbiz.go.jp/tools/imi_tools/index.html
  - https://blog.geolonia.com/2020/05/29/imi-tools.html
  - https://qiita.com/uedayou/items/4c9d30fc031a9bf6762e
GAS:javaScriptでリスト化されたタイトルを各シートのrange(1,1)にsetValue()する

# 環境
GAS
# 前提
criteriaシートのA1からB4まで、シート名とタイトルが記載されています。

```javascript:qiita&nbsp;Practice.js
const this_spread = SpreadsheetApp.getActiveSpreadsheet();

function Main() {
  const name_map = createMap();
  const error_list = [];
 for ([key, value] of name_map){
    try{
    const target_sheet = this_spread.getSheetByName(key);
    target_sheet.getRange(1,1).setValue(key + '：' + value); 
    }catch(error){
    error_list.push(key);
    }
  }
  if(error_list > 0){
    Browser.msgBox('error_list is ' + error_list);
  }
}

function createMap() {
  const criteria_sheet = this_spread.getSheetByName('criteria');
  let name_map = new Map();
  for(let count = 1; count <= 4; count ++){
    let key = criteria_sheet.getRange(count,1).getValue();
    let value = criteria_sheet.getRange(count,2).getValue();
    name_map.set(key, value);
  }
  return name_map
}

```
シンボルについて学習したこと

###シンボルを作成する上での注意点

```ruby:エラーが出る書き方
#識別子として無効な文字列（数字で始まる、ハイフン、スペースを含む文字列）を使うとエラーが発生
:5678             #=>SyntaxError
:rails-is-easy    #=>Nameerror
:rails is easy    #=>SyntaxError
:()               #=>SyntaxError

#シングルクオートで囲むとシンボルとして有効
:'5678'           #=>"5678"
:'rails-is-easy'  #=>"rails-is-easy"
:'rails is easy'  #=>"rails is easy"
:'()'             #=>"()"
```

```ruby:シンボルの中で式展開
#ダブルクオートを使う
title = 'Taro'
:"#{title.upcase}" #=> :TARO
```

###シンボルと文字列
文字列とシンボルは別物なので、互換性はない。しかし、文字列をシンボルに変換するメソッド、シンボルを文字列にするメソッドはある。

```ruby:
string = 'ruby'
sypbol = :ruby
string == symbol #=> false

#to_symメソッド:文字列をシンボルに変換
string.to_sym           #=> :ruby 
string.to_sym == symbol #=> true

#to_sメソッド:シンボルを文字列に変換
symbol.to_s           #=> "ruby" 
symbol.to_s == string #=> true  
```

参考文献
プロを目指す人のためのRuby入門
Servicenow Orlando Delta試験を受験してきた

#はじめに
ServiceNowでは、新バージョンが出るごとに再認定を受ける必要があります。
Delta試験と呼ばれていて、要は差分試験です。
今回はOrlando版です。
開催期間は4/9 ~ 7/8 (US時間MST基準)です。


#受験予約から受験終了までの流れ

- [Webassessor試験システム](https://www.webassessor.com/servicenowapj)にログイン
- 右上「試験の申込」
- Delta試験→今すぐ購入→チェックアウト
- 右上「評価」から受験開始
- 合格するとメールが届く(認定書のPDF)

#試験について
##試験範囲
差分試験なので、Orlandoの[リリースノート](https://docs.servicenow.com/bundle/orlando-release-notes/page/release-notes/family-release-notes.html)を確認しましょう。
英語なのが辛い…

##時間や問題数

- 時間は30分
- 問題数は6問
- 合格ラインは不明

Webassessorには約10問とありましたが、問題セットは6問の1セットしかなさそうです。

#おわりに
リリースノートとにらめっこすることが合格の近道だと思いました。
AZ-900 Microsoft Azure Fundamentalsを無料で取得しました！


__※2023/11追記…2023/08あたりからマイクロソフトの方針が変わったらしく、バウチャーの配布は行われていません。ご注意を。__


## はじめに
先日 **「AZ-900 Microsoft Azure Fundamentals」**　を無料で受験して合格してきたので、そのご報告とおすすめの記事です。

私のスキルは、

 - AWS SAA 所持
 - Azureはほぼ未経験

という感じです。ですのである程度クラウドには慣れています。
受験する際の目安にしていただければ。

## 一言でいうと
 - Microsoftが実施しているオンラインウェビナーに参加するとAZ-900を無料で受験できるバウチャーをもらえる！
 - AZ-900はウェビナーを一通り聞いて、Micorosoft Learnの該当部分を一通り通しでやればだいたい大丈夫

## Microsoft Azure Virtual Training Day: Fundamentals 
意外と知られてないんですが、Micorosoftさんでは各種トレーニングやセミナーなどを積極的に開催されています。
その中で、Azure初心者向けに「Microsoft Azure Virtual Training Day: Fundamentals」というのが行われています。

> **Microsoft Azure Virtual Training Day: Fundamentals**
は一般的なクラウドコンピューティングの概念やパブリック、プライベートおよびハイブリッド環境におけるクラウド、IaaS、PaaS、SaaSといったクラウドサービスに関する基礎的な知識をつけるためのトレーニングです。

内容的にはAzureだけでなく、一般的な内容も含んでいますので、初めてクラウドに触る方でもおすすめです。
実はこれ3月に受けるつもりだったのですが、COVID-19でセミナー自体がなくなってしまい…

しかしながらさすがはMicorosoftさん。

**すぐさまオンラインウェビナー形式に切替え！**
**しかもちゃんとAZ-900を受験できるバウチャー付き！太っ腹ですね。**


早速4月に参加しました！すごくわかりやすかったです。

普通のセミナーだとすぐにAZ-900を受験できるのですが、オンラインなのとCOVID-19の影響で5月まで試験会場が空いてませんでしたので、5月半ばに受験してきました。

## AZ-900 Microsoft Azure Fundamentals

さて、AZ-900の試験についてですが、総合的なAzureの基礎知識が問われます。
かといって、そこまで難しい問題はでません。

試験範囲については、こちらをご参考に。

https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900?wt.mc_id=learningredirect_certs-web-wwl

勉強については、Micorosoft LearnのAzureの基礎を一通りこなしておくといいです。

https://docs.microsoft.com/ja-jp/learn/paths/azure-fundamentals/

とりあえず丸暗記するぐらいまで読み込みをしました。
日常的に使っていることもあり、資格勉強、という枠での時間は10時間にも満たなかったです。

試験会場には必ず**2種類の身分証明書**を持っていくことをお忘れなく！

私の所感では、

- 意外とプレビュー中の知らないサービス名が出てきたけど論理的に考えれば回答できた。
- 「あれどうだっけな？」となる問題もあったので、おおよその把握だけでなくて、細かい仕様も見ておくとよい。

という感じでした。
私は60分の試験時間のうち、20分ぐらいで退出しました。合格ラインは700点でしたが、800点以上取得して合格です。

ちなみに**Microsoft系の資格は、適宜試験内容がアップデートされます。**
AZ-900も2020/05/28に更新される予定になっています。(だから滑り込んで受験したわけですね。)

## おわりに

- 実は 「**Microsoft Azure Virtual Training Day: Fundamentals**」、不定期に行ってたりします。 
- https://microsoft-events.connpass.com/  で探してみてください。運が良ければ見つかるかも！
- 次は**AZ-103:Microsoft Azure Administrator**を取得を目指していますが…AZ-103は **「一回目は落ちた」という情報が非常に多い**ので、戦々恐々しています。
- むしろ一回落ちてから受験するのがいいかもしれない…。
    - 2021/03 一発合格しました！
- 2022/02 AZ-304を取得しました！ 
- 2022/03 AZ-303を取得しました！2つ合わせてAzure Solutions Architect Expertです！
- 2023/02 AZ-700を取得しました！
- 2023/02 AZ-500を取得しました！
- 2023/02 AZ-400を取得しました！
- 2023/08 AI-900を取得しました！
- 2023/10 AI-102を取得しました！
- 2024/07 AZ-204を取得しました！

## 参考

[AZ-900 Microsoft Azure Fundamentals](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900?wt.mc_id=learningredirect_certs-web-wwl)

[MicroSoft Learn - Azureの基礎](https://docs.microsoft.com/ja-jp/learn/paths/azure-fundamentals/)

以上！

-------------------------------------
【変更履歴】
- https://azure.microsoft.com/ja-jp/community/events/
ではウェビナーが見つからなくなってしまったので、適切なURLに変更しました。
- https://microsoft-events.connpass.com/
で適宜情報発信してらしたので、そちらに変更。
jacaScript Mapをfor文で処理する

# 環境：
GAS


```javascript:qiita&nbsp;Practice.js
const this_spread = SpreadsheetApp.getActiveSpreadsheet();

function createMap() {
  const criteria_sheet = this_spread.getSheetByName('criteria');
  let name_map = new Map();
  for(let count = 1; count <= 4; count ++){
    let key = criteria_sheet.getRange(count,1).getValue();
    let value = criteria_sheet.getRange(count,2).getValue();
    name_map.set(key, value);
  }
  return name_map
}

```
マルチモジュールでIBでNamedColorを使用する方法

[こちら](https://devblog.xero.com/managing-ui-colours-with-ios-11-asset-catalogs-16500ba48205) を元に対応した内容ですが、あまり日本語で書いているところが少ないと思い書くことにしました。

XcodeのAssetでnamed colorを設定してIBで下記のように色を指定できて便利です。

![alt](https://miro.medium.com/max/1104/1*O_zUaua3r0hjbyXvGLeP0A.png)

※ [↑こちら](https://devblog.xero.com/managing-ui-colours-with-ios-11-asset-catalogs-16500ba48205) の画像を参照しています

しかし、マルチモジュールの場合、IBで設定した後に以下のような警告が表示されて、Assetで定義をしていた色を変更しても色の変更が反映されないことがあります。

```
2018-04-26 17:30:30.009855+1200 MyApp[82987:11407859] WARNING: Unable to resolve the color named "PrimaryText" from any of the following bundles: com.myfirm.MyApp, com.myfirm.MyApp
```

理由としては、IB内のxmlでは下記のようにnamedColorの名前と失敗した場合の時のfallbackColorは記載されていますが、どのモジュールにnamedColorの定義がされているかが記載されていません。
そのため、他のモジュールとかに色の定義がある場合、参照できずfallbackColor(恐らくIBで設定時の色)が使用されてしまうためです。

![alt](https://miro.medium.com/max/1400/1*j4FGK3X0QSDMShvBxtmMMg.png)

※ [↑こちら](https://devblog.xero.com/managing-ui-colours-with-ios-11-asset-catalogs-16500ba48205) の画像を参照しています

ならどのように防げば良いかと言うと、色のリソースはサイズがさほど大きいことはほぼないと思います。
なので、下記のように色のAssetのTargetを色を使用するモジュールそれぞれに含みfallbackColorではなくnamedColorの参照にxibやstoryboardでも成功させることで、Assetの色の定義を変更してもそれぞれのモジュールのIBで指定した色の箇所にも反映されるようになります。
(注意:色のリソースがモジュールごとに重複するのでわずかにアプリのサイズは大きくなると思います)

![ColorAssetsCheck.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308423/41328018-0256-d60e-fdbc-b63919b24927.png)
【言語処理100本ノック 2020】第6章: 機械学習

## はじめに
自然言語処理の問題集として有名な言語処理100本ノックの[2020年版](https://nlp100.github.io/ja/)が公開されました。
この記事では、以下の第1章から第10章のうち、「第6章: 機械学習」を解いてみた結果をまとめています。

本編は以下のリンク先に移転しました。
https://amaru-ai.com/entry/2022/10/12/202559

[全100問の解答へ](https://amaru-ai.com/entry/2022/10/15/204035)
golang dep にはまった

dep ensure -v
で数時間かかっても終わらないのでおかしいなと思ったら、
githubに登録したrsakeyにパスをつけていたことが原因だったっぽく、パスなしkeyを登録し直したら、1分で終わった。
ssh-agentも紹介してもらったけど、それを使えば大丈夫なのかは未確認。今度やってみよう。
inputタグにおけるtype属性について

#inputタグとは
テキスト入力やボタンなどの部品を作成する際に用いる
以下のように入力して用いる
`<imput type="○○" name="部品の名前" value="初期値">`

# 部品の形式~type属性~
`<input type="属性値">`と記述する

|属性値|内容|
|---|---|
|text|1行のテキストボックス|
|password|入力した内容にマスクがかかる（見えなくする）テキストボックス|
radio|ラジオボタン
checkbox|チェックボックス
file|ファイル参照ボタン
hidden|非表示のテキストボックス
submit|フォームの実行ボタン
image|画像を使たフォームの実行ボタン
reset|リセットボタン
buttun|汎用的なボタン

#参考
[Chrono Drive](https://html-coding.co.jp/annex/dictionary/html/input/)
SwiftUI使用時の `precondition failure: invalid input index: 2` のクラッシュ修正する

SwiftUIとCombineを使用している時に、ObservableObjectの値が素早く変更される時（自分の場合だと初期値が流れる→UserDefaultsを読み込んで値が流れる）に、UIコンポーネントの表示切り替えを if文で行っていると `precondition failure: invalid input index: 2` でクラッシュするという問題がありました。

# 解決方法
現状 `if` で分岐してクラッシュを回避するのは難しそうだったので、frameのheightを指定して非表示にするようにしました。(VStackの場合)もし、HStackを使用しているならwidthを指定すればいいと思います。
さらに、Imageなどのコンポーネント自体がサイズを持っている場合は親のサイズを変えても見えてしまう場合があるので、Opacityを0にします。

# 問題箇所の抜粋

```swift
    @State private var dataModel = DataModel()

    var body: some View {
        NavigationView {
            VStack {
                if dataModel.componentHidden {
                    SomeComponent()
                }

                SomeComponent()
            }
        }
        .onReceive(adapter.store.computed.dataModel) { (dataModel) in
            self.dataModel = dataModel
        }
    }
```

# 修正後
```swift
    @State private var dataModel = SupportedCardListTabDataModel()

    var body: some View {
        NavigationView {
            VStack {
                SomeComponent()
                .frame(height: dataModel.isAdvertiseHidden ? .zero : nil)
                .opacity(dataModel.isAdvertiseHidden ? .zero : 1)

                SomeComponent()
            }
        }
        .onReceive(adapter.store.computed.dataModel) { (dataModel) in
            self.dataModel = dataModel
        }
    }
```

# 参考資料
- https://www.reddit.com/r/SwiftUI/comments/fosrbf/precondition_failure_invalid_input_index/
- https://forums.developer.apple.com/thread/129171
- https://stackoverflow.com/questions/58304009/how-to-debug-precondition-failure-in-xcode
VBAでHello Worldを表示する

# VBAとは
「Visual Basic for Application」の略で、エクセルなどのMicrosoft Office商品をプログラムで操作するためのプログラミング言語のことです。

# マクロとは
エクセルの機能のひとつで、エクセル作業を自動化する機能のことです。エクセルの複数の手順をひとかたまりの操作として登録して、後で実行することができます。

# VBAを使うための準備　「開発」タブを表示する
エクセルでVBAを始めるために、エクセルのリボン（メニュバー）に「開発」タブを追加します。

1. 「ファイル」タブ→「オプション」をクリック
1. 「リボンのユーザー設定」をクリック
1. 画面右の「リボンのユーザー設定」配下に表示されるタブ一覧で「開発」にチェック

# VBEを立ち上げる
VBEとは、Visual Basic Editorの略で、マクロを作成するためのエクセルの機能のことです。マクロのコードを記述・編集するときは、Excelとは別のVBE画面を使います。
「開発」タブ→「Visual Basic」をクリックすることで、VBEのウィンドウが立ち上がります。

# Hello Worldを表示するプログラムを入力する
VBEウィンドウ内の左上に位置する「プロジェクトエクスプローラー」と呼ばれるエリアの「ThisWorkBook」をダブルクリックします。
VBEウィンドウ内の右上に位置する「コードウィンドウ」と呼ばれるエリアに以下を入力します。

```vb
Sub test() '「test」部はマクロのタイトルを表す。好きな文言を記入できる。1つのマクロは「Sub」から始まり、「End Sub」で終わる。「Sub」～「End sub」までのマクロ全体を「プロシージャ」という。
 MsgBox "HelloWorld!" 'MsgBoxはメッセージボックスを表示するメソッド。表示する内容はHello world
End Sub
```

VBEウィンドウを閉じ、エクセルファイルをExcel マクロ有効ブック (*.xlsm)　の形式で保存します。

# マクロを起動して、Hello Worldを表示する
VBEウィンドウを立ち上げ、メニューバーの再生ボタン（Sub/ユーザーフォームの実行ボタン）を押すと、メッセージボックスが立ち上がり、「Hello World」と表示されます。

# 追記：プログラムにはコメントを書こう
プログラムを入力するときは、コメントと呼ばれる備忘メモを書くようにしましょう。VBAはプログラムを上から順番に実行していきますが、コメント部は何が書いてあっても無視されます。
コメントを書くことで、あとでプログラムを見た時に、どんなプログラムなのかが理解しやすくなります。
コメントを書くときは、'（アポストロフィー）を使います。アポストロフィーより右側がコメントになります。
VBAで日付をYYYYMMDDの8桁数値で表示する

現在の日付を取得して、スラッシュ抜きのYYYYMMDD形式に変換し、メッセージボックスに表示するマクロです。

```vb
Sub eight_digits_date() 'マクロのタイトルを「eight_digits_date」と名づける
    Dim Date8 As String 'String（文字列）型の変数「Date8」を宣言
    Date8 = Format(Now, "yyyymmdd") 'Now関数を使って、yyyymmdd形式で日付を取得し、変数「Date8」に格納
    MsgBox Date8 'メッセージボックスで変数「Date8」の中身を表示
End Sub
```
VBAで今開いているエクセルのファイル名（ブック名）を取得する

アクティブのエクセルのファイル名を取得して、メッセージボックスに表示するマクロです。

```vb
Sub GetFileName()
    Dim FileName As String
    FileName = ActiveWorkbook.Name 'ActiceWorkbookオブジェクトのName情報を取得し、変数「FileName」に格納する
    MsgBox FileName 'FileNameに格納されている文字列をメッセージボックスに表示する
End Sub
```

※「オブジェクト」とは、操作を指示する際に、操作の対象となる「物」のことをいいます。このケースでは、オブジェクトは「ファイル（Book）」を指しています。
VBAで「ファイルを開く」ポップアップ画面からフルパスを取得する

ボタンを押すと「ファイルを開く」ダイアログボックスが立ち上がり、次にファイルを選ぶとファイルの保存場所情報（フォルダのパス、ディレクトリ）とファイル名を取得します。

```vb
Sub GetFilePath() '「GetFilePath」部はマクロのタイトルを表す。好きな文言を記入できる
    Dim FilePath As String 'String（文字列）型の変数「FilePath」を宣言
    FilePath = Application.GetOpenFilename()  'ApplicationオブジェクトのGetOpenFilenameメソッドを使って、ファイルパスとファイル名を取得する
    MsgBox FilePath 'メッセージボックスにファイルパスとファイル名を表示する
End Sub
```
VBAでフルパスからパスだけを取得する

# やりたいこと
フルパスの中から、ファイル名を除いたフォルダパスを取得します。

## フルパスとは
C:¥Users¥yamada¥Documents¥test.txt のようなcドライブからファイルの場所までを表す文字列のことです。この処理では、C:¥Users¥yamada¥Documents¥test.txtから、test.txtだけを取り除きます。

```vb
Sub GetFolderPath()
    Dim FilePath As String 'String（文字列）型の変数「FilePath」を宣言
    Dim FolderPath As String 'String（文字列）型の変数「FolderPath」を宣言
    Dim i As Integer 'Integer（整数）型の変数「i」を宣言
    
    FilePath = Application.GetOpenFilename()  'ApplicationオブジェクトのGetOpenFilenameメソッドを使って、ファイルパスとファイル名を取得する    

    i = InStrRev(FilePath, "\") 
        'InStrRev関数は、ある文字列の中から指定した文字を最後の文字位置から検索し、最初に見つかった文字位置を返します。帰ってきた数値を変数「i」に格納します。
    FolderPath = Left(FilePath, i - 1) 'ファイルのフルパスの内、左から数えてi文字目まで取得する
    
    MsgBox FolderPath 'メッセージボックスに変数「FolderPath」に入っている文字列を表示する
    
End Sub

```
VBAでエクセルのファイル名（ブック名）を今日の日付に変更する

# やりたいこと
いま開いているエクセルファイルのファイル名を今日の日付に変えるマクロを作ります。
例）　excel.xlsx → 20190101.xlsx

# 完成したマクロの操作イメージ
1. マクロファイルを開く。
1. 画面に設置してあるボタンを押すと、ファイル選択画面がポップアップで立ち上がる。
1. ファイルを指定して、「開く」ボタンを押すと、指定したファイルのファイル名が今日の日付に変わる。

# 処理のイメージ
1. [名前を変更しようとしているファイルの保存場所情報を取得する](https://qiita.com/smello/items/f1838cfbf3bed3f50abd)
1. [取得したファイルパスから、ファイル名を取り除く](https://qiita.com/smello/items/03bdd32e9e2bb577f858)
1. [現在の日付を取得して、取得した日付からスラッシュを取り除く](https://qiita.com/smello/items/da91ffd104efcc9f024c)
1. ファイル名を変更する（下記参照）

# 作成の流れ
1. 「開発」タブ→「コントロール」→「挿入」→「フォームコントロール」→「ボタンの画像」をクリックする。「マクロの登録」ポップアップウィンドウが表示される。
1. マクロ名に「FileNameChange」と入力、マクロの保存先を「作業中のブック」にして、「新規作成」ボタンをクリックする。VBEウィンドウが表示される。
1.  VBEウィンドウ内の右上に位置する「コードウィンドウ」と呼ばれるエリアに以下のコードを入力する。

```vb
Sub FileNameChange()
    Dim OldName As String 'String（文字列）型の変数「FileName」を宣言
    Dim NewName As String 'String（文字列）型の変数「FileName」を宣言
    Dim FolderPath As String 'String（文字列）型の変数「FolderPath」を宣言
    Dim i As Integer 'Integer（整数）型の変数「i」を宣言
    
    OldName = Application.GetOpenFilename()   'ApplicationオブジェクトのGetOpenFilenameメソッドを使って、ファイルパスとファイル名を取得する
   
    i = InStrRev(OldName, "\") '右から数えて最初の\が、左から数えて何文字目かを取得して、変数「i」に格納する
    FolderPath = Left(OldName, i) 'ファイルのフルパスの内、左から数えてi文字目まで取得する
    NewName = Format(Now, "yyyymmdd") 'Now関数を使って、yyyymmdd形式で日付を取得し、変数「NewName」に格納
    NewName = FolderPath & NewName & ".xlsx" '変数「NewName」に.xlsxを付加
    Name OldName As NewName 'Nameステートメントを使って、ファイル名を変更
End Sub

```

# 解説
ファイルの名前を変更するには、Nameステートメントを使用します。Nameステートメントでは、「元のファイル名」と「新しいファイル名」を指定します。

# 用語
ステートメントとは、ひとかたまりのコードのこと。
コードとは、「テキスト」のこと。
知らなんだ。gp2のボリュームサイズとベースラインパフォーマンスについて


# 概要
gp2の割り当てたボリュームサイズを増やすことで、IOPSの増やすことができると最近、社内のインフラエンジニア教えてもらった。
それまでは、io1に変更することでしかIOPSを増やすことができないと思っていて、EBSの割当をいつも使用するストレージ量でのみ考えていたので、調べたりして勉強になったのでまとめることにした。

# IOPSってなんだ
「Input/Output Per Second」の略。
ストレージがもつ1秒間にI/O数を指標化したもの。
ふむ。数字が大きいほうがより高性能であることがわかる。
ストレージをゴリゴリするような読み書きの多いアプリケーションの場合、パフォーマンスに影響するので、気にするべき指標の１つ。

# gp2のベースラインパフォーマンスについて

ボリュームサイズにより、表のように割当ボリュームサイズでベースラインが異なる。
あと継続してバーストできる時間とバーストに必要なIOクレジットの回復までの時間も異なるので注意が必要。

| ボリュームサイズ (GiB) | ベースラインパフォーマンス (IOPS) |  バーストできる （秒数) | バーストするため必要なIOクレジットが回復する秒数 |
| --- | --- | --- | --- |
| 1 | 100 | 1802 | 54,000 |
| 100 | 300 | 2,000 | 18,000 |
| 250 | 750 | 2,400 | 7,200 |
| 334 | 1002 | 2703 | 5389 |
| 500 | 1,500 | 3,600 | 3,600 |
| 750 | 2,250 | 7,200 | 2,400 |
| 1,000 | 3,000 | 該当なし* | 該当なし* |
| 5,334 | 16,000 | 該当なし* | 該当なし* |
| 16,384 | 16,000 | 該当なし* | 該当なし* |

## まとめ
・gp2は、100IOPS～16,000IOPSまでとなる。
・ベースラインパフォーマンスは、3 IOPS/GiBの割合で拡大。（ざっくりGib × 3とおぼえたらいい。）
・3,000IOPSまでバーストできるけど、IOクレジットの量に応じた時間だからIOクレジットが枯渇しないようにしないと調整しないといけない。
・IOクレジットは、ボリュームサイズにより秒数と回復までの時間が異なるので、注意。
・ベースパフォーマンスが3,000IOPSを超えると、バーストは関係なしと。

上記を意識して、構築したらコストもパフォーマンスもより最適化されたインフラが構築できる。