OmniAICreator/Qiita-1.07M huggingface dataset:
趣味と実益(＝自分の勉強)をかねて始めたPSRsの翻訳の話

この記事は[PHP Advent Calendar 2019](https://qiita.com/advent-calendar/2019/php) 21日目の記事です。

こんにちは、あのぶる(@thatblue / [@thatblue_plus](https://twitter.com/thatblue_plus))と申します。

最近趣味でPSRsの翻訳を始めました。
今日までにPSR-12とPSR-1の翻訳が終わっていて、こちらにまとめてあるのでよろしければどうぞ。
誤訳などありましたらどうかお手柔らかにご指摘ください……
[PSRs in Japanese by thatblue](https://thatblue.github.io/fig-standards/)

はじめはわりと最近出たPSR-12を勉強がてら翻訳していたら楽しくなってきちゃって、PSR-12から参照されていたPSR-1を訳し、今度はPSR-1から参照されいていたPSR-4に手を出そうとしたところで珍しく師走の慌ただしさに飲み込まれているところでした😇

PSR-12の翻訳が終わったときに[自分のブログ](https://blog.innotamago.com/entry/2019/10/14/231250)にも書いたのですが、新人の頃からドキュメントの翻訳活動に漠然とした憧れがあったので、実現まで随分かかってしまいましたがやれてよかったなーと思っています。

で、これだけで終わらせるのは流石にアレなので、自分で翻訳をしてみて気付いたことを簡単にまとめます。翻訳やってみたいと思っている人の参考になると嬉しいなぁって思います。

## 技術ドキュメントは比較的翻訳しやすいかもしれない(注: 簡単とは言ってない)
文書の目的に起因して、基本的に内容が明確なので解釈で悩む余地があんまりなく、悩んでもソフトウェア技術なので「実際に動かしてみたらいいじゃん」で解決するケースが多いなぁと感じました。
そのせいか、PSR-12を訳したときは文章量に対して序文が一番時間がかかりました。Lingueeなど知る限りの翻訳支援ツールを駆使してどう訳すのが適切なのかを必死に考えていました。

ということで、100%知らないところから勉強のためにと言うよりは、ある程度背景知識があり用語も含めて確認の手段を知っている技術についてのドキュメントを訳すのが望ましいかなと思います。
いや落ち着いて考えたら当たり前の話なんですけども。

## ドキュメントのライセンスをよく確認する
ドキュメントの翻訳は「改変」にあたるようなので、改変OKになっているかライセンスをよく確認しましょう。
OSSなどに属するようなドキュメントは概ね翻訳できそうなライセンスになってそうなので(※個人の感想です)ともかく、商用サービスのマニュアルや個人のブログはライセンスが判断できなければ公開前に許可を取るのが望ましいと思います。
ちなみにPSRsは[MITライセンス](https://www.php-fig.org/bylaws/licensing-policies/)でした。

## 自信がないけどやってみたい場合は翻訳プロジェクトを探して参加してみるといいかも
……いや、あの、「じゃあお前翻訳にそんな自信あるの」って言われると困るんですが……今回の動機は「PSRsをちゃんと読んで勉強したい」だったのでなんというかその許してください。

私は参加したことはないのですが、先達のサポートを受けられるのはやっぱりありがたいのではないかと思います。

## かの有名な[インフィニットループさんのPSR-1訳](http://www.infiniteloop.co.jp/docs/psr/psr-1-basic-coding-standard.html)がいかになめらかであるかがよくわかった
元々存在を知っていたのでPSR-1については「自分の勉強のため」と割り切ってはいたのですが、翻訳し終わってから改めて概要読んだだけで「ひえぇ(伏し拝み)」ってなりました。

---- 
それでは、あのぶる先生の次回作にご期待ください(!?)
差動2輪ロボットとタイヤの回転の関係

Δt秒の間の運動を考えたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550140/49665653-0fb3-c442-9a69-88f188f56904.png)
円運動する物体の速度は、$v=rω$より

```math
v_R=(ρ+d)ω \\
v_L=(ρ-d)ω \\
　\\
v_R+v_L=2ρω \\
v_R-v_L=2dω \\
　\\
ρω=v \\
　\\
v=\frac{v_R+v_L}{2} \\
ω=\frac{v_R-v_L}{2d} \\
　\\
v=rω \\
　\\
ρ=\frac{d(v_R+v_L)}{v_R-v_L} \\
 =\frac{d(\frac{v_R}{v_L}+1)} {\frac{v_R}{v_L}-1} \\
 =\frac{d(kv+1)} {kv-1} \\
 =d+\frac{2d}{kv-1} \\
```
かっこよく書くと、

```math
\begin{bmatrix}
v \\
ω
\end{bmatrix}
=
\begin{bmatrix}
\frac{1}{2} & \frac{1}{2} \\
\frac{1}{2d} & -\frac{1}{2d}
\end{bmatrix}
\begin{bmatrix}
v_R \\
v_L
\end{bmatrix}
```
つまり、速度と位置の関係を記述できた
<img width="747" alt="Screen Shot 2019-12-17 at 15.37.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550140/d611bf25-573f-c10e-ddbe-4f93459a5b78.png">
モーターの動きをシミュレーション

電圧Eを入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550140/27c3feb6-6f43-d6f6-a8fb-4f84b377e08f.png)モータの等価回路
Δt秒間のRL回路のステップ応答になる

```math
E = Ri(t) + L \dfrac{di(t)}{dt} \\
\dfrac{1}{i(t) - \dfrac{E}{R}} \cdot di = -\dfrac{R}{L} \cdot dt \\
\displaystyle\int \dfrac{1}{i(t) - \dfrac{E}{R}} \, di = -\int \dfrac{R}{L} \, dt \\
\log_e \left| i(t) - \dfrac{E}{R} \right|=\dfrac{R}{L}t+A
```
絶対値の中は$i(t) - \dfrac{E}{R}$ですが、i(t)は回路に流れる電流で、$\dfrac{E}{R}$はコイルLが短絡された状態（つまり、定常状態）での電流なので、$i(t) \leqq \dfrac{E}{R}$となり、絶対値の中は常にゼロ以下になります。よって、絶対値は外せる。

```math
\log_e \left( i(t) - \dfrac{E}{R} \right)=\dfrac{R}{L}t+A \\
\dfrac{E}{R} - i(t) = e^{-\frac{R}{L} t + A} \\
\dfrac{E}{R} - i(t) = e^A \cdot e^{-\frac{R}{L} t} \\
```
t=0で初期電流i<sub>0</sub>とすると、

```math
e^A = \dfrac{E}{R}-i_0 \\
\dfrac{E}{R} - i(t) = (\dfrac{E}{R}-i_0) \cdot e^{-\frac{R}{L} t} \\
-i(t) = -\dfrac{E}{R} + (\dfrac{E}{R}-i_0) \cdot e^{-\frac{R}{L} t} \\
i(t) = \dfrac{E}{R} - (\dfrac{E}{R}-i_0) \cdot e^{-\frac{R}{L} t}
```
Δt秒後の電流は
$$i_{t+1}=\dfrac{E}{R}-(\dfrac{E}{R}-i_t) \cdot e^{-\frac{R}{L} Δt}$$
痩せたいエンジニアが作ったもの

[TechCommit Advent Calendar 2019](https://qiita.com/advent-calendar/2019/tech-commit)21日目担当のK.Sです．

今回は，エンジニアの敵だと勝手に思っている食事管理について書きたいと思います．

勝手なイメージですが，エンジニアの方は座ってのお仕事が大半になるため，
運動不足による体型の変化が起きやすいと考えています．

食事や運動の自制がしっかりとできない私は，大学入学からどんどんと
体積的に向上し続けているため，ダイエットについて本気で考えてみました．

# 痩せるためには
痩せるために一番効果的なのは，食事管理です．

よく，30分運動をしても消費されるカロリーは数百kcalで，これはお茶碗の半分のお米に
相当します（てきとう）．みたいな例えありますよね．
つまり，食事管理を正しくすることが一番の近道だということです．

## 痩せるためのシンプルな公式

**摂取カロリー　−　消費カロリー　<　0**
この公式が痩せるための最強の公式．
この式から，食事制限による摂取カロリーを減らすか運動による消費カロリーを増やすかすれば
痩せることがわかりますが，最初に述べたことから食事管理によるアプローチを考えます．

食事管理というと，糖質制限とか朝〇〇ダイエットとか
朝食べないor食べるとか，夜控えた方がいいんだ，とかいろいろ言われていると思います．

人によっては簡単に行えるものがあると思いますが，結果に関しても個人差があるものだと思っています．

どれが自分に合うのかとか，どれが本当に聞くかとか調べてるうちに面倒になって投げ出してしまうことがありました．

そこで，原点に立ち返りました．
上記の公式に従いさえすれば痩せる．簡単な話．

## カロリー制限の罠

公式に基づき，摂取カロリーを0に近づければ，一番速く痩せるやろ．という考えは危険．
なぜなら人は，生きているだけでカロリーを消費しているからです．
これを基礎代謝と言います．

**摂取カロリー　−　消費カロリー　<　基礎代謝**
もし上記式が成り立ってしまうとどうなるでしょうか．
基礎代謝とは，心臓などの臓器を動かすときに必要となるカロリーですので，
不足すると死にます．

そこで体は，上記式を満たす状態になるとセーフモードとなり
カロリーの消費を抑えようとするため，痩せにくい体になります．

また，極端なカロリー制限は筋肉量の減少を招きます．
筋肉量は，基礎代謝に影響しており，減少すると基礎代謝も減ります．

つまり，無謀なカロリー制限は悪循環を招き痩せないわけです．

## じゃあどうすればいいのか
以上のことをまとめると，
**基礎代謝　<　摂取カロリー　−　消費カロリー　<　0**
を目指す必要があります．
このときの筆者のように運動をほとんどしない人は満たす条件が非常に狭くなるため，
日々の摂取カロリーを正確に把握していく必要があります．

しかし，めんどくさい．

# 食事管理アプリで記録
そこでアプリを作りました．
![スクリーンショット 2019-12-21 13.26.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235728/aafdf382-0361-0255-93f7-05542b761ef2.png)
[アプリトップページ]

![スクリーンショット 2019-12-21 12.54.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235728/d0c9ea23-f1a1-58e2-ced9-69aec479cd60.png)
[ユーザー登録後マイページ]

ユーザー登録と個人情報の登録によって，自動で基礎代謝を計算しています．
そのため，おおよそではありますが自分が何kcal以上摂取する必要があるかを理解できます．

![スクリーンショット 2019-12-21 12.58.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235728/24b3fac9-9df2-bc46-37dc-b3439ebebf64.png)
[食事管理画面]
肝心の食事管理画面です．
過去1週間分の摂取カロリーの推移がグラフによって可視化しています．
また，食事のタイミングを登録しているので，各タイミングごとの確認も可能です．

![スクリーンショット 2019-12-21 12.58.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235728/c34c9178-79d8-ca38-30a8-e1a965e3a429.png)
[昼に絞った場合]

![スクリーンショット 2019-12-21 12.55.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235728/f8bb45ab-1c76-776f-4491-c53cbc90b299.png)
[食事登録画面]

掲示板から作った感が半端ないですね．．．

# 反省・改善点など

## 食事メニュー登録がめんどくさい
めんどくさいからこそ，食事の量が減るなど期待できることもあるが，
アプリの使用が続けられないと元も子もない．．．

## グラフに基礎代謝の反映がない
せっかく計算しているのに，グラフに反映していないのでもったいない

## 平均的な消費カロリーの算出をしていない
体脂肪率なども登録すれば，おおよそはすぐに計算できる．

## 別日のメニュー詳細を見るリンクがない
その日のメニューが勝手に出るようになっているが，前日以降のメニュー一覧ページに移動できない．
グラフの点をリンクにしたかったが，だきょった．

## ユーザーの詳細登録を後付けで作ったため挙動が変
これに関しては原因がまだわかっていない．
railsのリソースベースルーティング？に基づいていないから？
（ユーザー1人に対して1セットの個人情報を紐付けようとしたため．）

# 結論
カロリーママを使おう．
BERTおよびWord2Vecで文の類似性を確認する

# BERTおよびWord2Vecで文の類似性を確認する

## TL;DR

文の類似性を確認する方法として`BERT`と`Word2Vec`を比較します。
文全体の類似性ではなくトークン単位での比較です。

BERTとWord2Vecによるベクトル化には[text-vectorian](https://pypi.org/project/text-vectorian/)を使用します。

## ソースコード

```python
from text_vectorian import SpBertVectorian

tokenizer_filename = '../bert-japanese/model/wiki-ja.model'
vectorizer_filename = '../bert-japanese/model/model.ckpt-1400000'

bert_vectorian = SpBertVectorian(
    tokenizer_filename=tokenizer_filename,
    vectorizer_filename=vectorizer_filename
)
```

```python
from text_vectorian import SentencePieceVectorian

word2vec_vectorian = SentencePieceVectorian()
```

```python
import numpy as np
import pandas as pd

def cossim(v1, v2):
    return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))

def get_vectors(vectorian, text):
    vectors = vectorian.fit(text).vectors
    tokens = vectorian._tokenizer._tokenize(text)

    return tokens, vectors

def get_df(original_text, my_text):
    data = []

    original_bert = get_vectors(bert_vectorian, original_text)
    original_word2vec = get_vectors(word2vec_vectorian, original_text)
    my_bert = get_vectors(bert_vectorian, my_text)
    my_word2vec = get_vectors(word2vec_vectorian, my_text)

    for i, token in enumerate(original_word2vec[0]):
        original_token = original_bert[0][i]
        original_bert_vector = original_bert[1][i]
        original_word2vec_vector = original_word2vec[1][i]
        my_token = my_bert[0][i]
        my_bert_vector = my_bert[1][i]
        my_word2vec_vector = my_word2vec[1][i]

        bert_sim = cossim(original_bert_vector, my_bert_vector)
        word2vec_sim = cossim(original_word2vec_vector, my_word2vec_vector)

        data.append((i, original_token, my_token, bert_sim, word2vec_sim))

        df = pd.DataFrame(data, columns=('index', 'original token', 'my token', 'cos diff(bert)', 'cos diff(word2vec)')).set_index('index')
        df['cos diff(bert)'] = 1- df['cos diff(bert)']
        df['cos diff(bert)'] = df['cos diff(bert)'].clip(0.01, 1).replace(0.01, 0)
        df['cos diff(word2vec)'] = 1- df['cos diff(word2vec)']
        df['cos diff(word2vec)'] = df['cos diff(word2vec)'].clip(0.01, 1).replace(0.01, 0)

    return df
```

```python
original_text = '今日は室内が大変暑いです。'
same_text = '今日は室内が大変暑いです。'
my_text = '今日は部屋がとても寒いです。'

same_df = get_df(original_text, same_text)
diff_df = get_df(original_text, my_text)

display(same_df.style.bar())
display(diff_df.style.bar())
```

## まとめ

同一の文の場合は差異がありません。

![](https://www.inoue-kobo.com/ai_ml/sentence-similarity/images/same-sentence-similarity.png)

一部が異なる文の場合は以下の様に差異が確認できます。

![](https://www.inoue-kobo.com/ai_ml/sentence-similarity/images/diff-sentence-similarity.png)

`BERT`の場合はトークンの前後の関係を考慮するためトークン毎の比較では単純な違いを確認することができません。
`Word2Vec`であれば、単純なトークン単位での違いを確認することが可能です。

## 参考文献

* [自然言語ベクトル化用Pythonモジュール(text-vectorian)をリリースしました](https://www.inoue-kobo.com/ai_ml/text-vectorian/index.html)
* [もっと簡単に Keras BERT でファインチューニングしてみる](https://www.inoue-kobo.com/ai_ml/keras-bert-with-text-vectorian/index.html)
ボディビルダーが泳ぐシェル芸

# ボディビルダーが泳ぐシェル芸とは？
![t.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143996/6385778e-03c4-b0c1-8144-b8530b20b87d.gif)
こういうアニメーションを作るシェル芸です。
ボディビルダーがなんか叫んでますね。ちょっとゆっくりにしてみましょう。
![t.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143996/ae210df4-3409-dbcd-5eb8-2e4a523a750d.gif)
正弦波泳法という泳ぎ方のようです。
作っていきましょう。
前提条件は、[`textimg`](https://github.com/jiro4989/textimg)、[`muscular`](https://github.com/amanoese/muscular)がインストールされていることです。

# コマンドができるまで
## STEP1. ボディビルダーを出す
ボディビルダーを出します。
コマンドと実行結果

```bash
$ muscular shout フロントリラックス -p front-relax
        .-~-.          
        /   \          
        |   /          
     ,_-/ ,.*`--.,     
   .r ;       ``  \    
  .`,`   ,:  ,.`A`,\   
 /,`/\`''  ''  ? \` \  ＿人人＿
/  /  \ ; , ; /   )  } ＞ フ ＜
| /    \:':': |   | 7  ＞ ロ ＜
| |    ) ':'  |  ,` /  ＞ ン ＜
( \    `-,_,-~}  | l   ＞ ト ＜
 `~   / `,  /' \ '"'   ＞ リ ＜
     ,7   \/   |.      ＞ ラ ＜
     {  ; |, ,  )      ＞ ッ ＜
     |,`: |`,`: |      ＞ ク ＜
     \` , /\`.; /      ＞ ス ＜
      |`;/  \ , |      ￣Y^Y^￣
      \``\   |` (      
      \ . )  {  /      
       \ `/  (  }      
        \ |  | /       
        ) \  | |       
     c~^_~d  V _`,     
                       
```
qiitaのシンタクスハイライトでちょっとカラフルになっちゃってますが、
` muscular shout `の` -p `オプションでポーズを指定しています。
## STEP2. スクロールしてアニメートする
1行ずつスクロールしてアニメーションにしましょう。
コマンド

```bash
$ muscular shout 上がれ！ -p front-relax|tee >(cat) >(cat) >(cat) >(cat)|tee >(cat) >(cat) >(cat) >(cat)|textimg -asl25
```
出力アニメ
![t.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143996/1541a7c6-1d49-a027-527a-4f5d4dd1f713.gif)
前ステップで出したボディビルダーは身長が24行あるので、
25人に分裂させて、25行ごとに区切ってやると
25行24フレームの、1行ずつずれたボディビルダーが得られます。
25人に分裂させるために、前ステップのコマンドのうしろに
``` |tee >(cat) >(cat) >(cat) >(cat)|tee >(cat) >(cat) >(cat) >(cat) ```
としていますね。ここが今回ちょっと苦しいところなんですけど、
5回リピートを2回かけて25回リピートしています。
続けて``` textimg -asl25 ```とすることで、25行ごとに区切ってアニメートしています。
## STEP3. 正弦波のスペースを入れる
ボディビルダーの左側に正弦波のスペースを入れてやると、
正弦波泳法になります。
コマンド

```bash
$ muscular shout 正弦波泳法 -p front-relax|tee >(cat) >(cat) >(cat) >(cat)|tee >(cat) >(cat) >(cat) >(cat)|awk '{PI=4*atan2(1,1);for(i=0;i<(sin(NR/25*PI*2)+1)*5;i++){printf " "}{print $0}}'|textimg -asl25
```
出力アニメ
![t.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143996/6dad158f-9713-f1f0-f9c8-88907a5a2a6f.gif)
前ステップのあと、``` awk ```のfor文で繰り返しスペースを入れています。
繰り返し回数を決めている部分は``` (sin(NR/25*PI*2)+1)*5 ```となっています。
25行ごとに位相が2πだけ進んで正弦波が一周します。
円周率PIは``` atan ```で得ています。
1を加えて5をかけることで、0から10までの幅の正弦波になります。
スピードアップしましょう。
コマンド

```bash
$ muscular shout 正弦波泳法 -p front-relax|tee >(cat) >(cat) >(cat) >(cat)|tee >(cat) >(cat) >(cat) >(cat)|awk '{PI=4*atan2(1,1);for(i=0;i<(sin(NR/25*PI*2)+1)*5;i++){printf " "}{print $0}}'|textimg -asl25 -d5
```
出力アニメ
![t.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143996/aea6b844-ddd1-9a2d-29dd-e99bf6271b5d.gif)
完成です。
# まとめ
` muscular `と` textimg `を使って、正弦波泳法で泳ぐボディビルダーのアニメを作ることができました。
いや正弦波泳法って何…？こわ…
MQLの基本的な関数とか

さっくりとだけ解説。
詳しい話は[このサイト](https://yukifx.web.fc2.com/sub/reference/03_mql4program/cone/mql4_ProgramRun.html)を見てください。

###最初についてくるvoidとかintとかdoubleって何？
戻り値の型です。代入するときに使います。
intは整数(integer)、doubleは小数（**倍**精度浮動小数点数）、void(何もなし)

例えば

```MQL:test
a = TimeCurrent();
```

みたいなことをすると、aにはその時のサーバー時間が「整数」で入ります。
「int TimeCurrent(){}」みたいに定義されてるので、整数が入るわけです。
このintがdoubleであったならば小数だし、voidであれば入れる値がないのでエラーとなるはずです。

他にもいろいろありますが、bool(真偽値)とstring(文字列)、datetime(日付時刻)だけでもいろんなことができます

#EA,インジケータ、スクリプト共通
###宣言部
下に羅列されている関数（On~~~）共通で使う変数、定数を定義する。
ここで宣言せず、以下の関数内で宣言した場合は、その関数のみで使われることになる。

例えば、EAが稼働した期間を測定したいとする。その場合、最初と最後のサーバー時間の差を求めればいい。
OnInit()EAを開始したときのサーバー時間を記録しておいて、OnTester()でその時のサーバー時間との差を求める。
複数の関数で同じ変数を扱う必要があるため、ここに定義する必要がある。

###int OnInit(){}
Initialize（初期化する）。voidもOK
EAが稼働し始めて最初に通る場所。
最初に初期化したいものを入れておく。
例）EAが開始したときのサーバー時間

###void OnDeinit(){}
Deinitialize（初期化をもとに戻す）。
EAを終了するときに呼び出される関数。
何に使うんだろ？ファイル書き込みを終了するとか？

#EA, インジケータ共通
###void OnTimer(){}
指定の時間が経過したら通る。
時間指定をするには、OnInit()内でEventSetTimer(int)を利用する。intには指定した秒数を入れる。
タイマーを解除するには、EventKillTimer()を利用する。
OnTickで良くない？って思う

###void OnChartEvent(){}
チャートに何かあったときに通る。
「何が」あったときに通すのかは設定できる。
例）クリックされた、更新された、カーソルが入った・出た

#EAのみ
###void OnTick(){}
Tickごとに処理される。めっちゃ使う。

###double OnTester(){}
バックテスト・最適化のときのみ。
OnDeinit()の手前で呼び出される
MT5ではカスタム最大を返すことができる。便利。

#インジケーターのみ
###int OnCalculate(){}
OnTickとほぼ同じ。インジケーターを表示するのに必要な値を計算する場所。

#スクリプトのみ
###void OnStart(){}
スクリプトを開始したときに通るはず。
ターミナルでSQL文を使ってDB操作

###MySQLに接続

```sql
mysql -u root
```
###データベースの確認

```sql
SHOW DATABASE;
```

 ###データベース作成

```sql
CREATE DATABASE データベース名;
```

###使用するデータベースの選択

```sql
USE データベース名;
```

###テーブル作成

```sql
CREATE TABLE テーブル名(カラム名 データ型);#カンマ区切りで複数カラム作成可。
```

###カラムを見る

```sql
SHOW columns FROM カラム名;
```
###カラムの追加

```sql
ALTER TABLE テーブル名 (カラム名 データ型);#カンマ区切りで複数カラム作成可。
```
ロボトレーサの直線の加速度のFF制御

ロボトレーサーに10[m]の直線を走らせる問題について考えましょう！
さて、入力できるのは電圧だけです。しかも、−9[V]〜9[V]
最大加速度に保つための電圧の表を作りたい
加速度制御のフィードフォワード制御と言うことになるのでしょうか。。
ロボトレーサーの概要
m：0.1[kg]
モータ：Maxon DCX 10 4.5V
https://www.maxongroup.co.jp/medias/sys_master/root/8828861612062/069.pdf
タイヤ：外径：0.013[m]→半径：r=0.0063[m]
　　　　重さ：0.02[kg]
　　　　慣性モーメント：J=(モータの慣性モーメント)+$\frac{1}{2}mr^2$
　　　　　　　　　　　　　$=0.151・10^{-7}+\frac{1}{2}・0.02・0.0063^2$
　　　　　　　　　　　　　$=0.151・10^{-7}+3.969・10^{-7}=4.12・10^{-7}[kg・m^2]$
~~タイヤにかかる垂直抗力は2輪だとすると、半分になるので、~~
~~最大静止摩擦力：$F_0=μ\frac{m}{2}g=1・0.05・9.8=0.49[N]$~~
~~最大加速度： $a=\frac{F_0}{m}=\frac{0.49}{0.1}=4.9[m/s^2]$~~
垂直抗力が半分になっても、モータが２つあれば、力も半分になるので関係ないんだった。。
最大静止摩擦力：$F_0=μmg=1・0.1・9.8=0.98[N]$
最大加速度： $a=\frac{F_0}{m}=\frac{0.98}{0.1}=9.8[m/s^2]$
確認：
10[m/s]で走行する時、$\frac{10}{0.0063}=15157[rad/s]$
$9.8[m/s^2]$で走行する時、F=maより、F=0.1*9.8=0.98[N]が作用反作用の法則よりタイヤにかかる
トルクに変換すると、$τ=0.98・0.063=6.2・10^{-3}[N・m]$

シミュレータ：
***
<img width="814" alt="Screen Shot 2019-12-21 at 9.29.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550140/10174622-25c4-bb6d-eaac-af1e2a13a6b0.png">
電圧Vを入力すると、Δt秒後
$$V=V_{in}-E_0$$

$$i_{t+1}=\frac{V}{R}-(\frac{V}{R}-i_t)・e^{-\frac{R}{L}Δt}$$

$$τ_{t+1}=Ki$$

モータは2つあるので、$τ=τ・2$

$$α_{t+1}=\frac{τ}{m・r^2+J}$$

$$ω_{t+1}=α・Δt$$

$$E_0=Kω$$
***
なんで、慣性モーメントに$m・r^2$足したのか？
加速度aで、慣性力F=maで、$\frac{r}{r}F=\frac{r}{r}ma$で、$\frac{1}{r}T=rmα$で、$T=r^2mα$で、
τ=Jαで、角加速度αが一致するはずだ。角加速度α[$m/s^2$]で走行するために必要なトルク=$r^2mα+Jα$
後は、αについて解く。
つまりね、質量mの物体をタイヤの半径rで動かそうとする時、慣性モーメントは$m・r^2$
もっと言うとね、タイヤは同じトルクを入力しても、質量mの大きさに比例して回転しにくくなるし、$r^2$に比例して、回転しにくくなわけね。
~~つまり慣性モーメントは、$τ=(m・r^2+J)=0.1・0.0063^2+4.12・10^{-7}=4.381・10^{-6}[kg・m^2]$~~
分けて考えないといけない！
ここで、$V_R,V_L$に分けて考えた場合を考える。
まず、必要なトルクは半分になり、必要な電流も半分になる。
また、慣性力も半分である。
$V=V_R=V_L$の場合について考えると、半分の加速度を目標値とした場合の、半分の慣性力の運動と等価になる。
よって、等価な慣性モーメントは、$(m/2・r^2+J)=2.4・10^{-6}[kg・m^2]$
***
逆算
***

$$a_r = 9.8[m/s^2]$$ 
$$→α_r = \frac{9.8}{0.0063}=1555.8$$

この時、必要なトルクは、

$$τ=(m・r^2+J)・α=(0.1・0.0063^2+4.12・10^{-7})・1555.8=6.2・10^{-3}[N・m]$$

モータは2つあるので、必要なトルクは半分で、3.1・10^{-3}[N・m

この時、必要な電流は、T=K・iより、

$$i=\frac{T}{K}=\frac{3.41・10^{-3}}{3.52・10^{-3}}=0.97[A]$$

この時、必要な電圧は

$$V=R(\frac{i_{t+1}-e^{-\frac{R}{L}Δt}・i_0}{1-e^{-\frac{R}{L}Δt}}) $$

$$V_{in}=V+E_0$$

```math
\begin{cases} 
\displaystyle 9<V_{in}:V_{in}=9\\ 
\displaystyle V_{in}<-9：V_{in}=-9
\end{cases}
```

***
とりあえずこれで、直線においては、最強の表が作れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550140/72d99c93-3d7f-fc39-fa60-61aa96d9528f.png)
・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550140/c453190c-4123-33dd-d13f-b1a45a27596b.png)

約2[s]で20[m]を初速0[m/s]から走れてしまう計算！
2019年度のロボトレース決勝は39[m]なので、ずっと、定常速度の16[m/s]で走ったら、約2.5[s]程で完走できる計算になる。

後、これは１次遅れ系に近似できるのでは？
営業マンが作れるGoogleAlerts+RSS+Teamsでノンプログラムで自動情報収集ツール

営業マンってアナログな感じっすよね。けどデジタルツール駆使もできるんやで。
市民開発者向けに非エンジニアでもノンプログラムでも色々できる事あるのでご紹介


<h3>課題：法人営業って情報収集大変だよね</h3>
結構大変なんです。
自分が担当している顧客の動向、担当している業界の動向、最新技術の知識武装、業界事例とかアーキテクチャとか、またクラウドプラットフォーマーが新しいの発表したよ、とか、関連する知識武装いっぱいあります。いっぱい。


<h3>課題解決案：自分の欲しいテーマだけ最新情報教えてくれるツール</h3>
が欲しいと思いました。
できれば自分の欲しいテーマを自分で好きに設定できて、いつでも変えられたり追加できたり削除したりできて、
見込顧客や業界や事例の最新情報を垂れ流してくれるやつ。
それを非エンジニアでもできる3分クッキングを編み出しました。やってみましょう。


<h2>STEP1：Googleアラート設定</h2>
Googleアラートとは、Googleさんがウェブ上の面白い新着コンテンツをチェックしてくれるツールです。

Googleアラートとググってポチるとこの画面が出ます
![コメント 2019-12-20 202708.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/b9f45644-4b88-d0a9-a853-5652ff1f1027.jpeg)



Google検索と同じように、気になるワードを入れます。
私は株式会社ヘッドウォータースに営業をしようと思ってますので、キーワードを入れて「アラートを作成」ボタンをポチると
「マイアラート」が設定されます。
![コメント 2019-12-20 203109.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/7e6c7feb-6743-d40f-8971-1c41d27c8041.jpeg)

マイアラートのペンのアイコン「編集」をクリックすると編集画面になります。
ここで配信先を「RSSフィード」を選び、「アラートを更新」ボタンを押します。
![コメント 2019-12-20 203505.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/d41a0487-4546-7944-fb3d-abdf06ee223f.jpeg)

なんか電波マークみたいなのが出てきました。これがRSSというやつです。
気になるワードは複数入れられますので最新情報チェックは逃しません！
この画面は後で使うので取っておきましょう。
![コメント 2019-12-20 204552.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/f42aec21-1672-253d-f318-40da060a2c7c.jpeg)


<h2>STEP2：Microsoft TeamsでRSSコネクタを設定する</h2>
Teamsを開いてGoogleアラート用のチャネルを追加します。
![コメント 2019-12-20 205826.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/5d81c4eb-9b2e-1ada-636e-e544a01d21fd.jpeg)

チャネル上部に出る「＋」タブをClickすると色んなコネクタが出てきます。見てるだけでワクワクすっぞ。
![コメント 2019-12-20 210050.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/8629961a-17ab-a24e-da7b-06b251a2d30a.jpeg)

その他のアプリをClickしてRSSと検索するとRSSコネクタが出てきます。
なぜかその他のアプリまで行かないとRSSが出てきませんので注意です。
![コメント 2019-12-20 210221.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/41aab8aa-517e-e12a-c714-6bb3546d9300.jpeg)

RSSを選んでチームに追加ボタンをClick！
![コメント 2019-12-20 210353.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/96fecaf2-e416-c19a-9868-f84fcd295348.jpeg)

さっき作ったチャネル名を検索して選択。次に「コネクタを設定」をClick
![コメント 2019-12-20 210652.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/ace14e3a-5001-4243-7bc8-0e3604e00138.jpeg)

RSSの設定画面になります。名前は適当につけてOKです。RSSフィードのアドレスは、「Googleアラート」に戻って電波マークを右クリックして「リンクのアドレスをコピー」して貼り付けます。
ダイジェストの頻度は15分、30分、1時間、6時間、12時間、毎日、毎週と選べますのでお好きにどうぞ。
![コメント 2019-12-20 211003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/34aa668e-18f0-96d3-61d6-e5b06952dc48.jpeg)

RSSコネクタ設定完了しました！
![コメント 2019-12-20 211406.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/b9bcc49a-1fb9-d6d9-640e-9152d9273def.jpeg)

<h2>出来上がりでい</h2>
ヘッドウォータースの最新ニュースがすぐ出てこないので
代わりに過去私がチェックしてたRSSで我慢してくさい。
![コメント 2019-12-20 212047.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31186/ebfafb7c-06de-54e8-c058-55b38947417d.jpeg)

<h2>まとめ</h2>
・Teamsコネクタ便利。カスタムできまくり

非エンジニアな営業マンでも市民開発者ツールを使う事でSalesTechを駆使できます。
PowerPlatformやiPaaSはノーコーディングで結構いじくれるので、日常の業務に課題に感じたらどんどんやってみたいと思います。
【Ansible】promptをfor文で記入する

# はじめに
promptにvarsの内容をfor文で書きたかったのですが、
どうやら改行は勝手に消されてしまうようです。

```yml:prompt_test.yml
---
- name: prompt TEST
  hosts: junos
  gather_facts: no
  vars:
    ansible_python_interpreter: /usr/bin/python3
    output_lists:
      - router1
      - router2
      - router3
  vars_prompt:
    - name: "usr_input"
      prompt: "
              here are output lists! \n
              {%- for i in output_lists -%}
              {{ i }} \n
              {%- endfor -%}
              "
      private: no
  tasks:
    - name: 'debug'
      debug:
        msg: '{{ usr_input }}'
```
# 実行結果(失敗)
for文で記入されていますが、改行が消されてしまいました。

```text

[ec2-user@ip-<ip addr> ansible]$ ansible-playbook -i hosts prompt_test.yml
 here are output lists!router1router2router3: test-test

PLAY [prompt TEST] **************************************************************************************************************************************************************************

TASK [debug] ********************************************************************************************************************************************************************************
ok: [junos_router_1] => {
    "msg": "test-test"
}

PLAY RECAP **********************************************************************************************************************************************************************************
junos_router_1             : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

# 解決策
|（パイプ）を使い、かつ-（ハイフン）を消して改行を入れることで上手くいきました。

```yml:prompt_test2.yml
---
- name: prompt TEST
  hosts: junos
  gather_facts: no
  vars:
    ansible_python_interpreter: /usr/bin/python3
    output_lists:
      - router1
      - router2
      - router3
  vars_prompt:
    - name: "usr_input"
      prompt: |
              here are output lists!
              {% for i in output_lists %}
               {{ i }}
              {% endfor -%}
      private: no
  tasks:
    - name: 'debug'
      debug:
        msg: '{{ usr_input }}'
```

# 実行結果(成功)
想定通りpromptをfor文で記入することが出来ました。

```text
[ec2-user@ip-<ip addr> ansible]$ ansible-playbook -i hosts prompt_test2.yml
here are output lists!
 router1
 router2
 router3
: test-test

PLAY [prompt TEST] **************************************************************************************************************************************************************************

TASK [debug] ********************************************************************************************************************************************************************************
ok: [junos_router_1] => {
    "msg": "test-test"
}

PLAY RECAP **********************************************************************************************************************************************************************************
junos_router_1             : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
【見積依頼のさばき方】Webサイト制作会社から依頼される機能開発の「予算感」がかなり違っていたので、丁寧に説明してみた

# 背景

あるクライアントが「宿泊予約管理システム」を求めていて、その要件が弊社のパッケージとかなり適合します。クライアントは弊社のことは知らず、クライアントと取引のあったWebサイト制作会社さん(以降T社)が弊社を探してくれました。(Google検索の10ページ目くらいから見つけてくれたそうです。感謝！)

このような経緯があったため、契約は以下のようになっています。

`クライアント` ⇔ `T社` ⇔ `弊社`

※T社と弊社は請負契約

各社の業務知識等は以下のようになっています。

| # | クライアント | T社 | 弊社 | 
|:--|:-:|:-:|:-:|
| 業務知識   | ◎  | △(じゃらん等の利用者目線のみ)  | ◎ |
| 情報システムの知見  | ×  | ×  | ◎ 
| Webデザインの知見 | ×  | ◎  | △(コーディングは可) | 

# 問題点

このプロジェクトのメインは、弊社パッケージの導入・カスタマイズです。ただT社さんは立場上、クライアントに「しっかりやってます」とアピールする必要があります。
とはいえシステムには手を加えることはできません。すると、できることはフロント画面のデザインや機能改修の提案が主となります。
色々と考えてくれるのは嬉しいし、なかには「おっしゃるとおり」というものもあるのですが残念ながらどれも着手できそうもありません。

理由は予算感です。

ちょっと話がずれますが、
情報システムでは「こうできたらいいな」という要望やアイデアは尽きることがありません。そして見積もりは高度なスキルと時間を要する作業です。
無数に発生するアイデアや要望を真面目に見積もりしているとどれだけ時間があってもたりません。

そこで「見積り依頼」に秩序を持たせるために依頼用フォームを用意して、様々な情報の入力を必須としています。「予算感」もその対象(必須選択)です。

[![Image from Gyazo](https://i.gyazo.com/d6a6b312adb17aa24eb4acf4733649c1.png)](https://gyazo.com/d6a6b312adb17aa24eb4acf4733649c1)

本題に戻ると、そこで入力される予算感が、一桁とはいきませんが、5倍は違うので、当然着手できない。というのが問題となります。(弊社パッケージの価値を高める提案なら、予算問わず実装を検討しますが、業務に精通したクライアントから学ぶことはありますが、T社さんは業務にもシステムにもうといので、いまのところ「それはいい！」という提案はありません。)

このままだと、T社さんも弊社もお互いに時間の無駄です。特にT社さんは見積もり依頼フォームを埋めるために、(システムに落とし込むには不十分とはいえ)それなりに詳細を検討して時間を要しているので、おそらく相当ストレスになっていると思います。

(なお、T社さんがクライアントと弊社の間にはいりたがって、コミュニケーションの質・速度の低下、手間の増加という問題もあるのですが、それは別の機会に。)

# 対策

「かなり予算感に乖離があります。」ということをT社様に率直にお伝えしました。

あまり、こういったケース(=プロジェクトの主役は業務に精通したシステム会社だが、ディレクションは業務・システムに知見のないWeb制作会社)は多くないと思いますが、おそらく同じ問題を抱えると思うので参考にして頂ければと思います。

---

見積もり依頼をいくつかいただきましたが「予算(感)」に大きな感覚の違いがあるという印象を受けました。

現状のままだとお互いに時間の無駄(依頼を受けてもすべて対応不可)なので、こちらの感覚を共有しておきます。

たぶん、御社がイメージできているのは「フロント画面への正常系の表示に要する工数 + ちょっと」程度かな？という印象です。

情報システムは目に見える部分より目に見えない部分のほうが遥かに多いです。(コード量でいうと、管理サイトはフロントの3倍)
また、正常系より異常系(の検討・設計・実装・試験)に多くの時間が費やされます。(80%は異常系に費やされるという主張もあります)
また、実装だけでなく、以下のようにその前後に付帯する作業があります。

| # | 工程 | 備考 |
|:-:|:--|:--|
| 1 | 見積もり | 要件確認のQ&A、実現方法の検討、見積の提示(前提条件や支払い方法などこまごま) |
| 2 | 設計 | データベース、管理画面、フロント画面。通常？バッチ要否？サーバレスがよい？異常系の考慮 |
| 3 | 実装・試験 | フロントと管理の両方 |
| 4 | デプロイ・動作試験 | Web環境にリリースして試験する。 |
| 5 | マニュアル更新 |  |
| 6 | プロジェクト管理 | 進捗・完了等の報告、細部のQ&A、相談 |

## 一万円でできる対応について
対応内容や支給されるもの、成果物によっても変わってきますが「1万円」でおさまる対応というのは、
管理サイトの改修やデータベースへの影響はなしで、フロント側もアルゴリズムの変更はなく、レイアウトをちょっと変更する程度とお考えください。

管理サイトのメンテナンス画面の追加が必要になるようなケースでは最低でも★万円は必要です。

## その他の考慮事項(見積もり金額の増減に影響するもの)
またINPUT/OUTPUTによっても異なってきます。こちらは「見積もり依頼フォーム」に追加しておきます。

・Input/支給されるもの・・・デザインやHTMLタグ・CSSは？ ※フロントはレスポンシブ
・Output/期待される成果物・・・ソースコードだけでいいのか？設計書も必要なのか？マニュアルは？

## 補足/「見積もり」依頼の考え方と見積り依頼フォームの役割

情報システムでは「こうできたらいいな」という要望やアイデアは尽きることがありません。
また、見積もり作業というのは、高度なスキルと時間を要する作業です。
思いつきレベルのアイデアや要望に対して「真面目に見積もり」しているとどれだけ時間があってもたりません。
当初から申し上げていますが、このあたり(仕様変更管理)がうまくコントロールできないとプロジェクトの失敗に直結します。

「見積もり依頼フォーム」は、見積もり依頼に秩序を持たせると同時にシステム側の見積もり依頼対応負担を軽減する目的で導入しています。
実際、予算感に大きな乖離があるご提案は「無理です」と即答できるので、大幅に時間を節約できています。
また、ご依頼に対して曖昧さをご指摘しましたが、こういった詰めの甘さなくすことで追加のQ&Aや手戻り工数を減らすことができますので、依頼時により深く検討していただけると良い(改修コスト削減)かと思います。

最後に、繰り返しになりますが、請負契約ではその改修の採否にかかわらず見積もりに要した工数は請求対象となりますのでご了承ください。

引き続きご協力をお願いいたします。
Swift MkMapViewで地図アプリ作成してみた（11）- ロングタップした位置の標高を国土地理院から取得する

#記事一覧
[Swift MkMapViewで地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)

#国土地理院のサーバ

国土地理院に、[標高を取得するWebAPI](http://maps.gsi.go.jp/development/elevation_s.html) が公開されています。
使用方法は上記のリンクを参照してください。

###使用例

>https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=140.08531&lat=36.103543&outtype=JSON

ブラウザで上記のURLにアクセスしてみてください。

>{"elevation":25.3,"hsrc":"5m\uff08\u30ec\u30fc\u30b6\uff09"}

上記の情報が表示されるWebページが表示されます。
elevationが標高ですので、指定した位置は標高25.3mとなります。

#国土地理院からロングタップした位置の標高を取得する

1. URLを生成する

    [ロングタップした位置にピンを立て距離を表示する](https://qiita.com/rain_00_00_09/items/d426a32ab8356a97fc78)で設定したピンの標高を取得するURLを生成する。

    ```swift:ViewController.swift：URLを生成する
    // 国土地理院のURL
    let baseUrl = "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?"
    // ロングタップ地点でクエリを設定する
    let lonUrl = "&lon=" + pointAno.coordinate.longitude.description
    let latUrl = "&lat=" + pointAno.coordinate.latitude.description
    // アウトプット形式をJSONに設定する
    let outtypeUrl = "&outtype=JSON"
    // URLとクエリを連結
    let listUrl = baseUrl + lonUrl + latUrl + outtypeUrl        
    // URLを生成する
    guard let url = URL(string: listUrl) else { return }
    ```

2. 標高を取得する

    URLSessionで生成したURLにアクセスして標高を取得する。

    ```swift:ViewController.swift：標高を取得する
   
    // URLを生成する
    guard let url = URL(string: listUrl) else { return }
    URLSession.shared.dataTask(with: url) { (data, response, error) in
        if error != nil {
            print(error!.localizedDescription)
        }
        guard let data = data else { return }
        // JSONを取得する
        let json = try? JSONDecoder().decode(JsonElevation.self, from: data)
        if nil != json {
            // mainスレッドで処理する
            DispatchQueue.main.async {
                // JSONから標高を取得する
                self.longTapElevation = (json?.elevation)!
            }
        }.resume()
    }
    ```

    サブスレッドからメインスレッドに切り替えるためには、DispatchQueue.main.asyncを使用する。

#余談：HTTPを使用する場合に設定すること（HTTPSは不要）
HTTP通信が非推奨のためHTTP通信する場合は、Info.plistを設定しないと実行時エラーとなる。

<img width="676" alt="Qiita(11)-01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/1de2cd99-fdcb-2b56-6aa0-d269c031fd2b.png">

App Transport Security Settingsを追加して、Allow Arbitrary LoadsにYESを設定する。
これでHTTP通信が可能となる。

#参考文書
[国土地理院　ヘルプ](http://maps.gsi.go.jp/help/index.html)
Railsでerbをhamlに変換する方法



Hamlって便利ですよねー！
ただrailsの初期設定ではerbファイルとして、生成されてしまいます。

どうせならHamlに統一してコーディングしましょう。


##gemのインストール

```
Gemfile

gem 'haml-rails'
```

を入れて

```
ターミナル

$　bundle install
```

```

$ rails haml:erb2haml
```

これで一括変換されます。
Railsでアプリを作る簡単な流れ


一からアプリを立ち上げるとなると、意外と、何からしていいか分からない人もいると思うので、まとめました。

(アプリのダウンロードなど、環境構築などは完了していること)



##アプリを作成する

保存したい場所に移動して

私はデータベース名は、mysqlでやってます。
指定しなければ、SQLiteというものが入ります。


```
ターミナル

$　rails new　アプリ名　-d mysql(データベース名)
```

##gemのインストール

```
ターミナル

$　bundle install
```




##コントローラーを作成する

投稿サイトを作る場合のコントローラーを作成します。
※コントローラー名は複数形にしましょう

```
ターミナル

$　rails g　controller　posts(コントローラー名)
```

```posts.controller.rb

class PostsController < ApplicationController
  def index(アクション名)
    #空でいいので作成する
  end  
end

```

##データベースを作成する

データベースが必要であれば作成します。
通常であれば2つのファイルが生成されます。

```
ターミナル

$　rails db:create
```


##モデルを作成する

データベースが必要な場合はモデルを作成します。
※モデル名は単数形にしましょう

```
ターミナル

$　rails g　model　post(モデル名)
```

モデルを作成すると、マイグレーションファイルも同時生成されます。
必要なカラムがあれば追加します。


```20190000_xx_xx.rb
class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      #t.(型名) :(カラム名), (オプション)
      t.text :content, null: false
      t.timestamps
    end
  end
end
```

カラムの追加が完了したら

```
ターミナル

$　rails db:migrate
```
これでデータベースの準備は完了です。


##トップページのルーティングを作成する



```routes.rb

 #root to: "コントロ-ラー名#アクション名"
 root to: "posts#index"

```




##トップページのviewを作成する


```
app/views/posts(コントローラー名)の中に

index(アクション名).html.erbを作成
```
```index.html.erb
 HELLO WORLD
```

##railsを起動する

```
ターミナル

$　rails s
```

localhost:3000で起動します
[AWS]APIGateway上でExpressのpublicルーティングを通したかった

#はじめに
[新卒ゆるゆるアドベントカレンダー21日](https://qiita.com/advent-calendar/2019/yuruyuru-freshman)担当です！
最近AWSを触らせてもらう機会があり、それについて少々。

#背景
「あんまアクセスないサイトだし、ServerlessでWebサービス作れたら低コストな運用が出来るのでは！？」っていう流れで、AWS,Lambdaで動くWebサーバの構築をNode.js&Expressを使って行いました。
Expressのスケルトンコードを用意し、普段のようにpublic配下にクライアントJSやCSSのリソースを入れ込んで、下記のexample.htmlように自身のURLを指定してリソースを読み込んでいました。
ですが、Serverless.ymlで特定のルーティングをLambdaFunctionに紐づけて定義してしまっているため、example.htmlのようなリソースURLをリクエストされても対応するLambdaFunctionが無いと怒られるだけでした。（この問題の解明に3日ほど費やしました）

```html:sample.html
<head>
<link rel="stylesheet" type="text/css" href="/public/css/example.css">
</head>
```
([以前書いた記事でExpressスケルトンコードでのサーバ構築手法も書いてるのでぜひご覧ください](https://qiita.com/Yujiro-Ito/items/c5c593886dd4373f030e))

#対応方法の検討
クライアントからのリソースのリクエストは「/public/」で始まる事から、以下の三つを検討しました。
<ol><li>/public/でアクセスできるLambdaFunctionを定義し、そこで実際の/public/フォルダから検索して返す
<li>/public/でアクセスできるLambdaFunctionを定義し、そこでS3バケットから指定されたリソースを引っ張ってきて返す
<li>CloudFrontを使い、/public/で来たリクエストをAPIGatewayではなく直接S3バケットに向ける</ol>
純粋なAPIGatewayとLambdaの動作、Expressの動作を保証しつつ、可用性を求めた結果3を選択しました。CloundFrontはcdnとして元々導入予定且つS3の運用コストの低さからこの選択は最善であると判断しました。

#対応
AWSConsole上からCloudFrontの設定をしていきます。
新しいDistributionを作り、OriginにはAPIGatewayのARNを、CustumOriginにはS3のARNを設定します。Originの設定例を図1に、Behhavioursの設定例を図2に示します。

*図1(Originの設定例)*![cloudFront1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141541/ecc0667d-7693-79d6-5aed-3ad411bcf608.png)


*図2(Behaviorsの設定例)*![cloundfront2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141541/07ea56aa-5331-3f0d-537e-ec816faaed7d.png)

#おわりに
アドベントカレンダーのタイトルにそぐわない内容だったかもしれませんが、もしServerlessでWebサーバを作る人の参考になれば幸いです。
実際にはAWSConsoleから直接Distributionをいじるのではなく、Terraformを使ってドキュメント化を行っております。いずれそれを記事にすると思います。
更にs3へのリソースデプロイもshellで自動化したので、それもいつか記事にするかもしれません。
ご興味がある方は是非ご覧になってください。
最後まで読んでいただきありがとうございました。
マンガでわかる Strategy

![169946D8-FFA1-48B1-A737-7EDF52F83C17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/815910e4-2876-d3d3-d947-87957ecc0747.png)

ゆにっとさん、それは趣味に走りすぎなのでは...

あ、はいすみません、よく知られたパターンなので遊んでしまいました。ストラテジーってネーミングがもうね...

Strategy パターンは GoF のデザインパターンの中でもっともわかりやすく、多用されるパターンです。オブジェクトから、ある特定部分の判断を行うアルゴリズムを分離し、それを別のオブジェクトに持たせて、has-a 関係で委譲してやる形です。

アルゴリズムを分離することには、3 つのメリットがあります。

ひとつは、言わずもがな「関心の分離」です。この部隊の戦力をもってすれば、どんな強大な敵も撃退できるのだ。けど、部隊の最前線は目の前の戦闘にしか集中できません。なので、大極を見た戦略判断は司令部に担ってもらうのです。SOLID の単一責任原則 (SPR: オブジェクトの責務はひとつ) です。

もうひとつは、`if` の排除です。すべての作戦に関する知識を持っていて、いまどの作戦行動中なのかを考慮する `if` 文を大量に抱えていること自体が、すでに部隊の集中力を阻害する余計な関心事です。なので、前線の兵士にはなるべく考えないようにさせ、判断を委譲する先をひとつ決めて、「伊作戦」なのか「呂作戦」なのか、はたまた次の作戦なのか、司令部への報告に対する応答戦術指令が適宜変わるようにするのです。

最後のメリットは、カンのいい人はもうわかっていると思いますが、この部隊は作戦さえ立案すればどんな行動でも取れるということ、つまり、オブジェクトの追加によっていくらでも拡張可能だということです。作戦が増えるたびに部隊を再訓練していては、臨戦態勢を維持できませんね。単純な追加によって挙動を拡張可能... これはまぎれもなく開放閉鎖原則 (OCP: 拡張に対してオープンに、変更に対してクローズであれ) です。

Strategy パターンにおいて重要なのは、戦力の主体はあくまで前線であることと、作戦を与えるのが司令官だということです。

防衛戦では作戦行動のイニシアチブが敵側にあるので、前線は独自の判断で応戦を開始ないといけません。司令部がいちいち Command を発行して動かしていては間に合わないので。Command はいちど実行すれば無効になって、次を待たないとだめですが、Strategy は切り変わるまでずっと存続し、何度もコール可能です。

また、部隊の各小隊が、自部隊の戦局 State が変わったからと勝手に作戦を変更したら大変です。映画とかでも、そういうのはたいがい死亡フラグですね。State の具象はたいてい、同一パッケージではなく外部にあり、自力で `new` できなくて、セッターなどで与えられるものなのです。

具体例がなくてわかりにくい? コンフィグでどのデータベースドライバを選ぶかで、JDBC や PDO の通信内容は変わりますよ、これでいいですか。外部から択一で与えられて、変更しないかぎり同じドライバが使われ続け、新たにデータベースエンジンが増えればドライバを追加で増やせる。はい、そういうやつです。ね、あるあるすぎでしょ。
仕事では使わないターミナルコマンド集（随時更新）

### はじめに
はじめにまずこの記事はあまり有益ではないかもしれません...
しかし、私自身このようなターミナルのコマンドは嫌いではないです、、むしろ好きです！！！笑
今回の記事は一部なので、今後も面白いと思ったコマンドがあれば随時更新していく予定です。
皆様も面白いコマンドが一つでも見つかるかもしれないので、よかったら見てください〜



### カレンダー
```
$ cal
```
![cal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/9dd05d58-6f3a-2636-abdf-f66ec46fbfb2.png)
割と便利ですね！ターミナル使用している時に気になったら使うかな？🧐笑



### 天気を調べる
```
$ curl wttr.in/{地域}
```
自分の住んでいる地域を入力すると
![tenki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/70312f42-5d08-2b29-bb03-b5b6b9579f8a.png)
上記のように出力される

### 好きな文字を入れると画面に大きく表示
```
$ banner {文字}
```
文字を入れると
![banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/1107815b-bd1a-de1b-c756-918748990151.png)
上記のように表示される。3文字以上だとほとんど文字が確認できないですね、、


--- 
###ここからはHomebrewが導入されていたら使用できるコマンドです。

[Homebrewの公式サイト](https://brew.sh/index_ja)
---導入されていない方へ---
上記の公式サイトにインストールの手順が書いてあります。

また、Homebrewとはなんぞや？と思われた方は、同僚がわかりやすく記事を書いてくれています。↓
[@yukiigarashi](https://qiita.com/yukiigarashi/items/17ca7e84ec56dfedddc1)の記事


### スターウォーズが動いてる
まずは、「brew」コマンドを使ってパッケージのインストールをします。

```
$ brew install telnet
```
次に

```
$ telnet towel.blinkenlights.nl
```
![star.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/ee9ebf1f-f958-99a6-c440-35ab5cf8e7c0.png)

ちょっと面白い！終わりたい場合は、controlキーと　]　を同時に押してから、q　→　enterキーを押せば接続が終了します。

### Nyancatが出てくる
```
$ brew install nyancat
```
次に

```
$ nyancat
```
![nyancat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/8e147ade-8db5-4293-6ecd-55ae8fa57fee.png)


### SLを走らせる
こちらもまずhomebrewで導入してから、slコマンドを入力する。

```
$ brew install sl
```
次に

```
$ sl
```
![sl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/cd941875-5433-774f-de8b-160eea7f6dca.png)

slが走っています。sl好きな方はぜひ

### アクアリウムのAAが流れる
```
$ brew install asciiquarium
```

次に

```
$ asciiquarium
```
![aqua.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/182a7110-d7c9-81cc-e0ca-58bef1c0c842.png)
仕事中に癒されたい方はぜひw

[参考サイト](http://neos21.hatenablog.com/entry/2018/05/13/080000)

### まとめ
自分が面白いと思ったコマンドの一部をまとめてみました。もっと面白いコマンドやこんなの知ってるよ！というものがありましたら、ぜひ教えて頂きたいです。
また、今回の記事で誤字、脱字、その他（間違っている知識等）ありましたら、お手数ですがご教授ください。

##### こっそり謝罪（笑）
###### このような記事は会社のアドベントカレンダーには似つかわしいかもしれません、、でも、ターミナルのコマンドが好きなので書いてしまいました！！！申し訳ありませんでした！多めにみてくださいませ🤣

---

### qnoteの皆様へ
いつもいろんな事を丁寧に教えてくださってありがとうございます！！！恵まれた人と環境に本当に感謝しながら働かせて頂いてます。もうすぐ実務4ヶ月になりますが、まだ会社に貢献できていないと思います。早く会社に貢献できるように努力しますので、これからもよろしくお願いします🙇‍♂️
【Railsチュートリアル】 NoMethodError in StaticPages#homeが出た時の対処法

#エラー発生

Railsチュートリアル第5章の5.1.1ナビゲーションをやってRailsサーバーを再起動すると下記のようなエラーが発生。

NoMethodError in StaticPages#home
undefined method full_title

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/74e68064-ce88-3447-63b4-7dd12ebdf227.png)

#原因 
ググってみると下記のサイトを発見。

「Rails Tutorialでrails sエラーで困っています・・・」
https://teratail.com/questions/12510

その回答として
「full_title を app/helper/下のファイルで定義すれば erb ファイル中で参照できると思います。」

試しにapp/helpers/application_helper.rbを見ると中身が空だった。

#対処法
Railsチュートリアル第4章「リスト4.2: full_titleヘルパーを定義する」の中身を書いたらエラーが解決し、無事表示された。このエラーが表示されたら、app/helpers/下を見てみよう。
Firestoreへの各種データの書き込みと表示


よく使う各種データの書き込み・表示・変換のメモ。

### サンプルコード


```js:index.js
const admin = require('firebase-admin');
const moment = require('moment');

admin.initializeApp({
    credential: admin.credential.cert('/path/to/key.json'),
    databaseURL: 'https://xxxxxxxxxx.firebase.com',
});

const db = admin.firestore();

//dataを定義
const _id = 1;
const _name = "Hoge";
const _age = "33";
const _hobbies = ['Golf', 'Fishing'];
const _birthday = "2011-01-11";
const _note = { pet: true, type: 'Dog' }
const _agree = true;

//async/awaitのために即実行形式にしてる
(async () => {

    //add 必要な形式に変換
    const res = await db.collection("members").add({
        id: _id, //そのまま数字
        name: _name, //そのまま文字列
        age: Number(_age), //数字から文字列
        hobbies: _hobbies, //そのまま配列
        birthday: admin.firestore.Timestamp.fromDate(moment(_birthday).toDate()), //文字列からTimestamp形式に
        note: _note, //Object型
        agree: _agree, //Boolean
        createdAt: admin.firestore.FieldValue.serverTimestamp(), //現在時
    });

    //登録されたid取得
    const docId = res.id;

    //docを取得
    const snapshot = db.collection("members").doc(docId).get();
    const doc = (await snapshot).data();

    //表示
    console.log(`id:${doc.id}`);
    console.log(`name:${doc.name}`);
    console.log(`age:${doc.age}`);
    console.log(`hobbies:${doc.hobbies[0]}`);
    console.log(`birthday:${moment(doc.birthday.seconds * 1000).format('YYYY-MM-DD')}`); //形式変換
    console.log(`agree:${doc.agree}`);
    console.log(`note:${doc.note.pet}`);
    console.log(`createdAt:${moment(doc.createdAt.seconds * 1000).format('YYYY-MM-DD')}`); //形式形式

})()
```

### 実行

```bash
node index.js

id:1
name:Hoge
age:33
hobbies:Golf
birthday:2011-01-11
agree:true
note:true
createdAt:2019-12-21
```
Azure ADガイドに乗ってないSlackへのSSO設定のポイント

Azure ADを使ってSlackにSSOするときに、いろいろハマってしまった経験をせっかくなので残しておきます。
Azure ADのガイドだけだと全然設定できなかったので…

#利用したプラン
・Azure AD P2（Enterprise Mobility+Security E5）
・Slack Pro Plus

#環境の特性
- E-mailは、O365のExchangeOnlineではなく、GSuiteを使っていたのでAzure ADのmail属性はnull
    - どうもAzure ADのmail属性は、Azure ADと同じテナント内のExchange Onlineをセットアップしないと入らないようです
    - 実際にPowershellでオブジェクトの属性を丸っと引っこ抜いたらnullでした

#セットアップ時のハマりどころ
URLの設定や証明書のアップロードは、Azure ADのSlackセットアップガイド通りで問題ないのですが…

###ハマりどころ1つ目：SlackでSSO設定が保存できない
Slack側でSSO設定を保存しようとすると、「SSO が有効化されていません
SAML レスポンスに必要な email属性が見当たりません。お使いのAzure設定を確認してください。」というエラーメッセージが出現。
![SlackのSSO設定画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554576/c36e30f6-9020-4254-55ae-b38bdde5993d.png)

**原因：Slack側で必須としているemail属性がAzure ADのClaimに必須情報として登録されていなかった**

**対策：email属性をAzure ADのClaimに必須情報として登録する**

SlackではNameID以外にメールアドレスも必須情報として必要としていて、これが設定されていないとAzure ADとの信頼構築時にエラーになってしまうのです。

####Step1:「新しいクレームの追加」を押す
<img width="671" alt="新しいクレームの追加.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554576/0a873ce4-a19f-a3c6-15e6-4fdba4f50ba1.png">

####Step2：「User.Email」をクレームに追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554576/aa88f2fe-7afe-0382-e624-90a237ca3477.png)

- 名前にUser.Emailと入力する
- 名前空間は空欄でOK
- ソース属性は、お使いの環境でEmailが保存されている属性を選択する
    - うちの場合は、ユーザー名にメールアドレスが設定されているので、userprincipalnameを選択

####Step3：Slackの管理画面で再度設定を保存する
これで保存できるはず。

###ハマりどころ2つ目：Azure ADの認証画面でエラー
SSOを使ってSlackにログインして、Azure AD側の認証画面でエラーコード`AADSTS75011`が出る（ごめんなさいスクショわすれました :bow: ）。

**原因:Slack側の`RequestedAuthnContext`で、`PasswordProtectedTr
ansport`の指定があった**

**対策:`RequestedAuthnContext`を送らないように設定を変更した**

`RequestedAuthnContext`に含まれる情報は、SAMLの仕様で定義されているもので、Service Provicer(今回はSlack）がIdentity Provider（Azure AD）に認証方法を指定するための情報なのです。
Azure ADは、`RequestedAuthnContext`に対応しているため、今回のように`PasswordProtectedTransport`の指定があれば、パスワード入力をAzure AD側で行わせることで何も問題はないです。ですが、今回SSOを構築した環境ではすでにWindows Hello for Businessをセットアップ済みでパスワード以外の方法（Windows Hello for Business）によってアカウントが認証されてしまっていたがためにSlack側の要求に答えられなかったようです。
今回は、 `RequestedAuthnContext` が省略されていてもAzure ADが動作するのと、
SP側から認証方法を指定しなくてもIdPであるAzure AD側でガッチリ認証できるので送信しないことにしました。

以下設定です。

####Step1:SlackのSSO設定にあるAuthnContextClassRefの設定を変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554576/81979991-3661-3be1-5c30-3cfead1cdd8e.png)
入力欄をクリックするとプルダウンメニューが出現するので、「このバリューは送信しない」をクリックします。

######※蛇足1
`RequestedAuthnContext`を送らないSPは結構あるようで、SalesforceやGSuiteも送っていないようです。SPの認証がショボいのでIdPでガッチリ認証しますってことなので、SPからわざわざ指定する必要もないのかもしれませんね。
カルシウムイメージング解析ツールCaImAnのセットアップ(Python)

この記事では、CaImAn(Calcium Imaging Analysis)というツールを紹介します。
公式サイト(https://github.com/flatironinstitute/CaImAn)
このソフトでは、カルシウムイメージングの動画のモーションコレクションから、細胞の取り出し、信号のデコンボリューションまでする様々な機能があります。現在のカルシウムイメージングの解析ツールのスタンダードであると思われます。

CaImAnはPython版とMATLAB版がありますが、Python版のインストール方法が煩雑で日本語資料が無いので以下にまとめます。
（MATLAB版の方が使い方が簡単なので、MATLABを持っている方にはそちらがお勧めです。）

##CaImAnのインストール
インストール方法はリンク先のInstallationにある通りです。Python 3.6推奨で、AnacondaもしくはMinicondaが必要です。macやlinuxはbashのコマンドを実行するだけでインストールできますが、windowsの場合は少し複雑です。
以下windowsで2018年末ごろに試して上手くいった場合になります。

まず前提として、Visual Studio 2017の”C++によるデスクトップ開発Tools”、”C/C++ CLI Tools”をインストールする必要があります。
マイクロソフトのホームページからVisual Studioの2017をダウンロードしましょう。Community Editionは無料です。
そのあとインストーラーを起動して、”C++によるデスクトップ開発Tools”と”C/C++ CLI Tools”の２つのワークロードにチェックを入れてインストールしましょう。

次にAnacondaにCaImAn用の仮想環境を作成します。
anaconda promptでコマンドを実行していきましょう。

```
git clone  https://github.com/flatironinstitute/CaImAn
cd CaImAn
conda env create -f environment.yml -n caiman
```

これでAnacondaにcaimanという仮想環境が作られました。次にC:\Users\(ユーザー名)\Anaconda3\envs\caiman\以下のフォルダにある２つファイルの操作をしましょう。
1.	「keras_activate.bat」を開いて、KERAS_BACKENDという環境変数をtheanoからtensorflowにする。
2.	「vs2015_compiler_vars.bat」というを削除する。

そうしたらCaImAnをインストールしましょう。

```
conda install -n caiman vs2017_win-64
activate caiman
pip install .
copy caimanmanager.py ..
conda install numba
cd ..
```

次に実行スクリプトや解析データを入れるフォルダを作りましょう。

```
caimanmanager.py install
```

これでカレントディレクトリにcaiman_dataというフォルダができました。解析はこのフォルダ内で行うのがいいと思います。

##デモのコードを実行してみる
\caiman_data\demos\generalにあるdemo_caiman_basic.pyがデモコードとして使えます。
実行して動くかどうかを確認しましょう。

```
cd caiman_data\demos\general
demo_caiman_basic.py
```

実行すると以下のような画面が出てきます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521288/485830e1-3802-49d4-3515-eef0afa517db.png)
これは細胞の形を抽出したものです。番号が振られています。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521288/26630041-aee0-b2bb-206f-40f7e9fcc96b.png)
そしてこちらは各細胞の輝度変化、つまり電気活動の変化を表しています。方向キーで細胞を切り替えて表示できます。

このデモコードでは動画(example_moviesフォルダにあるdemoMovie.tif)から点滅する細胞を抽出したということになります。コード内のパラメーターを調整することで結果も変化します。

##終わりに
これで、Python版のCaImAnが使えるようになりました。
MATLAB版の使い方やデコンボリューションの方法を別記事にする予定です。
細胞抽出のアルゴリズムですが、CNMF(条件付きの非負値行列因子分解)を用いて候補領域を取り出した後、CNN(畳み込みニューラルネットワーク)を用いて細胞かどうかの判定を行っているようです。
【React練習問題】①カウントアップ、ダウンをつくろう

# 概要
これはReactを学ぶ上で、実際の現場で利用できる実装を取得するためのプログラム。
可読性、パフォーマンスなども求める。

# 課題仕様
コードサンドボックスを利用する
https://codesandbox.io/s/

## 画面
・０から始まるカウントアップ、ダウンを実装する
・今どこまでカウントされているかを画面に表示すること
・カウントアップボタンを表示して押せるようにすること
・カウントダウンボタンを表示して押せるようにすること
・デザインの綺麗さなどは問いません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160041/9d9dc62e-7ed0-5bfd-8f14-93b2b250a3e3.png)


## ルール
・FCでつくる
・useStateを使う
・useCallbackを使う
・memoを使う
・カウントアップ、ダウンボタンをそれぞれコンポーネントに分ける

# 回答
https://qiita.com/takujiro_0529/items/ac3eeaed96b35f57d0fc
【Rails+PostgreSQL+Heroku】環境構築まとめ


##やりたいこと
rails new で作ったアプリをheorkuでデプロイしたい。
herokuではsqliteではなくpostgresqlを使わないとダメなので、初めからその設定をしておく。
psql 12.1
Rails 5.0.7.2

##railsの設定

```rails new e-stat-rails --database=postgresql```
```rails db:create```
```rails db:migrate```
```rails server```
localhost:3000で起動できているか確認。

####エラー対処
[【再起動して解決】connections on Unix domain socket “/tmp/.s.PGSQL.5432”?への対処](https://make-from-scratch.com/error-connections-on-unix-domain-socket-tmp-s-pgsql-5432/)

[【rails】Specified 'postgresql' for database adapter, but the gem is not loaded と怒られた件](https://www.setouchino.cloud/blogs/17)

##herokuへ
[Herokuへデプロイした時に「The page you were looking for doesn't exist. 」エラーが出る](https://qiita.com/tukinasikotonoha/items/1c487f08365ef864490b)
こうならないようにcontrollerとroutesを設定してrootでhelloworldと表示するようにする。

```ruby:application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html:"hello, world!"
  end
end
```

```ruby:routes.rb

Rails.application.routes.draw do
  root 'application#hello'
end
```

```git add .```
```git commit -m "hogehoge"```
```git push origin master```
```heroku create```
```git push heroku```
```heroku open```

できた！！
【機械学習】よく使うパッケージ一覧

この記事では、機械学習でよく使われるパッケージについておさらいしたいと思います。
細かいライブラリーの種類に入る前に、pythonのモジュール(module), パッケージ(package), フレームワーク(framework) の違いを整理したいと思います。

### モジュール (module)
モジュールは１つ以上のPython関数、クラス、グローバル変数等を含んだ、`.py` の拡張で終わるファイルです。
### パッケージ (package)
パッケージは複数のモジュールもしくはパッケージをまとめたダイレクトリーです。CやC++ではライブラリー(Library)とも呼ばれます。
パッケージは必ず `_init_.py` という特別なファイルを含みます。
### フレームワーク (framework)
フレームワークは複数のパッケージを含んだ、Webアプリケーションの開発の土台となる骨組みです。
Ex. Django, Flask 

## 機械学習で使われるパッケージ一覧
| パッケージ名 | 用途                     | 参考ドキュメント                              |
|--------------|--------------------------|-----------------------------------------------|
| Pandas       | データフレーム処理       | https://pandas.pydata.org/pandas-docs/stable/ |
| Numpy        | 行列計算                 | https://docs.scipy.org/doc/numpy-1.17.0/user/ |
| Scipy        | 行列計算                 | https://docs.scipy.org/doc/scipy/reference/ |
| Matplotlib   | 描画                     | https://matplotlib.org/3.1.1/contents.html    |
| Seaborn      | 描画                     | https://seaborn.pydata.org                    |
| NetworkX     | グラフ・ネットワーク計算 | https://networkx.github.io                       |
| scikit-learn | 機械学習                 | https://scikit-learn.org/stable/              |
| TensorFlow   | 深層学習                 | https://www.tensorflow.org                    |
| PyTorch      | 深層学習                 | https://pytorch.org                           |
|Keras         | 深層学習                 | https://keras.io                              |
コミットメッセージについて考えてみた


ある日の出来事です。
いつも優しくて、すごくお世話になっている先輩が、それを見た瞬間、鬼の形相になりました。

``` 
# コミットメッセージ
Update: 開発完了
```

冷や汗が止まりませんでした。。
もう二度とこのような悲しい出来事を生まないために、コミットメッセージの重要さと書くべきことについて考えていきます。

# なぜ重要なのか
コミットメッセージは将来の効率化のために書くものだと思っています。

例えば、
コードレビューをする際も、
レビュアーがメッセージを見ただけで
どのような改修をしたかが分かる状態になっていれば、スムーズにレビューを行うことができます。
コード修正においても、修正意図が分かるだけで、対象コードの修正要否が判断しやすくなると思います。

`git blame`したときに「開発完了」とだけ伝えられても何も分からず、
結局コードや過去の案件を調べなきゃいけなくなりますよね。(本当にごめんなさい。)

# 書くべきこと
5W1Hという言葉をよく耳にしますが、
gitでは以下のことが把握できるようになっています。

- When(いつ) 
  - いつ変更を加えたのかはタイムスタンプを見れば分かる
- Where(どこで)
  - 何に変更を加えたのかはリソース (file/dir) 名で分かる
- Who(誰が)
 - 誰が変更を加えたのかは author を見れば分かる
- What(何を)
  - どうやって変更を加えたのかはdiffを読めば分かる
- Why(なぜ)
  - なぜ変更を加えたのかはコミットメッセージを読めば分かる
- How(どのように)
  - どうやって変更を加えたのかは実装を読めば分かる

つまり、コミットメッセージには「Why」を書くべきで、変更の意図を伝えることが大事だということです。

加えて、プレフィックスをつけると、
どのような変更があったのかも分かりやすくなります。
    
### プレフィックス例　
- Add:
  - 機能の追加やファイル追加
- Fix:
  - バグ修正
- Update:
  - 更新
- Delete:
  - 機能削除やファイルの削除
- Revert:
  - コミットの巻き戻し
- Marge:
  - 統合
- Move:
  - リソースの移動
- Rename:
  - 名前の変更

# 過ちを正してみた
``` :before
Update: 開発完了
```
``` :after
Update: ○○システム Topページのロゴ画像を変更
```

まだまだ改善の余地はありそうですが、
一旦、鬼の形相は見なくて済みそうです。

# 最後に
私自身、コミットメッセージはとりあえず書いておけばいいと思っていました。
それは大きな間違いで、
将来の仲間への大きな負担となってしまい、
開発効率低下へと繋がっていきます。


思い当たる節がある方は、本記事をきっかけに改善していきましょう！

# 参考文献
[Who-T  OnCommitMessage](http://who-t.blogspot.com/2009/12/on-commit-messages.html)

# お知らせ
エイチームグループでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひとも[エイチームグループ採用ページ](https://www.a-tm.co.jp/recruit/)（[Webエンジニア詳細ページ](https://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-webengineer/))よりお問い合わせ下さい。

あるいは、[Qiita Jobs](https://jobs.qiita.com/)の[引越し侍Webエンジニアチーム](https://jobs.qiita.com/employers/a-hikkoshi/development_teams/173)、[自社サービスWebエンジニア／インフラからサービス改善まで！](https://jobs.qiita.com/postings/304)、[求む！引越し侍大規模リプレイスにおけるフロントエンドのリードエンジニア募集！](https://jobs.qiita.com/postings/317)の記事をみて、興味が出てきた方は是非Qiita Jobsのチャットでメッセージをください。


明日は「[キング・クリムゾン.js](https://qiita.com/hinora/items/26400d282c89afa323e3)」で沸かせてくれた[@herona](https://qiita.com/hinora)の記事になります！
乞うご期待！！