OmniAICreator/Qiita-1.07M huggingface dataset:
box-sizingで表示崩れを解決


box-sizingは簡単に言うと「**外に広げるか(content-box)**」「**中に狭めるか(border-box)**」

## padding や線を大きさに含めない：`content-box`

**paddingや線は幅や高さに`含まれない`状態になる**

![スクリーンショット 2019-12-19 16.27.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446210/2fa746a0-70b4-2521-6f02-4fcf53143229.png)


## padding や線を大きさに含める：`border-box`

**paddingや線は幅や高さに`含まれる`状態になる**
![スクリーンショット 2019-12-19 16.26.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446210/25e34c76-41f3-d9e5-98b3-6b8ef0684501.png)
初めて自然言語処理をword2vecでしてみました

今回は、[word2vec](http://taku910.github.io/mecab/)を使用して自然言語処理を行います。

自然言語や形態素解析やword2vecなどについては、詳しく説明してくださっている方がいらっしゃったのでそちらを参考にしてください。
**[自然言語処理（NLP）ってなんだろう？](https://qiita.com/MahoTakara/items/b3d719ed1a3665730826)**

**形態素解析**は、前処理の一部みたいです。本によるとなんらかの処理をする前に、プログラムが処理しやすいように**処理対象のデータを整えること**を**前処理**というみたいで、ほかにも**タグや記号を除去する(クリーニング)、半角と全角を揃える(正規化)などがあるようです。**

こちらの書籍を見ながら今回は、実行しています。
# 参考にした本

**[パソコンで楽しむ自分で動かす人工知能](https://www.amazon.co.jp/%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%E3%81%A7%E6%A5%BD%E3%81%97%E3%82%80%E8%87%AA%E5%88%86%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B074WRB13C)**
**中島能和  (著)**


# 実際にword2vecを使って自然言語処理を行った手順

**①word2vecをインストール**
**②word2vecをコンパイル**
**③データをダウンロードし学習する**
**④学習データをのぞいてみる**
**⑤関連語を表示させる**
**⑥単語の関係性を演算してみる**

## ①word2vecをインストール
```
$ git clone https:github.com/svn2github/svn2github/word2vec.git
```

## ②word2vecをコンパイル
```
$ cd word2vec
$ ls 
# .cとあるファイルはC言語のソースファイルなのでコンパイルして実行ファイルにする
$ make
```
※ファイル一覧に「makefile」というファイルがあり、このファイルにコンパイル(ビルド)の手順が書かれている。makeコマンドを実行すると、makefile(Makefile)ファイルに従ってコンパイルが行われる

## ③データをダウンロードし学習する
```
# データをダウンロードして学習する
$ ./demo-word.sh
```

※学習中の画面になります。text8を学習
![学習キャプチャー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236027/6336965a-a70a-2a01-a34c-657a13bdb4cf.png)

## ④学習データをのぞいてみる
```
# データの中身を見る
$ less text8
```
![学習中身.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236027/c9c95785-47c8-396f-82f1-e76e7940f2c8.png)

※text8(単語同士の関係性を学習するためのものなので、文章ごとに区切らず、「.」も「,」も改行も取り除かれた、約1700万語からなる超長文の英文

# ⑤関連語を表示させる
```
# word2vecに戻る(関連語の検索を再開する)
$ ./distance vectors.bin
# 関連語を表示する
$ Enter word or sentence (EXIT to break):
```
**franceと入力**
![距離.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236027/e96a807a-19f8-7669-2199-0227bbf1c20a.png)
※右側のdistanceは単語の距離を表し、数値が大きいほど関連が近い
**soccerと入力**
![スポーツ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236027/544925f8-a554-35e1-846d-acb6a63ee5cb.png)

**辞書にない単語を指定する**
![ない.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236027/ba7b9e47-cd53-e90d-900b-fc3027639523.png)


```
# 関連語の検索を終了するには
$ Enter word or sentence (EXIT to break):EXIT
```

# ⑥単語の関係性を演算してみる
3つの単語A,B,Cを入力すると、「**AとBの関係はCに対して何であるか**」を回答として出力している
**パリとフランスの関係は、ベルリンに対して何になるでしょうか。**
![単語の関係性.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236027/35f0a0ed-72a7-3536-3f5c-330de88e3b1e.png)

※**結果、ドイツ(germany)となりました。**
パリがフランスの首都なので、ベルリンに対してドイツという回答は期待通りになりました。
ただ、いくつか試してみましたが、あまりポピュラーでない単語の場合は精度が低くなるようです。

### 関連情報
> word2vec :単語をベクトルにするアルゴリズム。実用面では、word2vecで生成したデータを使って、
・文章中の単語の使われ方や特徴を解析したり可視化したりする
・検索語に指定した単語の関連語検索結果もあわせて表示する

> **書籍情報**
>> **[パソコンで楽しむ自分で動かす人工知能](https://www.amazon.co.jp/%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%E3%81%A7%E6%A5%BD%E3%81%97%E3%82%80%E8%87%AA%E5%88%86%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B074WRB13C)**
**中島能和  (著)**
Windows10　Hyper-V設定

**Hyper-vとは？**

Hyper-Vとは、Microsoftが提供しているサーバー仮想化技術のことです。
Hyper-Vを使用することで、一台のPCで複数台のコンピューター環境を仮想的に実現することができます。

**つまりWindows10のデスクトップで「Windows7」や「Linux」といった複数のOSを同時に実行することができる技術ということです。**

**例**
古いWindows環境を仮想マシンで再現してアプリケーションのテストをする
複数台の物理的なサーバーを仮想マシンで再現して1台のコンピューターに集約するなど、
さまざまな用途で使われます。

企業の仮想化では、VMwareのWorkstationやvSphereシリーズが定番ですが、Hyper-Vも仮想化技術として導入されることが増えているようです。

**Hyper-Vを利用できるWindows10エディション**

Hyper-Vは、もともとはWindows Serverだけで提供されていた機能。
Windows 8以降ではPro / Enterpriseなどの上位エディションにも標準搭載されるようになった。
Windows 10では、Pro / Enterprise / Education / Pro Educationに搭載されている（すべて64ビット版。Homeエディションには未搭載）。

**hyper-Vのメリット**
VMwareなどの仮想化ソフトウエアではライセンスを必要な数だけ購入する必要がある。
Windowsの標準機能であるHyper-Vの場合、低コストですぐに仮想化環境を実現できる。

**設定方法**
先ほど記述したHyper-Vに対応しているWindows10であれば、以下の記事を参考に設定が簡単にできます。

参考記事:(https://mitani.work/column/%E3%80%90%E5%AE%9F%E8%B7%B5%E7%B7%A8%E3%80%91windows10%E3%81%AE%E4%BB%AE%E6%83%B3%E5%8C%96%E6%8A%80%E8%A1%93%E3%80%8Chyper-v%E3%80%8D/)
spheroを動かしてみる②

#今回のお題
星形(五芒星)を描く

#工程
基本設計→詳細設計→実装→テストの順に実施

#基本設計
五芒星を描くための基本動作を考える
![星.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469881/e9511486-8cae-4fe5-938d-ca6e65c24a02.jpeg)
1. ①の地点からスタートする
2. ②に向けて直進
3. ②の地点で③への方向に向きを変える
4. ③に向けて直進

以降は直進と向きを変える動作を繰り返していく

#詳細設計
基本設計と前回作成した正方形の動作([spheroを動かしてみる➀](https://qiita.com/ymatsuda/items/f6c585ff9a22d2d4799a))を元に動作を考える

考えた結果のフローチャートが以下
![フロー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469881/b061ebf1-f314-e4ce-85b8-25abb7e7b44a.jpeg)

####解説
- 星形の一角が36°なので、方向を変えるには180°- 36°= 144°回転しなくてはいけない。
そのため、回転の設定値を144°にする必要がある

- 現在向いてる方向を0°にするために「Aimリセット」が必要。

#実装
詳細設計を元に作成したプログラムは以ｈ下。
![sekkei.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469881/e816bff4-649c-b2d2-97c8-3904b06c0cae.png)

#テスト結果
星形を描くことができなかった。

#できなかった理由を考える
テストすると、回転実行中にAIMリセットが実行されてしまい、うまく動作しなかった。
「停止」のヘルプを見てみると、処理を停止するのではなく、速度を停止させる処理だった。
AIMリセットを遅らせるためには、「停止」ではなく「ディレイ」が適切だった。

「停止」部分を「ディレイ」に変更。直進する時間が長かったため合わせて調整
設計しなおしたフローチャートは以下。
![詳細設計.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469881/2a434c9c-62fb-344a-2308-5e998912185d.jpeg)



#実際に作成したプログラム
![puroguramu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469881/d73e2224-6be8-6fca-aedc-f8ea6172c664.png)


#テスト結果
星型を描くことができた
Tee演算子

# 1. 趣旨
最近パイプ演算子を知った私でございますが、某テキストで「もちろん皆さんご存じの」のテンションで突然湧いてきた「Tee演算子」。こいつは何なんだ。
という、R超初心者の僕個人向け、超絶基礎的レファレンス。


# 2. パイプ演算子の仲間
どうやらこのTee演算子、パイプ演算子の仲間らしい。
なので、パイプ演算子のことを知らないと何言ってるのかわからない。

（一応パイプ演算子について）[パイプ演算子 - Qiita](https://qiita.com/zakkiiii/items/ecb7ddf55c7f1bfacecf)


# 3. Tee演算子「%T>%」
クリアな説明は難しいが、こちらの記事ではこのように紹介されている。

> これは%>%のように機能するが、右辺の結果を返す代わりに左辺の結果をそのまま返すという特徴がある
 - [magrittrのvignetteの訳 - Qiita](https://qiita.com/nozma/items/9e52b446c813d7e92c8a#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E3%83%91%E3%82%A4%E3%83%97%E6%BC%94%E7%AE%97%E5%AD%90)

んんんんんーーー難しい。

あたまのわるい僕向けの説明としては、ようは「寄り道」させる演算子。

## 3-1. 前提

パイプ演算子と同様に、コイツもRで標準で使える演算子ではないらしい。
そして、パイプ演算子を使う場合はdplyrを使ったが、Tee演算子を使う場合は**magrittr**というパッケージが必要になる。

```R
library(magrittr)
```

## 3-2. Ex.

```R
sum(1:10) %T>% plot() %>% sum(., 100) %>% print()
[1] 155
# print()の出力結果と同時に、sum(1:10)のプロット図が表示される
```
おわかりいただけただろうか。

これを分解すると、こういうことになる。

```R
# 寄り道
sum(1:10) %>% plot()

# 本流の計算過程
sum(1:10) %>% sum(., 100) %>% print()
```
結局、`plot()`に一旦寄り道するけど、一つ手前の関数`sum(1:10)`の出力結果をその次の関数`sum(., 100)`のオブジェクトとして引き渡している。
つまり、**本流の計算は二行目の式**であり、Tee演算子に続く関数`plot()`は、**本流の計算には影響させない**ということ、らしい。

これが寄り道の具体的中身。

### 3-2-1. ちなみに
この「T」一文字を抜かすと、出力結果が全く異なる。

```R
> sum(1:10) %>% plot() %>% sum(., 100) %>% print()
[1] 100
# print()の出力結果と同時に、sum(1:10)のプロット図が表示される
```
`plot()`はあくまで図表を描写する関数なので、それ自体が出力するオブジェクトは空（NULL）になる。そのため、`sum(., 100)`の出力結果は0+100=100となるので、`print()`の出力結果も100になる。
つまり、普通のパイプ演算子だと、本当は本流の計算に影響させたくない部分も本流の一部を構成してしまう。その結果、本流の計算結果にも影響を与えてしまった。

これを避けるためにも、Tee演算子が必要だということになる。

## 3-3. 活用
Tee演算子の後には、だいたい`print()`や`plot()`が来ることが多いらしい。
これによって、計算全体に影響を与えることなく、計算の途中過程をアウトプットすることができる。

# 4. まとめ
パイプ演算子を使って記述しているときにTee演算子を使うと、全体の計算に影響を与えることなく途中の計算結果を表示したりプロットしたりすることが可能になる。ということでしょう。多分。


#5. イメージ
「%T>%」は浮気の演算子。
結婚発表直後に浮気疑惑をフライデーされるも、その後の新婚生活にもメディア出演にはほとんど影響がなかった、オードリー春日Tをイメージすればよい。

```R
> m_1_grandprix(kasuga) %>% marriage() %T>% friday() %>% tv_ranking(., 2019)
[1] 398本
```


余計にわかりづらいか。
Chromeの標準機能でWebページ全体をスクリーンショットする

スクロールが必要な画面の全体をスクリーンショットする方法です。
拡張機能や設定は不要でデフォルトのまま使えます。

# スクリーンショット

- `Command` + `option` + `i` (デベロッパーツール)
- `Command` + `shift` + `p` (Run command)
- `full` を入力してEnter (Capture full size screenshot)

スクリーンショットはダウンロードフォルダに保存されます。

# お試し

https://www.apple.com/jp/mac ココのサイトのキャプチャを試します。

<img width="1086" alt="スクリーンショット 2019-12-19 16.00.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/fe74bd90-ee7c-be60-80eb-1a3119fd8045.png">

`Screenshot Capture full size screenshot` を選択します。

[www.apple.com_jp_mac_-min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/475d06a4-b163-9b66-181b-ae942f5c9268.png) こんな感じのファイル名でスクリーンショットされてダウンロードされます。
[Rails] redirect_back と戻る目的で使うredirect_toは同じ速度だった

直接newアクションに飛ばすか、`redirect_back `を使用するかで悩んだけども、速度は全く一緒だったらめ、可読性を考慮して `redirect_to` を採用することにした。

```ruby:test_controller.rb
redirect_to action: 'new' and return
redirect_back(fallback_location: worker_new_path) and return
```
macOS Catalina python 情況

### クリンインストールした、Catalinaには、どんな pythonが入っているか調べた。

環境
macOS Catalina 10.15.2
MacBook Pro (Retina, 15-inch, Late 2013)
CPU Corei7 2.3GHz
Memory 16 GB 
Xcord 11.3 & コマンドラインツール
Homebrew 2.2.1

サブのマシンで、テストとか実験サーバー用に使っています。
初期化して開発環境は、 Dockerと、java程度しか入れていません。
メインで使っているマシンは、upgradeインストールで開発環境は結構グチャグチャになっています。
shellはzshです

クリーンな状態でPythonは何が入っているのか調べました。pythonタブで見ると以下でした。

```zsh

% python<tab>
python            python-config     python2           python2.7         python2.7-config  python3           pythonw           pythonw2.7

% which python3
/usr/bin/python3
```
### python3 が /usr/bin/に入っている
python はシンボリックリンクで、python2になっていました。
pipはどうだろうと見てみると

```zsh
% ls -l /usr/bin|grep pip   
-rwxr-xr-x   1 root   wheel     31456 12  5 18:33 pip3
```
pip3が入って居ました。

```zsh
% pip3 list
Package    Version
---------- -------
pip        19.0.3 
setuptools 40.8.0 
six        1.12.0 
wheel      0.33.1 
You are using pip version 19.0.3, however version 19.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
```

現在通っているパスは

```zsh
% echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

Homebrewでインストールされたパス /usr/local/bin が優先なっている。

### 自分の開発の為にはどうしようか考える
- インストールされているpython3環境をpip3も入っているのでそのまま使う /usr/bin/
- brewでpython3をインストールして使う /usr/local/bin/
- python.org から公式版を」インストールする /Library/Framework/以下
- Dockerで必要な環境コンテナを立ち上げる

### パスが違うので複数入れても管理は出来る
私はSystem管理者なので環境が再現しやすくだれでも使い安いHomebrewでのインストールを勧めます。
個人的にはDocker派なんだけど。
brewでのインストールは

```zsh
% brew install python
```
上記でインストールできる
ちなみに２系は brew install python@2 だそうだ

---
インストールされているpython3でコーディングしたという実例も検索すると出てくるが。
ぐちゃぐちゃになった場合、uninstall しやすいbrewが便利だろう

### IDEについて
- jupyter notebook Webベースの開発環境
    - pip3 install jupyter
- jupyterLab Webベースの開発環境
    - pip3 install jupyterlab
- PyCharm　Python　_iDE 有料版と無料版PyCharmCEがある　日本語サポートもある
    - Web App開発、DB開発なら有料版が便利
    - 無料版PyCharmCEもDataScienceなど一般的な開発には十分
    - https://www.jetbrains.com/ja-jp/pycharm/

### Docker派は、いろいろをpullして、runするだけです
- jupyter pythonだけの環境が欲しければ、jupyter/scipy-notebook がお勧め
    - miniconda ベース　python3, jupyter, numpy, pandas, matplotlibは入っている
    - docker pull jupyter/scipy-notebook
- python, R, juliaの環境が欲しければ、jupyter/datascience-notebook
    - scipy-notebookをベースで,Rパッケージ、Juliaがはいっている
    - docker pull jupyter/datascience-notebook
- tensorflow2 ならば
    - docker pull tensorflow/tensorflow
- PyTorch　ならば
    - docker pull pytorch/pytorch
Lambda＠Edgeについてまとめる

# はじめに
Lambda@Edgeを初めて使い、色々戸惑うことが多かったため調べたことをまとめる。
また、都度追加していく。

# Lambda@Edgeとは
Lambda@EdgeとはCloudFrontの機能の1つで、CloudFrontのエッジサーバでコードを実行するLambda関数のこと。ユーザーに近い場所でコードが実行されることでアプリケーションのパフォーマンスが向上する。
CloudFrontのイベントをトリガーとしてコードを実行する。


## トリガー
上述の通り、CloudFrontのイベントをトリガーとし、イベントがあったCloudFrontと同リージョンで起動する。指定できるCloudFrontのイベントは以下の4つ。

1.ビューワーリクエスト
2.ビューワーレスポンス
3.オリジンリクエスト
4.オリジンレスポンス
<img width="631" alt="スクリーンショット 2019-12-17 19.53.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429159/67030b91-8b95-588c-9272-dddacb85af96.png">
Lambda@Edgeのトリガーをビューワーリクエストに設定すると、CloudFrontがキャッシュを保有しているかに関わらずビューワーからリクエストがある度にLambdaが起動する。キャッシュがある場合に起動させたくない場合はトリガーを `オリジンリクエスト` に設定する。

## ログ
Lambda@EdgeのログはLambda同様CloudWatchLogsに保存されるが、**Lambda関数が起動したエッジサーバがあるリージョンのCloudWatchLogsに保存**される。

# Lambda@Edgeの作成する際の注意
## リージョン
Lambda@Edgeは**バージニア北部リージョン**でLambda関数を作成する。

## 作成方法はLambda関数と同様
恥ずかしい話ですが、Lmadba@Edgeを使用する前、Lambda@Edgeというサービスがあるものだと思っていたんですが、Lambda関数をバージニア北部リージョンで作成し、CloudFrontのイベントをトリガーとすることでLambda@Edgeになるということみたい。

## IAMロール
Lambda＠EdgeにアタッチするIAMロールは、サービスプリンシパル `lambda.amazonaws.com` と `edgelambda.amazonaws.com` が引き受けることができるロールである必要があるため、以下の信頼ポリシーを記述したIAMロールを作成する。

```json:ロールの信頼ポリシー
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "Service": [
               "lambda.amazonaws.com",
               "edgelambda.amazonaws.com"
            ]
         },
         "Action": "sts:AssumeRole"
      }
   ]
}
```

IAMポリシーを作成

```json:IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:GetFunction",
                "lambda:EnableReplication"
            ],
            "Resource": "arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:<関数名>:<バージョン>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudfront:UpdateDistribution"
            ],
            "Resource":"arn:aws:cloudfront::xxxxxxxxxxxx:distribution/<ディストリビューションID>"
        }
    ]
}
```

## 関数の編集後はCloudFrontにデプロイする
関数を編集して保存後CloudFrontにデプロイして、編集内容が各エッジサーバに反映される。
ちなみに、Lambda関数はバージョン管理しておりデプロイする際に自動でバージョンアップされ、それがデプロイされる。

#参考
[Lambda@Edge](https://aws.amazon.com/jp/lambda/edge/)
[Lambda@Edge 用の IAM アクセス権限とロールの設定](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html)
[初心者]DockerによるRails環境の構築(Windows)

初心者向けのDockerによるRails環境の構築です。
また、OSはWindowsです。

Windowsユーザーは、この環境構築の段階でとても苦しみますよね:sob:
私もとても時間がかかりました......

この記事がそういった方々の参考になれたら嬉しいです:v:
# 目次
- [Docker for Windowsのインストール](#docker-for-windowsのインストール)
- [Docker Toolboxのインストール](#docker-toolboxのインストール)
- [Rails開発環境構築用ファイル](#rails開発環境構築用ファイル)
- [Docker Toolboxをお使いの場合の注意点](#docker-toolboxをお使いの場合の注意点)
- [Railsの環境構築](#railsの環境構築)

##Docker for Windowsのインストール
>Dockerの公式サイトURL　https://www.docker.com

以下の順に進める。

1.Product
2.GET DOCKER COMMUNITY EDITION
3.下にスクロール
4.DOCKER FOR WINDOWSのDownloud from Docker Store
5.Get Docker
6.実行>アイコン実行>
7.PowerShellで`$ docker -v`で確認
8.`$ docker run hello-world`を実行
9.`>Hello from Docker!`と表示されればOK! :innocent:

##Docker Toolboxのインストール
>Docker ToolboxのダウンロードページURL 
https://docs.docker.com/toolbox/toolbox_install_windows

1.Get Docker Toolbox for Windows > 実行 > VB||Gitはあるなら無視
2.\next > install > DQTを実行 > 待つ > `$ docker -v`で確認
3.`$ docker run hello-world`を実行
4.`>Hello from Docker!`と表示されればOK! :innocent:

##Rails開発環境構築用ファイル

```yaml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
volumes:
  db-volume:

```
```dockerfile:Dockerfile
FROM ruby:2.4.5
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
```
>修正箇所）Dockerfile/ruby:2.4.5←任意のバージョンで

##Docker Toolboxをお使いの場合の注意点
IPアドレスを確認するには、ターミナル（コマンドプロンプトなど）で次のコマンドを実行します。
`$ docker-machine ip default`
このコマンドの結果表示されたIPアドレスが、Docker Toolboxで動かしている仮想マシンのIPアドレスになります。
Docker Toolboxをお使いの場合は、このIPアドレスを使用して
`http://<確認したIPアドレス>:3000 `
のようにアクセスしてください。

<a id="anchor5"></a>
##Railsの環境構築
docker-compose.ymlファイルの置いてあるディレクトリで実行。

1.Railsのコンテナを起動してRailsのプロジェクトを作成するコマンド
`$ docker-compose run web rails new . --force --database=mysql`

2.Railsイメージのビルド実行コマンド
`$ docker-compose build`

3.config/database.ymlの修正内容

default内の項目を修正
password: **password**
host: **db**

4.コンテナをデタッチドモード（バックグラウンド）で実行するコマンド
`$ docker-compose up -d`

5.RailsのコンテナでDB作成のタスクを実行するコマンド
`$ docker-compose run web bundle exec rake db:create`
ActiveModel::Attributesを使う

ここでは、Rails 5.2で導入された[ActiveModel::Attributes](https://github.com/rails/rails/blob/master/activemodel/lib/active_model/attributes.rb)について紹介します。RubyのクラスにActiveRecordのカラムのような属性を加えられます。

サンプル:
https://github.com/kazubon/blog-rails6-vuejs/blob/master/app/forms/entries/form.rb

クラスにActiveModel::ModelとともにActiveModel::Attributesをインクルードします。

```ruby
class Entries::Form
  include ActiveModel::Model
  include ActiveModel::Attributes
```

クラスメソッドattributeに属性名と型を渡すと、attr_accessorと同じように属性が使えるようになります。指定できる型の種類については、Railsのソースを直接参照してください。

https://github.com/rails/rails/blob/master/activemodel/lib/active_model/type.rb

attributeをクラスの冒頭に並べておくと、「このクラスは何をパラメータとして受け取るのか」を明示できるというメリットもあります。なお、この例のtagsは配列で、指定できる型がないので型を指定していません。

```ruby
  attribute :title, :string
  attribute :body, :string
  attribute :draft, :boolean, default: false
  attribute :published_at, :datetime
  attribute :tags
```

defaultオプションで初期値を指定できます。Procも指定できます。

```ruby
  attribute :published_at, :datetime, default: ->{ Time.now }
```

属性を使うには、superでActiveModel::Attributesのinitializeメソッドを呼び出す必要があります。

```ruby
  def initialize(user, entry, params = {})
    @user = user
    @entry = entry
    super(params)
  end
```

この`super(params)`は次のように置き換えても同じです。

```ruby
    @attributes = self.class._default_attributes.deep_dup
    assign_attributes(params)
```

ActiveRecordのカラムと同じく、attributeで加えた属性に値を入れると、数値、時刻、ブーリアンのような型に合わせて値が変換されます。時刻（:datetime）では次のような感じです。

```ruby
  form.published_at = "2019/12/19 12:30"
  form.published_at #=> 2019-12-19 12:30:00 +0900
  form.published_at = "xxxxx"
  form.published_at #=> nil
```

ブーリアン（:boolean）では、`[false, 0, "0", :"0", "f", :f, "F", :F, "false", :false, "FALSE", :FALSE, "off", :off, "OFF", :OFF]` が false、それ以外は true になります。空文字列はnilになります。

```ruby
  form.draft = "1"
  form.draft #=> true
  form.draft = "0"
  form.draft #=> false
```

インスタンスメソッドattributesで「属性名 => 値」のハッシュが取り出せます。

```ruby
form.attributes
#=> {"title"=>"Foo", "body"=>"bar", "draft"=>false, "published_at"=>2019-12-15 15:40:00 +0900, "tags"=>["Ruby", "Rails"]}
```

インスタンスメソッドまたはクラスメソッドのattribute_namesで属性一覧が取り出せます（Rails 6で追加）。

```ruby
form.attribute_names
#=> ["title", "body", "draft", "published_at", "tags"]
```

以上です。

ActiveModel::Attributes を使わずに型キャストをしたいときは、 [ActiveRecord以外で型キャストを使う](https://qiita.com/kazutosato/items/9073e76bdca669085fba) を参照しくてください。
iOSエンジニアがWebをペアプロで実装してみた話

# はじめに

[GameWith Advent Calendar 2019](https://qiita.com/advent-calendar/2019/gamewith)の19日目の記事になります。

今回の記事は**iOSエンジニアの自分がWebの新施作をフロントエンジニアとペアプロをしながら実装した時の話**です。
自分は普段GameWithの**価値検証チーム**という少人数のチームで、アプリやWebの大幅な数値改善が見込めそうな施作をメインに企画・進行・実装まで一通り担当しています。

基本的に価値検証フェーズと本実装フェーズで分けて実装しており、価値検証フェーズにて目標数値に達したもののみ本実装フェーズに移行しています。
価値検証フェーズでは片方のみに展開することでUXが下がるといった施作以外は基本的にはスピード重視と施作を撃てる数を増やすためにiOS・Androidのどちらかのみで実装しています。

今回の施作はコンテンツの性質などから両OSで実装するのがベターとの判断になったので、Webで実装したものを両OSのWebViewで表示するといった形式を取っています。

## Webの知識
自分は去年、`Vue.js(+Element UI)`と`Firebase`を使い、GameWithアプリとは別に担当していた動画アプリの管理画面を0から実装しましたが、Webの技術領域にはあまり明るくなく正直 `JavaScript`, `HTML`, `CSS`とかも普段全然触らないので当時勉強し直しながら作りました。

それから1年以上経っていたのと、今回は[GameWith Web](https://gamewith.jp/) 内の新機能だったので、ドメイン知識もそこまでなかったため、要所要所でペアプロという形式を取り進めることにしました。

去年のブログ
[Firebaseをプロダクトに採用して得た知見 #GameWith #TechWith](https://tech.gamewith.co.jp/entry/2018/11/09/122551)

# ペアプロ

エンジニアの方には馴染みがある言葉だと思いますが、ペアプロの定義を引用して貼っておきます。

> ペアプログラミング（英: pair programming）は、2人のプログラマが1台のワークステーションを使って共同でソフトウェア開発を行う手法という説明が起源である。(wikipedia)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66235/fce34ec8-ad89-848a-03f6-b1b768be6c10.jpeg" width="450">

上記は社内でペアブログ（共同でブログを執筆）していた時の写真なのですが、上記のように基本的にはひとつのモニターを見ながら進めていきました。
ペアプロでは実際にキーボードを操作してコードを書く人を**「ドライバ」**、もう1人を**「ナビゲータ」**と呼ぶのですが、自分はドライバの役割でした。

## 進め方

まずWeb側の開発環境の準備・整備など基本的には、先に社内の手順ドキュメントを見ながら済ませておきました。

今回のペアプロでは基本的には、1日30分〜最大2時間を目安に行っていました。

1日1画面の実装を目標に、まずペアプロで大枠の進め方の確認。
他の画面のコードの書き方などを参考にしながら、なぜこのように書くのか、なぜこのような使い方をしているかなど社内独自のルール的なものまで共有をしてもらいました。

ペアプロが終わった後は一人で基本的に作業を行い、次の日に前日生じた疑問などを質問したりして、疑問を解消してからまた、実装画面の進め方を決めるなどの作業を繰り返しました。

# ペアプロのメリット

ペアプロを大体一週間ほどして以下のメリットを感じました。

(※ ドライバとナビゲータ間のスキル度合いが同等の場合、また別のメリットがあるかとは思いますが、今回はWebのスキルに差がある二人でのペアプロでの効果例です)

### 作業効率の向上

普段の一人で開発を行う業務よりも集中力が維持できました。
個人個人で集中できる時間の範囲は異なるとは思うのですが、一度だけ2時間がっつりペアプロを行った日に終始プロジェクトに向き合い、頭を使い、話し合いながらコードを書いたため終わった後に疲れて軽く頭が痛くなるくらいの集中でした。

実際にペアプロでは個人の作業よりも怠けることなく作業を進める可能性が上がるといった規範意識の増大の効果が見込めるそうです。

### 効率の良い教育的側面

個人で勉強し、調べながらでも実装を行うことはできますが、ナビゲータがいることによって設計の質が向上したり、コードレビューをリアルタイムで受けながらコードを書くことができるので、素早く学習することができます。
コードの正確性の向上もそうですが、知識や技術の共有をペアプロを通して効率よく受けることができました。

# 終わりに

今回、新機能を一通りWebで実装したことで、今後新しいWebの施作が価値検証チーム内で上がってもiOSエンジニアの自分が担当できるなといった自信がつきました。
また今回のペアプロを通してWeb技術への興味が以前よりも湧いたことも大きな収穫です。

[[iOS][Swift]JavaScriptと相互通信](https://qiita.com/usayuki/items/6979d0d6f7d8f5b302ad)といった内容を両者自分で実装することでより深くWebとiOSの連携についても理解することができました。

今回は教育的側面の強いペアプロでしたが、非常に有意義な時間だったので、またスキルが同等なiOSエンジニア同士でiOSアプリ実装のペアプロもやってみたいなと思いました。

ナビゲーターをやってくれた[tiwu_official](https://qiita.com/tiwu_official)さんありがとうございました！
npmについて

全然覚えられていないということでここでアウトプットをして、
覚えてみよう作戦です。


#npmって？

便利なパッケージツール。

Node.jsを使う上で必須のツール。



##npmの正式名称
npm = Node Package Manager

だからnpmなのか！

正式名称を聞くと覚えやすい！

npmの正式名称からも解るように、Node.jsのパッケージ（Package ）を管理する（Manager）ツールです。

###引用してきたサイト,参考にしたサイト
https://techacademy.jp/magazine/16105
Python3エンジニア認定基礎試験　-備忘録と問題傾向-

# Python3エンジニア基礎認定試験

#### ■受験詳細
受験日：通年（パソコンスクールなどでも開催しているため試験会場を要確認）
申込URL：http://cbt.odyssey-com.co.jp/pythonic-exam.html
受験料金：1万円（税別）

#### ■試験概要
試験名：Python3 エンジニア認定基礎試験
（英名：Python 3 Certified Engineer Basic Examination）
資格名：Python3 エンジニア認定基礎試験合格者
（英名：Python 3 Basic Grammar Certification）
概要：文法基礎を問う試験
問題数：40問（すべて選択問題:1問25点計算）
試験時間：60分
合格ライン：正答率70％
出題範囲：オライリー・ジャパン「Pythonチュートリアル 第3版」および一般的知識

#### ■模擬試験URL
https://diver.diveintocode.jp/exam

# 筆者のプログラミングレベル
初心者です。

■Progato
・ruby
・python

■Kaggle
・触りだけ

■Rails tutorial
・最終14章まで完了

# 模擬試験内容

ここからは問題を元に回答を記述していきます。

######問1：仮想環境にインストールされたすべてのパッケージを表示するオプションを選択肢の中から選びなさい。

正解：`pip list`


pipはパッケージ管理で利用されている。
主として行えるのはパッケージの、
・インストール
・アップグレード
・リムーブ
そのほか様々なコマンドがあり、以下表に一部をまとめてみる。

|subcommand|　　　　　　　　　　　意味|
|:--|:--|
|install|パッケージを指定してインストール可能<br>--updateで最新バージョンをインストール可能|
|uninstall| installの逆|
|freeze| インストールされたパッケージのリスト表示（install向け表示）|
|list| 仮想環境にインストールされたすべてのパッケージを表示|
|show| show パッケージ名でパッケージ情報を表示|

######問2：以下のプログラムを実行した際の出力結果を選びなさい。


正解：`0 1 2`

```python
num_list  = [2, 4, 6, 4, 4, 2, 6]
for i in range(num_list.count(4)):
    print(i, end=' ')
```

countは対象の数を数えるメソッド。
forで繰り返しているかつ end = ' ' が入ることによって、
0 1 2と表現される。

######問3：以下のプログラムを実行した際の出力結果として正しいものを選択しなさい。

正解：`Noro`

```python
def dive_into_code(teacher, *mentor):
    print(teacher)

dive_into_code('Noro', 'Nakao', 'Miyaoka')
```

あぶれた位置引数('Nakao', 'Miyaoka')を(*menter)にまとめて代入している。

```python:類似問題
dic = [
    ['Noro', 'Nakao', 'Miyaoka'],
    ['Kimura', 'Miyashita', 'Shibata'],
    ['Matsumoto', 'Tanaka', 'Ivan'],
]

print(list(zip(*dic)))
```

正解：` [('Noro', 'Kimura', 'Matsumoto'), ('Nakao', 'Miyashita', 'Tanaka'), ('Miyaoka', 'Shibata', 'Ivan')]`


######問4：以下のプログラムを実行した際の出力結果として正しいものを選択しなさい。

```python:模擬試験問題
dive_into_code = [(1, 'Noro'), (2, 'Nakao'), (3, 'Miyaoka'), (4, 'Kimura')]
dic = dive_into_code
#1は第二要素を昇順にする。0なら第一要素で昇順にする。
dic.sort(key=lambda dic: dic[1]) 

print(dic)
```
正解: `[(4, 'Kimura'), (3, 'Miyaoka'), (2, 'Nakao'), (1, 'Noro')]`
なのでK→M→Na→Noでsortしているわけですね。

######問5：以下のプログラムを実行した際の出力結果として正しいものを選択しなさい。
正解: `xxxxCODExxxxDIVExxxxDIVE`

```python:replace.py
d = 'xxxxDIVExxxxDIVExxxxDIVE'

print(d.replace('DIVE', 'CODE', 1))
```

文字列.replace(置換前の文字列, 置換後の文字列, 最大回数)

######問6：以下のプログラムを実行した際の出力結果として正しいものを選択しなさい。
正解：`3.142`

%全体の幅.小数点以下の幅f

```python:format.py
print("出力結果:")
print('円周率は%5.3fである。'%math.pi)

円周率は3.142
```

######問7：以下のプログラムを実行した際の出力結果として正しいものを選択しなさい。

正解：` [('Noro', 'Kimura', 'Matsumoto'), ('Nakao', 'Miyashita', 'Tanaka'), ('Miyaoka', 'Shibata', 'Ivan')]`

zipを用いてリスト型：listを辞書型：dictionaryにする方法

```python:zip.py
dic = [
    ['Noro', 'Nakao', 'Miyaoka'],
    ['Kimura', 'Miyashita', 'Shibata'],
    ['Matsumoto', 'Tanaka', 'Ivan'],
]

print(list(zip(*dic)))
```

以下を参考にしました。
https://pg-chain.com/python-dictionary-list


以上です
sbtを使ってDockerize

# dockerizeに便利なプラグインを追加

sbt-native-packager：https://github.com/sbt/sbt-native-packager

```scala:plugins.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.5.1")
```

## プラグインを有効化
```scala:build.sbt
enablePlugins(JavaAppPackaging)
```

# Dockerfile自動生成
```bash
# Dockerfileを自動生成
$ sbt docker:stage

target/docker/stage/opt/Dockerfileが作成される
```

## おまけ
```bash
# Dockerイメージを生成
$ sbt docker:publishLocal
```
DockerとDocker ComposeをUbuntu18.04にインストールする。2019年冬

# 追記: 2022/01/18

**[2022年冬バージョン](https://qiita.com/abetomo/items/7ec217c28b54bce7a336) も書いたのでよければご確認ください。**

# 概要

2019年12月にUbuntu18.04にDockerをインストールする手順についてまとめます。
なるべく新しいのを入れます。

# 環境

```
% cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
```

# とりあえず何もしないでaptで入れられるやつ

```
% sudo apt update
% sudo apt install docker docker-compose
```
```
% docker -v
Docker version 18.09.7, build 2d0083d
% docker-compose -v
docker-compose version 1.17.1, build unknown
```

# なるべく新しいのを入れる

* https://docs.docker.com/install/linux/docker-ce/ubuntu/
* https://docs.docker.com/compose/install/

これらの方がが新しいみたいなのでこちらを使います。
**「とりあえず何もしないでaptで入れられるやつ」でインストールしましたがそれらはなかったことにして、Docker系は何もインストールしていない状態からの手順を書きます**

# Get Docker Engine - Community for Ubuntu

https://docs.docker.com/install/linux/docker-ce/ubuntu/

詳細は上記URLの公式ドキュメントを参照してください。
実行したコマンドだけ書きます。

```
% sudo apt update
% sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
% curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
% sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

```
% sudo apt update
% sudo apt install docker-ce docker-ce-cli containerd.io
% docker -v
Docker version 19.03.5, build 633a0ea838
```

`docker: Got permission denied` と出る場合は以下のコマンドを実行する。

```
% sudo usermod -aG docker ${USER}
```

上記コマンドを実行した後、一度exitしてからログインしなおせばエラーが出なくなる。

# Install Docker Compose

https://docs.docker.com/compose/install/

詳細は上記URLの公式ドキュメントを参照してください。
実行したコマンドだけ書きます。
上述の通りDockerのインストールは済んだ状態で進めます。

```
% sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
% sudo chmod +x /usr/local/bin/docker-compose
% docker-compose -v
docker-compose version 1.25.0, build 0a186604
```

（上記は1.25.0をインストールする例です。https://github.com/docker/compose/releases に新しいのがあればそれをインストールすると良いです。）
（2021/10追記: v2がリリースされたのでそちらをインストールすると吉だと思います。）

`/usr/bin` に `ln` を作っておくと親切だと思うけど必須ではない。

```
% sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
```

# まとめ

https://docs.docker.com/ の手順に従い、新しいDockerがUbuntu18.04にインストールできました
ReactでuseStateを上手く扱うにはどのように書くのがベストか

Hooks を使ってコードを書いていると、`useState()`の宣言が多くなってしまってごちゃごちゃしてしまうことがある。
このような問題に直面した時にどのように書いていくのが良いのだろうか。

単純に書いた場合、Class Component に慣れている方は、stateをまとめて宣言した方が見栄えが良いと思われるかもしれない。
これについて[ReactのドキュメントのFAQ](https://ja.reactjs.org/docs/hooks-faq.html#should-i-use-one-or-many-state-variables)を読むと、次のように書いてある。

> すべての state を 1 つの useState 呼び出しに含めても動作しますし、フィールドごとに別に useState を持たせることでも動作はします。しかしこれらの両極端の間でうまくバランスを取り、少数の独立した state 変数に関連する state をグループ化することで、コンポーネントは最も読みやすくなります。state のロジックが複雑になった場合は、それをリデューサで管理するか、カスタムフックを書くことをお勧めします。

つまり、**基本的に少数の独立した state に分割して宣言する**ことで、Custom Hook を作りやすくなり、リファクタリングしやすくなったり、コードが見やすくなるのである。

また、「どうにも上手くグループ分けができず、汚くなってしまった。」という時に限って`useReducer()`を使って、処理をまとめるのが良いと考える。

それ以外にも`useReducer()`の利用場面として、以下のような場面がある。

- **複数階層にまたがって更新を発生させるようなコンポーネント**ではパフォーマンスの最適化になる(https://ja.reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down)
- **前回のstateに基づいて**、stateを更新したいような場面(https://overreacted.io/ja/a-complete-guide-to-useeffect)

そのため、次のようなステップでコードを書いていくのが良いと思われる。

1. `const x = useState(0);`のように独立させて宣言してみる
2. `const [position, setPosition] = useState({ x: 0, y: 0});`のようにして役割ごとにまとめてみる
3. それでも上手くいかない場合は、`useReducer()`を使うというようにしたほうが共通化しやすいと考える。

メモ程度にまとめてみました！
間違っている所や他に意識しているようなことがあれば教えていただけたら嬉しいです。
eslint[nodejs + TypeScript]

eslint memo

とりあえずこれ入れとけシリーズ

# npm install

```
npm i -D @types/pretty-hrtime @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-prettier prettier pretty-hrtime
```

# .eslintrc.js

```js:.eslintrc.js
module.exports = {
  env: {
    browser: true,
    commonjs: true,
    es6: true
  },
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended",
    "prettier/@typescript-eslint"
  ],
  globals: {
    Atomics: "readonly",
    SharedArrayBuffer: "readonly"
  },
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: "module",
    ecmaFeatures: {
      modules: true
    }
  },
  plugins: ["@typescript-eslint"],
  rules: {}
};
```

# WebStorm

Preferences > Languages & Frameworks > JavaScript > Code Quality Tools > ESLint
`Automatic ESLint configuration` に設定する

画面にESLintのエラーが出てくれるようになる

###ショートカット

(Mac): prettier `command + option + shift + p`

prettierで整形してくれる
Javascriptレシピ②

Javascriptの簡単なメモです。
アプリ制作に応用できる基本レシピですので、参考にされたい方はどうぞ。


###アラートのポップアップ表示
```html
<input type='submit' value='wanko' onClick='alert('といぷー');'
```
クリックするとonClick関数が実行される。
alert()でも書ける。

###演算子
```
算術演算子

足し算　+
引き算　−
掛け算　*
割り算　/
あまり　%

代入演算子
a = a+5; 
a += 5;

a = a-5;
a -= 5;


同じ意味です。

単項演算子

a = 10 % 4;
a++; //3

a--; //2
```

###onload

onloadはイベントハンドラーです。
ページを読み込んだ後に実行する処理を決めることが出来ます。

```js

window.onload = () => {
    alert('toypoo');
};
```

単一の要素に対してonloadは単一のイベントハンドラーしか設定できません。
複数指定したい場合はaddEventListenerを使いましょう。



###filterメソッド

配列オブジェクトから特定の条件の配列を新しく生成します。

配列の要素の値value
数値インデックスindex
配列要素を格納した配列オブジェクトを指定できます。

```js

const date = [1,2,3,4,5];
const result =date.filter(value =>{
    return value % 2 ===1;
});

const wanko = ['toypoo','pome','siba'];
const dog = wanko.filte(value => {
    return value ==== 'toypoo';
});
```

###callback関数


callback関数は他の関数に引数として渡される関数です。
イベントハンドラに多く使われます。

```js

const wanko = () => {
    //
}
pome(wanko);


const wanko = response => {
    const data = this.response;
    console.log('data.name');
}

const sayWanko(){
    const rewuest = new XMLHttpRequest();
    request.open('GET', 'http://',true);
    reques.responseType = 'josn';
    request.addEventListener('load', 
    wanko);
    request.send();
}
```

###foreachメソッド



配列への繰り返し処理が書けます。


```js

const dogs = ['pome','toypoo','siba'];
dogs.foreach(dog => {
    console.log(dog);
});
```

配列に対しての処理です、dogという引数を受け取り配列の数分繰り返し処理を行ってくれます。
dogを引数にしていますが引数がaでも動きます。

```js

const dogs = ['pome','toypoo','siba'];
dogs.foreach((dog,number) => {
    console.log(number + 1)+'匹目は'+dog);
});
```

引数が2つになりました。
第一引数に配列のデータ、第二引数にindex番号を受け取っています。
配列の一番目は0ですので+1してあげる必要があります。


##bind


関数に対してthisや引数を指定、
他の関数との結びつけが出来ます。


```js

function wanko(){
    console.log(this);
}
const dog = say.bind('toypp');
dog();


function wanko(a,b,c){
    return a + b + c;
}
const sum = wanko.bind(null, 10, 10);
console.log(sum());
```

###onClick


マウスクリックに対しての処理をするイベントハンドラーです。

```js


document.getElementById('button').onClick = () => {
    document.getElementById('text').innerHTML = 'わんこ';
};


document.getElementById('button').onClick = () => {
   this.classList.toggle('wanko');
};
```

###index

indexメソッドは文字列や配列に指定した文字があるか探して、あればその位置を変えしてくれます。

```js

const arr = ['a','b'.'c'];
const index = arr.indexOf('b');
console.log(index);
```

先頭は０、存在しない場合は-１です。

第二引数に開始位置を指定することも出来ます。


###クラス

classを使うことでオブジェクト指向プログラミングが簡潔に書けます。

```js

class Wanko {
    constructor(name) {
        this.name = name;
    }
    say() {
    console.log(this.name);
    }
}

const dog = new Wanko('toypoo');
dog.say();
```

newでWankoクラスのインスタスを生成するたびにconstructorによる初期化が行われます。


###replaceメソッド

replaceメソッドでは置換処理を行うことが出来ます。
文字列による置換と正規表現による置換が可能です。

```js

const str 'わんこ<br>わんこ<br>わんこ';
const dog = str.replace(/<br>/g,'\n');
console.log(dog);
```
Docker上で mysqlコンテナにログインする方法

# Docker上でMySQLにログインするには、docker composeのコマンドと一緒にmysqlのログインコマンドを入力する必要があります。


Docker上では以下のコマンドでMySQLにログインできます。

```
$ docker exec -it [コンテナ名] mysql -u root -p
```


では、確認していきます。
まず、`docker-compose ps`コマンドで、MySQLのコンテナが起動していることを確認します。

```
$ docker-compose ps
指定されたパスが見つかりません。
  Name                Command               State                  Ports
---------------------------------------------------------------------------------------
composer   /bin/sh /docker-entrypoint ...   Exit 0
laravel    docker-php-entrypoint /usr ...   Exit 0
mysql      docker-entrypoint.sh mysql ...   Up       0.0.0.0:33306->3306/tcp, 33060/tcp
nginx      nginx -g daemon off;             Up       0.0.0.0:8080->80/tcp
php-fpm    docker-php-entrypoint php-fpm    Up       9000/tcp
```

コンテナ名（Name）が`mysql`になっているコンテナが起動中のmysqlコンテナです。

さっそく、ログインしてみます。


```qiita:ターミナル
$ docker exec -it mysql mysql -u root -p
Enter password:
```
ログイン成功後に、生成されているデータベースを一覧表示できていることがわかります。

```qiita:実行結果
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9

~(省略)~

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>show datases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)
```

以上です。
Docker勉強中で分からないことが多いので、積極的に勉強中です！
リモデ切断後にリモート先端末を自動ログインさせる

#要件
Windows端末にリモートデスクトップ接続した後、
セッションを切断する際にリモート先の端末を自動ログインさせたい。

#やったこと
リモートを切断するときに下記コマンドで切断する。

```
tscon 1 /dest:console
```

これで切断すると、リモート先の端末が自動でログインしてきました。

リモート先でCMDも使えない環境であればタスクスケジューラで、
「リモートログインした5分後にこのバッチを実行する。」を追加すればOKですね。



#最後に
とりあえず試験してみたところタスクスケジューラでの動作もOKでした。

画面表示必要なシステムだとメンテナンスでリモート切った後に
自動ログインしてもらわないと、困ることあると思うので
よかったら試してみてください。

#参考資料
[tsconコマンド詳細](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/tscon)
backgroundの詳細設定とショートハンドの使用


```app.css
background {
background: url(/assets/img/picture/xxx.jpg) no-repeat center/cover;
}
```

### 一行のスタイルシートで記述
上記はすべて「background」の指定のため、**ショートハンド（複数指定）**を使って短く記述できます。
ショートハンドでは`/cover`とすることで background-size: cover を指定することができます。


## `background-repeat` 背景画像を繰り返して表示する

|指定|説明|
|:--|:--|
| repeat | 全面にリピートして表示します。デフォルトはこの状態です。 |
| repeat-x | X方向、つまり横方向にリピートして表示します。 |
| repeat-y | Y方向、つまり縦方向にリピートして表示します。 |
| no-repeat | 名前の通り、リピートはしません。 |


## `background-size` 背景画像のサイズを調整する

画像が大きすぎて要素からはみ出してしまう時

| 指定 | 説明 |
|:--|:--|
| auto | 自動算出します。基本は元画像の大きさそのままです。 |
| contain | 元画像の縦横比は保持して、要素に元画像が全て収まるように調整してくれます。 |
| cover | 元画像の縦横比は保持して、要素をちょうどよく覆うサイズにしてくれます。 |
| 数値(px) | 明示的にpxで大きさを調整します。 |
| 数値(%) | 要素に対しての割合で指定します。 |

## 背景画像の位置を調整することができるプロパティ

| 指定 | 説明 |
|:--|:--|
| キーワードで指定 | center、left、right、top、bottomという風に、位置を言葉で指定します。 |
| 数値(%) | 要素の左上からの位置を、要素を基準にしたパーセンテージで指定します。 |
| 数値(px) | 要素の左上からの位置を、明示的にpxで指定します。 |

## `background-size`

： `auto` 基本そのままの大きさ
： `cover` 要素を埋める
: `contain` 背景画像全体が見える
Aurora Serverless MySQL(5.6) で日本語データを扱えるようにする

# 文字コードを変えよう
[Aurora Serverless を作ってみた](https://qiita.com/tokiha0s/items/e25e670f9cd0094bfb04)ものの、
`latin`という文字コード(character set)が標準で
日本語や🍺を扱えなかったので使えるようにする。

## 環境(2019/12/19)
- Aurora Serverless
    - MySQL
    - aurora 5.6

# 設定方法

## パラメータグループを作成

RDS > パラメータグループ
画像はAurora Serverless むけの設定なので注意。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545251/158696ec-083b-3ea4-0bb7-84767a63e82c.png" width=500>

## パラメータを設定
上部の「パラメータを編集」を押下し、以下のように設定していく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545251/f71cbede-34ca-1ea4-488c-30a29020c54b.png)

### character_set

[ただの utf8 だとこういうふうになる](https://tmtms.hatenablog.com/entry/2016/09/06/mysql-utf8)ので、`utf8mb4` を選択。

```
character_set_client = utf8mb4
character_set_connection = utf8mb4
character_set_database = utf8mb4
character_set_results = utf8mb4
character_set_server = utf8mb4
```

### index column size の拡張(optional)
utf8mb4 を設定して、 `varchar(255)` のキーカラムとか作ると
`mysql Index column size too large. The maximum column size is 767 bytes.`
と、[こういう理由](https://blog.kamipo.net/entry/2012/11/13/102024)で怒られる。

そんな長いキーカラム作るなよって話もあるんだけど、
[そういうの気にせずに typeorm から使いたい](https://qiita.com/tokiha0s/items/65523f95d2cecfe42ced)のでその制限を拡張する。

```
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix = 1
```

### 拡張したindex column sizeを使うために
CREATE文で、 `ROW_FORMAT=DYNAMIC` を指定する必要があった。

```sql
CREATE TABLE `retweet` (`tweetId` varchar(255) NOT NULL, ...) ENGINE=InnoDB ROW_FORMAT=DYNAMIC
```

## パラメータグループを反映

対象のデータベースの「変更」から、作成したパラメータグループを選択して保存
しばらくすると反映されるはず

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545251/ed487833-7d71-f5a4-534d-d21a16a07ae0.png" width="400">

## 結果の確認
`show variables like "character%"` すると見える

なんか utf8mb4 じゃないけどまあ問題なく使えてるから大丈夫なんでしょう。。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545251/64c8bbad-339f-a4b1-cd36-fb10bdc02779.png" width="500">
せっかくTypescriptなんだからJSONを自動でvalidationしよう(ajv+typescript-json-schema)

# はじめに

- Validationコードを手で書きたくなかった
- JSON schemaを手書きしたくなかった(typescriptの型定義を使ってほしい)

国内外たくさんやってることだけど、真似しても使うのに時間がかかった。
最小構成のコードを書く。


## まず、Validationができてない状態とは？

```typescript:index.ts
interface Cat { 
    name: string,
    age: number
}

const catObj = JSON.parse('{"name":"tamago", "weight":2.0}');
const cat = catObj as Cat;

console.log(cat.age); //undefined （Catのageはオプショナルじゃないのに！）
```



## さあ、validationしよう

1. 実行前にtypescriptコードから[typescript-json-schema](https://github.com/YousefED/typescript-json-schema)でJSON schema(.json)を生成する
2. 実行時に[ajv](https://github.com/epoberezkin/ajv)でJSON Schemaを読み込んで、JSONをvalidationする


### 1.実行前にtypescriptコードからtypescript-json-schemaでJSON schema(.json)を生成する

#### typescript-json-schemaをインストール

```shell
% npm install typescript-json-schema -g
```


#### typescriptコードからJSON schemaを生成

型情報が含まれるtypescriptファイル

```typescript:cat.ts
interface Cat { 
    name: string,
    age: number
}

export {Cat};
```

cat.tsのCat型のスキーマをCatSchema.jsonに吐き出す
（cat.tsのように単独ファイルにしていなくてもいい）

```shell
% typescript-json-schema --strictNullChecks true --noExtraProps true cat.ts Cat > CatSchema.json
```

> --strictNullChecks    Make values non-nullable by default.                         [boolean] [default: false]
> --noExtraProps        Disable additional properties in objects by default.         [boolean] [default: false]


### 2. 実行時に[ajv](https://github.com/epoberezkin/ajv)でJSON Schemaを読み込んで、JSONをvalidationする

#### ajv他をインストール

```shell
% npm install ajv --save
% npm install @types/node --save-dev
% npm install @types/ajv --save-dev
```

#### コード全体

```typescript:index.ts
import * as fs from 'fs'
import * as Ajv from 'ajv';

import {Cat} from './cat' 

const myJSON = '{"name":"tamago", "weight":2.0}'
const catObj = JSON.parse(myJSON);

const ajv = new Ajv();
const catSchema = JSON.parse(fs.readFileSync('./CatSchema.json').toString());
const validate = ajv.compile(catSchema);

if(validate(catObj)){
    console.log('validation ok');

    //安心してasを使おう
    const myCat = catObj as Cat;
}
else{
    console.log('validation ng');
    console.error(validate.errors);
}
```

実行

```shell
% ts-node index.ts
validation ng
[ { keyword: 'additionalProperties',
    dataPath: '',
    schemaPath: '#/additionalProperties',
    params: { additionalProperty: 'weight' },
    message: 'should NOT have additional properties' } ]
```

[ts-node](https://github.com/TypeStrong/ts-node)便利なのでよく使っています。

typescriptの型定義のオプショナルもちゃんと扱ってくれるようです。


## まとめ

事前のJSON Schema生成はいるが、自動でvalidation環境が作れる。
丁寧な日本語メッセージを返したい場合は、ErrorObject型をアレコレしましょう。

Typescriptの標準機能で欲しい。
API経由でSlackのポストをチャンネルに送信するとき、たまに現れる不要な改行を消す

# 現象
API経由でSlackのポストをチャンネルに送信すると、なぜかたまに不要な改行が現れて困っていました。ここでは、それを修正します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80956/f49977b1-bdf9-7d4e-f7e2-12b5cce9364d.png)


# ポストとは
https://slack.com/intl/ja-jp/help/articles/203950418
> ポストを使うと、Slack 上で直接、書式付きのドキュメントを作成し、編集・共有することができます。プロジェクトの計画や議事録など、長文のコンテンツを共有して共同編集するのにおすすめです。
チャンネルへメッセージを送信するのとは異なり、ポストでは追加の書式設定オプションが利用でき、他のメンバーと共同作業することができます。

# API経由でポストを普通に送信する場合
[SlackのAPIドキュメント](https://api.slack.com/methods/files.upload)
APIで送信するArgumentsはこんな感じになります。

```
$content = 'ポストの本文\n\nこの下に不要な改行が現れるhttps://qiita.com/\n\nこういうときに、下の行に改行は現れないhttps://qiita.comこの下の行を見よう改行は現れなかった本文終わり'

{
    token: [access_token],
    channels: [channels],
    initial_comment: [initial_comment],
    content: $content,
    filetype: "post",
    title: [title]
}
```

しかし、このままでは冒頭の画像のように、なぜか2行目の下に謎の改行が現れてしまいます…

# たまに現れる不要な改行を消す
## 改行の現れる条件
URLを文末として、そのすぐあとに改行が続くときに、余計な改行が増えます。
冒頭だと`この下に不要な改行が現れるhttps://qiita.com/`に当たる部分です。

一方、文末がURLでない場合は改行が増えません。たとえば、以下のような場合です。
`こういうときに、下の行に改行は現れないhttps://qiita.com この下の行を見よう`

## 修正方法
URLが文末に来るときは、下記のように、半角スペースを改行前に1文字入れると正しくポストできるようになります。

```
// ここを
$content = 'ポストの本文\n\nこの下に不要な改行が現れるhttps://qiita.com/\n\nこういうときに、

// こうだ！
$content = 'ポストの本文\n\nこの下に不要な改行が現れるhttps://qiita.com/ \n\nこういうときに、
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80956/53576a5d-06d5-115b-c6d0-e77a5f5af862.png)

無事修正されました！
みなさま楽しいSlack連携ライフを！
データサイエンス学ぼう

### Python
(未記載）

### 機械学習（入門）
1. [モデルの仕組み](https://qiita.com/buithean2010/items/1835d05fac5dd0107b19)
2. データ分析入門
3. 機械学習の初モデルを作りましょう。
4. モデルを検証しましょう(Model validation)
5. Underfitting and Overfitting
6. Random Forest
7. まとめて練習宿題

### 機械学習（中級）
（未記載）
メモ：[Python3]datetimeを好きなフォーマットの文字列に変換

## strftime()を使う
```python
>>> from datetime import datetime
>>> datetime.now().strftime('%Y%m%d-%H%M%S')
'20191219-140750'
```
https://docs.python.org/ja/3/library/datetime.html#strftime-and-strptime-format-codes


## ISO 8601 形式

```python
>>> datetime.now().isoformat()
'2019-12-19T14:11:53.346885'
```
transformプロパティを使って要素を上下中央に配置する


### HTML

```index.html
<div class="box>
  <img src="dummy.png" alt="" width="24" height="24" class="img" >
</div>
```

### CSS

```app.css

.box {
   position:relative;
   height:300px;
}
.img {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
}

```

### absolute による要素の固定

![IMG_4833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446210/61e0d0da-ef58-1a75-e8d0-92b3de869448.jpeg)


`absolute` による要素の固定は**赤い丸の点**
**`左上`**を起点としているので、`left: 50%` `Top:50%`ではこの位置になる。
これでは**`Box`要素**に対して上下中央ではないので、

```app.css
transform: translate(-50%, -50%);
```

![IMG_4834.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446210/8f0fbafe-96e3-10b0-5a03-af216572a43c.jpeg)


**`translate(X方向の距離, Y方向の距離)`**
translate()関数では、X方向とY方向の距離で2D移動を指定します。 Y方向の距離は省略することができますが、この場合のY方向の距離は0となります。[tx, ty]
**`translateX(X方向の距離)`**
translateX()関数では、X方向の距離で移動を指定します。
**`translateY(Y方向の距離)
translateY()関数では、Y方向の距離で移動を指定します。
【Laravel】イベントとリスナーの関係について整理する

Laravelには、イベントとリスナーという機能があります。

[Laravelの公式サイト](https://readouble.com/laravel/5.5/ja/events.html?header=%25E3%2582%25A4%25E3%2583%2599%25E3%2583%25B3%25E3%2583%2588%25E3%2583%25AA%25E3%2582%25B9%25E3%2583%258A%25E3%2581%25AE%25E3%2582%25AD%25E3%2583%25A5%25E3%2583%25BC%25E6%258A%2595%25E5%2585%25A5)には、イベントとリスナーの作成方法は書かれているものの、イベントとはなにか、リスナーとは何かについては書かれていないようです。

エンジニアとして基礎中の基礎だから教えるまでもないということなのでしょうか。
残念ながら僕はその基礎ができていないようなのでイベントとリスナーについて調べてみました。

## イベントとリスナーの関係性

[https://www.ritolab.com/entry/35](https://www.ritolab.com/entry/35)
こちらの記事を参考にすると、こう説明されています。

>オブザーバパターンとは、デザインパターンの一つで、簡単に言うと監視される側と監視する側の関係を持つプログラム構造で、監視される側の変化（イベント=発行）を、監視する側（リスナー=購読）がキャッチして処理を行う。

イベントとリスナーの関係のことをオブザーバーパターンというらしいです。
そして、毎回混乱するのは、**監視される・監視する**の意味です。

監視の定義が曖昧すぎて、もっと噛み砕いてもらわないとわかりません。
なので、僕なりに噛み砕いてみました。

### イベントとリスナーの書き方

イベントは監視される側らしいのですが、まず誰に監視されるのかというと、リスナーですね。ここまではわかります。
そして、何を監視されるのか、これは、**イベントの中身**です。

イベントは、以下のようなeventヘルパを利用することで呼び出すことができます。
`event(new AccessDetection(str_random(100)));`

そして、`EventServiceProvider.php`にイベントが起こった時にリスナーを発動させるよう登録をしておきます。

```EventServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App\Events\Event' => [
            'App\Listeners\EventListener',
        ],
        // アクセス時にイベントを発行する側
        'App\Events\AccessDetection' => [
            // テキストを生成＆書き込みを行うリスナー側
            'App\Listeners\MakeTextListener',
        ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        //
    }
}
```

`app/Events/AccessDetection.php`の中身に、値の受け渡しなどを記述しておきます。
そうすると、イベントが呼び出されたときに、リスナーで値を使うことができます。

最後に、リスナーの内容を記述します。

```app/Listeners/MakeTextListener.php
<?php

namespace App\Listeners;

use App\Events\AccessDetection;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class MakeTextListener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  AccessDetection  $event
     * @return void
     */
    public function handle(AccessDetection $event)
    {
      // テキストファイル作成
       $file = sprintf('%s/%s.txt', storage_path('texts'), date('Ymd-His'));
      touch($file);
      // 書き込み
       $current = file_get_contents($file);
      $current .= $event->param;
      file_put_contents($file, $current);
    }
}
```

### イベントからリスナーが発動するまでの流れ

イベントが起こって、リスナーが発動するまでの流れを整理しておきます。

1. コントローラーでeventヘルパを使って、イベントを起こす
2. プロバイダーに登録してあるイベントが呼び出される
3. イベントに記述した値がリスナーに受け渡される
4. リスナーが発動する


このような流れになります。

## イベントとリスナーの使いみち

一般的には、コントローラーをコンパクトにするために使われます。

例えばメール送信機能は、ユーザ登録時、購入時、更新時などで共通して使われますが、それをコントローラーに書いていたら内容が重複してしまいます。

なので、イベントとリスナーに記述しておいて、それぞれのコントローラからイベントを起こすだけで、メール送信ができるようにしておくのです。

使いみちはいろいろありますが、メールやslackへの通知の際に使うのが一般的かなと思います。
機械学習入門：モデルの仕組み

## シナリオ
海外に住んでいる親友が不動産投資で数千万円稼ぎまし。ビジネスを広めたがるので、あなたを「ビジネスパートナーになってくれない？」と誘います。彼がお金を出して、データ分析スキルのあるあなたが物件の価格を予測するパータン（モデル）を作ります。

## 決定木 (Decision Tree)
「どうやって物件の価格を予測、判断しているのか」とあなたが聞きました。
「直感だよ」って答えられました。
機械学習で直感により価格予測モデルを作るのはありえないでしょう？
もっともっと詳細的に聞いて、あなたが何となく分ってきました。
<img width="257" alt="simple-decision-tree.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427676/61707d86-3022-6527-ae6d-cc8ee4032474.jpeg" style="margin-left:25%">

物件の価格が２つグループに分けられます。

つまり、物件価格の予測は、以下２ステップで行われます。
1. 物件を２つのグループに分ける
2. グループごとの価格をセットする

この手順は、fitting modelもしくはtraining modelと呼ばれます。
モデルをfitするデータは、training dataと呼ばれます。

fitしたモデルを使って、投資しようとする物件の価格を予測しましょう。

## モデルを改善する
どれの決定木がtraining dataに合っていますか。
<img width="771" alt="which-tree.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427676/26acfef8-bc2e-4f5a-c845-23613b6dc7e4.jpeg">

普通に考えると、決定木１の方が良いと思われますね。大きい物件が小さいのより高いでしょう？ただし、大きさのみで物件価格が決まるわけではないですね。他にも物件価格に影響を与えるたくさん要因（場所、構築年など）があります。
他要因も含めて決定木は以下のようになります。
<img width="411" alt="deeper-tree.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427676/c039a4d0-708f-ac7d-671d-be040a43e81b.jpeg">


物件の特徴に相応しいパスを選択して、予測価格は決定木の底ノードにあります。
予測物価を持つ底ノードはleafと呼ばれます。

#次へ
決定木の枝数とleaf値はデータにより決まります。
次回は、データ分析を行いましょう。










> 他の関連記事は[こちら](https://qiita.com/buithean2010/items/1835d05fac5dd0107b19)です。
強化学習３９　Colaboratory+ Breakout + chainerRL GPUを使う

中学生から大学生までのAI初学者を対象にしています。
強化学習３８まで終了していることを前提にします。

このシリーズも、ついにGPGPUに突入です。
ChainerRL/examples/atari/train_dqn_ale.py
を改造して使います。改造したものは、
chokozainerRL/train_dqn_ale.py
に入れておきました。
Colaboratory notebookは、github/chokozainerの
dqn_ale.ipynbsを使用してください。

こちらのdqnは、NatureDQNを使っています。
こちらと同程度と推測されます。
https://chainer-colab-notebook.readthedocs.io/ja/latest/notebook/hands_on/chainerrl/atari_sample.html
こちらでは、11時間かかると紹介されていましたが、もう少しかかる印象です。

最初に考えるべきは、時間です。
こちらを参考にしてください。
https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935
９０分ルールと１２時間ルールがあるので、途中でセーブする必要があります。
結論から言うと100000stepsで、約10分間かかります。
10000000stepが推奨されているようですが、1000分間＝16時間くらいは必要になります。
でも、300000stepでそれなりに学習は進みますので、5時間くらいあれば、なんとなく雰囲気はつかめます。

次に容量です。
1回のバックアップ保存で、約30Mbのファイルができます。なので、100000〜500000stepsの間でバックアップサイクルを決めるといいでしょう。
chokozainerRLでは、args.checkout_frequencyで設定します。

最後に、途中からの学習です。
直前のバックアップが、「376842_except」だったとします。

```python
args.load_agent=thisdir+"/376842_except"
args.step_offset=376842
```
のように設定すると途中から実行されます。

面倒だったので、3500000stepsで終了しましたが、max174まで学習できました。