OmniAICreator/Qiita-1.07M huggingface dataset:
DatabricksでMLflowを使う② - 実験パラメータとメトリクスの可視化 -

# はじめに
前回のこちらの記事ではDatabricks上でMLflowを使って機械学習モデルのトレーニングを行った履歴をノートブック上に統合するための方法について書きました。

[DatabricksでMLflowを使う① - ノートブック上での実験トラッキング -](https://qiita.com/knt078/items/49a14a83c45f3f501ee7)

Databricksのマネージド型MLflowではUI上でトレーニングモデルのパラメータやメトリクスの比較、モデルのステージングなどを行うことができます。

この記事では実験ごとのパラメータやメトリクスを可視化して比較する部分について書いています。

# 実験ごとのUI画面
前回記事でノートブック上で実験ごとのメトリクスなどを確認した画面から、図中赤枠の部分をクリックします。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/cc6da995-e758-ac74-1744-e87089408375.png)

実験ごとの情報がまとめられた画面に移ります。メトリクスやパラメータ、統合されているノートブックなどが表示されます。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/6a1b77f9-7af1-b798-f8f1-f5b2a425edb9.png)

下のほうにスクロールすると、アーティファクトファイルとしてモデルや環境設定のデータ、実験結果のスクリーンショットなどが保存されています。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/01f94f02-f52a-510d-7053-493bc3d885a7.png)

ノートブックにMLflowを統合した場合は実験idが自動で割り振られて、実行結果ごとにrun_idが割り振られて管理されます。アーティファクトファイルはDBFS内のディレクトリに保存されます。

# 各実験の比較
ノートブックから「Runs」の右にある下図の赤枠部分をクリックします。
![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/802f758f-1258-0550-c698-24bc864f6153.png)

各実験の一覧が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/a239aeb9-e084-9001-8b39-a2b408730a8d.png)

比較したい実験を選択して「Compare」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/3b2d8e44-f6e6-c3dc-793f-1e8dc82c5c27.png)

パラメータやメトリクスが比較できます。それぞれのrun idをクリックすると前述の実験の個別ページに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/79f4e745-d20d-aa42-c033-74996cad2616.png)

下にスクロールするとパラメータやメトリクスを可視化して比較することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/d038266a-9491-7395-133f-c013ac56acb5.png)

# おわりに
今回はDatabricksのUI上で実験パラメータやメトリクスを可視化して比較しました。
次回はトレーニングしたモデルを本運用に移行するためのステージングについて書きたいと思います。

前回記事：[DatabricksでMLflowを使う① - ノートブック上での実験トラッキング -](https://qiita.com/knt078/items/49a14a83c45f3f501ee7)
STL：mapの要素アクセス方法　at と operator[]

STL の`map`を使っていて頭に入れておくべきことがあったので、ここにメモしておきます。
`std::map`の指定キーに対応する要素の参照を返す（要素へアクセスする）方法は大きく2つあります。
さあ、あなたはどっち？

#map::at
1．存在しないキーを指定すると、`std::out_of_range`の例外を送出する
2．`const`な`map`にもアクセスできる
　　`map`をメンバ変数としていて、`const`メンバ関数の中で`map`の要素にアクセスする時に使える。
　　※`const`参照渡しでも同様

```例.
// mapにある要素の値を変数に代入したり
variable = map.at(key);

// ある値をmapにある要素に代入したり
map.at(key) = value;

// constなmap2を生成する
const std::map<key, value> map2(map);

// map2にある要素の値を変数に代入できる
variable = map2.at(key);
```

#map::operator[]
1．存在しないキーを指定すると、自動でデフォルト値の要素が追加され、その参照を返す
2．`const`な`map`にはアクセスできない

```例.
// mapにある要素の値を変数に代入したり
variable = map[Key];

// ある値をmapにある要素に代入したり
vector[Key] = value;

// constなmap2を生成する
const std::map<key, value> map2(map);

// コンパイルエラー
variable = map2[key];
```

#サンプルコード
「え？どゆこと？」
そう思ったあなた、是非ご自身の環境で以下のコードを試してみて下さい。

```sample.cpp
#include <iostream>
#include <map>
#include <stdexcept>

int main()
{
    // キー：文字列、値：intとしたmapを生成する. 
    std::map<std::string, int> sampleMap;

    // sampleMapに"John"をキーとした要素を詰める. 
    sampleMap.insert(std::make_pair("John", 5));

    // sampleMapに"Ken"をキーとした要素を詰める. 
    sampleMap["Ken"] = 10;

    std::cout << "###std::map::at" << std::endl;

    // at
    try
    {
        std::cout << sampleMap.at("John") << std::endl;
        std::cout << sampleMap.at("Ken") << std::endl;
        std::cout << sampleMap.at("Tom") << std::endl;

        // キーチェック時に例外を投げるため、この処理は実行されない. 
        std::cout << "Complete..." << std::endl;
    }
    catch (std::out_of_range& sampleException)
    {
        std::cout << "can't find the key!" << std::endl;
        std::cout << "Error : " << sampleException.what() << std::endl;
    }

    std::cout << std::endl << "###std::map::operator[]" << std::endl;

    // operator[]
    try
    {
        std::cout << sampleMap["John"] << std::endl;
        std::cout << sampleMap["Ken"] << std::endl;
        std::cout << sampleMap["Tom"] << std::endl;

        // キーチェック時に例外を投げず、自動追加されるデフォルト値が出力され、実行完了となる. 
        std::cout << "Complete..." << std::endl;
    }
    // キーチェック時に例外は投げない. 
    catch (std::out_of_range& sampleException)
    {
        std::cout << "can't find the key!" << std::endl;
        std::cout << "Error : " << sampleException.what() << std::endl;
    }

    std::cout << "End..." << std::endl;

    return 0;
}
```

```出力.
###std::map::at
5
10
can't find the key!
Error : invalid map<K, T> key

###std::map::operator[]
5
10
0
Complete...
End...
```

あ、`int`だとデフォルト値は0なのね。

#まとめ
`vector`とは異なり、存在しないキーに対応する要素へアクセスを、上記2つのどちらで行っても、未定義処理が行われることはありません。
若干用途が異なるので、どちらを使うかはケースバイケースでしょうかね。
ElasticBeanstalkにLaravelアプリケーションをリリースするときのebextension設定

Laravelをプロダクションでリリースするときには、configキャッシュやrouteキャッシュをすると、より効率的に実行されてアプリケーションのレスポンスが向上します。

ElasticBeanstalkにリリースする場合は、`.ebextensions/*`に.configファイルを置くことで、リリース時のコマンドを追加することが出来ます。

```yaml:.ebextensions/laravel_cache.config
container_commands:
  01-cache_config:
    command: "php artisan config:cache"
  02-cache_route:
    command: "php artisan route:cache"
  03-cache_view:
    command: "php artisan view:cache"
```

以上で、config、route、viewのキャッシュをアプリケーションをアップロードした後に生成することが出来ます。`container_commands`はApacheサーバーの再起動前に実行されます。
【メモ】tableを使わない表の作り方


tableを使用するととても綺麗な表ができるので多用していたのですが
safariで表示するとうまくいかないので**tableの卒業をここに宣言します！！**


横並びをfloatを使って実装するものが多くみられたんですけど
floatはあまり好きではないのでflexで。


--- HTML ---

```
<dl>
  <dt>タイトル</dt>
  <dd>内容</dd>
  <dt>タイトル</dt>
  <dd>内容が入ります。内容が入ります。内容が入ります。内容が入ります。内容が入ります。内容が入ります。内容が入ります。内容が入ります。内容が入ります。内容が入ります。文字の大きさ、量、字間、行間等を確認するために入れています。</dd>
  <dt>タイトル</dt>
  <dd>内容が入ります。</dd>
</dl>
```



--- CSS ---

```
dl{
  display:flex;
  flex-wrap: wrap;
  border: 1px solid #ccc;
  border-top: none;
}
dt{
  background: #ddd;
  width: 30%;
  padding: 10px;
  box-sizing: border-box;
  border-top: 1px solid #ccc; 
}
dd{
  padding: 10px;
  margin: 0;
  border-left: 1px solid #ccc;
  border-top: 1px solid #ccc; 
  width: 70%;
  box-sizing: border-box;
}
@media (max-width: 320px) {
  dl{
    flex-flow: column nowrap;
  }
  dt,
  dd{
    width: 100%;
  }
  dd{
    border-left: none;
  }
}
```


![スクリーンショット 2020-08-31 10.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693240/0a4bde1f-6cee-5922-4457-12a63dd315dd.png)


こんな感じの表の出来上がり！

dl,dd,dtを使用したところ、一応safariでも動いてくれているので満足です！！




かじちゃん。
Xcode tamplates の作り方

#### 一言で言うと

`~/Library/Developer/Xcode/Templates/File Templates`にテンプレートファイルを置いておくと、Xcodeでファイルを新規作成する時使える。

#### Clean Architecture用のテンプレートファイル
https://medium.com/swift2go/installing-the-clean-swift-template-in-xcode-6b4367006827

#### テンプレートファイル作成法

Xcodeに元からついてくるファイルテンプレートは、以下のフォルダに格納されているので参考にするといい。

`/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/`

https://medium.com/@popcornomnom/swift-tutorial-how-to-create-own-xcode-file-template-for-ios-and-macos-d2e535ed62c5
https://help.apple.com/xcode/mac/9.0/index.html?localePath=en.lproj#/dev7fe737ce0
USB3.0の特徴

応用情報技術者平成30年春期 午前問12

USB3.0の特徴として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/1ff9536e-0ed2-63d0-c69d-7899e5ec40ae.png)

１、USB3.0は、現在最も普及している周辺機器接続のためのシリアルインターフェイスのバージョン3に当たる規格です。
・USB2.0と比較して、最大転送速度がおよそ10倍になるなど様々な進化を遂げています。
・コネクタの形状はUSB2.0と同じですが、内部が青色になっているかどうかで識別可能になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5bee42b5-f6e3-9cfe-8d0c-566c5fbfc846.png)

・USB2.0までは半二重でしたが、USB3.0は完全な全二重通信を実現しています。

・Wireless USBは、無線通信で機器同士を接続する規格ですが、USB3.0ではWireless USBをサポートしていません

・最大供給電流は，USB2.0は、500ミリアンペアである。
　USB3.0のバスパワーによる最大供給電流は900mA（約80%増）に大幅増強されています。
　※USB1.1や2.0規格では電流500mA、電圧5V、電力2.5Wの供給が行え、USB3.0規格になると、電流900mA、電圧5V、電力4.5Wまで供給できます。

・ピン数は5本(USB2.0)から9本に増えましたが、ピン形状の工夫により後方互換性を保っているのでUSB2.0のケーブルも指すことができます。


２、全二重通信と半二重通信の違いについては、よく電話とトランシーバにたとえて説明されることがあります。

・電話では、通話者は互いに同時にしゃべったり、聞いたりすることができます。もっとも、人間では互いが同時にしゃべったままですと、話が進みません。このように両者が同時にしゃべったり聞いたりできる通信方式を、全二重（FULL DUPLEX）通信方式と言います。

・これに対して、トランシーバのように自分のしゃべりが終わるたびに、いちいち送信と受信の切り換えを行い、聞いている間はしゃべれず、しゃべっている間は相手の話を聞くことができないような通信方式を、半二重（HALF DUPLEX）通信方式と言います。

※トランシーバ (transceiver) とは、送信機 (transmitter) と受信機 (receiver) からなる造語で、電気通信やデータ伝送分野において電気信号の送受信を行う機器あるいは電子回路を指す。

参照：

https://www.ap-siken.com/kakomon/30_haru/q12.html

USB給電の基礎知識
https://www.pro.logitec.co.jp/houjin/usernavigation/hddssd/20191227/index.html#:~:text=%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%E3%81%AE%E3%83%9D%E3%83%BC%E3%83%88%E3%81%ABUSB%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E3%81%A0%E3%81%91%E3%81%A7%E7%B5%A6%E9%9B%BB%E3%81%8C%E5%8F%AF%E8%83%BD,-USB%E3%81%A7%E8%A1%8C&text=%E3%81%A1%E3%81%AA%E3%81%BF%E3%81%AB%E3%80%81USB1.1%E3%82%842.0,W%E3%81%BE%E3%81%A7%E4%BE%9B%E7%B5%A6%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

全二重通信と半二重通信方式
https://www.m-system.co.jp/mstoday/plan/mame/b_network/9602/index.html
メモリインタリーブ

応用情報技術者平成30年春期 午前問11

メモリインタリーブの説明として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e4e1fcde-85fe-e766-3e34-5c0e8e396b31.png)

１、メモリインタリーブは、　memory interleaving
物理上は1つである主記憶領域を、論理的な複数の領域(バンク)に分け、これに並列アクセスすることで見かけ上のアクセス時間の短縮を図るメモリアクセス高速化の手法です。分割する個数によってデュアルチャンネル(2分割)やトリプルチャンネル(3分割)といった呼ばれ方をすることもあります。

・interleave は「重ね合わせる」とか「多重化する」という意味があります。
ここは、interは内部だろうね、内部で、バンクごとで離れるで覚えしやすいかな。

２、キャッシュメモリと主記憶の同期を制御する方式の1つであるライトバック方式
新しい情報をキャッシュメモリに取り出すとき，キャッシュ上では不要になった情報を主記憶に書き込む。

・ライトバックwrite backとは、CPUと記憶装置の間で記録を一時的に保管するキャッシュメモリーの動作方式のひとつで、CPUが記憶装置にデータを書き込む際、いったんキャッシュメモリーにデータを書き込み、処理の空き時間ができてからキャッシュメモリーからメインメモリーに書き込む方式のことである。

キャッシュと記憶装置に同時にデータの書き込みを行うライトスルー方式に比べて、キャッシュが記憶装置よりも記憶動作が高速であるという特性を活かすことができ、動作が高速になるという長所があるが、キャッシュとメインメモリーとの間でデータが必ずしも整合するとは限らず、ライトスルー方式よりも制御が多少困難になるという短所もある。

３、ディスクキャッシュの説明
主記憶のアクセス時間と磁気ディスクのアクセス時間とのギャップを補う。

４、キャッシュメモリと主記憶の同期を制御する方式の1つであるライトスルー方式
主記憶の更新と同時にキャッシュメモリの更新を行う。

・ライトスルーwrite throughとは、
CPUと記憶装置の間で記録を一時的に保管するキャッシュメモリーの動作方式のひとつで、CPUが記憶装置にデータを書き込むと同時に、キャッシュメモリーにも同じ内容を書き込む方式のことである。

データをいったんキャッシュに書き込んでから順次記憶装置に書き込むライトバック方式に比べて、キャッシュと記憶装置との間でのデータが常に一致し、制御も容易であるという長所があるが、記憶装置よりもキャッシュの方が記憶動作が高速であるという特性を活かすことができないので、ライトバック方式よりもCPUの待ち時間が大きくなるという短所もある。


ーーーーーーーーーーーーーーーーーーー
補足
メモリインタリーブの目的として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d0fed1ac-5f6d-f10d-659e-fc0c66ebecc9.png)

１、メモリインタリーブは、物理上は1つである主記憶領域を、同時アクセス可能な複数の論理的な領域(バンク)に分け、これに並列アクセスすることで見かけ上のアクセス時間の短縮を図るメモリアクセス高速化技術です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/dcdb9cff-eb88-6082-4187-d3606bbdbc95.png)



参照：
interleave 
http://www.shunzei.com/lecture/words/memory_interleave.html

https://www.ap-siken.com/kakomon/23_aki/q10.html

ライトスルー
https://www.weblio.jp/content/%E3%83%A9%E3%82%A4%E3%83%88%E3%82%B9%E3%83%AB%E3%83%BC#:~:text=%E3%83%A9%E3%82%A4%E3%83%88%E3%82%B9%E3%83%AB%E3%83%BC%E3%81%A8%E3%81%AF%E3%80%81CPU,%E6%96%B9%E5%BC%8F%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82

ライトバック
https://www.weblio.jp/content/%E3%83%A9%E3%82%A4%E3%83%88%E3%83%90%E3%83%83%E3%82%AF


https://www.ap-siken.com/kakomon/28_aki/q10.html
edgeのdevtoolsを英語にする

# 概要
ある日、edgeのdevtoolsを開いたら日本語になっていたので英語にする方法を調べました。

# 設定方法
1. devtoolsの設定を開く
2. ブラウザーの言語に合わせる、からチェックを外す

# 解説
以前は `edge://flags` にローカライズを無効化する設定があったのでそちらで無効化していたのですがいつの間にかなくなっていました。
おそらくedge 85からなくなったようです。
ただ、changelog的な記事は見つけられませんでした。

# 参考
https://blogs.windows.com/msedgedev/2020/02/04/localizing-edge-devtools/
Π (パイ)、積の記号

#Π (パイ)

積の記号と呼ばれ、総乗(総積、Product)を表す。
ギリシャ文字の「P」を指す。
繰り返し数値を掛けて、合計を求める時に使用する。

```math
\prod_{k=i}^{n} a
```

1.「変数[$i$]」は「変数[$k$]」の初期値
2.「変数[$k$]」が「変数[$n$]」の値になるまで「数式[$a$]」の結果を繰り返し掛ける

```math
\prod_{k=i}^{n} a=\prod_{k=0}^{99} f(k)=result
```

```c
int n = 99;
int i = 0;
int result = 0;
for (int k = i; k <= n; k++){
    result *= f(k);
}
return result;
```



```math
\prod_{k=i}^{n} a=\prod_{k=1}^{100} 10=result
```

```c
int n = 100;
int i = 1;
int result = 0;
for (int k = i; k <= n; k++){
    result *= 10;
}
return result;
```

```math
\prod_{k=i}^{n} a=\prod_{k=3}^{15} (k^2+k)=result
```

```c
int n = 15;
int i = 3;
int result = 0;
for (int k = i; k <= n; k++){
    result *= (k * k) + k;
}
return result;
```

・以下のサイトを参考にさせていただきました。
[C# 統計･微分積分･線形代数への道 @0kuwa](http://1studying.blogspot.com/2017/09/c_90.html#kuw02)
Σ (シグマ)、和の記号

#Σ (シグマ)

和の記号と呼ばれ、総和(合計、Summation)を表す。
ギリシャ文字の「S」を指す。
繰り返し数値を足して、合計を求める時に使用する。

```math
\sum_{k=i}^{n} a
```

1.「変数[$i$]」は「変数[$k$]」の初期値
2.「変数[$k$]」が「変数[$n$]」の値になるまで「数式[$a$]」の結果を繰り返し足す

```math
\sum_{k=i}^{n} a=\sum_{k=0}^{99} f(k)=result
```

```c
int n = 99;
int i = 0;
int result = 0;
for (int k = i; k <= n; k++){
    result += f(k);
}
return result;
```

```math
\sum_{k=i}^{n} a=\sum_{k=1}^{100} 10=result
```

```c
int n = 100;
int i = 1;
int result = 0;
for (int k = i; k <= n; k++){
    result += 10;
}
return result;
```

```math
\sum_{k=3}^{15} (k^2+k)=\sum_{k=3}^{15}k^2 +\sum_{k=3}^{15}k
```

```c
int n = 15;
int i = 3;
int result = 0;
for (int k = i; k <= n; k++){
    result += (k * k) + k;
}
return result;
```

```c
int n = 15;
int i = 3;
int result[2] = { 0, 0 };
for (int k = i; k <= n; k++){
    result[0] += (k * k);
}
for (int k = i; k <= n; k++){
    result[1] += k;
}
return (result[0] + result[1]);
```

```math
\sum_{k=0}^{99} 2k=2\sum_{k=0}^{99}k
```

```c
int n = 99;
int i = 0;
int result = 0;
for (int k = i; k <= n; k++){
    result += 2 * k;
}
return result;
```

```c
int n = 99;
int i = 0;
int result = 0;
for (int k = i; k <= n; k++){
    result += k;
}
return (2 * result);
```

・以下のサイトを参考にさせていただきました。
[C# 統計･微分積分･線形代数への道 @0kuwa](http://1studying.blogspot.com/2017/09/c_90.html#kuw01)
[Terraform] Windows機でAzureリソースを構築しようとするとtimeoutになるのでDockerで解決

# 何が起こったのか
Windows機で Terraform を利用して Microsoft Azure のリソースを構築しようとしたところ、`terraform plan` が Timeout する。

```
C:\path\to\terraform> terraform plan

Error: timeout while waiting for plugin to start
```

# 原因
issue が挙がっていました。
[Error: Failed to instantiate provider "azurerm" to obtain schema: timeout while waiting for plugin to start](https://github.com/hashicorp/terraform/issues/25133)

Windows で TREND MICRO 製品（ウイルスバスター等）を使っている場合に発生するということですかね。
そして golang に原因があり、Terraform 側での対処ではない、と。

# 解決方法（回避方法）
「mac/linux を調達する」「ウィルスバスターを切る」などの対応を取れるのであればそれでもいいのかもしれませんが、私の場合はそうではなかったので。
Windows機で Linux ベースの Docker コンテナを動かし、そこで Terraform を実行することにします。

## ファイル等の準備
### フォルダ構成
```
your-folder-name/
 ├─ docker/
 │   └─ Dockerfile
 ├─ terraform/
 │   ├─ aaa.tf
 │   ├─ bbb.tf
 │   └ ...
 └─ docker-compose.yml
```

### Dockerfile
```dockerfile
FROM alpine:3.7

ARG terraform_version="0.13.1"

# install terraform.
RUN wget https://releases.hashicorp.com/terraform/${terraform_version}/terraform_${terraform_version}_linux_amd64.zip && \
    unzip ./terraform_${terraform_version}_linux_amd64.zip -d /usr/local/bin/

# set time-zone=JST
RUN apk --update add tzdata && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata && \
    rm -rf /var/cache/apk/*

# create workspace.
COPY ./terraform /root/terraform

# move to workspace
WORKDIR /root/terraform

```

### docker-compose.yml
```yml
version: "3"
services:
  terraform:
    container_name: "terraform"
    image: local/terraform
    build:
      context: ./
      dockerfile: docker/Dockerfile
    volumes:
      - ./terraform:/root/terraform

```

## 実行
```bash
# Dockerイメージをビルド。初回だけでOK。
> docker-compose build

# コンテナ起動＆ログイン
> docker-compose run --rm terraform

### 以降は、Dockerコンテナの中での作業になる。

# Terraform を実行
$ terraform init
$ terraform plan
$ ...

# 終了時。Dockerコンテナから抜ける。
$ exit

```

これで解決（回避）できました。
初心者がgemをインストールする前に知っておいた方がいいこと

Railsで開発する際は必ずbundlerでgemを管理するようにする。


#  `gem install Gem名` でGemをインストールした場合は全部グローバルに入る。

これ重要。Qiitaでもよく`gem install Gemの名前`でインストールして～なんて記事を見かけるがこのコマンドだとbundlerで管理できていないためバージョン管理を自分でしないといけなくなる。
bundlerで管理するなら`gemfileの中に記載してbundle install`をする。



# bundlerの使いかた
```
bundle install
```
だとグローバルにGemがインストールされる。
ただ、複数アプリで同じGemがインストールされたとしても各アプリが必要としてるバージョンのGemはそれぞれインストールされます。(アップデートされる複数バージョンが共存)

ちなみに

```
bundle install --path=Gemをインストールしたいパス
```

ってやれば指定したパスにGemがインストールされるので、グローバルのGemは汚染されない。
でもこの `path` オプションは廃止予定で、

```
bundle config set path 'Gemをインストールしたいパス'
```

で事前にパスを指定しておくようになった。

BundlerでGemをインストールする時のパスはRailsアプリのディレクトリ内の `vendor/bundle` が一般的。

`--path` と `bundle config set path` についてはここ参考
https://qiita.com/devzooiiooz/items/8babd82f780f01812f9d

「そもそもインストール先を指定する必要ある？」っていう意見もある
https://qiita.com/jnchito/items/99b1dbea1767a5095d85



# Rubyだけで何かCLIアプリを作る場合
Bundlerを使っても使わなくてもOK。(Bundler使う場合は自分でGem install bundlerしないといけない)
[Web開発] 最新フロントエンドチートシート(Cheat Sheet)まとめ

# はじめに

技術があふれるフロントエンド分野 JavaScript、Angular、React、Vue、GraphQLなど、すべての記述の文法を覚えることはできません。 
必要なたびに探して使わなければならないのが現在フロントエンド開発の現実です。
それなら、上記の技術文法すべてを1か所で見られたらどうでしょうか？ 
全体的な文法が一目で簡単に見れる良質の資料があるので共有します。
それでは今日も楽しいコーディング！

## JavaScript ES2015

![JavaScript ES2015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/ad478f17-fa2c-2f7e-2eb2-c1ff2d9b49de.png)

https://devhints.io/es6

## JavaScript

![JavaScript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/f99ba093-90f5-715d-63d6-4999318766d6.png)

http://overapi.com/javascript

## JavaScript正規表現式

![JavaScriptRegex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/1e327cd7-74f5-7a97-72b7-35dcfc5e60ba.png)

https://www.debuggex.com/cheatsheet/regex/javascript

## React

![React.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/d2fe65e7-fced-658b-710d-7b783796a582.png)

https://devhints.io/react

## Redux

![Redux.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/2a830fea-dfbb-3a69-7df0-e292440c3d72.png)

https://github.com/linkmesrl/react-journey-2016/blob/master/resources/egghead-redux-cheat-sheet-3-2-1.pdf

## Vue.js

![Vue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/499def78-8ab5-5e00-bbde-584b3d7d3f86.png)

https://vuejs-tips.github.io/cheatsheet/

## Vuex

![Vuex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/7ac2ac5a-e2e1-1bd5-6372-b4010fc420b5.png)

https://vuejs-tips.github.io/vuex-cheatsheet/

## Angular4

![Angular4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/22cbbb18-2a8b-616c-9a0b-27e734c7dc16.png)

https://angular.io/guide/cheatsheet

## Flexbox

![Flexbox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/b47a8370-a2b4-01e3-12b5-70451e9fa296.png)

https://yoksel.github.io/flex-cheatsheet/

## SCSS

![SCSS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/f55330c3-678b-50bf-2442-09c952ee1804.png)

https://devhints.io/sass

## Stylus

![Stylus.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/2803121a-502c-dccc-4e81-1e47d95e31e3.png)

https://devhints.io/stylus

## GraphQL

![GraphQL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/ead474af-8064-a1c1-9b54-9cf676d1fbcd.png)

https://raw.githubusercontent.com/sogko/graphql-shorthand-notation-cheat-sheet/master/graphql-shorthand-notation-cheat-sheet.png

# 備考

* 特にありません。
Gutenbergで「グループ化」が表示されない問題のしょうもなさすぎる原因

Wordpress5.3.2でブロックを複数選択するとグループ化が行えるはずだが、なぜか「グループ化」が表示されない。

原因がよくわからず、期待を込めてWordpress5.5にアップデートしてみたけどやっぱりだめ。
もしやと思ってプラグインを停止してみてもやっぱりだめ。

調べても同じエラーが発生している情報が見当たらず、こうなったら無理やりfunction.phpに何か書いてやろうとファイルを開いてみたら

```php:function.php

//ブロックエディタの設定　表示するもの
add_filter( 'allowed_block_types', 'custom_allowed_block_types' );
function custom_allowed_block_types( $allowed_block_types ) {
 $allowed_block_types = array(
 // 一般ブロック
 'core/paragraph', // 段落
 'core/heading', // 見出し
 'core/image', // 画像
 'core/quote', // 引用
 'core/list', // リスト
 'core/file', // ファイル
 'core/video', // 動画

 // フォーマット
 'core/table', // テーブル

 );
 return $allowed_block_types;
}

```
**こんなん書いてた！！！**

**そりゃ表示されないわ・・・**

そういや当初クライアントサイドで管理するということで、機能を絞ったんだった。
ブロックマネージャーはあるけど、ユーザー毎に設定する必要があるからfunction.phpに書いたのすっかり忘れてた。

##$allowed_block_typesを書くと、それ以外の機能は表示されない
アップデートしても当然同じ。
そんな当たり前の、お粗末すぎる結末だけど、世の中広いのでひょっとしたら同じ事でハマってる人がいるかもしれないので記事に残してみました。
おしまい。

【2020/9/2追記】
解決策を書くの忘れてた。
function.phpの上記部分を削除（コメントアウト）して解決です。
これまた当たり前ですが、一応ね。
Google スプレッドシートを csv でダウンロード

次のようなデータを csv でダウンロードする方法です。
![gsheet_aug31_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/52ef1ae8-5331-11c5-6e83-a14262c19ed9.png)

共有の設定を次のようにします。
>このリンクを知っているインターネット上の全員が閲覧できます
![gsheet_aug31_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/687cc1a4-817f-c11b-eedb-c447ef7ca110.png)

ダウンロードコマンド

```bash:go_get.sh
SPREADSHEET_ID="1D1hk5LH6O3BlFehaBgnzfGtbcr*****"
#
wget -O data.csv "https://docs.google.com/spreadsheets/d/"${SPREADSHEET_ID}"/export?gid=0&format=csv"
```

次のような　csv がダウンロードされます。

```csv:data.csv
,,,
Sep/20/2016,茨城県,筑西市,下館図書館
Sep/21/2016,栃木県,栃木市,栃木図書館
Sep/22/2016,茨城県,結城市,ゆうき図書館
Sep/23/2016,茨城県,筑西市,下館図書館
Dec/23/2016,茨城県,結城市,ゆうき図書館
Dec/24/2016,栃木県,栃木市,栃木図書館
Jan/17/2017,栃木県,宇都宮市,南図書館
```
【学習備忘録】vim入門

#vimとは

vimとはテキストエディタの1つである。
一般的なテキストエディタと違い、VimはCUI、キーボードのみで操作されることを前提としていたため、キーボードのみですべての操作が可能になっている。その基本的な操作方法はviと同じで、状況に応じてモードを使い分けることでテキストを編集していき、小さなコマンドの組み合わせをその場で作ることによって多種多様な機能を実現できます。


#vimで使用するコマンド

vimはviから派生したテキストエディタであるので、主にLinuxのコマンドを使用する。

**基本的なコマンド**
起動した状態をはノーマルモードです、その状態から <font color="Red">「i」</font> を入力すると入力モードに切り替わります。
入力モードから <font color="Red">「esc」</font> を入力すると、ノーマルモードに戻ります。

Vimを終了するには<font color="Red">「:」</font> を入力してしてコマンドラインモードに切り替えてから<font color="Red">「q」</font> を入力してエンター。これで終了できます。

変更点を無視して終了したい場合は<font color="Red">「:q!」</font> と入力する。!をつけると変更を無視して終了できます。
Vimを使用してファイルを書き換えて保存する場合、:の後に<font color="Red">「wq」</font> と押すことで保存して終了することができる。
なお、:wだと保存されてVimは終了しない。
ファイル名を変えて上書き保存したいときは:wの後に、変更したいファイル名を続ければ変更かつ保存できます。

**移動系のコマンド**
ノーマルモードで、<font color="Red">「gg」</font>と入力すると一番先頭に移動する。逆に1番下に移動したいときは<font color="Red">「G」</font>と入力することですぐに移動できる。

<font color="Red">「^」</font>を入力すると行頭に移動できます。逆に<font color="Red">「$」</font>を入力すると行末に移動することができます。

**検索・置換コマンド**
ノーマルモードで<font color="Red">「/」</font>を入力した後に、検索したい単語を入力してエンターを押すと、その単語の位置に移動してくれます。

:でコマンドモードに切り替えます。<font color="Red">「s」</font>その後に続けて<font color="Red">「/」</font>と行内にある置換したい単語や文字を入力します。またその後に続けて/と変更後の文字や単語を入力します。
この場合だと一番最初にマッチした文字しか置換されません。行内にあるマッチした１番目以降の文字もまとめて置換したい場合は後に続けて/と<font color="Red">「g」</font>を入力します。
例):s/a/A/g　「a」をすべて「A」に置換

**取り消しコマンド**
<font color="Red">「u」</font>を入力すると元に戻ります。uを押す前の処理後の状態にしたい場合は、control + rで状態を変えられます。

#感想
vimはコマンド操作で扱うエディタなので、最初はとっつきにくく、敷居が高いなと思っていましたが、
説明を聞くと思ったよりは複雑ではなく使いこなせると便利だなという印象を受けました。
また仕事でviを使うことがるので、それに通ずるコマンドをいろいろ学ぶこともできました。

標準のエディタであるにも関わらず高性能で挙動も軽く、どの環境でも使用できるので慣れてしまうと他のエディタには戻れないという話を聞いたので、是非使いこなせるようになりたいです。
NAND型フラッシュメモリ、NORフラッシュメモリ

応用情報技術者平成30年春期 午前問10

NAND型フラッシュメモリに関する記述として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/93cfccc2-c0e5-fd8f-ef12-aa4b4b9f76ec.png)

１、フラッシュメモリは、
・電気的に書き換え可能であり、
・電源を切っても記憶内容が消えない不揮発性のメモリです。

２、NAND型フラッシュメモリは、
・USBメモリやSDカード及びSSD等の記憶媒体として使われているタイプで、
・NOR型フラッシュメモリよりも集積度に優れ、安価に大容量化できる特徴があります。

３、NAND型フラッシュメモリでは、
・データの書込み及び読出しはページ単位、
・データの消去はブロック単位（ページを複数まとめた単位）で行います。

４、NOR型フラッシュメモリと違い
NAND 型は
・データの書き込みが速く、
・ページ単位で書込み及び読出しを行う
・ランダムな読み出しが低速である
・主に「データストレージ」としての利用に適する
・PCやスマートフォン、デジタルオーディオプレーヤー、デジタルカメラなどの記憶媒体として使っている
・回路が小規模で高集積化が比較的容易であるため、容量あたりの単価が低く、大容量のデータ保存に向いています。そのため、先に挙げた電子機器とのデータ移動によく使用されるUSBメモリやSDカード、ノートPCなどに搭載されているSSDにもNAND型フラッシュメモリが採用されています。

NOR 型は
・比較的読み出し処理が高速
　※NAND型フラッシュメモリがデータへ端から順にアクセスする(シーケンシャルアクセス)のに対し、NOR型フラッシュメモリでは、データのある場所がわかっていればそこに直接アクセス(ランダムアクセス)できます。
・NOR型は高集積化には向いておらず、容量あたりの価格はNAND型よりも高価になってしまいます。
・NOR型フラッシュメモリではプログラムをメインメモリ(RAM)にコピーすることなく直接実行できるという特徴も持ちます
・こういった理由から、NOR型フラッシュメモリは、ルータ、プリンタ、デジタルカメラ、GPS、車載機器、携帯電話などの、HDDが使用できない環境で、制御プログラムを保存、実行するための記憶装置として使用されています。

・読み込みが早く、信頼性が高い。１バイト単位で書込み及び読出しを行う。


https://www.fujitsu.com/jp/group/fsm/documents/products/find/19-1j-13.pdf
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/2d175094-b9de-10b3-90ea-548e1eb49c6c.png)


-------------------------------------------
補足
フラッシュメモリに関する記述として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e72fd98d-8a52-d8c7-e0c2-47328f34fd41.png)

１、フラッシュメモリは、電気的に書き換え可能であり、電源を切ってもデータが消えない半導体メモリ です。区分的にはEEPROM(Electrically Erasable Programmable ROM)の一種ですが、1バイト単位の書込みを行う従来のEEPROMとは異なりブロック単位での書き換えを行います。

２、
・高速に書換えができ，CPUのキャッシュメモリなどに用いられる。
⇒SRAM(Static RAM)の説明です。

・紫外線で全内容の消去ができる。
⇒UV-EPROM(紫外線消去型EEPROM)の説明です。

・周期的にデータの再書込みが必要である。
⇒DRAM(Dynamic RAM)の説明です。

・ブロック単位で電気的に内容の消去ができる。
⇒フラッシュメモリの特徴です。
　※ブロック単位：ページを複数まとめた単位


参照：
https://www.ap-siken.com/kakomon/30_haru/q10.html#:~:text=%E3%83%95%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%AF%E3%80%81%E9%9B%BB%E6%B0%97%E7%9A%84,%E5%8C%96%E3%81%A7%E3%81%8D%E3%82%8B%E7%89%B9%E5%BE%B4%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

http://fast-macro.com/Johosyori/h30HaruOuyou/h30HaruOuyou-10.html

NAND型フラッシュメモリとは
https://news.mynavi.jp/article/20200331-1007032/


https://www.ap-siken.com/kakomon/28_aki/q21.html
【覚書】webpackでバンドルしたjs内のfunctionをhtmlから呼ぼうとしてnot definedとなったら

```source.js
//(省略)

const hoge = () => {
    console.log("htmlから呼んだでー")
}

//(省略)
```

上記jsソースをwebpackでバンドルすると`bundle.js`が生成されるものとします。

```caller.html
<!--(省略)-->

<script src="bundle.js"></script>

<!--(省略)-->

<a href="#" onclick="hoge">htmlから呼ぶでー</a>

<!--(省略)-->
```

こんな感じで書いておくと、`not defined`のエラーが出てしまいます。
なぜなら、`source.js`で定義した`hoge`という名前は、バンドル後の`bundle.js`では別の名前（アルファベット1文字とか）になってしまっているからです。

これを解決するには、次のように**html側ではなくjs側でonclick属性を指定する**と良いでしょう。
便宜上、jQueryを使用した例で記述します。

```source.js
//(省略)

const hoge = () => {
    console.log("htmlから呼んだでー")
}

//追加
$("#caller").on("click", hoge);

//(省略)
```

これに対応してhtml側も変更します。

```caller.html
<!--(省略)-->

<script src="bundle.js"></script>

<!--(省略)-->

<!-- onclickを削除して、js側から特定するためのidを追加 -->
<a id="caller" href="#">htmlから呼ぶでー</a>

<!--(省略)-->
```

html側にonclickをどうしても書きたい場合、グローバルに定義する方法もあります。
下記の記事を参照してください。

[webpackでビルドしたbundle.jsの関数をonclickで動かしたかった話。](https://qiita.com/HiA/items/4ee716212e4121681526)
[【メモ】webpack環境下においてonclickで関数が発火しなかった件](https://qiita.com/ketabawo/items/b9ef093c5ee6e9891297)
CISC、MIMD、RISC、VLIW

応用情報技術者平成30年春期 午前問9

プロセッサの高速化技法の一つとして，同時に実行可能な複数の動作を，コンパイルの段階でまとめて一つの複合命令とし，高速化を図る方式はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/3d587bec-6982-80ca-8ca4-670bcdd83c4b.png)

１、VLIW(Very Long Instruction Word)とは、
プログラムのコンパイル時に依存関係のない複数の命令を1つの複合命令にまとめ、同時に実行させる手法です。「very long」の名が示すように1つの命令がとても長くなります。

通常のパイプライン処理では、命令の依存関係などをCPUが判断しながら実行していきますが、
VLIWでは、
・あらかじめ並列動作が可能な状態になっているので、CPU処理のオーバーヘッド減少と高速化が望めます。
・ただし、ソースコードからプログラムを作成するコンパイラの設計はその分難しくなります。

２、CISC
Complex Instruction Set Computerの略。複雑で多機能な命令セットでコンピュータを構成する設計方法です。
複雑命令とは１つの命令が一連の複雑な処理を実行する方式です。CISCは、いろいろな処理をできるだけ少ない命令回数で済ませることで、マイコンのパフォーマンスを上げる演算方式といえます。

３、MIMD
Multiple Instruction, Multiple Dataの略。複数の命令とそれに対応するデータを、それぞれが独立している複数のプロセッサに振り分けて並列処理をする方式です。
MIMD型のマシンは、独立して機能する複数のプロセッサを持つ。
複数のプロセッサーを持つコンピューターにおいて、プロセッサーがそれぞれ個別の命令を並列に実行させることで、データの処理の流れも複数になる方式。

４、RISC
Reduced Instruction Set Computerの略。CPUに与える命令を短く固定長化し、専用の論理回路で高速に実行できるようにした命令セットでコンピュータを構成する設計方法です。
縮小命令は１つの命令が簡単な処理しか行わない命令です。ですが、簡単な命令の分、1つ1つの命令は高速に実行されます。RISCは、複数の縮小命令を高速に実行することで、トータルでマイコンのパフォーマンスを上げるという演算方式となります。


---------------------------------
補足
プロセッサの実行効率を上げる，VLIWの説明はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/4f436afe-f0ae-381f-4663-548cb4afdd07.png)

１、
・依存関係のない複数の命令を，プログラム中での出現順序とは異なる順序で一つずつ実行する。
⇒複数の命令を１つにまとめパイプラインで同時に実行します。

・各命令フェッチ，デコード，実行，演算結果の出力などの各段階を並列に処理する。
⇒パイプライン処理の説明です。

・同時に実行可能な複数の動作をまとめて一つの命令として，同時に実行する。
⇒VLIWの説明です。

・複数のパイプラインを用いて複数の命令を同時に実行させる。
⇒スーパースカラの説明です。　superscalar

参照：
https://www.ap-siken.com/kakomon/30_haru/q9.html

CISCとRISC、何が違う？
https://ednjapan.com/edn/articles/1404/07/news001.html#:~:text=CISC%EF%BC%88%E3%82%B7%E3%82%B9%E3%82%AF%EF%BC%89%E3%80%81RISC%EF%BC%88,%E3%82%92%E7%95%A5%E3%81%97%E3%81%9F%E8%A8%80%E8%91%89%E3%81%A7%E3%81%99%E3%80%82

MIMD
https://kotobank.jp/word/MIMD-9157

https://www.ap-siken.com/kakomon/28_aki/q11.html
TypeScriptの型定義パッケージ（@types/~）はどのバージョンをインストールすればいいのか

Node.jsで管理されたTypeScriptプロジェクトでは、外部ライブラリとしてnpmパッケージを使用することができます。
パッケージ自体がTypeScript用の型定義ファイルを提供していればいいのですが、残念ながら提供していないことがままあります。
その場合でも、[DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)というリポジトリで管理されている`@types/<package-name>`という型定義パッケージが公開されていれば、それを使うことができます。
さて、この型定義パッケージはどのバージョンをインストールすればいいのでしょうか。

## 問題

今、TypeScriptプロジェクトにおいて`<package-name>`パッケージをインストールしようとしています。
`<package-name>`パッケージは、次のバージョンが公開されています。

- `1.0.0`
- `1.0.1`
- `1.1.0`
- `2.0.0`

また、このパッケージに対応する`@types/<package-name>`パッケージは、次のバージョンが公開されています。

- `1.0.0`
- `1.0.1`
- `1.1.0`
- `2.0.0`

`<package-name>`パッケージの`1.0.0`バージョンをインストールしたい場合、`@types/<package-name>`パッケージはどのバージョンをインストールすべきでしょうか。

## 解答

`<package-name>`パッケージの`1.0.0`バージョンをインストールしたい場合、`@types/<package-name>`パッケージは`1.0.x`バージョンの最新版である`1.0.1`バージョンをインストールします。

```sh
$ npm i -D @types/<package-name>@1.0.1
```

または、パッチバージョンを省略して自動的に`1.0.x`バージョンの最新版をインストールします。

```sh
$ npm i -D @types/<package-name>@1.0
```

## 解説

DefinitelyTypedで管理されている型定義パッケージのバージョンは、[Semantic Versioning](https://semver.org/)におけるメジャーバージョンとマイナーバージョンのみを本体のパッケージに合わせるようになっています。

>This is because only the major and minor release numbers are aligned between library packages and type declaration packages.

出典：[DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.](https://github.com/DefinitelyTyped/DefinitelyTyped#how-do-definitely-typed-package-versions-relate-to-versions-of-the-corresponding-library)

`x.y.z`バージョンに対する型定義パッケージのバージョンは`x.y.0`から始まり、`x.y.1`、`x.y.2`のようにアップデートされていきます。

>The patch release number of the type declaration package (e.g. .0 in 10.12.0) is initialized to zero by Definitely Typed and is incremented each time a new @types/node package is published to NPM for the same major/minor version of the corresponding library.

出典：[DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.](https://github.com/DefinitelyTyped/DefinitelyTyped#how-do-definitely-typed-package-versions-relate-to-versions-of-the-corresponding-library)

したがって、`@types/<package-name>`パッケージは`1.0.x`バージョンの最新版である`1.0.1`バージョンをインストールすればいいというわけです。

## 参考リンク
- [DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.](https://github.com/DefinitelyTyped/DefinitelyTyped)
「実践Rustプログラミング入門」に入門する(1日目)

[「実践Rustプログラミング入門」,初田直也他,秀和システム,2020](https://www.shuwasystem.co.jp/book/9784798061702.html)を参考に,Rustでの開発を体験する。

# Section2-2 開発環境を構築する(p.29)
[rustup-init.exe](https://rustup.rs/)を実行するだけ。
# VSCodeをインストールする。
今回使用したのは[VSCodeUserSetup-x64-1.48.2.exe](https://code.visualstudio.com/download)。
実行するだけでインストール終了。
# VSCode Extensionをセットアップする。
p.34に「rust-analyzer」の設定に関する話があるが、
VSCodeから今回は「Rust0.7.8」をインストールするだけで、シンタックスハイライト、関数名チェックなどを行ってくれる様子。

間違えている箇所を即座に指摘してくれる。
![vscode_20200831_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059/b747640e-4ade-6154-2dab-9f607394d9bf.png)
[AWS]Amazon Comprehendを使って、自然言語処理をしてみた。

## サービス概要

　Amazon Comprehend は、機械学習を使用してテキスト内でインサイトや関係性を検出する自然言語処理 (NLP) サービスです。
[https://aws.amazon.com/jp/comprehend/](https://aws.amazon.com/jp/comprehend/)
自然言語処理については、クラスメソッドさんの動画がわかりやすかったです。

### テキスト分析ってどんなことできるの？（日本語対応している機能）
- テキストから出現頻度の多いキーワード（名称）を抽出できる。
- テキストの感情分析ができる。
- 言語を判定できる（日本語、英語など）

## **使ってみた**
1.AWSのマネジメントコンソールの検索画面からサービス画面にアクセスしてください。
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/f9f9f033-aa57-f60c-b41b-08384d6aafc9.png)


2.`Launch Amazon Comprehend` を押下 
![Untitled 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/00c48adf-e7a2-160d-4735-94664a63e6b4.png)


3.サンプルで入っている文字は削除！好きな文字を入力！！
※今回は例として以下を入力（ウィキペディアのAWSのページから引用）

```markdown
Amazon Web Services（アマゾン ウェブ サービス、AWS）とは、Amazon.comにより提供されているクラウドコンピューティングサービスである。ウェブサービスと称しているが、ウェブサービスに限らない多種多様なインフラストラクチャーサービスを提供している。これらのサービスは全世界で22の地理的リージョンで提供されている（2019年9月現在、利用に制約のあるリージョンを含む）。AWSの有名なサービスにAmazon Elastic Compute Cloud (EC2) とAmazon Simple Storage Service (S3) がある。各組織が独自に保有し、仕様変更には長時間の物理的な作業を必要とするサーバファームと比較して、AWSは需要に応じた計算能力を、設定変更のみで速やかに提供出来ることが強みである。クラウドの分野でのAWSの世界的シェアは33％前後で世界1位である[1]。世界的シェア13%前後で世界2位のMicrosoft Azureを大きく引き離している。
```

4.`Analyze` を押下
![Untitled 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/6037b4a4-cca2-76d1-0e0d-7a4c8ed1d538.png)


5.結果はすぐにページ下部に表示され、タブで各種分析結果を確認できるようになります。
**Entities**（カテゴリーとキーワードが抽出されます)
![Untitled 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/53af8651-8dc6-810f-ae1d-72f8e0729a0e.png)


**Key Phrases（フレーズ？）**
![Untitled 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/fdd12594-c968-367f-7817-e34a521aeabd.png)


**Language**（言語）
![Untitled 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/2efd96c7-8449-533b-f922-94408f635029.png)


**Sentiment**(感情分析)
![Untitled 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550295/4b7fdbab-e630-084c-f2d4-454f7fbf1bca.png)


## どんなことに利用できそうか？
例えばWEBアプリケーションで、CURD機能のあるものだとすると以下の機能を作るために使えそうだなと思いました。

- 掲示板、レビュー、コメント欄等の攻撃的な発言の非表示（荒らし対策）
- ニュース、ブログ、SNSでの関連表示のために利用する。
- 文章をテキスト分析して、タグなどを自動生成する。

## 最後に

今回は、マネジメントコンソールから利用したが、他のサービスorアプリと連携させるためには、S3経由で、テキストをcomprehendに食わせる必要があります。
MapKitで地図を表示する

シンプルにコードから地図を表示します。

<img width="380px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/e84a52f2-165b-49d2-9e1b-661dfc59d922.jpeg">

## ソースコード

```swift:MapViewController
import UIKit
import MapKit

final class MapViewController: UIViewController {

    private let mapView: MKMapView = {
        let mapView = MKMapView()
        mapView.translatesAutoresizingMaskIntoConstraints = false
        return mapView
    }()

    fileprivate func setupUI() {
        view.addSubview(mapView)
        mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        mapView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        mapView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        mapView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
    }

    override func viewDidLoad() {
        setupUI()
    }
}
```
mapkitをimportします。


```swift:呼び出し元
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let scene = (scene as? UIWindowScene) else {
            return
        }
        let window = UIWindow(windowScene: scene)
        self.window = window
        window.makeKeyAndVisible()

        let vc = MapViewController()
        window.rootViewController = vc
    }
・・・
}
```


## 参考
https://developer.apple.com/documentation/mapkit
plantuml vscode で表示

# plantuml vscode で表示したい
- Java SDKのインストール
- Markdown Preview Enhancedのインストール
- やり方

## Java SDKのインストール
https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/7babea58-1bd5-f9c6-911e-a681aa161dd6.png)
対応のSDKを選択してインストール

## Markdown Preview Enhancedのインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/0b385bc1-9ac3-c2d4-039a-fcd5ef68b07e.png)
インストール後VSコードの再起動

## やり方
対象コードで、右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/8ad1a67b-07d0-4f99-8c68-5064997e714e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/4eafe8b9-5764-dcbd-d676-6d2c851b8a9e.png)
こんな感じで表示されます。
オーバーライド、オーバーロード、カプセル化、汎化

応用情報技術者平成30年春期 午前問7

オブジェクト指向プログラミングにおいて，同一クラス内に，メソッド名が同一であって，引数の型，個数又は並び順が異なる複数のメソッドを定義することを何と呼ぶか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/a886044f-dc4d-6351-f27e-a1a541c947a3.png)

１、オーバーライドは、　overwrite
スーパークラスで定義されたメソッドをサブクラスで再定義することです。

２、オーバーロードは、 overload
あるクラス内で引数や型が異なる同じ名前のメソッドを定義することです。

３、カプセル化は、 encapsulation
オブジェクト内の詳細な仕様や構造を外部から隠蔽することです。

４、汎化は、
複数のクラスの共通する性質をまとめて，抽象化したクラスを作ることです。
共通の親クラス（＝スーパークラス）です。

参照：
https://www.ap-siken.com/kakomon/30_haru/q7.html
複数サーバから一括ファイルコピー(windows  .bat)

#【概要】
備忘録。
svlist.txtにコピーしたいファイルのあるサーバーのアドレス。
日付つけたい場合%YYYYMMDD%を使用。

##【コード】
set SCR_DIR=%~dp0
set YYYYMMDD=%DATE:/=%

if not exist log mkdir log

FOR /F %%A IN (%SCR_DIR%svlist.txt) DO (
	net use \\%%A\IPC$ <パスワード> /user:<ユーザー名>
	pushd \\%%A\d$\temp_r\log
	copy 〈コピーするファイルパス〉　〈コピー先ファイルパス〉　
	popd
)
【rails】バリデーションとは

#バリデーションとは？
オブジェクトがDBに保存される前に、そのデータが正しいかどうか検証する仕組みをバリデーションと呼ぶ。
例えば、メールアドレスを入力して欲しい場合、メールアドレス以外が入ったものが送られた時、DBに保存しないようにする。

使い方の構文
validates :指定した属性またはオブジェクトorカラム名, バリデーションヘルパー: 

例
```
validates :title, presence: true
```

```
validates :category, acceptance: true
```

```
validates :title,    length: { minimum: 1 }       # 「1文字以上」
validates :title,    length: { maximum: 75 }      # 「75文字以下」
validates :title,    length: { in: 1..75 }        # 「1文字以上75文字以下」
validates :password, length: { is: 8 }            # 「8文字のみ」
```

バリデーションヘルパーの種類
・presence
空でないかを検証
・absence
からであるかを検証
・uniqueness
値が唯一であり、重複していないかを検証（メアドの入力等で使える）
・acceptance
チェックボックスがオンになっているかどうか検証（同意した。のチェックの際に使っている）

他にもバリデーションヘルパーはある。
そのほかはこちらを参照
https://pikawaka.com/rails/validation

#エラーメッセージの表示方法

バリデーションを設定すると、設定したバリデーションヘルパーがture or falseの状態で正しいく入力されているかどうか判断することができるが、
これだけでは、ユーザーが間違って情報を入力した場合、なぜ間違っているのか認識することができない。
→エラーメッセージを設定する必要がある。

エラーメッセージを設定する構文 例userモデルの場合
```
<% if @user.errors.any? %>
  <div id="error_explanation" class="alert alert-danger">
    <ul>
      <% @user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>
```

上記では、まずエラーがあったか確認をしている。
errors.full_messagesは
全てのエラーメッセージを配列で自動的に取得している
複数のメッセージが格納されていることもあるので、全て表示するには each でループで回す。


#エラーメッセージの日本語化
このままの設定では、エラーメッセージが英語になってしまう。
メッセージを日本語化するには、
rails-i18n
と言うgemを使用する。

順序としては、
①　gem file　に'rails-i18n'を追加し、bundle install
②　config/application.rb内に　config.i18n.default_locale = :ja　
③　その後、サーバーを起動すると、エラーメッセージの一部が日本語化されているが、email、nameのようなカラムは日本語化されていない。

そこでカラム名を日本語化していきましょう。config/localesないにja.ymlを追加し以下を入力してください。

```
ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
      user:
        name: 名前
        email: メールアドレス
```
GoでPDFを画像に変換する

# はじめに

Go で PDF ファイルを１ページずつ画像に変換します。

変換の方法をいくつか調べてみましたが、内部で [ImageMagic](https://imagemagick.org/index.php) を利用する Go のライブラリ [gographics/imagick](https://github.com/gographics/imagick) が簡単そうでしたので、そちらを用いて実装しています。


# 事前準備

### ImageMagic のインストール

利用するライブラリ (gographics/imagick) が内部で ImageMagic を利用するために、あらかじめ ImageMagic をインストールしておく必要があります。

*例：macOS で ImageMagic をインストールする場合 (brew)*

```shell-session
$ brew install ImageMagic
```

### gographics/imagick のインストール
次にライブラリ (gographics/imagick) を利用するために `go get` でライブラリをインストールします。 ImageMagic のライブラリをリンクするために以下を実行しておく必要があります。

```shell-session
$ export CGO_CFLAGS_ALLOW='-Xpreprocessor'
```

あとはいつも通り `go get` でインストールできます。

```shell-session
$ go get gopkg.in/gographics/imagick.v3/imagick
```

# PDFから画像への変換の仕方

フリーで配布されている [サンプルのPDF](https://github.com/onocom/sample-files-for-demo-use) を変換します。
*（コードの説明はインラインで記述しています。）*

```go
package main

import (
	"fmt"
	"log"

	"gopkg.in/gographics/imagick.v3/imagick"
)

func main() {
	// ImageMagic を初期化する。
	imagick.Initialize()
	defer imagick.Terminate()

	mw := imagick.NewMagickWand()
	defer mw.Destroy()

	// 解像度を設定する。
	err := mw.SetResolution(150, 150)
	if err != nil {
		log.Fatal("failed at SetResolution", err)
	}

	// 変換元のPDFを読み込む。
	err = mw.ReadImage("data/sample-pdf.pdf")
	if err != nil {
		log.Fatal("failed at ReadImage", err)
	}

	// ページ数を取得する。
	n := mw.GetNumberImages()
	log.Println("number image: ", n)

	// 出力フォーマットをPNGに設定する。
	err = mw.SetImageFormat("png")
	if err != nil {
		log.Fatal("failed at SetImageFormat")
	}

	// １ページずつ変換して出力する。
	for i := 0; i < int(n); i++ {
		// ページ番号を設定する。
		if ret := mw.SetIteratorIndex(i); !ret {
			break
		}

		// 画像を出力する。
		err = mw.WriteImage(fmt.Sprintf("out/test_%02d.png", i))
		if err != nil {
			log.Fatal("failed at WriteImage")
		}
	}
}
```

### 出力結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76146/44e44289-9954-5ad8-2740-d6aece2aa4fc.png)

# APIのドキュメント

https://godoc.org/gopkg.in/gographics/imagick.v3/imagick

# 所感

* ライブラリの選択肢があまりなかった。
WordPressのパーマリンクにindex.phpが表示される

久しぶりにWordPressを触ったら、パーマリンクがおかしくなる問題が。。。

##状況

WordPressで、URLにindex.phpを噛んじゃう。
こんな感じ↓

https://sample/index.php/投稿記事名/

理想(本当)は
固定ページを表示させる時に、

https://sample/固定ページ/

で、表示されるはずなのにできず、

https://sample/index.php/固定ページ/

だと表示される、謎。。。


##環境

MacBook Catalina
MAMP
PHP 7.4.2
WordPress 5.5.5(5.4.2も試した)

##解決方法

原因が全く分からず、苦労しました。。。

(そもそも、いつから発現してるのか、不明。)
(PCの不良でジーニアスバーに連れてっているので、それが原因かなぁとも)

単純に、MAMPの設定の話でした。

MAMPのhttpd.confの中


```httpd.conf
<Directory />
    Options Indexes FollowSymLinks
    AllowOverride None
</Directory>
```

AllowOverrideがNoneになっていたのが原因。

```httpd.conf
<Directory />
    Options Indexes FollowSymLinks
    AllowOverride All
</Directory>
```

Allにしたら、直りました。。。

https://sample/固定ページ/

で表示されました。

AllowOverrideはApacheのアクセス権限について、なんですね。。。

勉強になりました。

###参考リンク
http://bashalog.c-brains.jp/10/11/16-121901.php
[JavaScript] 英語動画「クロージャー(closure) 」で一番再生されている動画の和訳　No.2

Youtubeチャンネル　Techsithの45万回以上再生されているクロージャー(Closure)に関する動画を日本語でまとめてみました。

#クロージャー(Closure)とは

以下のコードでは、仮引数(parameter)passedが設定してあり、functionの中には定数inner=2があります。
とてもシンプルです。実引数(arguments)に3を入れることで5が出てきますね。

```
const addTo = function(passed) {
  const inner = 2;
  return passed + inner;
};

console.log(addTo(3));
```

しかしJavascriptでは、この仮引数passedを設定しなくても5をconsole.logで出すことが可能なんです。
functionの上にconst passed = 3を置いてみましょう・・・　5が出てきます

```
const passed = 3
const addTo = function() {
  const inner = 2;
  return passed + inner;
};

console.log(addTo());　//結果　5
```

これをクロージャーといいます。　
JavaScriptではfunctionの外側に設定されている変数(定数)をfunctionの内側からアクセスすることが可能です。それはJavaScriptには「レキシカルスコープ」という機能が採用されているからなんです。

#functionもオブジェクトというところに注目！

ちょっと上記コードのaddToをconsoleでみてみましょう・・・　
![Screen Shot 2020-08-30 at 19.07.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647842/ef8d4eb4-70ff-fa92-d118-bb981d161601.png)

【ここはよく、じっくり読んでください】
このようにみてみると・・・functionオブジェクトに、外側で定義したconst passedがプロパティとして入っていて、それの値(value)が3となっています！

つまり、クロージャーはマジックでも適当な機能でもなんでもなくて、JavaScriptの機能として、「functionオブジェクトのプロパティに、外側で定義された変数(定数)がPRESERVED(保存)されるから」function内で使用することが出来る。。ということなんです！！　（これは衝撃）

＊オブジェクトやプロパティがまだわからない人は、「しまぶー」さんのYoutube動画でとてもわかりやすく、詳しく説明してくれています。

#他の例もみてみましょう!!

```
const addTo = function(passed) {
  const add = function(inner) {
    return passed + inner
  };

const addThree = new addTo(3);
const addFour = new addTo(4);

console.log(addThree(1));　// 結果 4
console.log(addFour(1)); // 結果　5

}
```

1) まず、addThreeをみてみると　addToの仮引数passed に3が入力されていますね！
「外側で設定された変数は内側functionオブジェクトのプロパティとして保存される」クロージャーのルールにより、function add(functionオブジェクト)ではもうすでに passed = 3 が入ってます！！！ （ヤバすぎる！！！）

2) つまり、addThreeには、初期設定としてもうすでにpassedが入っている。
console.log(addThree(1))としてあげると、4が結果として出てくるということになります。


この動画では繰り返し、クロージャーは機能とかではなくて、ただ単に「外側で定義された変数はfunctionオブジェクトにプロパティとして"保存"される」ということを強調していました。そう考えると、確かにfunction内で当たり前のように使用できることも納得ですね！


参考動画: https://www.youtube.com/watch?v=71AtaJpJHw0&list=PLhiwWzNTSiJnjMWJ2Xn1fYiWewl0qnRIH&index=21&t=6s
nginxのconfigファイル設定後の再起動(リロード)方法

nginxにて、各種configファイル編集後
彼らを有効化するために再起動(リロード)する方法です。

```
$ sudo service nginx reload
```

以上です。


▼参考:Nginx - ログフォーマット、アクセスログについて！
https://www.mk-mode.com/blog/2013/01/16/nginx-access-log/#
【Go】net/httpパッケージでhandlerが二回実行される

# 問題
Goのnet/httpパッケージを使ってhttpサーバを立てると、リクエストを処理する関数が二回実行される。（一回で良いのに）

具体的には、下記のようなコードを実行して、

```golang:main.go

package main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Println("handle")
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe("127.0.0.1:8080", nil)
}

```
http://127.0.0.1:8080 にアクセスした後にページを更新すると、
![aaaaaaaaaaaaaaaaaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265053/73236038-9efc-871a-c73a-a137f8d4f45b.png)

handler関数が2回実行されている。なんでやねん。

# 原因
どうも、Chromeが

* http://127.0.0.1:8080
* http://127.0.0.1:8080/favicon.ico

の両方にリクエストを送っているのが原因らしい。（https://github.com/golang/go/issues/1298 ）

## favicon.icoって何やねん
ホームページのシンボルアイコンとして使われる画像ファイルらしい。（https://wa3.i-3-i.info/word14168.html ）

# 解決策

favicon.icoへのリクエスト時は何もしないハンドラを登録する。

```golang:main.go
package main

import (
	"fmt"
	"net/http"
)

// 本命のハンドラ
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Println("handle")
}

// 何もしないハンドラ
func handlerICon(w http.ResponseWriter, r *http.Request) {}

func main() {
    // 本命のハンドラを登録
	http.HandleFunc("/", handler)

    // 何もしないハンドラを登録
	http.HandleFunc("/favicon.ico", handlerICon)

	http.ListenAndServe("127.0.0.1:8080", nil)
}

```

# あとがき
軽くハマったが英語でググったらすぐ解決した。英語で調べるのだいじ。
WPF(XAML)でいのちを輝かせる

#完成形
![inochi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/9b69f5ab-6338-5356-8179-466878c4060b.png)

#コード
```xml

 <Grid>
        <Canvas>
            <Ellipse Canvas.Left="27" Canvas.Top="107" Fill="red" Height="106" Width="106" />
            <Ellipse Canvas.Left="113" Canvas.Top="139" Fill="red" Height="94" Width="94" />
            <Ellipse Canvas.Left="115" Canvas.Top="68" Fill="red" Height="94" Width="94" />
            <Ellipse Canvas.Left="175" Canvas.Top="10" Fill="red" Height="100" Width="100" />
            <Ellipse Canvas.Left="265" Canvas.Top="25" Fill="red" Height="130" Width="130" />
            <Ellipse Canvas.Left="304" Canvas.Top="134" Fill="red" Height="72" Width="152" />
            <Ellipse Canvas.Left="325" Canvas.Top="195" Fill="red" Height="110" Width="90" />
            <Ellipse Canvas.Left="282" Canvas.Top="285" Fill="red" Height="130" Width="140" />
            <Ellipse Canvas.Left="196" Canvas.Top="356" Fill="red" Height="132" Width="132" />
            <Ellipse Canvas.Left="124" Canvas.Top="362" Fill="red" Height="92" Width="92" />
            <Ellipse Canvas.Left="98" Canvas.Top="286" Fill="red" Height="108" Width="60" />
            <Ellipse Canvas.Left="35" Canvas.Top="198" Fill="red" Height="120" Width="120" />
            <Ellipse Canvas.Left="40" Canvas.Top="124" Fill="White" Height="56" Width="56" />
            <Ellipse Canvas.Left="43" Canvas.Top="131" Fill="Blue" Height="26" Width="26" />
            <Ellipse Canvas.Left="322" Canvas.Top="42" Fill="White" Height="56" Width="56" />
            <Ellipse Canvas.Left="347" Canvas.Top="47" Fill="Blue" Height="26" Width="26" />
            <Ellipse Canvas.Left="345" Canvas.Top="325" Fill="White" Height="66" Width="60" />
            <Ellipse Canvas.Left="377" Canvas.Top="335" Fill="Blue" Height="26" Width="26" />
            <Ellipse Canvas.Left="228" Canvas.Top="417" Fill="White" Height="50" Width="50" />
            <Ellipse Canvas.Left="243" Canvas.Top="444" Fill="Blue" Height="20" Width="20" />
            <Ellipse Canvas.Left="79" Canvas.Top="249" Fill="White" Height="54" Width="54" />
            <Ellipse Canvas.Left="91" Canvas.Top="251" Fill="Blue" Height="24" Width="24" />
        </Canvas>
    </Grid>
```
#参考にさせていただいた記事
[PythonとOpenCVでいのちを輝かせる](https://qiita.com/Takayoshi_Makabe/items/07e4553362fc14d7ddb1)
laravelでMailHogを使ったときに詰まった話

環境はlaravel7 Ubuntu20.04

タイトル通りの内容。
以下の2つのエラーについて対処法を書く。

1,cannot send message without a sender address

2,Address in mailbox given [127.0.0.1] does not comply with RFC 2822, 3.6.2.

1は送信者アドレスが無いと送れません。
2は指定されたメールボックス内のアドレスがメールアドレスとして正しくない
と言っている。メールボックスはgivenの後の[]。

対処法

.envファイルのMAIL_の各部分を記載しよう。(以下正しく送れた例)

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=sample　
MAIL_PASSWORD=sample
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=sample@laravel.jp
MAIL_FROM_NAME="${APP_NAME}"

参考書とかサイトだとUSERNAME以下はnullで書いているところが多い。
そのままだと以上のようなエラーが出るので注意。

以上です。