OmniAICreator/Qiita-1.07M huggingface dataset:
2018年のビッグデータの向かう先と注目分野

2017年も終わりつつある中、2018年の技術トレンドを予測する記事がオンラインメディアにもよくみられます。特に、企業活動の中で浸透しつつあるビッグデータが、この先、どこに向かうのか、2018年の注目分野は何かについて目につきましたので、ピックアップしてご紹介します。
ひとつはビッグデータを分析環境にスムーズにもってくるための技術、たとえばデータストリーミング技術となります。ビッグデータの分析手法としてはAIがますます重要視されてきています。ビッグデータのソースとしては消費財のマーケティング・トランザクションデータからIoTそれに製造業における工場の製造機器のリアルタイムな稼働状況データにまでひろがりつつ、それにともない新たな技術的な課題がみえてくる2018年となりそうです。


※下記サイトからの転載。ビッグデータ・AIなどに関するトピックを毎週取り上げています。
[TechCrowd: https://www.techcrowd.jp/related/](https://www.techcrowd.jp/related/)



#[2018年のビッグデータ分野はどうなる--注目トレンド5選] (https://japan.zdnet.com/article/35112447/)
ZDnet Japanの海外コメンタリーで、海外CBS Interactive発の記事を日本向けに編集したものです。
まとめると、Machine Learningを構築するフレームワークも整備されつつあり、Machine Learning とAIの進歩によって推進されるイノベーションと、データ駆動による自動化を容易にするテクノロジーの進化、たとえば・ストリーミング技術や・トランザクション処理とアナリティクス処理のハイブリッド化などや、データ駆動型製品によってますます生み出される多くのデータにより、優れた洞察がもたらされ、さらなる利益がもたされる結果、投資が活性化されより優れた製品が登場し、多くのデータが生み出されるという循環が進むだろうということのようです。

５つの注目すべき技術トレンドとしてピックアップされているものは以下の通り。
 ・Machine Learningのフィードバックループ
 ・アナリティクススタックの拡大
 ・Insight Paas
 ・トランザクション処理とアナリティクス処理のハイブリッド
 ・ストリーミング処理技術のメインストリーム化

#[製造業IoTとは何か、インダストリアル・ビッグデータが分かれば見えてくる！](http://monoist.atmarkit.co.jp/mn/articles/1712/11/news002.html)
ITmediaの発行する日本の製造業のものづくりに関するオンラインメディア”MONOist”の記事です。インダストリアル・ビッグデータに関するソリューションを提供しているISIDからの製品紹介およびインダストリアル・ビッグデータを扱う際のポイントの解説記事です。

現状のビッグデータの手法は、基本的にWebマーケティングなどのマーケティング向けビッグデータ分析で成功している手法を、そのまま製造業のエンジニアリング業務に展開し、結果を出せないでいるケースが多いとのこと。

商業ビッグデータが相関関係や統計的な優位性が重要であるのに対して、機器の構造によるシステム全体と、コンポーネント間の関係が複雑に関連している製品、機器や生産設備においては、物理法則などの因果関係を踏まえたうえでデータ分析をしないと、よい結果を導き出せないことがポイントのようです。

また、ビッグデータ分析結果の「説明性」が産業分野では重要になるとのこと。確かに、ディープラーニングなど、なぜだか結果が出たという面がありますが、高度な品質を求められる産業設備の故障予知などに適用するためには、
結果の正当性を理解できるように説明できる面も重要になるようです。

#[ビッグデータ×メールで何が実現できるのか？スタディサプリが明かす秘伝のメールマーケ] (https://markezine.jp/article/detail/27139)
Markezineに掲載された、チーターデジタル主催の「Back to Mail Marketing 2017」における、リクルートマーケティングパートナーズでビッグデータエバンジェリストを務める萩原静厳氏の講演「One to Oneメールマーケティング」の紹介記事です。秀逸です。

月額980円で、小学・中学・高校・大学受験に必要な5教科18科目、1万本以上の授業動画を配信するオンライン学習サービス「スタディサプリ」における、データ分析とメールマーケティングの事例を紹介してくれています。

印象的なコメントを列記します。

・今までユーザーの会員情報は『氏名』『年齢』『住所』などストックなもので、それをマーケティング活動に使っていたが、『訪問回数』『前回訪問日』などのフローな情報こそ重要だと考えている。
・表現力（＋情報量）はデジタルのコミュニケーション手法の中でメールが一番強い
・パーソナライズすると「あなたの」好きなものはこれですよねとレコメンドがホットになっていくが、それを見せるのは情報量を担保できるメールが適している


#[製造業におけるビッグデータ活用の盲点と対策（2）] (http://diamond.jp/articles/-/154558)

DIAMOND onlineの「ポスト・ビッグデータ時代の経営」特集の中の記事です。現在、多くの企業で主として取り組まれているビッグデータ対応は、センサー等の「扱いやすい、定型化されたビッグデータ」で、機械のデータを集約したものと言えます。これだけでも、製造現場の生産性向上、高度化を図ることは可能ではありますが、今後、企業がさらなる競争力を得るためには、企業の英知が集約された真のビッグデータである暗黙知の活用は必須であり、暗黙知を形式知とするための現場の知見のデジタルデータ化のプロセス、非定型のデータの自然言語処理などによる定型データへの変換などの手法の説明をしてくれています。
Jenkinsでキューにたまった同名のジョブをPipelineからキャンセルする

例えば、ジョブAのビルドが終わる前に複数回ビルドを起動した場合を想定します。

**【ビルド実行中】**
1. ジョブA #1

**【キュー】**
1. ジョブA #2
2. ジョブA #3
:
n. ジョブA #n

という状況になります。
こんな時に、キューに積まれた`ジョブA #2`〜`ジョブA #n`をPipelineからサクッとキャンセルするスクリプトが以下になります。

```groovy
// ジョブ名を取得
def jobName = env.JOB_NAME

// キューの取得
def q = jenkins.model.Jenkins.getInstance().getQueue()
def items = q.getItems()

def len = items.length
for (i=0;i<items.length;i++){
    def taskName = items[i].task.getName()

    // ジョブ名とタスク名が一致したらキャンセル
    if(taskName == jobName){
        items[i].doCancelQueue()
    }
}
```

個人的にはPipelineでスクリプトの最後の方に設定しています。
何の役に立つのか？ というと、Pipelineを使う前でしたが以下のような無限ループに陥りまして。

1. Jenkinsのジョブをビルド
2. ビルドの中で`git push`
3. gitbucketが`git push`を検知して、Jenkinsのジョブをビルド（1に戻る）

延々とビルド数が増えていくのでキャンセルしたかったんです。
というわけで、Pipelineの最後にスクリプトを設定しておくとキャンセルされます。

補足ですが、上述のキューにたまった状態でキャンセルすると、キューにたまった`ジョブA #2`以降はなかったことになるので、次にジョブAをビルドしたときは`ジョブA #2`から採番されます。
GCPでComputeEngineのバックアップを定期取得

バックアップといえばコードはバージョン管理システムに入れて、DBデータはCloud SQLでバックアップの機能あるし、画像ファイルはGoogle Cloud Storageで管理すればいいだろ？
そんな風に考えていた時期がありました。いやもっと最小構成でいいんだこれが。DBなんかWEBサーバと同居でいいから。ていうか今そこまで手がまわらないからとりあえずサーバの定期バックアップ頼む！　スナップショットでいい。とりあえずなにもないよりは断然いい！！　そんな感じでバックアップ取りたいときに。

# 構成と仕様

* 常設サーバは１台（WEBサービス、DB同居）
 * 他の管理サーバは立てたくない
 * 自宅のPCすら定期的に立ち上げるかは保証できない
 * つまり本番稼働しているサーバからバックアップをキックしたい。
* 常設サーバから日次でスナップショットの取得／削除を投げる
 * 過去１週間分は必須だけど増やしすぎてもアレなので順次削除したい
 * とはいえうっかり忙しかったときのために、過去１週間−日次、それ以上過去−月次（月末分）で保存しておこうと思う
 * 月次分が増えすぎるのは、気づいた時に手動削除

# 事前準備

バックアップを動かすサーバで以下を実行。gcloud入ってなかったら入れてください。

```
gcloud auth login
gcloud config set project [project-id]
```

# スクリプト

```shell
INSTANCE_NAME=[your-instance-name]
SNAPSHOT_ZONE_NAME=[your-snaphot-zone-id]
SNAPSHOT_PREFIX=[your-snaphot-prefix]
 
 
if [ `date -d '1 day' +'%d'` = "01" ];then 
    gcloud compute disks snapshot -q ${INSTANCE_NAME} --zone=${SNAPSHOT_ZONE_NAME} --snapshot-names=${SNAPSHOT_PREFIX}-${INSTANCE_NAME}-`date +'%Y%m'` 
fi 
 
for i in `seq 8 14`;do 
    gcloud compute snapshots delete -q ${SNAPSHOT_PREFIX}-${INSTANCE_NAME}-`date -d "${i} days ago" +'%Y%m%d'` 
done 
 
gcloud compute disks snapshot -q ${INSTANCE_NAME} --zone=${SNAPSHOT_ZONE_NAME} --snapshot-names=${SNAPSHOT_PREFIX}-${INSTANCE_NAME}-`date +'%Y%m%d'` 

```

※毎日動くことを想定しているのなら古いsnapshotのdeleteは1日分（8日前分）だけでいいはずですけれども、なんとなく、つい、念のため。存在しないスナップショットに対し削除かけるとエラーが返ってきますが問題はないです。

# cronに設定

日次で設定。時間はまあ適当に。

```
0 0 * * * bash /path/to/your/backup.sh
```

# 動作確認OS

Debian GNU/Linux 9 (stretch)
結局のところmemcacheとredisどっちがいいの？という問題に対する私的結論サマリ

# 問題の概要

memcacheはもう古い！　次はRedisだ！　と言われてから幾星霜、意外とあちこちで生き残っているmemcache。新規でmemcache使ってるというお話もちらほらと耳にするけれど、実際のところそれいいの？　どうなの？　どっちがいいの？　ということで自分なりの結論を出すために調べてみました。

# まずは結論

悩んだらRedis

# その理由

* memcacheとredisは、費用面、パフォーマンスについては大差はない。
 * 唯一、使用するメモリ量がredisのほうが若干多くなりやすいらしいけれどそれも格納するデータの内容次第で必ずしもそうであるとは言い切れない（らしい）。
 * いっぽうで使用しなくなったメモリの解放についてはRedisのほうが優秀。（FLUSHの時だけの可能性はある）
 * 個人的には初期の学習コストも変わらないと思う（どっちも簡単）（素晴らしい）
* memcacheのできることはRedisもできる。Redisのできることのうちmemcacheにはできないことがある。例えば以下。
 * データの永続化（ただし永続化設定するとその精密さに応じてパフォーマンスは下がる）
 * master/slave構成
 * 暗号化
 * ソート
* 使用するケースや規模が事前に正しく決められるならmemcacheのほうがいい場合もある。
 * ただし大抵の場合正しく決められない。
 * 後から（稼動後数年経過も含む）使い方が変わるとかいう場合もある。
 * システムは生き物だからね！
* だから”念のため”Redisにしておくほうがいい
 * 必要になったら全部memcacheからredisに置換するぜー！って覚悟のあるひとはとりあえずなんでもいい。せっかくだから俺はmemcacheを選ぶぜ！でいい。
 * しかしRedisでも別にいい。
 * Redisとmemcacheの併用という可能性はサーバ費用の問題があるので除外した。
 * なお、永続化が必要なデータ/永続化が不要なデータが混在している場合それをRedis/memcacheを併用して使い分けるっていう手も考えたけれど（１システム内にRedisが2種類あるとわかりにくいとか云々）、永続化の要不要の判断をミスった場合のことを考えたら、もういっそ全部永続化でいいよ！　ね！（expireはつけよう）

# 参考

* [stackoverflow - Memcached vs. Redis?](https://stackoverflow.com/questions/10558465/memcached-vs-redis)
* [Redis作者自身によるRedisとMemcachedの比較](https://yakst.com/ja/posts/3243)
* [AWS - エンジンの選択](http://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/UserGuide/SelectEngine.Uses.html)
* [本当は怖いMemcached](https://qiita.com/taruhachi/items/a844bf373623991873ff)

# なお、本当にすごくどうでもいい話として

名前的にはmemcacheのほうが好きです。なんとなく。
numpy.any

```python
Z = np.random.randint(0,3,(3,10))
print(Z)
Z = Z.any(axis=0)
print(Z)
print((~Z).any())
```
* e.g.

```
[[0 1 2 0 0 2 0 0 0 0]
 [1 1 1 1 0 0 2 0 1 0]
 [2 1 0 2 2 0 1 2 1 0]]
[ True  True  True  True  True  True  True  True  True False]
True
```
```
[[0 0 2 0 0 1 1 0 2 0]
 [2 1 0 1 2 0 1 2 0 2]
 [2 2 1 0 0 1 2 0 1 0]]
[ True  True  True  True  True  True  True  True  True  True]
False
```
# Refs.
* [numpy.any](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.any.html)
argsort

```python
Z = np.random.randint(0,10,(3,3))
print(Z)
a = Z[:,1]
b = a.argsort()
print(a)
print(b)
print(Z[b])
```
* e.g.

```
[[9 9 8]
 [6 9 7]
 [7 1 6]]
[9 9 1]
[2 0 1]
[[7 1 6]
 [9 9 8]
 [6 9 7]]
```

# Refs.
* [numpy.argsort](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.argsort.html)
DynamoDB ローカルでチュートリアル

DynamoDBをローカルで動かすことができたので、メモ。
あとはチュートリアルを試しながらって感じで。

###1. ローカル実行用にDynamoDBをダウンロード

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html

###2.解凍し当該フォルダで実行

```
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
```
###3.テーブルにアクセスしてみる

```
terminal$ aws dynamodb list-tables --endpoint-url http://localhost:8000
```
実行結果

```
{
    "TableNames": []
}
```

##ブラウザでチュートリアル
下記URLにアクセスするとチュートリアルを試せる
http://localhost:8000/shell/

![スクリーンショット 2017-12-30 9.15.07.png](https://qiita-image-store.s3.amazonaws.com/0/119864/6d62c90d-499e-1cc5-628c-798818f86724.png)

右側のコンソール上で、 `tutorial.start()` と入力するとチュートリアルが開始される。

チュートリアルを進めていくと、最初にImageテーブルが作成される。
`KeySchema` が、primary key となり、ユニークなものとなる。

```
// This CreateTable request will create the Image table.
// With DynamoDB Local, tables are created right away. If you are calling
// a real DynamoDB endpoint, you will need to wait for the table to become
// ACTIVE before you can use it. See also dynamodb.waitFor().
var params = {
    TableName: 'Image',
    KeySchema: [
        {
            AttributeName: 'Id',
            KeyType: 'HASH'
        }
    ],
    AttributeDefinitions: [
        {
            AttributeName: 'Id',
            AttributeType: 'S'
        }
    ],
    ProvisionedThroughput:  {
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1
    }
};
console.log("Creating the Image table");
dynamodb.createTable(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});
```

![スクリーンショット 2017-12-30 9.25.31.png](https://qiita-image-store.s3.amazonaws.com/0/119864/c10a9fd8-7004-2acd-2f7a-6af556173505.png)

ターミナルでもImageテーブルが作成されていることが確認できる。
```
terminal$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Image"
    ]
}
```
C++で初めてのゲーム開発する時に、気をつけて欲しいこと

# C++で初めてのゲーム開発する時に、気をつけて欲しいこと

## 最初に

こんにちは、ろっさむです。

この記事は書き忘れていた初心者[C++ アドベントカレンダー](https://qiita.com/advent-calendar/2017/syoshinsya-cpper)に登録します。ほんと申し訳ないです。

今回は私自身が専門学校に通っていた頃、自分がやらかしたことや、共に開発する仲間に「これだけは気をつけて欲しい」と思ったことを、対処法を添えてご紹介します。

## ファイル名やフォルダ、コメントに、個人の名前をつけるな！

これは、学生さんたちが集まって共同開発する際に、分担しようとして失敗するケースです。たまにあります。

**やめてください。**

分担後に、誰か一人が途中で抜けたり、進捗が滞った際はどうするんでしょう。その人の名前のフォルダに入ってファイルをいじって、そのコードのコメントに「// ここからは(個人名)が書いた」とでも書くんでしょうか。

最初のうちは、フォルダには作成する機能の名前をつけましょう(例えば、フォルダ名は「Enemy」で、その下には敵の実装に直接結びつくようなコード類を入れておく)。

また、ソースファイル名やコメントに関しても、できるだけ個人に依存しないものにしましょう。誰か一人がその機能の担当となったとしても、そのコードを編集するのはその人だけとは限りません。

ソースファイル名は、その中で行う処理がどのような機能を持つかで決まります。コメントは、直近のクラスや処理が、一見した時や名前だけではわかりにくい時に補足として説明を加えましょう。

1つの機能を分担するのであれば、そのような用途にも対応した言語機能がC++にはあります。

また、「誰が作ったクラスかわからなくなるじゃないか！」と思う人もいるかもしれません。その件に関しては次項を確認してください。

## コードの受け渡しにUSBを使うな！

これもグループ制作の時にありがちでした。

確かにUSBでのやり取りは楽です。敷居が低いですし。でも、よく考えてください。そのUSB、忘れたり無くしたらどうするんですか。しかも一つ前のバージョンとの差分とかも、見ることができません。新バージョンと区別するために古い方のフォルダの名前に日時情報を付与するのも変ではありませんか。延々と古いコードが蓄積されてメモリを圧迫する事態も起きます。

**やめましょう。**

プログラマなら世に出ているツールを使って、手間暇のかかる手動バージョン管理を闇に葬りましょう。

今回の場合だとGitが最適です。無料で使えますし。あと就活とかにもGitの経験は役立ちます。Git用に使えるウェブサービス、GithubやBitbucket等もあるし。

Gitを使えば、

- 誰が編集した
- いつ変更があった
- その時の変更箇所の提示
- 登録しているコード等の変更履歴

などなどの情報を残していくことが可能です。また、最新のバージョンをGit側に置いておくことで、自分のローカルに最新のバージョンを落としてきて誰にも迷惑かけずに簡単にテスト用コードを試したり、上手くいかなかったら最新のバージョンまで巻き戻したりすることもできます。

「でもGit難しそうだよ...」

と思うのもわかります。ほんとなら、チーム制作が行われる前に授業としてあった方がいいのかもしれませんが、ないものはしょうがないです。なので、自分たちで1日だけでも勉強して実際に使ってみましょう。

Gitを実際に開発に使う場合に必要となる勉強は以下のみです。

- Gitの概念
- リポジトリ作成
- clone
- checkout
- add
- commit
- push
- revert
- reset

できればエンジニアだけでなくデザイナーさんも使用できるようになるのが望ましいです。

## 変数名にaとかbとか、testとか、パッと見て何に使われているかわからない名前はやめよう！

ちゃんと、どのように使われているかがわかる変数名にしましょう。英単語を思いつかない時はGoogle翻訳に自分がやりたいことを文にして投げてみたらいいと思います。

ただし、凝りすぎてめちゃくちゃ長い名前になったり、日本人があまり馴染みのない英単語を使いまくると、逆にわかりづらくなります。できるだけ日本人がパッと見て理解できる単語で名前をつけると、他人にも、3ヶ月後の未来の自分にも優しいコードとなるでしょう。

また、グローバルな変数(又はマクロや別名用の大文字変数)の名前の接頭辞にアンダーバー(＿)を使わないようにしましょう。一応、グローバル名前空間以外であれば、接頭辞アンダーバーは認められていますが避けた方が無難です。接頭辞アンダーバー+英大文字は絶対禁止なのでやめましょう。言語処理に必要な予約語に使用されているため、意図しない影響が出てくるかもしれません。それからアンダーバーを二つ連続(__)で使用するのもよろしくないです。

あとは、名前をつける際に命名規則として、クラス名にはパスカルケース、関数や変数名にはキャメルケース、マクロには大文字スネークケース、といったようにチームで揃えておくと、グッと見やすいコードへ近付きます。

## ifや、forを何重にも入れ子にするな！関数に分けよう！

正直何重にも連なっていると見辛いし直感的にわかりにくいしバグの元となります。関数ごとにわけましょう。ほんとに。

## その他

- グローバル変数は使わない。
- 継承に頼り切りにならない。

など、まだまだあるとは思いますが、私個人で最低限気をつけて欲しい部分はこんな感じです。

この記事に関して、付け足したい項目や不明点などあればTwitterなどにてご連絡ください。以上。
LSTMの簡易まとめ

TensorFlowの[BasicLSTMCell](https://www.tensorflow.org/api_docs/python/tf/contrib/rnn/BasicLSTMCell)で実装されているLSTMについてのまとめ。詳細は論文https://arxiv.org/abs/1409.2329

# 変数
小文字はn次元ベクトル
大文字はn*n次元行列
$x_t$ : 前の層からの入力
$z_t$ : 今から出す自分の層の出力
$z_{t-1}$ : 1ステップ前の自分の層の出力
$c_t$ : このステップで計算するメモリ
$c_{t-1}$ : 1ステップ前のメモリ
$i$ : input ゲート
$f$ : forget ゲート
$o$ : output ゲート
$g$ : input modulation ゲート

わかりやすいように論文とは若干notationが違います.

# 計算
4つあるゲート$i, f, o, g$は全て$x_t, z_{t-1}$をつなげてからアフィン変換したもの. 例えば$i$は以下の式で計算する. $W_i, V_i, b_i$が学習するべきパラメータ.
$$ i = sigm(W_i x_t + V_i z_{t-1} + b_i) $$
$f, o$は添字を変えるだけで、$g$は添字を変えて、さらに$sigm$を$tanh$にする.

メモリは以下の式で計算する. $ \odot　$は要素ごとの積
$$ c_t = f \odot c_{t-1} + i \odot g $$

出力は以下の式で計算する.
$$ z_t = o \odot tanh(c_t)$$


# 図にするとこんな感じ
![IMG_20171231_083724.jpg](https://qiita-image-store.s3.amazonaws.com/0/214997/00218ce0-0945-e787-f339-80def07b23ad.jpeg)

論文呼んだだけで、コードの中身は見てないのでほんとにあってるかは謎です。
matplotlib の legend(凡例) の 位置を調整する

凡例を表示する```plt.legend```には3つのパラメータがあります.
- bbox_to_anchor
- loc
- borderaxespad

bbox_to_anchorでは, 凡例の枠の, 図全体に対する相対的な位置を決定します。 図全体の左下を(0, 0), 右上を(1, 1)としたタプルで与えます。この位置のことをアンカーと呼ぶことにします。

locでは、アンカー(bbox_to_anchorで指定した位置)に, 凡例の枠のどの部分を合わせるかを決定します。loc='upper left'ではアンカーに枠の左上を合わせ、loc='center'では中心を合わせるなどの設定ができます。

borderaxespadでは、アンカーと、locで指定した枠の部分の間の距離を設定することができます。

## 例
```python
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

x = np.arange(0, 10, 0.1)
s = np.sin(x)
c = np.cos(x)
plt.plot(x, s, "r", label="sin")
plt.plot(x, c, "k", label="cos")
```
### アンカーを右上にして、凡例枠の右上をアンカーに合わせる。余白をあけない。

```python
plt.legend(bbox_to_anchor=(1, 1), loc='upper right', borderaxespad=0, fontsize=18)
```
![download.png](https://qiita-image-store.s3.amazonaws.com/0/214997/c08d9b73-3f5d-0f60-8e67-c71ea31721db.png)

### アンカーを右上にして、凡例枠の右上をアンカーに合わせる。余白をあける。

```python
plt.legend(bbox_to_anchor=(1, 1), loc='upper right', borderaxespad=1, fontsize=18)
```
![download-2.png](https://qiita-image-store.s3.amazonaws.com/0/214997/3aec3f66-7d59-2013-4a1e-53d275c60764.png)

### アンカーを右下にして、凡例枠の右下をアンカーに合わせる。余白をあける。

```python
plt.legend(bbox_to_anchor=(1, 0), loc='lower right', borderaxespad=1, fontsize=18)
```

![download-3.png](https://qiita-image-store.s3.amazonaws.com/0/214997/3a4cd442-fcd8-20d5-b19a-96debb3f745f.png)

### アンカーを外の左下にして、凡例枠の左上をアンカーに合わせる。

```python
plt.legend(bbox_to_anchor=(0, -0.1), loc='upper left', borderaxespad=0, fontsize=18)
```
![download-4.png](https://qiita-image-store.s3.amazonaws.com/0/214997/8467a1f5-e14a-7e65-1b45-61634e21d6d4.png)

### アンカーを外の右上にして、凡例枠の左上をアンカーに合わせる。

```python
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=18)
```
![download-5.png](https://qiita-image-store.s3.amazonaws.com/0/214997/b2b23840-f942-3b79-9251-ca57d728d3d6.png)

## locの候補
‘best’ 
‘upper right’ 
‘upper left’ 
‘lower left’ 
‘lower right’ 
‘right’ 
‘center left’ 
‘center right’ 
‘lower center’ 
‘upper center’ 
‘center’
Cloud9上でJupyterを動かせる環境を作ってみた

#参考記事
参考というかほぼこのままなのだけど、githubのcloneは容量オーバーしてうまくいかなかったので単純な手順のみでまとめてみました。
https://qiita.com/y__sama/items/58419e85f39265fe6df8
#Cloud9への登録
https://c9.io/signup
ここからそのまま登録してください。
#Workspaceの追加
workspacesの「Create a new workspace」を押して適当な名前をつけて「python」を選択して作成。
#Anacondaのインストール

```
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
pyenv install anaconda3-4.0.0
pyenv rehash
pyenv global anaconda3-4.0.0
```

#Jupyter起動

```
jupyter notebook --ip 0.0.0.0 --port 8080 --no-browser
```

これで`https://<workspace名>.<user名>.c9users.io`を立ち上げれば、セキュリティはやばいらしいですがとりあえず使えるようになりました。
AWSのEC2を使ってJupyterをブラウザから使えるようにする方法

#イントロ
初心者のため、いろんなサイトを見ながらやっているうちにつまったことがあったのでメモ。
#AWSのアカウントを作成からEC2インスタンスの作成
下のページを参考にさせていただきました。
https://qiita.com/Arashi/items/629aaed33401b8f2265c
ちなみにpemファイルは接続する位置に置いておく必要があります。
もし、Windowsで`C:\Users\user`から接続するときにはuserフォルダの中にpemファイルを置いてください。
#Anacondaのインストール
下のページを参考にさせていただきました。
https://qiita.com/Salinger/items/c7b87d7000e48be6ebe2
https://qiita.com/cafedrip/items/f944f72016ced4ff4361
現時点での最新バージョンは
`https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh`のようなので、
`wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh`
で取得して実行するといいのかと思われます。

ちなみに`~/.jupyter/jupyter_notebook_config.py`の設定をするときはLinuxの黒い画面テキストエディタで編集します。vimが使えない人は下記ページを参考にしてみてください。
http://www.sejuku.net/blog/5570
基本的には、そのままの状態だと書き込めないので「i」を押してINSERTモードにして編集したあとに「Esc」を押して「:wq」(write quitの略だと思ってます)で保存できます。
INSERTモードじゃないときに「/」を押して検索したい語句を打ち込むと検索もできるので便利です。
#AWSのEC2インスタンスへの外部からのアクセスを許可する
下記ページを参考にさせていただきました。
https://www.ipentec.com/document/document.aspx?page=amazon-ec2-add-rule-to-security-group
EC2インスタンスの初期設定では、Jupyterが起動するポート8888(もしくは`jupyter_notebook_config.py`の`c.NotebookApp.port = XXXX`で指定したポート番号)は外部からのアクセスができないようになっているようなので、外部からのアクセスを許可する設定に変更します。
#Jupyterを起動する
```$ jupyter notebook &```
で起動して
` http://[サーバのホスト名 or IP]:8888/ `
でブラウザからアクセスできます。
この時、前に起動に失敗したりしていると8888がすでに使用されていて8889等で起動してうまくいかない場合があります。
その場合、
https://hydrocul.github.io/wiki/commands/netstat.html
で使用しているプロセスを特定し、停止しても問題なさそうであれば`kill -9 プロセス番号`で8888を開放して再度Jupyterを起動してみてください。
#初心者メモ
①LinuxはDebian系(Ubuntuとか)とRedhat系(CentOSとか)でコマンドが違うらしい。
最近はapt-getではなくaptが推奨されているという話。
http://sig9.hatenablog.com/entry/2015/06/21/081407
https://qiita.com/pocket8137/items/e8370697927220d3fc3c
②Linuxで書いてある手順通りにやってできない場合のよくあるエラー
-Pathが通っていない
-インストールするものが足りていない(もともと使用している環境が違うから)
-パッケージをupdateとかupgradeしていない
-なぜか再インストールしたらうまくいくこともある
-なぜか再起動したらなおることもある
Jupyterで入っているはずのライブラリが使えないとき(no moduleエラーが出るとき)

~~# イントロ~~
~~正直Linuxとかよくわかっていないのでやり方が正しいのかわかりません。~~
~~本当はもとの場所にpathを通す方法とかが正しいのかもしれません。~~
~~とりあえず動かせる環境にしたい、ライブラリが使えるようにしたいという人向け。~~

# Jupyter上でpythonに入っているはずのパッケージが使えない場合
~~のようなかたちでJupyter上に記述して「Shift+Enter」で実行すると動くことがあります。~~
~~Jupyterから見えるところ、アクセスできるところにライブラリがいないということなんでしょうか…。~~
前にインストールしたはずなのにっ！っていう人。

## 現在動いているpythonにインポートされているパッケージをJupyter上で確認
```
!pip freeze
```
で入っているコマンドを確認できるはずです。

### `!`をつける理由
pythonが起動していてもこの`!`をつけることでコマンドラインの操作([コマンドラインの入力](https://www.weblio.jp/content/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E5%85%A5%E5%8A%9B)は黒い画面でカタカタするやつです)ができます。
(vimというエディタでも同じような動作ができるので、ほかのプロセス実行中にコマンドを使いたい場合に`!`をつけるとできるものは多いのかもしれません。)
それと同じようにJupyter上からpythonを実行するときも、`!`をつけることでコマンドラインでの操作が実行できます。
コマンドラインで`pip freeze`と打つのと同じようにpython上からコマンドが実行できます。

## importしたパッケージがいない場合
違う環境にインストールしている可能性があります。

### pythonのバージョン違いの場合

pythonはpython2系とpython3系に分かれています。
pipでインストールするかpip3でインストールするかによってインストールされる場所が違います。
自分が今、どっちのpythonを起動しているか確認しましょう。
Jupyter上で下記のpythonを実行するとversionが出力されるようです。

```
import sys
print(sys.version)
```

というわけで、python3を実行中の場合にはJupyter上から

```
!pip3 install {パッケージ名}
```
でインストールができるはずです。

### 環境違いの場合

pythonの開発を行うときに仮想環境を作ることがあります。
`virtualenv`という仮想環境でパッケージをインストールした場合、virtualenvをactivate状態にしていない場合にはパッケージを使用できません。

```
{virtualenvで作ったフォルダへのPATH}/bin/activate
```

にした状態でpythonのバージョンを確認し、使いたいパッケージをインストールします。


とにかくアプリを動かしたいだけでpythonの動く環境を把握していなかったので大幅に修正しました。
間違いがありましたらご指摘いただけるとありがたいです、
OwnMemo Self-flowing SC

```javascript
class Contract {
  constructor({event, contract}) {
    this.event = event;
    this.contract = contract;
  }
  occurrenceEvent() {
    this.event();
    this.executionContract_();
  }
  executionContract_() {
    this.contract();
  }
}

const p1 = {money:1000, colaStock:2};
const p2 = {money:1000, colaStock:5};

//event => send money
//contract => exchange money and cola.

const sampleContract = new Contract({
  event: () => {
    p1.money -= 100;
    p2.money += 100;
    console.log('send money')
  },
  contract: () => {
    p2.colaStock -= 1;
    p1.colaStock += 1;
    console.log('executionContract')    
  }
});

sampleContract.occurrenceEvent();
//check result
console.log(p1)
console.log(p2)
```
OwnMemo VendingMachine

It is my own memo.

The solidity is too difficult.
So, try creating vending machines with javascript and try smartContract understanding.

```javascript
class Item {
  constructor({name, price}) {
    this.name = name;
    this.price = price;
  }
}

class VendingMachine {
  constructor() {
    this.stockMap = new Map();
    this.inputMoney = 0;
  }

  setItemList({itemList}) {
    itemList.forEach((item, itemId) => {
      this.stockMap.set(itemId, item);
    });
  }

  isInputedMoney({moneyNum}) {
    this.inputMoney = moneyNum;
    console.log(`input ${this.inputMoney} Yen`);
  }

  isPushedBtn({itemId}) {
    if(this.stockMap.has(itemId) !== true) {
      console.log(`not have item`);
      return;
    }
    const buyItem = this.stockMap.get(itemId);
    if(this.inputMoney < buyItem.price) {
      console.log(`insufficient money.`);
      return;
    }
    console.log(`Buy ${buyItem.name}`)
  }
}

//make Item
const cola = new Item({name: "Cola", price: 100});
const cider = new Item({name: "Cider", price: 100});
const orangeJuice = new Item({name: "OrangeJuice", price: 100});

//make vendingMachine
const vendingMachine = new VendingMachine();
vendingMachine.setItemList({itemList: [cola, cider, orangeJuice]});

//run code
vendingMachine.isInputedMoney({moneyNum: 100});
vendingMachine.isPushedBtn({itemId: 1})
```
Holoviewsのファイル保存及びgrid上に並べるメモ


Holoviewsとはmatplotlib plotly bokehなどのwrapperである。
公式: http://holoviews.org/
基本的な使い方: https://qiita.com/driller/items/53be86cea3c3201e7e0f

## file出力

形式を選ぶ
renderer = hv.renderer('bokeh').instance(fig='html')
renderer = hv.renderer('matplotlib').instance(fig='png')

出力のpathを指定
renderer.save(gridspace, 'fname', style=dict(Image={'cmap':'jet'}))

## grid上に並べる

dict = {(x,y): holoviewsのplotオブジェクト}
hv.GridSpace(dict, kdims=['x_name','y_name'])

# sample code

```python
import numpy as np
import holoviews as hv

def sine_curve(phase, freq):
    xvals = [0.1* i for i in range(100)]
    return hv.Curve((xvals, [np.sin(phase+freq*x) for x in xvals]))

phases      = [0, np.pi/2, np.pi, 3*np.pi/2]
frequencies = [0.5, 0.75, 1.0, 1.25]
curve_dict_2D = {(p,f):sine_curve(p,f) for p in phases for f in frequencies}
gridspace = hv.GridSpace(curve_dict_2D, kdims=['x', 'y'])
#renderer = hv.renderer('bokeh').instance(fig='html')
renderer = hv.renderer('matplotlib').instance(fig='png')
renderer.save(gridspace, 'fname', style=dict(Image={'cmap':'jet'}))

```
package-lock.jsonの管理をプロジェクトごとに変更する

npm v5から導入されたpackage-lock.jsonの管理についてです。
Node v８がLTSになったためv6からアップデートしてみたのですが、package-lock.jsonが意図せず更新されコンフリクトが発生することがあったのでpackage-lock.jsonの管理について考えてみました。
下記は環境はNode v8.9.0で確認済です。

# 対象読者
- チーム内でpackage-lock.jsonのコンフリクトが頻発する人
- プロジェクトごとにpackage-lock.jsonの管理を変えたい人

# .npmrcを使う
`npm config`コマンドで行うnpm周りの設定をプロジェクト単位で行うためのファイル。
package.jsonと同じディレクトリ階層に.npmrcというファイルを作ります。
例えば

```
npm config set save-exact=true
```
は以下のように.npmrcに記載します。

```
save-exact=true
```
そうすることでグローバルではなくプロジェクト単位でconfigを設定できます。

# dependenciesやdevDependenciesのバージョンを固定
普通に`npm install --save`とかするとpackage.jsonのdependenciesのバージョンに`^`が付くと思います。
この`^`や`~`が付くことでパッケージのバージョンのアップデートが意図せず行われることがあります。
`^`や`~`の意味については[package.json のチルダ(~) とキャレット(^)](https://qiita.com/sotarok/items/4ebd4cfedab186355867)を参考にしてください。
この`^`や`~`をデフォルトで付けないようにするためには.npmrcに以下を記載します。

```
save-exact=true
```
こうすることでパッケージのアップデートは防ぐことができるかと思います。
試しに`npm install --save (何かのパッケージ)`し、package.jsonを確認すると`^`や`~`が付いていないことが確認できると思います。
意図しないパッケージの更新がなくなり、意図しないpackge-lock.jsonの更新も減るでしょう。

# optionalDependenciesを無効にする
webpackやpm2を使っているとfseventsというパッケージがインストールされていると思います。
これはwebpackなどwatch機能に使うchokidarという依存パッケージが一緒にインストールされていて、そのchokidarがfseventsに依存しているためインストールされます。
しかし、このfseventsというパッケージはmacosでしか使えません。私が所属するチームではmac使いとLinux使いがいるためこのfseventsのインストールの有無の差が必ず出てしまっていました。
そのため、macosで`npm install`すると必ずfseventsが追記されてしまいパッケージに変更がなくてもgitの差分が出てしまっていました。
このfseventsはchokidarのoptionalDependenciesでした。
fseventsがなくても問題なかったのでoptionalDependenciesはインストールしないようにしました。
.npmrcに以下を記載することでoptionalDependenciesをインストールしないようにします。

```
optional=false
```

これでoptionalDependenciesがインストールされなくなり、macosとLinuxで依存パッケージの差を少なくしました。
また、こうすることでmacosでもfseventsがpackage-lock.jsonに記載されることがなくなりました。

# package-lock.jsonを使わない
あまりおすすめではありませんが、package-lock.jsonの管理をやめるのも一つの手段だと思います。
`npm shrinkwrap`はあったけど、そもそもnpm v5になるまでpackage-lock.jsonは無かったわけなので・・・
ただし、これは依存関係が壊れても問題ないようなプロジェクトに限って使用してください。
私のチームでは公開しているサービスはすべてpackage-lock.jsonを作成しGit管理していますが、一部の社内でしか使わないものに関してはpackage-lock.jsonを使ってない場合もあります。
まず.npmrcに以下を記述しpackage-lock.jsonが生成されないようにします。

```
package-lock=false
```
念のため.gitignoreにも追加しておきましょう。

```
package-lock.json
```

最後に意図しないパッケージのアップデートが無いように.npmrcに以下を記述しましょう。

```
save-exact=true
```

基本的にはpackage-lock.jsonは作成・管理することをおすすめしますが、GitHub上でも結構な人が.gitignoreにしていたりしていたので紹介しました。

最後までお読み頂きありがとうございました。
他にもこ「こうやっているよ」や「こうした方がいい」などあれば教えていただけると幸いです。

# 参考

- [npm-config](https://docs.npmjs.com/misc/config)
- [package.json のチルダ(~) とキャレット(^)](https://qiita.com/sotarok/items/4ebd4cfedab186355867)
python3 SyntaxError: non-default argument follows default argumentはなぜ起こるのか

すっかり忘れていたのか、久しぶりにこのエラーに引っかかったので備忘録がてらメモ。

#default argumentとは
デフォルトで値が与えられている引数のこと。色々な使い方があるが不確実なイベントに対応するためのプレースホルダーとして使ったり用途は様々。

```
def myfunc(value=None):
    if value is None:
        value = []
    # modify value here
```

#結局このエラーは何を言っているのか
引数の数 > 1という前提において、default argument（`def foo(x, y, default_arg=1): return default_arg, y, x,`←の一番右の引数）はルールとして最初の引数として配置できませんよと言う意味。

#なぜか
結論から言うと引数同士の混乱を防ぐため。SOFで素晴らしい回答を見つけたのでそれを引用しておく。

>
```
def fun1(a="who is you", b="True", x, y):
...     print a,b,x,y
```
_Suppose its allowed to declare function as above, Then with the above declarations, we can make the following (regular) positional or keyword argument calls:_
>
```
func1("ok a", "ok b", 1)  # Is 1 assigned to x or ?
func1(1)                  # Is 1 assigned to a or ?
func1(1, 2)               # ?
```
>
_How you will suggest the assignment of variables in the function call, how default arguments are going to be used along with keyword arguments._
>
```
>>> def fun1(x, y, a="who is you", b="True"):
...     print a,b,x,y
... 
```

defaultなのかそうでないのかの線引きをするためにdefault argumentは最後に配置するよう定められているわけだ。

#参考
- [Default Parameter Values in Python](http://effbot.org/zone/default-values.htm)
- [Why non-default arguments can't follows default argument?
](https://stackoverflow.com/questions/16932825/why-non-default-arguments-cant-follows-default-argument)
【問題解決】「Maven Clean」で、「The requested profile "pom.xml" could not be activated because it does not exist.」という警告が発生



# 環境
* Eclipse Pleiades 4.7
* Maven 3.3.9 (Eclipse pleiadesに組み込まれていたもの. EMBEDDED）
* Java8
* Spring Boot 1.5.7


# 問題
「Maven Clean」を実行した際に、警告が発生しました。

## 警告が発生した操作
1. Eclipseのプロジェクトを選択し、右クリック
2. 「実行→Maven Clean 」を選択
    * Maven Installなど、Maven Clean以外でも発生した


## 警告内容
コンソールに「[WARNING] The requested profile "pom.xml" could not be activated because it does not exist.」というメッセージが表示されました。

```txt:console
[INFO] --- maven-clean-plugin:2.6.1:clean (default-clean) @ demo ---
[INFO] Deleting C:\MyProgram\pleiades_4.7\workspace\demo\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.548 s
[INFO] Finished at: 2017-12-31T02:08:08+09:00
[INFO] Final Memory: 11M/243M
[INFO] ------------------------------------------------------------------------
[WARNING] The requested profile "pom.xml" could not be activated because it does not exist.
```

# 原因

Eclipseで、アクティブMavenプロファイルに「pom.xml」が指定されていたことが、原因のようです。
Mavenのプロファイルが完全に理解していないため、「ようです」という表現にしました。
デフォルト設定が`pom.xml`だったと思うので、Eclipseの設定でなくpom.xmlの中身に問題があると思うのですが、知識不足のためよく分かりません。。。

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/2075c72e-7794-c708-092b-a02953491264.png)



# 解決策

1. Eclipseで、プロジェクトのプロパティを開く
2. 「Maven」を選択
3. 「アクティブMavenプロファイル」を空欄にする

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/23af5d37-1fa3-c0c0-290f-76428e4fd5ad.png)

再度「Maven clean」を実行したら、警告は消えました。



# 参考にしたサイト
* [Spring Maven clean error - The requested profile “pom.xml” could not be activated because it does not exist](https://stackoverflow.com/questions/28192761/spring-maven-clean-error-the-requested-profile-pom-xml-could-not-be-activate/28193342#28193342)
* [STS(SpringBoot)からMaven Installを行った際にpom.xmlに関する警告が発生する。](https://teratail.com/questions/39512)

# よく分からないこと
* Mavenのプロファイル。アクティブとは？
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十四章 モデルの整合性を維持する12 プロジェクトがすでに進行中の場合

# これまでの十四章
- [第四部 戦略的設計 第一四章 モデルの整合性を維持する](https://qiita.com/YasuhiroKimesawa/items/6e8e5503a05ce9515a79)
- [境界づけられたコンテキスト](https://qiita.com/YasuhiroKimesawa/items/901ac764340275b93d61)
- [継続的な統合](https://qiita.com/YasuhiroKimesawa/items/6a58743c90c5b707c29d)
- [コンテキストマップ](https://qiita.com/YasuhiroKimesawa/items/626384c84145870ec5af)

##  
- [共有カーネル](https://qiita.com/YasuhiroKimesawa/items/7895d8c28137bd34008a) 
- [顧客/供給者の開発チーム](https://qiita.com/YasuhiroKimesawa/items/c9668a437499897fa9d5)
- [順応者](https://qiita.com/YasuhiroKimesawa/items/ab4782d5e727075e2d87)
- [腐敗防止層](https://qiita.com/YasuhiroKimesawa/items/bf22f7a970d5ee29a111)
- [別々の道](https://qiita.com/YasuhiroKimesawa/items/259cff6e393d5d03e274)

##
- [公開ホストサービス/公表された言語](https://qiita.com/YasuhiroKimesawa/items/bfec2a083483d348dc9c)

##
- [パターンを選択する](https://qiita.com/YasuhiroKimesawa/items/829a95eaed6f0b31eccc)

# プロジェクトがすでに進行中の場合
プロジェクト進行中にパターンを取り入れるケースです。

まずは、**現在の境界づけられたコンテキストを定義する**。現状を把握することです。

次に、**継続的な統合**を改善すること。どこかに**変換コードがあれば、腐敗防止層**を作成しまとめること。

現状を整理するのが最初のステップ。これが出来てから、次の作戦へ。

１回のイテレーションでは、変換が大きすぎて対応できないので、ステップ分割して進めます。

## 別々の道から共有カーネルへ

**小さなサブドメイン**を選択して、両方のコンテキストで重複するものから着手する。必ずテストコードを書くこと。１週間に一度は統合することが大事です。

なんとなく、ここまでするなら別々の道の方がいい気もしますが、統合を目指すなら少しずつ着手していきましょう。

両チームのメンバーから集まったグループが統合を進めていきます。

## 共有カーネルから継続的な統合へ

コアドメインを統合していく。チーム間でメンバのローテンションをし、両方のモデルを理解している人を増やしていく。

統合の頻度は１日に１度にしていく。

次は別のケース。レガシーシステムを廃止していくケースです。
## レガシーシステムを段階的に廃止する。

1回のイテレーションで移行できるような、レガシーシステムの特定の機能を識別して、腐敗防止層を併用しながら段階的にレガシーシステムを廃止していく手法です。

レガシーシステムで現在使用していないモジュールを全体が切り替わるまで稼働させておくのがポイント。
粗末な設計のソフトウェアだと、一度に切り離すのが難しく、使用していないとわかっていても、稼働させておくのが現実的。

上記を何度も繰り返すことで、段階的にレガシーコードがビジネスにかかわらなくなり、切り離すことができるようになる。

レガシーを稼働しながら、新システムへ移行していくので、腐敗防止層は収縮したり、膨張したりする。

・・・ということですが、できるものでしょうか。。。というのが感想ですが、一気に移行しようとすると、レガシーで設計がまずいシステムではそれを解析するだけで何年もかかってしまう。。。というのは経験しています。

なので、腐敗防止層を使って段階的に配する方法について、検討する価値自体はあるかと思います。
EMアルゴリズム徹底解説（おまけ）〜MAP推定の場合〜

先日の記事、[EMアルゴリズム徹底解説](https://qiita.com/kenmatsu4/items/59ea3e5dfa3d4c161efb)で触れられなかった、EMアルゴリズムによるMAP推定について少し解説します。
つまり、モデルのパラメーター$\theta$の事後分布を、$\theta$に関して最大化してMAP推定値を求める仕組みです。これは下記のような${\hat {\theta }}_{\mathrm {MAP} }$を求める方法です。

```math
{\hat {\theta }}_{\mathrm {MAP} }(x)=\arg \max _{\theta }f(\theta | \boldsymbol{X})
```

なので、最尤推定の時にターゲットとした$\ln p(\boldsymbol{X}|\theta)$ではなく、$\ln p(\theta|\boldsymbol{X})$を対象にします。MAP推定の場合に変分下限がどうなるかをみてみると、下記のように最尤推定の時の変分下限$\mathcal{L}$に、$\ln p(\theta) - \ln p(\boldsymbol{X})$が足されたものが導出されます。

<img width="743" alt="equ_0046.png" src="https://qiita-image-store.s3.amazonaws.com/0/50670/3826196d-377f-56ed-46a6-1e8ef77d2f38.png">

次に、$\ln p(\theta | \boldsymbol{X})　$ と $ \mathcal{L}'(q, \theta)$の差を見てみると、最尤推定の時と同一のKLダイバージェンスが導けることがわかります。これにより、EMアルゴリズムのEステップは最尤推定の時と変わらないことがわかります。

<img width="755" alt="equ_0047.png" src="https://qiita-image-store.s3.amazonaws.com/0/50670/72748867-f3fe-4dcf-684c-dd7c7e0d5a66.png">

<img width="740" alt="equ_0048.png" src="https://qiita-image-store.s3.amazonaws.com/0/50670/da63e9bd-7e38-34cb-9ed0-8640b46a56e8.png">

次に$\theta$に関する変分下限の最大化を見ていきます。これは先ほどの$\mathcal{L}'$を分解すると見えてきます。最尤推定の時の変分下限$\mathcal{L}$と比べ$\ln p(\theta)$が加わっています。これをMステップで利用して新しい$\theta$を求めればMステップとなります。

<img width="672" alt="equ_0049.png" src="https://qiita-image-store.s3.amazonaws.com/0/50670/e4fc6c8b-787b-ab2d-db48-bf75c3b46faa.png">

あとは最尤推定の時のEMアルゴリズムと同じですね:grinning:
公式手順をアレンジして、Ubuntu16.04でMagnetのマスターノードの構築を行う方法

#はじめに
Magnetのマスターノード構築手順として、Ubuntu17.04を使った手順が公式サイトで公開されております。
http://magnetwork.io/MAGNET_MN_SETUP_LINUX.pdf
http://magnetwork.io/wp-content/uploads/2017/12/COLD-WALLET-MASTERNODE-SETUP-on-LINUX.pdf

…が、大体のVPSで用意されているイメージはLTSな16.04であり、そのままの手順で進めたとしても構築は完了しません。
(バイナリ配布されたmagnetdが使えない)

当記事は、Ubuntu16.04でマスターノードを構築したい方を対象に、公式手順ベースのアレンジ方法を掲載します。

#前提知識
当記事をお読み頂く上で、以下の前提知識が必要となります。

* SSHなど、ターミナル経由でのUbuntuの基本的操作を身に付けていること。
* 公式手順の内容を大体理解し、実施出来る事(細かい手順は掲載しませんので)

#アレンジ箇所
基本的に公式手順の内容を実施して行きますが、

>INSTALLING THE DAEMON

のくだりの部分の手順が変わります。
Ubuntu16.04では配布されているバイナリが使えないので、ソースからビルドを行います。

##githubからソースをダウンロード
gitが入っていない場合はあらかじめインストールしておいて下さい。

```
git clone https://github.com/magnetwork/magnet.git
```
##ソースのビルド
以下のコマンドでソースをビルドして行きます。

```
cd magnet
chmod +x src/leveldb/build_detect_platform
chmod +x src/secp256k1/autogen.sh
cd src/leveldb
make libleveldb.a libmemenv.a
cd ..
make -f makefile.unix && strip magnetd
```

ビルドはかなり時間がかかります。
そこら辺のVPSの最安環境だと1時間以上かかると思われますので気長に待ちましょう。

出来上がったmagnetdは/sur/local/binあたりに置いておくとどこからでも呼べるので幸せになれると思います。

#おわりに
Magnetの手順書は丁寧に出来ている感じで、書かれた通りに実行して構築が終わる手順書になっていると思いますが、あくまでもマスターノード手順書であって、サーバーのセキュリティ面に関する内容の記載はありません。

特にローカルウォレットを使わない手順ですと、1万MAG以上入ったウォレットの場所を晒し続ける格好となりますので、出来る限りのセキュリティ対策を行っておきましょう。

ウォレットのバックアップもお忘れなく。
Node.jsサーバーでGitHubhook受け取ってpushだけで簡単にページ反映させる

### 前提条件
- Node.js 多分v6以上かつ、
- GitHubhookを受け取れるサーバーがある
- `npm init`はもうしてる場所
- GithubのDeployKeyはもちろん通してある

### 本文
PHPとかはいっぱいあるのにNode.jsのサンプルあんまない！:sweat:
[github-webhook-handler](https://github.com/rvagg/github-webhook-handler)を使うとちょー簡単です！！　ただ、`Buffer.from`を内部で使ってるので4系とか古いNode.jsでは動かない。。。です多分。。。:sleeping:

ということでぱぱっとインストール

```shell
$ npm install github-webhook-handler -S
```

#### サンプルコード
とりあえずログまで取るようにしてる適当なサンプルコードです。
github-webhook-handlerのerr.messageはJsonなので、それに習ってlogは全部Jsonに揃えとくと綺麗かも。
execでコールバックが山なりになってますが、[exec-then](https://github.com/ragingwind/exec-then)とか使うともっと綺麗になるかもですね〜〜:blush:

```javascript:github-webhook-handler.js
'use strict';

const logFilePath = './github-webhook.log';
const PORT = '7777';
const SECRET = process.env.WEBHOOK_SECRET || 'secret'; // ソース上にsecretがあるのはあれなので環境変数にしておくと良いかもっていう
const REPOSITORY_NAME = 'hoge'; // よしなに変えて
const errorMessages = {
    noMatch: 'not match repository or branch'
};

const fs = require('fs');
const http = require('http');
const exec = require('child_process').exec;
const createHandler = require('github-webhook-handler');
const handler = createHandler({
    path: '/webhook',
    secret: SECRET
});

const writeLog = (data) => {
    fs.appendFileSync(logFilePath, data+"\n", (err) => {
        if (err) {
            writeLog(JSON.stringify({error: err})+"\n");
            throw err;
        }
    });
}

http.createServer((req, res) => {
    handler(req, res, function (err) {
      res.statusCode = 404;
      res.end('no such location');
    })
  }).listen(PORT);

handler.on('error', (err) => {
    writeLog(err.message);
});
  
handler.on('push', (e) => {
    const payload = e.payload;
    const repoName = payload.repository.name;
    const branch = payload.ref.split("/").pop();
    let log = {
        pull: {
            error: '',
            stdout: ''
        },
        restart: {
            error: '',
            stdout: ''
        }
    };

    // リポジトリの確認とmasterが更新されたらっていう判断
    if (repoName !== REPOSITORY_NAME && branch !== 'master') {
        writeLog(JSON.stringify({ error: errorMessages.noMatch }));
        return;
    }
    
    // んで最後に反映する処理をよしなに書いておく...
    exec('git pull origin master', (err, stdout, stderr) => {
        if (err) { log.pull.error = err }
        log.pull.stdout = stdout;
        writeLog(JSON.stringify(log));

        exec('npm install', (err, stdout, stderr) => {
            if (err) { log.pull.error = err }
            log.pull.stdout = stdout;
            writeLog(JSON.stringify(log));

            exec('forever restart app.js', (err, stdout, stderr) => {
                if (err) { log.restart.error = err }
                log.restart.stdout = stdout;
                writeLog(JSON.stringify(log));
            });
        });
    });
});
```

これでGitHubhookのpushで`hostname:7777/webhook`を叩くようにしておけばページが反映されそうですね。
んでとりあえず死ぬと困ると思うのでデーモン化して起動しとこうかな...:innocent:

```shell
$ npm install -g forever
$ WEBHOOK_SECRET=hogehoge forever start github-webhook-handler.js
```

### オチ
やっぱCIツール使いましょう:smiley:
Redisの読み方がわからない

##ずっと「レディス」と読んでいた

しかしながら先日職場で「レーディス」と呼ぶ人がいた。
気になったので調べた。

##検索した

「レディース」というのも出てきた。
「レーディス」はない。
おおむね「レディス」のようだ。

##しかしカタカナでは発音がわからない

いつも愛用しているWeblioには単語の登録自体がなくて不明。
「レディス」だとしても、アクセントが「レ」にあるのか「ディ」にあるのか気になる。
アクセントが「ディ」にあって、若干「レディース」に聞こえるかもしれない。

##本家の動画を見た

[本家redislab.com](https://redislabs.com/)
おもっきし「レディス」やん。

##本家以外

[channel9](https://channel9.msdn.com/Series/Youve-Got-Key-Values-A-Redis-Jump-Start/01)
ここも「レディス」やね。

##ところが

[英語IPA変換ウェブツール](https://tophonetics.com/ja/)みたいなものがあったので入れてみた。


redisと入れて変換してみると発音記号が...

riːˈdaɪz (イギリス英語)
rɛdiz (アメリカ英語)

となる。聞いてみると、若干動画の発音の方が短めだけど、それなりにあってる。
てっきり発音記号も[redis]だと思ったのに...。

##わからんくなったやん

うーん、実は僕に聞き取れないだけで、nativeにとっては「レディズ」なのかもしれない。
ま、いっか。「レディス」もしかしたら「レディズ」ということで解決。

---
####追記 (2018/04/10)
eytyetさんからコメントで本家のQandAの情報をいただきました。ありがとうございます！
赤のred[réd]が基本ですね。


なを、その後、ググってみたら、結構昔から外国でも疑問が出ていたこともわかりました。
https://groups.google.com/forum/#!topic/redis-db/MtwjZC5gCeE
https://www.quora.com/How-do-you-pronounce-Redis
https://www.howtopronounce.com/redis/
ここら辺は、若干リディスに聞こえる…。
.prettierrcのvalidationチェック


schemastore.orgにホストされている[JSON schema](http://json.schemastore.org/prettierrc)を利用して行う

```js
"trailingComma": "es6" <= こういうのをうっかりpushしないようにしたい
```
 
## `.prettierrc`サンプル
```json:.prettierrc
{
    "printWidth": 120,
    "tabWidth": 4,
    "singleQuote": true,
    "trailingComma": "es7"
}
```

## validation実行

```js:validate.js
const { get } = require('axios');
const { readFileSync } = require('fs');
const { Validator } = require('jsonschema');

const valid = new Validator();

(async () => {
	try {
		const result = valid.validate(
			JSON.parse(readFileSync('./.prettierrc', 'utf-8')),
			(await get('http://json.schemastore.org/prettierrc')).data
		);

		if (!result.errors) {
			console.log('no error!');
		} else {
			result.errors.forEach(e => console.log(e.stack));
		}
	} catch (err) {
		throw new Error(err);
	}
})();
```

## 出力例

```sh
instance does not match allOf schema <#/definitions/optionsDefinition> with 1 error[s]:
instance.trailingComma is not one of enum values: none,all,es5
```
mongodbがerror111になった話

Mongoが止まりました。
$ mongo
と打ってもerror111と出る
→焦ってググる
ps aux | grep cron
とかやる。

mongod.lockを消せば良いとわかったが、
なぜかmongod.lockがない。

最終的にログを良く読んだら db/dataがないと言われてることに気づきました。
焦ると人間見落とすなあ。

https://docs.mongodb.com/manual/tutorial/manage-mongodb-processes/
を見なさいと言われたので、この通りに作った。

結果mongod.lockも出現

https://qiita.com/hahirusan/items/278b1f5435c0d127ab02
が参考になりました。
【問題解決】Maven Installで「No compiler is provided in this environment.」というエラーが発生



# 環境
* Eclipse Pleiades 4.7
* Maven 3.3.9 (Eclipse pleiadesに組み込まれていたもの. EMBEDDED）
* Java8
* Spring Boot 1.5.7


# 問題
「Maven Install」でエラーが発生しました。

## エラーが発生した操作
1. Eclipseのプロジェクトを選択し、右クリック
2. 「実行→Maven Install 」を選択

## エラー内容
コンソールに「No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?」というメッセージが表示されました。

```txt:console
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 7 source files to C:\MyProgram\pleiades_4.7\workspace\demo\target\classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
[INFO] 1 error
```


# 原因
「Perhaps you are running on a JRE rather than a JDK?」というメッセージの通り、JREで実行していました。

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/258c1b3d-75c3-ef57-f07c-0419085d4f62.png)

また、Eclipseの「設定→Java→インストール済のJRE」を開き、パスを確認すると、JREのパス（`C:\Program Files\Java\jre1.8.0_144`）になっていました。

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/ab802323-2165-3fe4-e157-696983e3747e.png)

# 解決策
インストール済のJREのパスを、「JRE」でなく、「JDKフォルダ配下のJRE」に変更しました。

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/a6589a2c-a200-def8-07ae-b4a915aeeef4.png)

再度「Maven install」を実行したら、エラーは消えました。

# ハマった原因
そもそも私はなぜ、JREのパスを設定していたのでしょうか？
たぶん、以下の項目が原因なんだと思います。

* 「インストール済JRE」という名前から、「JREのパス」を設定すべきだと思っていた
* JDKフォルダの中に、JREフォルダが存在することを知らなかった
    - [プライベートJREとパブリックJRE](https://www.java.com/ja/download/faq/helpful_concepts.xml)
* JREのパスが設定されている状態で、今まで特に問題が起きなかった（Spring Bootなどが起動できた）


# 参考にしたサイト
* [“No compiler is provided in this environment”エラーについて：Java](https://teratail.com/questions/3546)
* [STSのMaven install実行時の「No Compiler」エラーについて)](https://teratail.com/questions/81172)
* [No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?](https://stackoverflow.com/questions/19655184/no-compiler-is-provided-in-this-environment-perhaps-you-are-running-on-a-jre-ra?newreg=24fb3a944f034a6f964443046dc54fda)

# よく分からないこと
* 「JRE」と「JDK配下のJRE」の違い
* 「JRE」が設定されている状態で、Spring Bootを起動できる理由
Google Spread APIの認証で弾かれる場合の対処

以下のように、Google Spread APIの認証で弾かれる場合、
>
HttpError 403 "The caller does not have permission."

ホームディレクトリにある「.credentials」をフォルダごと削除してみる。
※Windowsの場合、「C:￥Users￥(ユーザー名)￥.credentials」

そうすると、次回の自作スクリプト実行時に、再度認証作業が行われ、うまくいくことがある。
CloudFrontに接続できないデバイスがある場合の対処方法

#どうやっても繋がらない

[デバイス]-CloudFront-APIGateway-Lambda（S3に保存）というサーバーレス構成を作っています。
これに対して画像を送信しようとしてるんだけど、どうにも接続できない。
なんで？と思って色々調べてみたら、コレが怪しいということに気が付きました。

[SNI 非対応クライアントのために API Gateway をハックする](https://blog.manabusakai.com/2016/09/api-gateway-sni/ "SNI参考")

確かにデバイス自体は古いので、SNIに対応していない可能性がある。
とはいえ、サーバーレス構成からサーバー構成にするのは悔しい。

#SNI非対応クライアントへの対応
ということで、ならばSNI非対応クライアント用に対応させればいい。
CloudFrontを調べてみるとこんなものがある。

[CloudFront で HTTPS リクエストを供給する方法の選択](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/cnames-https-dedicated-ip-or-sni.html "CloudFront で HTTPS リクエストを供給する方法の選択")

「代替ドメイン名を使用するように CloudFront を構成すると、CloudFront は、各エッジロケーションの専用 IP アドレスを使用するか、Server Name Indication (SNI) を使用して、HTTPS リクエストを供給できます。このセクションでは各オプションの仕組みについて説明します。 」

ということは、代替ドメイン名を使用するようにCloudFrontを構成する、ということをすればSNIを使用しない構成になるということだ。

#専用IPアドレスの料金
なればやってみよう！という前に、料金の確認。

[専用 IP 独自 SSL](https://aws.amazon.com/jp/cloudfront/pricing/, "料金")

「毎月 600 USD をお支払。この月額料金は時間数で案分。」

「6 月に 24 時間だけ使用の場合、（1 日/30 日）* 600 USD = 20 USD となります。」

非常に高い。試すとしてもリミットは1時間まで！

#やってみよう
まとめると、これを実現するには、以下2つのことが必要ということ。

　1.CloudFrontで独自証明書を使用する
　2.専用IPアドレスモードに変更する

1はコチラがとても参考になりました。ありがとうございます。
[Amazon CloudFrontの独自ドメインSSL証明書をAWS CLIでアップロードする](https://dev.classmethod.jp/cloud/aws/amazon-cloudfront-certificate-aws-cli/ "AWS-CLIで証明書をアップロードする")

結果、こんな感じで独自証明書が選択できます。
![ssl-select](https://s3-ap-northeast-1.amazonaws.com/uploadtestbucket-s3/qiita/sni/SSL%E9%81%B8%E6%8A%9E.PNG)

独自証明書を選択すると、専用IPアドレスモードが選択できるようになります。
ということで選択します。
![ALL-clients](https://s3-ap-northeast-1.amazonaws.com/uploadtestbucket-s3/qiita/sni/ALLClients.PNG)

#結果
[デバイス]-CloudFront-APIGateway-Lambda（S3に保存）というサーバーレス構成で接続することができました！わーい！

但し、すぐにCloudFrontの構成を元に戻しました。高すぎる。
まぁ、デバイス側では対応できないこともあるでしょうし、お金出せるのであればやっていいと思います。
今日はここまで。
メモ: Pandasの時系列データから特定時間帯を抜き出す

# モチベーション
複数日にまたがるデータから特定の時間帯（例えば株式市場の開いている時間）などを取り出したいとき、datetime.datetimeオブジェクトとの比較ではうまくいかない（datetime.datetimeオブジェクトは年月日を指定しなければならないため、一つのオブジェクトとの単純な比較ではかけない）しどのようにすればよいのかわからなかった。
# 手法
結論から言うとdatetime.timeをうまく用いればよい。panda.Timestampはdatetime.datetimeを継承しているので、datetime.datetimeの持つ種々のメソッドを持っている。datetime.datetimeオブジェクトはdatetime.timeを返す関数timeを持っているので、それと目的の時刻をdatetime.timeとしたものをうまく比較すればよい。すなわち
`df[(df["time"].apply(lambda x:x.time()) > time(huga)) & (df["time"].apply(lambda x:x.time()) < time(huge)) ]`
のように選んでやればよい。
#具体例
例えば9時から15時のみのデータを取り出したいときは以下のようにすればよい。

```python3:sample.py
import numpy as np
import pandas as pd
from datetime import time,timedelta
start = pd.Timestamp("2017-12-01")
end = pd.Timestamp("2017-12-03")
df =  pd.DataFrame(  pd.date_range(start, end  ,freq="10T"),columns = ["time"])
df[(df["time"].apply(lambda x:x.time()) > time(hour=9)) & (df["time"].apply(lambda x:x.time()) < time(hour=15)) ]
```


もっと良いやり方があるかもしれないので編集リクエスト待ってます。
VIMの矩形選択

いつも忘れるんで、メモである。

vimの矩形選択はcntl+Vである。
ここで、矩形を選択できる。

普通は、これで、ヤンク(y)してペースト(p)するぐらいだが・・

さらには、選択後にIとするとインサートモードになって、
上の一行に文字を追加したあとescでインサートモードを終了すると、
全行にその追加文字を追加できるという優れものである。

コメントを追加するなんて、お手の物という感じである。

問題は文末なのだが、最後の行を選択するときに文末＄を指定すると
行の文末まで指定するという意味になる。
当然Aで文字を追加すると、きれいに全行の文末に追加するという
仕様である。

いやいや、りっぱりっぱ！
Ubuntu 16.04 での 最新 tmux 導入手順

# はじめに

tmux 2.4 から 後方非互換のコマンドオプションが入り、Ubuntuのデフォルトのパッケージリポジトリのtmuxが古いことにより、tmuxの実行時に `usage: send-keys [-lRM] [-t target-pane] key ... ` というwarningが実行時に出るようになったため、最新のtmuxのビルドを使用することでこの問題を解決した。

ここではその時に行ったtmuxのビルドと設定方法について記述する

# 最新の tmux のビルド・設定方法

tmux は github上で開発が行われているため、masterのブランチをビルドして適当なbinディレクトリに配置するだけで良い。

Ubuntu 16.04 では、build-essentials と automakeが必要になる。

srcコードは `$HOME/src/tmux` で管理し、 バイナリは `$HOME/bin/tmux` に配置する。

以上を踏まえると、以下のコマンドを実行することで、tmuxのビルドと設定ができる。

```bash
sudo apt update 
sudo apt install -y build-essential automake libevent-dev ncurses-dev pkg-config bison
mkdir -p $HOME/src
mkdir -p $HOME/bin
cd $HOME/src && git clone git@github.com:tmux/tmux.git
cd $HOME/src/tmux && sh autogen.sh && ./configure && make 
cp $HOME/src/tmux/tmux $HOME/bin/
echo 'export PATH=$HOME/bin:$PATH' >> $HOME/.bashrc
source $HOME/.bashrc
```
Anacondaで機械学習の環境を作る（初心者版）

#目的
Anacondaを使って
機械学習（ディープラーニング）用の環境を作る

#ハードウェア
- MacBook Air (13-inch, Early 2015)
- 1.6 GHz Intel Core i5
- メモリ　8 GB

#ソフトウェア
- Mac OS Sierra 
- Anaconda-Navigator 1.6.11 
- Python 3.6
- Keras 2.1.2
- TensorFlow 1.4.1 

（最新版は1.4.2だけどSierraでは1.4.1でないとエラーが出る)

#やりかた
##Anacondaから仮想環境を作る
1. Anaconda-Navigatorの左カラム`Enviroments`を選ぶ
2. `create`から新しいEnviromentを作る（仮想環境になる）

##TensorFlowのインストール
- 先にTensorFlowを入れておくと良い

- Anaconda-Navigatorからインストールしてもうまく動かないようなので
pipでインストールする

3. 新しいEnviromentに移動
4. 右の三角をクリック、`Open Terminal`でターミナルを開く
5. [こちら](https://github.com/lakshayg/tensorflow-build)からTensorFlow 1.4.1のバイナリ(~.whl)をダウンロードして、適当なフォルダに入れておく
6. 以下のコマンドをターミナルへ入力

```
pip install --ignore-installed --upgrade /path/to/binary.whl
```

＊注意　`pip install tensorflow`だと最新版の1.4.2がインストールされてしまう

##Kerasのインストール
- Anaconda-Navigatorからインストールしてもうまく動かないようなので
pipでインストールする

7. 4で開いたターミナル（仮想環境のターミナル）のまま
8. 以下のコマンドをターミナルへ入力

```
pip install keras
```

##確認
- successful...とメッセージが出たらインストールはうまくいっているはず
- でも　`import keras`でエラーが出ないかを確認する

##追記(2019-04-11)
手元のマシンもMojaveになったので、デフォルトでインストールしたらどうなるか、近いうちに試してみようかと思う
GoogleHomeで声でメモってメールで送信する

## はじめに
ぱっと買い物を思いついた時にメモを取りたいときが多いけれども、筆記用具は近くにないしスマホも触れない。
声でメモができればよいのに…**GoogleHomeでやればいいじゃない。**
![homeからメール.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/db83b1f7-69ad-da6c-4d77-93fcc368a8e7.jpeg)

## 必要環境
GoogleHome本体
Googleアカウント
IFTTTアカウント

## やったこと
 1. GoogleHomeのセットアップ
 2. IFTTTの設定
 3. 実際に喋ってみる

## 1. GoogleHomeのセットアップ
GoogleHomeアプリの通りに進めていけばOK
無線LANのパスワードを入れる必要もないのはびっくりした。


## 2. IFTTTの設定
IFTTTは、WEBサービスとWEBサービスを繋ぐことができるサービスで、今回は「GoogleHomeに喋った」ら「喋った内容をGMailを使用して指定されたアドレスにメール送信」するという設定を行う。

IFTTTトップ （https://ifttt.com/discover） の、右上の自アカウントからNew Applet
![newapplet.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/d262ab70-c17a-93dc-a9a9-d96f8ce0bedd.jpeg)

+This をクリックし
![this.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/c79eea39-4150-37db-557f-c1ec7304e2b7.jpeg)

検索窓にgoogleと入力し、GoogleAssistandをクリック。
![GA.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/c1f549ca-962a-a7e5-34c2-f92c12a70222.jpeg)

今回は話しかけた内容をメールしたいので、Say a phrase with a text ingredient をクリック
![phares.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/c1645838-011b-8177-6569-11111cdabf51.jpeg)

設定画面が開くので、各種設定をしていく。
What do you want to say? は ねえGoogle に続く今回の処理を起動するための言葉。
今回はわかりやすく、「メモして $」にしておく。
$ は実際にメモする内容のこと。この場合は「メモして」の後に喋った内容がメールされる。

What's another way to say it? (optional) は What do you want to say? 以外の言葉でも処理を起動できる。
今回は使いそうな「メモって $」にした。

What do you want the Assistant to say in response? はコマンドが起動され処理された場合の、GoogleHomeからの返事。
今回は「メモをメール送信しました」にした。

Language はもちろん「Japanese」

最後に Create trigger をクリックし設定完了。
![設定.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/98480f2e-d620-5f79-dd7d-f4d6991a22b1.jpeg)

次にThatである、Gmailの設定
+Thatをクリック
![that.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/66839940-aa5b-89cd-0f16-cc02f9ca919c.jpeg)

Gmailで検索し表示されたGmailアイコンをクリック
![gmail.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/6ebb2597-b508-eec7-9ef7-23f3ca5fb846.jpeg)

今回はただメールを送るだけなので、Send an email をクリック
![gmail send.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/ab3cf9c1-ef46-9170-c620-7d127e02a7ae.jpeg)

設定画面が開くので、各種設定をしていく。
To address には送信先アドレスを指定
Subject はタイトルです。分かりやすいように、「{{TextField}} 」を設定。{{TextField}} は実際に喋った内容を言葉にしたものが入ります。
Body (optional) は、実際にメール本文にあたります。「Google Home からのメモ 「{{TextField}}」」
を設定。
そして最下部の、Create action をクリックし設定。

![gmail設定.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/1daa85cf-b0d5-83c5-c991-68ea2922e3b6.jpeg)

そして最後に設定確認が表示されるため、Finish をクリック
![最後.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/0e547290-7a17-82fb-cb77-d59ae7a77e08.jpeg)

## 3. 実際に喋ってみる
実際にGoogleHomeに喋ってメモをとってみる。
「ねえGoogle、メモして。会社帰りに食器洗い洗剤を買う」
これで、*「Google Home からのメモ 会社帰りに食器洗い洗剤を買う」*というメールが受信できれば成功です。

## 終わりに
今回は単純に声でメモしてメールを送るだけだったので目標は達成できた。
意外と手や目は使っていても口は空いてる場合が多いので、喋ってメモは意外と使えます。
しかしIFTTTとか使わず純正機能で Google Keep とかと連携できないもんかなあ

IFTTTは他にも色々なThatがあるので、組み合わせを変えるだけで喋った内容をTweetするとか、GoogleDocsに書き込むとか面白そう。
コードを書く必要もないためどんどん使っていきたい。