OmniAICreator/Qiita-1.07M huggingface dataset:
date_selectにバリデーションかける

f.date_selectで過去の日付は弾き方。


```:Gemfile
gem 'jc-validates_timeliness'
```
```
$ bundle install
```
必要なファイル群をインストール

```
bundle exec rails g validates_timeliness:install
```
エラーメッセージを日本語表示するためにファイルをコピー。

```
cp config/locales/validates_timeliness.en.yml config/locales/validates_timeliness.ja.yml
```

```validates_timeliness.ja.yml
ja:
  errors:
    messages:
      invalid_date: "は正しい形式で入力してください。"
      invalid_time: "は正しい形式で入力してください。"
      invalid_datetime: "は正しい形式で入力してください。"
      is_at: "は %{restriction} である必要があります。"
      before: "は %{restriction} より前を指定してください。"
      on_or_before: "は %{restriction} 以前を指定してください。"
      after: "は %{restriction} より後を指定してください。"
      on_or_after: "は %{restriction} 以降を指定してください。"
  validates_timeliness:
    error_value_formats:
      date: '%Y-%m-%d'
      time: '%H:%M'
      datetime: '%Y-%m-%d'
```

日付だけ表示されればよかったので、時間と秒は削除しました。

ja.ymlを持っていない場合はインストール

```
wget -O config/locales/ja.yml https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml
```

あとはmodelにバリデーションを書くだけ。
今回は昨日以前の日付を弾きたかったので、on_or_after: Date.todayを追記
```model_name.rb
validates :column_name, timeliness: { on_or_after: Date.today }
```

以上です。
無理解な職場でのコーディングに関するありがちな発言

コーディングに関する発言でありがちな発言の例を書いてみました。

###「引数にconstがついてないなんて、気にしてんじゃねえよ。ちゃんと動けば問題ないだろう。」
**間違っている理由：**
　ソースコードは、コンパイラのために書くのではなくて、コードを保守・追加開発する同僚のために書くものです。読みやすさは、人のために必要です。引数にconstが書いてあれば、それが入力であって、値が変わることがないことが、誰にでも自明なものになります。

###「引数にconstがついてないけど、ドキュメンテーションコメントで@param[in] p1 cv::Point と書いてあるんだからいいだろう。」
**間違っている理由：**
　ドキュメンテーションコメントは、const修飾子の代わりになりません。
const　修飾子がついている引数を関数内部で値を書き換えようとすると、コンパイラがエラーを返します。
　ドキュメンテーションコメントは、嘘を書いても、コンパイラはチェックをすることがありません。ある時点では正しかったドキュメンテーションコメントが、いつの間にか古くなって正しくなくなることがあります。ですから、const属性をつけることが可能な引数には、必ずconst属性をつけることです。

###「余分なヘッダファイルのincludeがあったってかまわないだろう。」
**間違っている理由：**
　ヘッダファイルで余分なincludeをしていると、単体テストがしづらくなります。単体テストをしやすくするためには、極力小さなモジュールとして、その範囲でテストをすることです。余分なincludeがあると、テストしようとする対象に影響を与えるファイルの数が増えてしまうのです。単体テストをしようとするならば、余分なヘッダファイルのincludeは少しでも減らしたくなっていくはずです。


###「参照渡しじゃなくて、ポインタ渡し使っているからって気にしなくていいだろう。」

**間違っている理由：**
　ポインタ渡しは、引数の意味がいろんな意味を持ちえます。それに対して参照渡しでは、意味が明確です。意味が明確な分だけ、そのコードを読む人、利用する人は使い間違えることが減ります。ささいなことに思うかもしれませんが、ささいなことの積み重ねが、読んで理解しやすいコードと、理解しがたいコードの違いを生みます。
　参照渡しで書いてあるソースコードは、ポインタ渡しで書いてあるコードよりも間違ったコードを書きにくくなります。参照渡しをしていると、NULLポインタの心配がないことの1点でも得をした気分になります。

###「不要なコードを削除しているだって、そんなことより、新しい実装の部分を早く書けよ。」
**間違っている理由：**
　不要なコードがあることは、ソースコードの理解を妨げることになります。不要なコードがあれば、不要なコードに対する保守が発生します。不要なコードに対するテストを書かなければなりなくなります。コードのカバレージがあがらなくなります。不要なコードがいっけん、もっともらしいコードとしてあると、目的の本物のコードを保守しているつもりが、使っていないコードの側をいじっていただけになって、貴重な自分の時間を失ってしまいます。


###「コードがきたないだと。そんなことを気にしているより、さっさとコードを書け。」

**間違っている理由：**
　ソースコードが汚くなると、次の機能の追加で間違える可能性が高まります。だから、コードを分かりやすく、保守しやすくしておくことはとても大切です。


###「データ構造が汚いだって、今までそれで書いて動いているんだから、ほっといてくれ。」
**間違っている理由：**
　そのデータ構造を使っているために、チームとしての開発のしやすさを損なっていませんか。秘伝の奥義を理解した人だけ利用できるのをすごいだろうと思っていませんか。データ構造をわかりやすいものにすることで、同じことが誰にでも理解しやすいものになります。そのことで、間違った使い方がされなくなります。また、そのライブラリを利用したコードを書きやすくなります。だから、データ構造が汚い場合には、リファクタリングをする価値があります。



-------------------
付記
> 一言、「Effective C++ 読め」で済みそうな…

そうなんです。
ただ、「Effective C++ 読め」で読んでくれる人ばかりじゃないのが悲しいところです。

---
qiita [Effective C++(第3版)メモ](http://qiita.com/ktsujino/items/ec0759dbeb40f76b4d2b)

---
qiita [Effective C++（項1〜5）解説](http://qiita.com/MoriokaReimen/items/58f183d421bb932cbbda)

qiita [Effective C++(項6〜10)解説](http://qiita.com/MoriokaReimen/items/bf301530e8f5d6d2fe90)

qiita [Effective C++（項11〜15）解説](http://qiita.com/MoriokaReimen/items/a2b00e8da6f6ec83949b)

qiita [Effective C++（項16〜20）解説](http://qiita.com/MoriokaReimen/items/4b51a41c9e8871907e80)

qiita [Effective C++(項21〜25)解説](http://qiita.com/MoriokaReimen/items/7aa1b7ba0bf27c829e16)

qiita [Effective C++（項26〜30）解説](http://qiita.com/MoriokaReimen/items/844da71c709f7813283a)
さくら共有サーバーにmecabをインストールしてpythonから呼び出してみる

#概要
この記事では、
さくら共有サーバーにmecabをUTF-8でインストールします。
その後、pythonからmecabを呼びだし、形態素解析をやってみる。
さくらレンタルサーバは、root権限が付与されないため、
ユーザディレクトリにインストールします。

#前提条件
・手順の中のコマンドは、bashで記載してます。bashに変更する方法は、
　補足の「さくらのレンタルサーバで bash を標準にする」を確認すること！



#インストールするもの
・mecab本体(mecab-0.996)
・mecabの辞書
・Pythonのパッケージ管理システムpip
・mecab-python

#手順
##mecab本体のインストール

(1)以下のサイトからmecab本体をダウンロードします。
http://taku910.github.io/mecab/#download

(2)mecab本体を解凍する
tarコマンドで本体を解凍します
`tar xvfz ./mecab-0.996.tar.gz `

(3)解凍したディレクトリに移動する
`cd mecab-0.996`

(4)コンパイル、ビルドする
ユーザディレクトリにインストールするため以下のようなコマンドを打つ
`./configure --prefix=$HOME/local --with-charset=utf8 --enable-utf8-only`

`make
make install`

私の環境では、以下の場所にインストールされました。
~/local/bin/mecab

(5)インストールされたか確認する
`mecab -v`
正常にインストールされていれば、上記のコマンドを打つと「mecab of 0.996」
というようなログが表示される。

##ipaの辞書を入れる
(1)以下のサイトからmecabの辞書、ipa辞書をダウンロードします。
http://taku910.github.io/mecab/#download

(2)ipa辞書を解凍します
`tar xvzf mecab-ipadic-2.7.0-20070801.tar.gz `

(3)辞書のフォルダに移動します
cd mecab-ipadic-2.7.0-20070801

(4)ユーザディレクトリにインストールするため以下のようなコマンドを打つ
辞書の文字コードをutf-8にしています。
utf-8にしている理由は、WEBで呼び出すためです。
`./configure --with-charset=utf8`

ただし、ここでutf-8に設定しても、mecabを実行したあと、
出力結果の文字コードがEUCのままになっていることがあります。

その場合は、「mecab-ipadic-2.7.0-20070801」内の
「csv」と「def」の拡張子のファイルをUTF-8に変換して上書きします。

UTF-8に変換するコマンドとそれを確認するコマンド
`
nkf -w --overwrite *.csv
nkf -w --overwrite *.def
nkf --guess *.*
`

参考
さくら共有サーバー、UTF-8の辞書でmecabを使う方法
http://nymemo.com/sakura/258/


(5)コンパイル、ビルドする
ユーザディレクトリにインストールするため以下のようなコマンドを打つ

`make
make install`

私の環境では、以下の場所に辞書がインストールされました。
~/local/lib/mecab/dic/ipadic


##mecabの動作確認

以下のように辞書を指定してmecabを起動します。

`mecab -d ~/local/lib/mecab/dic/ipadic`
ターミナルの設定は、UTF-8にしています。

成功すると以下のように表示されます。

`
[home@www1635 ~/local/etc]$ mecab -d ~/local/lib/mecab/dic/ipadic
すもももももももものうち
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS
`

#pythonのライブラリをインストールする

##pipをインストールします。
pipをインストールする理由は、pipを使ってmecab-pythonをインストールするため。

`easy_install --prefix=~/.local pip`

##pipがインストールされたことを確認
`[home@www1635 ~/local/etc]$ pip --version
pip 9.0.1 from /home/homedir/.local/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7)
`
##mecab-pythonのインストール

`pip install mecab-python --user`
--userが付いている理由は、サクラサーバではroot権限が使えないためユーザディレクトリにインストールします。

#pythonでmecabを動かす

こんなソースコードを書きます。

```pytb:sample.py
# coding: UTF-8

import MeCab

#辞書の場所を指定する（なぜかフルパスで指定しないと動かない）
userdic_path="-d /home/homedir/local/lib/mecab/dic/ipadic"
t = MeCab.Tagger("-Ochasen " + userdic_path)

text = u'すもももももももものうち'
encoded_text = text.encode('utf-8')# 
meData = t.parse(encoded_text )
print meData
```


実行すると以下のような文が出力されます
`a すもも	スモモ	すもも	名詞-一般		
も	モ	も	助詞-係助詞		
もも	モモ	もも	名詞-一般		
も	モ	も	助詞-係助詞		
もも	モモ	もも	名詞-一般		
の	ノ	の	助詞-連体化		
うち	ウチ	うち	名詞-非自立-副詞可能		
EOS
`

以上です！
次は、MeCabの実行結果をWEBブラウザーで表示させる方法を記事にします。

#補足

さくらのレンタルサーバで bash を標準にする
http://note.sicafe.net/sakuraVPS/sakura_vimInstall.html
LASSO, Ridge regression, erastic netをRで実行

# 前提知識

## LASSO
Least Absolute Shrinkage and Selection Operator
つまり、２乗誤差と$L^1$罰則項を用いて行う線形回帰のこと。
<strike>ネーミングセンスなさすぎだろと思う。なにがLeastでAbsoluteなShrinkageなのか不明だし、Selectionしてるとはいえ、Operatorではないだろ。</strike>

$\{ y^{(i)}\}$ を結果変数、 $\{ \boldsymbol{x}^{(i)} = {}^t(x^{(i)}\_1, \dots , x^{(i)}\_P) \}$ を説明変数とし、 $y^{(i)} = \sum\_p \beta\_p x^{(i)}\_p$ の式で回帰を行うとして、

```math
E_\lambda = \sum_i \left| y^{(i)} - \sum_p \beta_p x^{(i)}_p \right|^2 + \lambda \left\| \boldsymbol \beta \right\|_1
```

を最小化する。
パラメタの多くが0になる結果が返ってくるので、sparse modelingで活躍する。

## Ridge regression

LASSOの罰則項が$L^2$ノルムの場合。
これは、Bayes統計でも出て来る。ノイズが正規分布であると仮定して、パラメタの共役事前分布を取った場合。

最小化するのは、下の式の $\alpha = 0$ の場合のもの。

## erastic net
<strike>これもネーミングセンス無くない？どこらerasticでどこがnetなの？？？</strike>
罰則項が$L^1$と$L^2$のあわせ技になっているもの。

```math
E_{\lambda, \alpha} = \sum_i \left| y^{(i)} - \sum_p \beta_p x^{(i)}_p \right|^2 + \lambda \left ( \alpha \left \| \boldsymbol \beta  \right \|_1 + (1 - \alpha) \left \| \boldsymbol \beta \right \|_2^2 \right )
```

を最小化する。
sparse modelingした時、説明変数の間に強い相関があると、回帰結果が不安定になる。
それを抑えるために、相関がある説明変数の係数が同じ程度の値になるよう、$L^2$ノルムを入れていると解釈できる。

# Rのコード

以下のライブラリを使用
`glmnet`

適当にcsvか何かからdataframeを作っておいて、

```y <- unlist(dplyr::select(dataframe, result_variable))
x <- scale(as.matrix(dplyr::select(dataframe, -result_variable)))
```
で説明変数`x`と結果変数`y`を準備
（`dataframe`のなかの`result_variable`が結果変数の場合）

## LASSO

`fit <- glmnet(x, y)`
で出せる。

交差検証で最適な$\lambda$を探すなら、
`cvfit <- cv.glmnet(x, y)`

## Ridge regression

`fit <- glmnet(x, y, alpha = 1)`
で出せる。

交差検証で最適な$\lambda$を探すなら、
`cvfit <- cv.glmnet(x, y, alpha = 1)`

## erastic net

`fit <- glmnet(x, y, alpha = hoge)`
で出せる。

交差検証で最適な$\lambda$を探すなら、
`cvfit <- cv.glmnet(x, y, alpha = hoge)`

`hoge`には、誤差関数＄E\_{\lambda, \alpha}＄の$\alpha$を入れよう。

# plot系
`plot(fit)`
で、solution path（$\lambda$の値を変えたとき、$\boldsymbol{\beta}$の各成分がどう変わるかのグラフ）を見せてくれる。

`plot(cvfit)`
で、$\lambda$の値を変えたときにどのように誤差関数が変化するかを教えてくれる。

`coef(cvfit, s="lambda.min")`
で、誤差最小の$\lambda$でのパラメタがわかる。

# 参照
岩波データサイエンス vol.5
`help(glmnet)`
TeXのフォーマティングについては→[TeX 書式での数式表示が崩れるメモ](http://qiita.com/komiya_atsushi/items/11911355d2a2d0431bc2)
MinecraftサーバーでMySQLを運用する時のベストプラクティス

# 概要

MinecraftサーバーでMySQLを運用するときは以下の点を考慮して行ったほうが良いです。

* マイグレーションツールを使って、データベースを定義する
* プラグインでデータベース定義に関わるクエリを実行しない
* DBパスワードなどは環境変数に書く

以下にそれぞれの理由を書いていきます。

# マイグレーションツール

データベースではテーブルの定義、インデックスを貼るという作業が必要になります。
それらの作業を以下のようにして行うのは望ましくないです。

* サーバープラグインでCREATE TABLE等を実行する
* MySQLに直接ログインしてテーブルを作成する

一つ目の理由ですが、これは単純に変化に対応するのが大変だからです。
テーブルの作成、更新などを行うのは難しく、再現性がありません。
ある環境ではテーブルが作成されるけど、別の環境ではテーブルが作成できないというトラブルが発生します。
これらの問題は頑張れば解決できますが、得られるものは少ないと思います。

二つ目ですが、MySQLに直接ログインして操作するのは事故の原因になります。
間違えて名前の違うテーブルを作成して、削除するときに別のテーブルを削除してしまってデータが消えた。
というようなオペレーションミスが発生する確率が高いです。

これらの問題を解決してくれるのがマイグレーションツールです。
データベースの定義を補助してくれるツールです。

マイグレーションツールは色々なものがあるので、環境に合わせて選定してください。
http://qiita.com/narikei/items/8a71c5439edc9cb66550


## 筆者の環境　Rails

筆者の環境ではRailsのActiveRecordを使ってDBを管理しています。
選定理由として、Railsで管理画面を作る予定があったこと、筆者がRailsに慣れているためです。

マイグレーションファイルの作成はローカルで行い、サーバー上では

```
git pull
bin/rails db:migrate
```

でデータベースを更新しています。
DB定義はRailsで全て行うという方式にしています。
運用しているLinuxサーバーでは、RailsとMinecraftサーバーが入っています。

動かしているサーバーが、ローカルサーバー、devサーバー、prodサーバーがありますが、
このお陰で、全てのサーバーで同じデータベース環境を構築することができます。

プラグイン側では基本的にSELECT、UPDATE、INSERTしか行わないようになっています。

# 環境変数

プラグインにデータベースのパスワードなどを書かなければならない時があります。

```kotlin
host = "localhost"
port = 3306
database = "test"
username = "minecraft"
password = "password

Class.forName("com.mysql.jdbc.Driver")
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password)
```

こんなコードがあったとします。
データベースのパスワードをそのまま書いてしまっているのでセキュリティ的に問題あります。
gitやプラグインには含めたくないので環境変数として設定します。

~/.bash_profileに以下のように書きます

```bash:.bash_profile
export DATABASE_HOST="localhost"
export DATABASE_PORT="3306"
export DATABASE_DATABASE="test"
export DATABASE_USER="minecraft"
export DATABASE_PASSWORD="password"
```

そしてコードを環境変数を参照するように変更します。

```kotlin
host = System.getenv("DATABASE_HOST")
port = Integer.parseInt(System.getenv("DATABASE_PORT"))
database = System.getenv("DATABASE_DATABASE")
username = System.getenv("DATABASE_USER")
password = System.getenv("DATABASE_PASSWORD")

Class.forName("com.mysql.jdbc.Driver")
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password)
```

このようにすることで、データベースの情報を秘匿することができます。

# 終わりに

開発中のサーバーでまだ本格始動はしていないですが、個人的に得られた知見をまとめてみました。
他に良い方法があれば教えていただけるとありがたいです。

Minecraftサーバーではymlファイルをデータベースとして使っているところが多いですが、
ちょっと敷居が高いかもしれないですが、MySQLの方が高速でデータ管理も行いやすいのでおすすめです。
TensorFlow の複数プロセスで queue を共有

# はじめに

タイトル通りの内容です。
TensorFlowで分散処理をする場合queueだとかVariableだとか状態を持つような特殊なoperationを複数のプロセス間で共有する必要があります。
そのあたりの情報が少ないのでメモを残しておきます。
まずはqueueの場合です。

# 多分最小に近いサンプルコード

2つプロセスを立ち上げるので、2つコードを用意します。
`enqueue.py`はqueueにひたすらデータを詰めていくコード、`dequeue.py`はqueueからひたすらデータを取り出していくコードです。
重要なのはRandomShuffleQueueを作る時に両方のコードで同じ`shared_name`を指定しているところです。

```enqueue.py
import tensorflow as tf

server = tf.train.Server(
    tf.train.ClusterSpec({"local": ["localhost:2222", "localhost:2223"]}),
    job_name="local",
    task_index=0
)

q = tf.RandomShuffleQueue(
    capacity=10,
    dtypes=[tf.float32, tf.string],
    name="q",
    shared_name="shared_queue",
    min_after_dequeue=0
)
enqueue_op = q.enqueue_many(vals=[[0, 1, 2], ["a", "b", "c"]])

with tf.Session(server.target) as sess:
    for _ in range(10):
        sess.run(enqueue_op)
```

```dequeue.py
import tensorflow as tf

server = tf.train.Server(
    tf.train.ClusterSpec({"local": ["localhost:2222", "localhost:2223"]}),
    job_name="local",
    task_index=1
)

q = tf.RandomShuffleQueue(
    capacity=10,
    dtypes=[tf.float32, tf.string],
    name="q",
    shared_name="shared_queue",
    min_after_dequeue=0
)
dequeue_op = q.dequeue()

with tf.Session(server.target) as sess:
    for _ in range(10):
        print(sess.run([dequeue_op]))
```

それぞれ以下のように動かしてみましょう。

```
python enqueue.py
```

```
python dequeue.py
```

`dequeue.py`を実行すると以下のように`enqueue.py`でqueueに詰めたデータを取り出すことができました。

```
[[2.0, 'c']]
[[0.0, 'a']]
[[2.0, 'c']]
[[2.0, 'c']]
[[0.0, 'a']]
[[1.0, 'b']]
[[2.0, 'c']]
[[1.0, 'b']]
[[1.0, 'b']]
[[0.0, 'a']]
```

やったね。

# 参考

* http://stackoverflow.com/questions/39196176/how-can-i-push-tensors-to-a-tensorflow-queue-and-pull-them-from-another-process
* https://www.tensorflow.org/api_docs/python/tf/Graph
CloudFront Lamba@EdgeでBasic認証する

**2017/8: GA版にあわせて書き直しました**

CloudFront + S3オリジン構成の場合、Basic認証を使ったコンテンツ保護が出来ませんでしたが、[Lambda@Edge](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html)によって可能になりました。

下記の機能を提供しています。

- 一部のパスだけを認証の対象にできる。この例では、パスに`secret`が含まれるものだけが認証の対象です
- Authorizationヘッダがなかった場合に401ではなく403を返すことで、ブラウザの認証ダイアログが表示される
- 認証エラー時にBodyを返却する
- 複数のクレデンシャルに対応している

今のバージョンは、クレデンシャルがそのままハードコードされてるので、ソースの取り扱いにご注意を。
パスワードはハッシュをかけた方が安全ですが、これはTODOとします。

```javascript
'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;

  const errorContent = '\
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\
<html><head>\
<title>401 Authorization Required</title>\
</head><body>\
<h1>Authorization Required</h1>\
<p>This server could not verify that you are authorized to access the document\
requested.  Either you supplied the wrong credentials (e.g., bad password), or your\
browser doesn\'t understand how to supply the credentials required.</p>\
</body></html>\
';

  const credentials = {
    'user1': 'pass1234',
    'user2': 'pass5678'
  }

  if (request.uri.match(/secret/i)) {
    var authorities = request.headers.Authorization || request.headers.authorization
    if (authorities) {
      let authorized = false;
      for (let user in credentials) {
        var secret = new Buffer(user + ':' + credentials[user]).toString('base64');
        for (var i = 0; i < authorities.length; i++) {
          if (authorities[i].value.split(" ")[1] === secret) {
            authorized = true;
          }
        }
      }
      if (authorized) {
        console.log("match: " + authorities);
        callback(null, request);
      } else {
        console.log("not match: " + authorities);
        callback(null, {status: '403', statusDescription: '403 Forbidden',
                        headers: {
                          'content-type': [ { key: 'Content-Type', value: 'text/html; charset=UTF-8' } ]
                        },
                        body: errorContent.toString('utf8')
                       });
      }
    } else {
      // Client did not send authorization
      callback(null, {status: '401', statusDescription: '401 Unauthorized',
                      headers: {
                        'www-authenticate': [{ key: 'WWW-Authenticate', value: 'Basic' }]
                      }
                     });
    }
  } else {
    console.log("do nothing");
    callback(null, request);
  }
}
```
Eclipse for Macでコード補完ができるようにする

**追記**
Spotlight検索のショートカットキーが「Control + Space」なのはOS X Yosemite以前、
OS X El Capitan以降は「⌘ + Space」にデフォルトが変わったようです。
※ただし、YosemiteからバージョンアップしたEl Capitanは「Control + Space」を引き継ぐ

##Windowsの場合

「Ctrl + Space」でコード補完機能が利用できます。
例えば

```java:
main
```

 と入力して「Ctrl + Space」を入力するだけで

```java:
   public static void main(String[] args) {
        }
```

このように利用頻度の高いメインメソッドを自動補完してくれます。

##Macの場合

「Control + Space」を入力してみると…

![スクリーンショット 2017-04-12 23.12.52.png](https://qiita-image-store.s3.amazonaws.com/0/45588/e829610c-428d-4439-927a-531847725e4c.png)

そうです、macOS（OS X）ではデフォルトではSpotlight検索のショートカットキーなんです。
Eclipseのショートカット設定よりOS側が優先されてしまい、コード補完してくれません。

##対策1：Eclipseのショートカットキーの設定を変える

Eclipseはショートカットキーを任意のものに変更できます。

<img width="400" alt="20150516195749.png" src="https://qiita-image-store.s3.amazonaws.com/0/45588/28b4657a-c8c0-a741-2615-65cbb9e6ccba.png">

**1.メニューバーの「Eclipse」 → 「環境設定」を選択**
**2.「General」→「Keys」の中から「Content Assist」を選択**
（検索欄に「content」と入れるといいです）

<img width="400" alt="20150516195749.png" src="https://qiita-image-store.s3.amazonaws.com/0/45588/39af1414-463d-2529-0235-f495d972caa4.png">

**3.Binding欄に任意のショートカットキーを入力**

「Ctrl+Space」などOS標準のショートカット以外を設定しましょう。

##対策2：macOS（OS X）のショートカットキーの設定を変える

Spotlightを起動するショートカットキーも変更することができます。

<img width="400" alt="20150516204134.png" src="https://qiita-image-store.s3.amazonaws.com/0/45588/2dcb18f4-0ca2-4061-4255-91bf1c21891f.png">

**1.LaunchpadやDockから「システム環境設定」を開く**
**2.右上の「検索」欄にSpotlightを入力、サジェストされる「キーボードショートカット」を選択**

<img width="400" alt="20150516190207.png" src="https://qiita-image-store.s3.amazonaws.com/0/45588/05bfd702-b84d-c62b-40c5-33662bac6305.png">

**3.「Spotlight 検索を表示」の右、赤枠内をクリックして任意のキーを設定**
　　（※ チェックボックスから無効化も可能）


---
これで無事にMacでもコード補完が使えるようになりました。
Rails4の既存プロジェクトにRedux+React導入を検討する(1日目)


## 結論
最終的にはReduxを既存プロジェクト(Rails4)に導入するのは、フロントエンドエンジニアがほとんどいない現在のチームでは学習コストが高すぎるので、まずはReactのみを導入してコンポーネント単位でJSを書くことへの抵抗を無くすことを目指すことにしました。

この記事ではその決定に至るまでに学んだことを書いていきます。

## Railsのフロントエンド開発環境の導入方法を調査
reactだけではなくES6やnpmを活用してJSのコードを書いていきたかったので、Webpackのビルド環境を入れることにしました。

Rails4にWebpackを導入する際には以下の2つの方針があります。

* 1. Webpackのコンパイルファイルを`app/assets`配下に置く
* 2. RailsのSprocketsは完全に捨ててWebpackで全てのビルドを行う

2の方針はJS/CSSの圧縮・結合、キャッシュ対策のダイジェスト追加、sass/AltJSの変換等を全てwebpackに置き換える必要があります。

結構大規模な既存プロジェクトでnamespace毎に異なるマニフェストファイルで多数のJSファイルを読み込んでいるような環境だったので、Sprocketsを捨て去るだけで一大プロジェクトになりそうだと思い、今回は1の方式を取ることにしました

## Webpackの書き方を学習

Webpackの書き方については以下の2記事を押さえておけば大体理解できるようになるかと思います。

* webpack.config.jsの読み方、書き方 - dackdive's blog http://dackdive.hateblo.jp/entry/2016/04/13/123000#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB

* 【意訳】Webpackの混乱ポイント - Qiita http://qiita.com/chuck0523/items/caacbf4137642cb175ec

## Reduxチュートリアルで学習(環境構築編)

Reactはある程度書けるようになっていたので、以下の記事を元にReduxを基本から学ぶことにしました。

Reduxチュートリアル動画を見ながらReduxを基礎の基礎から - Qiita http://qiita.com/insight3110/items/4d212ecef6992e8eaee5

以下学んだことの要点を整理します。

### 必要なnpmモジュールの用途理解
* babel-core
	* 以前は`babel,babel-cli`が必要だったが、現在は`babel-core`に置き換わっている
	* ES6等のトランスコンパイルによく利用されるライブラリbabelを使うのに必要

* babel-loader
	* webpackでbabelを使ってトランスコンパイルするのに必要
	* トランスコンパイルとはES6等のブラウザで直接表示できない新しい技術を使っているコードをブラウザが認識できるコードに変換する作業のこと

* babel-preset-es2015
	* ES6を素のJavaScriptにトランスコンパイルするのに必要
	* 内部ではtransform-es2015-arrow-functions, transform-es2015-block-scoping等のpresetを読み込んでいる

* babel-preset-react
	* Reactを素のJavaScriptにトランスコンパイルするのに必要
	* transform-react-jsx等のpresetを読み込んでいる
	* これのおかげでReact内でJSXを使うことが出来る

* expect
	* テストで使うアサーションライブラリ
	* テストはdescribeやit等のテストを書く上で便利なAPIを提供してくれるテスティングフレームワークと個々のテストの判定を行うアサーションライブラリで構成される
	* テスティングフレームワークにはJasmine,mocha等があり、アサーションライブラリにはchai,expect等がある
	* 今回のチュートリアルではexpectを使っている
	* よくJSではさらにテスト実行環境用としてKarmaを別途使い、Karma+Jasmine+expectとかの構成でテストする

* react
	* その名の通り、reactを使うのに必要


* react-dom
	* DOMにコンポーネントを出力するのに必要
	* reactv0.14からReactから分離されたため、別途読み込みが必要
	* ちなみにReactのバージョンはv0.14->v15.xに一気にバージョンアップした

* react-redux
	* reduxとreactを連携させるために必要。reduxは状態管理のためのフレームワークなのでreact以外にも組み合わせることが可能。

* redux
	* Fluxにインスパイアを受けたフレームワークであるreduxを使うのに必要

* webpack
	* JS/CSS/画像等のファイルに対して圧縮/結合/変換等の処理を行うことが出来るツール。用意されたAPIを使った簡単な設定を書くだけで良いため、自身で処理内容を逐一書かなくてはいけなかった従来のgruntやgulpよりも遥かに楽

### babelの設定方法

babelを使ったトランスコンパイルに使うデフォルトのpresetを指定する。
方法には以下の2つがある。今回は入門ということもあり.babelrcを用意することにした。

* 1 .babelrcを配置する
* 2 package.jsonのbabelオプションに指定する

## 次回の内容
環境構築は終わったので、次回はReduxチュートリアルをやってみて学んだReduxの構成要素・原則について書いていきます。

## 参考文献
Rails 4.2でSprocketsを捨ててwebpackに移行する - Qiita http://qiita.com/dakatsuka/items/c815a27b9740c843bee0

webpackで作るSprockets無しのフロントエンド開発 - クラウドワークス エンジニアブログ http://engineer.crowdworks.jp/entry/2016/05/24/174511

.babelrcと.eslintはpackage.jsonに - Qiita http://qiita.com/sakana/items/c64abe5db3f9ea76dbf2
Rでcsv, xlsxを吐き出す方法

よく使うけど、毎回必ず忘れるのでここに書いておこー。

## csv
コード
`write.csv(data, file='path')`

`data`には、csvに吐きたいデータを、
`path`にはファイルのパスを。
（よく使うのは、`/Users/username/Dropbox/hogehoge`とか）

## xlsx
コード
`write.xlsx(data, file='path', sheetName='name', append=TRUE)`

`data`はxlsxに吐きたいデータを、
`path`にはファイルのパスを、
`sheetname`でシートの名前を設定可能
`append = TRUE`だと、`path`で指定しているファイルに新たにシートを付け加える挙動になる。
エンジニアのキャリアやサービスの考え方ですごく参考になった記事


エンジニアの記事は色々と読みますが、その中でも個人的に面白くて参考になったと思った記事です！



###キャリアに対して

[私が独自に発見した、一番ラクな天職の見つけ方。
(#面白法人カヤック社長日記 No.18)]
(https://www.kayac.com/news/2016/11/yanasawa_blog_vol18)


> 同じことをしていても、多くの気づきがある人とない人がいる。気付きがある人というのはそのことに対する才能があります。

例もわかりやすいので自分が何に向いているかの参考になります！

<br>
[有名技術ブロガー堤修一氏に聞く、「情報発信」からキャリアをデザインする方法【特集：エンジニア育成の本質】]
(http://type.jp/et/log/article/hrd_tsutsumi)

堤修一さんの記事です！
情報発信の大事さがわかります。
> そういう視点であらためて自身のブログの黎明期を振り返れば、質より量とは言いつつも、一方では質を向上させるための試行錯誤は欠かさなかった。

アウトプットの質も気をつけねば、、そこらへん気をつけます(´°̥̥̥̥̥̥̥̥ω°̥̥̥̥̥̥̥̥｀)



<br>
[キャリアって何だろうね【連載:村上福之】](http://type.jp/et/log/article/fukuyuki35)


> キャリアとして、カードをたくさん持っている方が、戦える場所が増えるからね。

村上福之さんの記事です。とても参考になります。他の記事も面白いです。

[ 非コミュプログラマーが独立するのに必要なたった2つの勇気【連載:村上福之①】](
http://type.jp/et/log/article/post_29)





<br>
[エンジニアで稼ぐために大切な１５のこと](
http://qiita.com/kazukichi/items/7379b75fba2f90d3cf45)

kazukichiさんのqiita　なんだか心がズキズキしますw
> 企業から搾取されているエンジニア達、ぜひ自分で立ち上がって自分の人生を勝ち取って欲しいと思います。
行動しなければ何も生まれません。
<br>

[WEBサービスで起業したい人に読んで欲しい１９のコト]
(http://qiita.com/kazukichi/items/aeba286c2a750081e5c0)
こちらもkazukichiさんの記事
とにかく行動しなければと思える内容です！

<br>

[Write Code Every Day](
https://speakerdeck.com/twada/write-code-every-day)
記事ではないのですが、習慣化の大事さがすごくわかるスライドです。



<br>
###サービスに対して
<br>
下記２つは２つともpaji (id:hajimeataka) さんの記事です。
2011年の記事ですが、めちゃくちゃ参考になります。
今でこそグロースハックなどの言葉がありますが、それらに通じるような考えがこの時にすでに言及されています。
番外編もオススメです。

[Webサービスを作ってスタートダッシュを決める戦略１１つ（＋番外）](http://www.paji.me/entry/20110810/1312943715)


>
1. 自分自身が有名になる
2. 有名人、アルファブロガーに紹介してもらう
3. ブームに乗る、ホットなテーマに取り組む
4. プレスリリース、宣伝可サイトに書き込み、友人・知人に知らせる
5. SEO対策
6. はてなブックマークでホットエントリーを取る
7. 自分のWebサービスからユーザーを流す
8. 最新の技術を取り入れたサービスを作る
9. コンテストに参加する
10. 勉強会や講演会などのイベントやコミュニティに参加する
11. ネーミング、キャッチフレーズにこだわる、秀逸なデザイン


他の記事も参考になります。

[今年こそWebサービスを作りたい人に伝えたい５つのこと（＋番外編）](http://www.paji.me/entry/20110214/1297645090)

<br/>
【個人メモ】[jQuery] スマホでアクセス時にリンク先を切り替える

(参考)
http://creatorhyp.com/tips/tips-linkchange/

(Javascriptを使う場合)
http://hacknote.jp/archives/3414/
(```indexOf()```の仕様)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
リモートで削除済みのブランチをローカルからも削除する

他人が削除したリモートブランチが残っていて、削除できなかったときのメモです。

###こんなときに使う

・masterにマージ済みで、削除されたはずのリモートブランチが `git branch -a` で出てくる
・ローカルブランチは `git branch -D` で削除済み
・`git push origin :hope`しても消えない
・`git fetch`しても消えない

###コマンド
`git fetch --prune`
または
`git fetch -p`

###メモ

`git fetch` だけではリモートブランチを取り込むだけで削除はしません。
「--prune」「-p」というオプションを指定することで削除されたブランチも更新されます。
react-webpack-rails-tutorialのBasic Demo Setupでコケまくったのでメモ

[shakacode/react_on_rails](https://github.com/shakacode/react_on_rails) は Webpackを使ってRailsでReactを動かすためのGemです。

これを用いたチュートリアル

- [shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial)

の README にある [Basic Demo Setup](https://github.com/shakacode/react-webpack-rails-tutorial#user-content-basic-demo-setup) をやろうとしたら、エラーがたくさん出たのでその対処法を書いておきます。

開発環境はMacです。

## `bundle install` できない


`capybara-webkit`のインストールでエラーが出ました。`qmake`が使えないことが原因だったので、`qt`を入れました。

（まぁ７番目の指示で`which qmake`して`qmake`入っているか確認して、と書いてあるのでこれに気づくべきでした）

```
$ brew install qt@5.5
$ brew link --force qt55
```

[Installing Qt and compiling capybara webkit · thoughtbot/capybara-webkit Wiki](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit#macos-sierra-1012-el-capitan-1011-and-yosemite-1010)


## `yarn install` できない

README の 11 番目に`yarn`を実行して、とありますが、途中で止まってしまいました。

原因は自分の環境のpythonのバージョンが3系だったことによるnpmのsleepが動かせないことだったため、pythonを２系にしたら`yarn install`できました。

## `foreman start -f Procfile.hot` できない

まず、指示にあるコマンドは正確には`bundle exec foreman start -f Procfile.hot`だと思います。

次に、コマンドが動かない原因ですが、自分の場合`node-sass`が原因だったので、`node-sass`をrebuildしました（正直よくわかっていない）。

```
$ cd client
$ npm rebuild node-sass
```

これで無事、デモを見ることができました。ちなみに指示の14番目では`Open a browser tab to http://localhost:3000 for the Rails app example with HOT RELOADING`と書いてありますが、おそらく [localhost:5000](localhost:5000) の間違いです。

![スクリーンショット 2017-04-12 22.16.10.png](https://qiita-image-store.s3.amazonaws.com/0/90682/57c0285f-b14d-5349-7858-dd6301f638ef.png)

いろいろと大変でしたが、とりあえずデモが動かせて良かったです。環境によっては別のところでつまる可能性がありますが、この記事が参考になれば幸いです。
MacにGitLab-CI-Runnerをインストールして、ローカルのみでも使う

[GitLab Meetup Tokyo #2](https://gitlab-jp.connpass.com/event/52276/)に行った際のenomotok_の発表を見て、思い立って試したメモ。

## 実行すること

```shell-session
$ brew install gitlab-ci-multi-runner
$ brew services start gitlab-ci-multi-runner
$ git clone https://gitlab.com/xxxxx/xxxxx.git
$ cd xxxxx
$ gitlab-ci-multi-runner exec docker test_job
```

## 何をするのか

homebrewにはgitlab-ci-multi-runnerがあります。 [^1]
gitlab-runner自体はDockerベースでテスト実行ができるので、そのプロジェクトに`.gitlab-ci.yml`があれば、そこに定義されたテストジョブをいつでも好きなタイミングで実行できます。

## 以下、自分用メモ

### 環境変数は？

`--env` で突っ込める。複数指定するときは全部指定すればいい。

### コミット前にテストできる？

確認した範囲では、無理っぽい。
まぁ、`git commit --ammend`を繰り返すか、あとでrebaseすればいいんじゃないかと。

~~これで、Invalid YAMLなんてGitLab.comに言われずに済む~~

[^1]: この記事を作るときまで、検索すらしなかった
ApacheのRewrite機能でスマホの時だけ遷移先を変えたった

スマホでどのページにアクセスしても、```http://example.com/```にリダイレクトする
適用したいフォルダに.htaccessを作成して以下を記述

```apache
RewriteEngine On

RewriteCond %{HTTP_USER_AGENT} (iPhone|Android.*Mobile|Windows.*Phone) [NC]

RewriteRule ^(.*)$ http://example.com/ [QSA,L]
```

(参考)
[メインで参考にしたURL]
https://allabout.co.jp/gm/gc/386483/3/#a386483p3case2

[Internal Server Errorが出る時の原因と対処法]
https://allabout.co.jp/gm/gc/23962/4/

[正規表現を用いて全てのURLを特定のURLに遷移させる]
http://weblabo.oscasierra.net/apache-rewrite-2/
※転送の無限ループの例も記載されている

[Apacheが用意した変数名一覧]
http://weblabo.oscasierra.net/apache-rewritecond-base/
FESSメモ

- Fess10.0.3のKuromoji辞書
https://ja.osdn.net/projects/fess/forums/18580/37656/

> Fess 10ではドキュメントの言語判定を行い、そのドキュメントに
最適な各言語用のAnalyzerを適用するようにしています。
形態素解析されたものが結果の上位に来ないような場合は
ドキュメントの言語判定で日本語として判定されていない可能性があります。

なるほど。。Analyzerの設定もしくはソースを見れば、どんなドキュメントをどう解析するかがわかりそう。めもめも。

- どういったドキュメントの時にどのAnalyzerが割り当たるかはこの設定ファイルかな？
~~https://github.com/codelibs/fess/blob/master/src/main/resources/fess_indices/fess/doc.json~~
https://github.com/codelibs/fess/blob/master/src/main/resources/fess_indices/fess.json

投稿に対してコメントをいただきましたので、修正しました。ありがとうございます。＞shinsuke_sugayaさん

コメントいただいた内容が正に知りたい内容でしたので、こちらにも載せておきます。
>どのAnalyzerを使うかの言語判定ロジックはelasticsearchの機能ではなく
https://github.com/codelibs/elasticsearch-langfield
のプラグインで拡張された機能になります。
ただ元にしているlangdetectの言語判定機能が間違うことがあるので、HTMLについては、htmlタグのlang属性があればそれを使うようにしています。
あとは、Analyzerまわりは検索の肝になる部分ですので、
https://github.com/codelibs/elasticsearch-analysis-fess
でAnalyzer自体を自動検出したりとか、elasticsearchにいろいろとプラグインで機能追加しています。

Analyzerの自動検出とか、心をくすぐる文言だ。面白そう。今日は時間がないから、土日にソースを眺めてみよう。と言いつつ、休日はやらない気がする。。＃電車の移動中に見るかな。^^

- Analyzerの設定
http://fess.codelibs.org/ja/11.0/config/analyzer.html
>検索のためのインデックスを作成する際、索引として登録するために文書を切り分ける必要があります。 Fess では、文書を単語に分解する機能を Analyzer として登録しています。 Analyzer は CharFilter、Tokenizer および TokenFilter により構成されます。
~中略~
Analyzer の設定は Fess の起動時に fess インデックスが存在しない場合に app/WEB-INF/classes/fess_indices/fess.json で fess インデックスを作成して登録されます。 Analyzer の構成方法は elasticsearch の Analyzer のドキュメントを参照してください。

ふむふむ。結局elasticsearchを調査か。。

- ElasticSearchのアナライザの設定
http://christina04.hatenablog.com/entry/2015/02/02/225734

>configで設定する
アナライザを指定せずにインデクスを作成した場合にこの設定がデフォルトとなります。
今回はバイグラムでアナライザを設定します。
設定
/etc/elasticsearch/elasticsearch.ymlを編集します。

- Elasticsearchのインデックスの格納場所
http://qiita.com/uzresk/items/e0b10c14875b79c450f2

>デフォルトは/var/lib/elasticsearch。この下にnodes/0/_state/global-0.stという感じでインデックスが格納される。

- ElasticsearchからデータをCSV形式でワンライナーで取り出す
http://qiita.com/gingi99/items/f7dc57193fbf978eb63b

>以下でElasticsearchにあるindex一覧を取得できる。
$ curl -XGET [IPアドレス or ホスト名]:[ポート番号]/_aliases?pretty
コードレビュー 6か条

## 謝辞
コードレビューを1から教えてくれた現場に敬意を。

## 1.コメントには重みをつけろ
- 重みのないコメントは相手にストレスを与えていると思え
  - must > should > nits > imo > ask
     - askは特殊だと思うけど使いやすかったので記載

## 2.些細な指摘(imo/nits)は５つ以内
- 本当に修正してほしい指摘を埋もれさせない
- 数を限定することで、レビュイーのコメントクオリティを担保
- どうしようもないコードに慈悲はないので除外

## 3.論理的に説明できないのであれば指摘しない
- 原則書き手を尊重せよ
- 己の美的感覚で指摘をするな
 - 論理的でない美的感覚は百害あって一利なし
 - どうしてもやりたければチームでルール化せよ
- 1分理解5分反映を意識する
 - 修正コミットを直接積むのも良いだろう
 - ペアプロも良いだろう

## 4.コメント全部に対応しない
- 理解できないコメントは無視で良い
- 無視されてストレスに感じるなら、コメント全てが悪いと思え
 - 重みを変える
 - 説明を変える
 - ペアプロする
 - 直接話をする
- その指摘は常に正しくないと思え
 - 自分は常に正しくないと知れ

## 5.一回のレビューで終わらせろ
- 修正->コミット->修正の無限ループを悪だと思え
 - 無限ループはレビュアーを疲弊させる
 - チームの雰囲気も悪くなる

## 6.approve or +2 されたら即マージしろ
- ユーザーへ素早く価値を届けろ
- マージされないことによるレビュアーのストレスを排除せよ
- マージを恐れない
 - revertがある
- マージできない理由を述べよ

-----

## 参考文献
[デキるプログラマだけが知っているコードレビュー7つの秘訣](https://www.slideshare.net/rootmoon/7-37892729)
[コードの健全性: 礼儀正しいレビュー == 役立つレビュー](https://developers-jp.googleblog.com/2019/12/respectful-reviews.html)
[レビューの仕方@Open8](https://speakerdeck.com/yosuke_furukawa/rebiyufalseshi-fang)

## 最後に
ええ、あなたの想像の通りです。ただの私の愚痴でした。
お付き合いありがとうございました。
Cloud KMSを使ってみる

#概要
GCPでは以下３つの暗号化ソリューションを提供しており、今回は暗号化キーの作成や管理をクラウドベースで行うことができるサービスであるCloud KMSを使ってみる。（Encryption by defaultは利用者が気にしなくてもGCP側で勝手に暗号化してくれる）

<img width="654" alt="Screen Shot 2017-04-12 at 17.29.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/5647f84f-24d4-369a-f2c1-d96e961b180c.png">

引用：https://cloudplatform-jp.googleblog.com/2017/01/managing-encryption-keys-in-the-cloud-introducing-Google-Cloud-Key-Management-Service.html

Cloud KMS API を利用することで介すことで、秘密管理やエンベロープ暗号化ソリューションの一部として、キーの作成、使用、ローテーション、破棄を可能にしている。

#鍵の作成

手順1. KeyRing名とlocationを設定
KeyRingはCryptoKeyをグルーピングしたものであり、GCPの特定のロケーションに属する。（グルーピングした方が管理しやすいため）。

![resources2.png](https://qiita-image-store.s3.amazonaws.com/0/95399/166ed3b1-ca16-964f-65ec-2057707fd7df.png)
引用元：https://cloud.google.com/kms/docs/object-hierarchy

<img width="461" alt="Screen Shot 2017-04-12 at 16.44.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/2756fce0-5b44-7c90-4c4a-7d76c9c7eb67.png">

手順2. Key名を設定
CryptoKeysはKeyRingからの権限を継承する。
<img width="449" alt="Screen Shot 2017-04-12 at 17.04.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/86a91379-7803-6ff4-2bd6-b8624b975d8a.png">

作成すると以下の画面で確認できる。
<img width="787" alt="Screen Shot 2017-04-12 at 17.05.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/50d6123e-a3d1-9754-ba4b-fcebb90868a4.png">

#Cloud KMSで管理している鍵を使って、ファイルの暗号化と復号を行う。

暗号化と復号を行うPythonのコードはクイックスタートのコードを使用する。

```
gsutil cp -r gs://cloudkms-eap-resources/quickstart .
```

以下のコマンドでファイルを暗号化

```
$ python crypter.py $PROJECT_NAME encrypt /tmp/test_file /tmp/test_file.encrypted
```

```
$ cat /tmp/test_file.encrypted 
CiQAkyqlpvH5W7e/W5nZluSZeitnT9gPENSj+s3gG0tQLqQPJKMSMwCiNopxhxTc7nBaS0u8ZtDzr/Pjz8a7Lqb2wF7LzcOwLvVPo8+
CMR7uWffW7FvYZ61/pA==
```

以下のコマンドでファイルを復号

```
$ python crypter.py $PROJECT_NAME decrypt /tmp/test_file.encrypted /tmp/test_file.decrypted
```

```
$ cat /tmp/test_file.decrypted 
Hello KMS
```
API経由で鍵を操作し、ファイルに対して暗号化と復号ができることを確認した。
C言語のポインタを含む構造体の初期化まとめ。

C99に準拠した内容です。  
C11でも特に変わっていなさそう。
C言語の仕様で次の構造体の初期化はどうなるのか、少しまとめておきたい。

```C
#include<stdio.h>

struct S
{
    int val;
    void *ptr;
    int val2;
};

int main(int argc, char *argv[])
{
    struct S a_var = {0};
    static struct S s_var;

    // 自動変数の表示
    printf("%d\n%d\n", a_var.val, a_var.val2);
    if (a_var.ptr == NULL)
    {
        // NULLのときの処理
    }

    // 静的変数の表示 => 初期化していないので、.bssに置かれる。
    printf("%d\n%d\n", s_var.val, s_var.val2);
    if (s_var.ptr == NULL)
    {
        // NULLのときの処理
    }
    return 0;
}
```

下記の2ページの内容をまとめてみる。

[スタックオーバーフロー：C言語のポインタ変数を含む構造体初期化について](https://ja.stackoverflow.com/questions/33824/c%E8%A8%80%E8%AA%9E%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E5%A4%89%E6%95%B0%E3%82%92%E5%90%AB%E3%82%80%E6%A7%8B%E9%80%A0%E4%BD%93%E5%88%9D%E6%9C%9F%E5%8C%96%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
[スタックオーバーフロー：how about .bss section not zero initialized](http://stackoverflow.com/questions/3532334/how-about-bss-section-not-zero-initialized)

算術型：int / long / char 等  

| 初期化状態 | auto / 算術型 | static / 算術型  | グローバル / 算術型 |
|---|:-------|:--------:|:---------:|
| 未| 不定 | 0 | 0 |
| 済| 初期化値 | 初期化値 | 初期化値 |

| 初期化状態 | auto / ポインタ型 | static / ポインタ型  | グローバル / ポインタ型 |
|---|:-------|:--------:|:---------:|
| 未| 不定 | NULL | NULL |
| 済| 初期化値 | 初期化値 | 初期化値 |

配列や、構造体の先頭要素のみを明示的に初期化した場合
（上記ソースの「struct S v={0};」みたいなやり方）は
先頭要素以外staticやグローバル変数の未初期化変数と同様の方法で初期化される。

ということで、上記の構造体を利用するコードでは、初期化が完了すると以下の値を持つことになる。

```C
 a_var.val -> 0
 a_var.ptr -> NULL
 a_var.val2 -> 0

 s_var.val -> 0
 s_var.ptr -> NULL
 s_var.val2 -> 0
```

ちゃんとC99の規格に準拠していれば、NULLは「数値型に変換した時0と一致する」ということなのでC言語で言うところのint型の0とNULLの値は一致しなければならない。  
（ただし、C言語のソース上ではその比較はやってはいけない（可読性下がるからマジやめてね）って話と言う認識でいる）

ということは、自作でOS作ってる人はプログラムローダとか作るときは責任持って.bssをゼロ埋めしてあげる必要があるのだなぁ。

間違っても1とかで埋めてはいけない。

[追記]
スタックに格納した変数はコンパイラが0クリアするコードを書いてくれるはずだよ　と言うツッコミが有ったので、BinaryNinjaでディスアセンブルしてみる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30037/e82c5c33-c512-1150-40a1-cfaf3d573659.png)

スタックに確保されたやつは赤枠の部分みたいに、代入コードが生成されて初期化されるのを忘れていた。
指摘されて　あー　そういえば！ってなった。

ちなみに、.bssの方はどうなっているかをobjdumpで見る。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30037/9922e8ad-26cb-c06b-74ee-2fc22eb3ec5b.png)

とりあえずBinaryNinjaでも見てみる。
.bssの初期化値はファイルに書かれて無いはずだけど
（.bssはセクションフラグにLOADが存在しない、ALLOCのみ）
BinaryNinjaが勝手に解釈して勝手にゼロを代入している。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/30037/3cfe9ace-1a85-87a2-6ea5-5024222fc34c.png)

だからまぁ、ローダー側はC言語の規格に準拠する処理系と言いたいなら、.bssをゼロ埋めしてあげよう。

以上
EC2でFlaskを動かすための準備

# Flaskとは
- [Flask](http://flask.pocoo.org/)はPythonのフレームワーク

# やること
- Pythonをインストール
  - pyenvからインストールする。
- Flaskをインストール

# pyenv install
```
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
```

# パスを通す
```
$ vi .bash_profile

export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
```

# pythonのバージョン一覧を確認
```
$ pyenv install --list
```

# pythonをインストール
```
$ pyenv install your-version
```

# Cコンパイラーがなくて怒られたら
```
yum -y install gcc
```

# これで怒られたら
```
pip x.x.x requires SSL/TLS

# これで解決
yum install openssl-devel
```

# ここで再チャレンジ
```
pyenv install 3.5.0
```

# バージョン指定
```
pyenv global 3.5.0
```

# 参考
- バージョン指定はshell/local/globalの３週類がある。それぞれのスコープが異なる。

# Flask install
```
pip install --upgrade Flask
```
redmine_issue_checklistで、あるトラッカーだけチェック状況に応じて進捗率が連動する設定にしてみた

redmine_issue_checklist　プラグインで
あるトラッカーの場合は、進捗率が連動する様に修正してみました。
https://github.com/Restream/redmine_issue_checklist

![checklist.PNG](https://qiita-image-store.s3.amazonaws.com/0/150778/fbaff755-8920-8b10-79ef-f221e95b0f16.png)


元々、チェック状況に応じて進捗率を自動で変更するオプションがあるのですが、全てのチケットに対して有効になってしまうので、結局、機能をOFFにして使用しています。
基本的に、覚え書きとか、抜け漏れ防止の用途にチェックリストを使っているので、それがそのまま進捗になる事が無いのでOFFの方が良かったのですが、あるトラッカーでは、チェック状況＝進捗率としたくなって、少し修正してみました。

```ruby:app\controllers\issue_checklists_controller.rb
22行目
if (Setting.issue_done_ratio == 'issue_field') && RedmineIssueChecklist.settings[:issue_done_ratio]
  done_checklist                   = @checklist_item.issue.checklist.map { |c| c.is_done ? 1 : 0 }
  @checklist_item.issue.done_ratio = (done_checklist.count(1) * 10) / done_checklist.count * 10
  @checklist_item.issue.save
end

↓↓↓↓↓↓↓↓

# トラッカーID3 (サポート)以外は、チェックリストでの進捗更新をしない
if (Setting.issue_done_ratio == 'issue_field')  && (@checklist_item.issue.tracker.id == 3) && RedmineIssueChecklist.settings[:issue_done_ratio]
  done_checklist                   = @checklist_item.issue.checklist.map { |c| c.is_done ? 1 : 0 }
  if (@checklist_item.issue.checklist.count != 0)
    @checklist_item.issue.done_ratio = ((done_checklist.count(1) * 10).to_f / @checklist_item.issue.checklist.count).round * 10
  end
  @checklist_item.issue.save
end
```

※ついでに、０除算しない様にバカ除け追加と、計算が切り捨てだったのを四捨五入に修正しています。

```ruby:app\models\issue_checklist.rb
12行目
# after_save :recalc_issue_done_ratio 
↓↓↓↓↓↓↓
after_save :recalc_issue_done_ratio  

26行目
def recalc_issue_done_ratio
  return false if (Setting.issue_done_ratio != 'issue_field') || !RedmineIssueChecklist.settings[:issue_done_ratio]
  done_checklist   = issue.checklist.map { |c| c.is_done ? 1 : 0 }
  issue.done_ratio = (done_checklist.count(1) * 10) / done_checklist.count * 10
  issue.save
end
↓↓↓↓↓↓↓↓
# トラッカーID3 (サポート)以外は、チェックリストでの進捗更新をしない
def recalc_issue_done_ratio
  return false if (Setting.issue_done_ratio != 'issue_field') || (issue.tracker.id != 3) || !RedmineIssueChecklist.settings[:issue_done_ratio]
  done_checklist   = issue.checklist.map { |c| c.is_done ? 1 : 0 }
  if (issue.checklist.count != 0)
    issue.done_ratio = ((done_checklist.count(1) * 10).to_f / issue.checklist.count).round * 10
  end
  issue.save
end
```

bitnami 3.3.0, ie11, redmine_issue_checklist v2.1.0
HoloLensでダブルタップを検知する

#はじめに
３月初めよりインターンで株式会社ゆめみ(https://www.yumemi.co.jp/ja) にてHoloLensの研究開発をしている近大生のよっしーです。
国内でこの１月から提供を開始したMicroSoft製MRデバイスのHoloLensについての記事を書いていきます。

#すること
**ダブルタップを検知する**

HoloLensはシングルタップのみ。みたいに思い込んでいたのですが、実はすごく簡単にダブルタップが取れるのを知ったので解説します。

#解説
ドキュメントを見てもらうと一目でわかります。tapCountでタップ数が取れるので、このカウントが1ならシングルタップ、2ならダブルタップとなります。
<img width="867" alt="スクリーンショット 2017-04-12 20.50.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/114709/111498ee-6034-5cc9-0f00-16623b2510ae.png">
https://docs.unity3d.com/ScriptReference/VR.WSA.Input.GestureRecognizer.TappedEventDelegate.html

#実装例

関連部分以外全てを省いているのでご注意ください。

```csharp:DoubleTap.cs
void Awake() {
    NavigationRecognizer = new GestureRecognizer();

    NavigationRecognizer.SetRecognizableGestures(GestureSettings.Tap);

    NavigationRecognizer.TappedEvent += NavigationRecognizer_TappedEvent;
}

private void NavigationRecognizer_TappedEvent(InteractionSourceKind source, int tapCount, Ray ray) {
    if (tapCount == 1) {
        System.Diagnostics.Debug.WriteLine("Single tap");
    } else if (tapCount == 2) {
        System.Diagnostics.Debug.WriteLine("Double tap");
    }
}

```

追記: 4/13/2017
古いバージョンのHoloToolkitを気づかずに使っていて投稿時知らなかったのですが、以下の方法も使えます。

```csharp:IInputClickHandler.cs
using HoloToolkit.Unity.InputModule;
using UnityEngine;

class SomeObject: MonoBehaviour, IInputClickHandler {
    private void Start() {
        InputManager.Instance.AddGlobalListener(gameObject);
    }

    private void OnDestroy() {
        InputManager.Instance.RemoveGlobalListener(gameObject);
    }

    // MARK: - IInputClickHandler
    public void OnInputClicked(InputClickedEventData eventData) {
        if (eventData.TapCount == 1) {
            System.Diagnostics.Debug.WriteLine("Single tap");
        } else if (eventData.TapCount == 2) {
            System.Diagnostics.Debug.WriteLine("Double tap");
        }
    }
}
```
やさしいPSR


#PSRとは

**PHP Standards Recommendations** の略。

標準的にPHP全般で準拠したほうがいいようなルールをまとめたもの。
「フレームワークがルールに則って作られたら、学習コストがやたらかかったりみたいなことが防げるよねー」
ということで作られたらしい。

##バージョン

PSR-4まではうまくいっていたとのこと、です。


#内容

メソッド名を同じようなルールにしておく、とか。
議論して決まっていくものらしい。

##「ACCEPTED」とかって何？

承認されたやつ、ということらしいです。

##例えば...

"Logger Interface"

あくまで「インターフェース」なので、引数とメソッド名だけを統一する感じらしい。


#PSRの見る夢

「全てのフレームワークを今よりも簡単に理解できるようになる...」的な？

#業務上のPSRを使うメリット

会社内で独自のコード規約を使ったりすると

「`{`の位置とか、だけでプルリク投げたくない...」
「会社内で独自のコード規約つくるのめんどくさい...」

ということがあると思うので、PSRをみんなで使えばちょっと幸せになりそう...？

##PSRチェックツール

PHP Coding Standards Fixerというものがある。
https://github.com/FriendsOfPHP/PHP-CS-Fixer

PSRに則って、スペースとかを入れてくれるもの。
ただし、間違ってるところの洗い出しとかは出来ないみたいです。

#参考

PSRについて： http://qiita.com/mikakane/items/c076dac67e69635e8b3e
PHP-CS-Fixerについて： http://qiita.com/mikakane/items/e15f1bd21cc6e15863c7
[Go] gorilla/schema でデコードする際の必須フィールド指定

https://github.com/gorilla/schema でGoのstructへデコードする際に、
必須のフィールドを持たせてバリデーションしたい場合。

## tl;dr

タグオプションの `required` を使う。

```go
type Person struct {
	Mail        string `schema:"mail,required"`
	PhoneNumber string `schema:"phone_number"`
}
```

### example

例として、URLパラメータをデコードしてみる。

```go
package main

import (
	"fmt"
	"net/url"

	"github.com/gorilla/schema"
)

type Person struct {
	Mail        string `schema:"mail,required"`
	PhoneNumber string `schema:"phone_number"`
}

func main() {
	q1 := url.Values{}
	q1.Add("mail", "hoge@example.com")

	p1 := &Person{}
	d1 := schema.NewDecoder()
	if err := d1.Decode(p1, q1); err == nil {
		fmt.Printf("1. error does not occur.\n")
	}

	q2 := url.Values{}
	q2.Add("phone_number", "11122223333")

	p2 := &Person{}
	d2 := schema.NewDecoder()
	if err := d2.Decode(p2, q2); err != nil {
		fmt.Printf("2. error occurred.\n%v", err)
	}
}
```

```bash
$ go run main.go
1. error does not occur.
2. error occurred.
mail is empty
```

[ドキュメント](http://www.gorillatoolkit.org/pkg/schema) では触れられてないが、
ソースコードをみれば、[requiredオプションのチェック](https://github.com/gorilla/schema/blob/dfd60678a6033f19803293695dcd30f40ed3cd19/decoder.go#L93)があることが分かる。
Mac での Mcrypt PHP extension required. 対処方法(別バージョン)

## はじめに

homebrew でインストールした PHP で `Mcrypt PHP extension required.`のメッセージが出るようになったけど、[こちらの現象](http://qiita.com/massa142/items/a5715b15232bdf5c5e9e)ではなかったっぽくて、最終的に[ここ](https://github.com/Homebrew/homebrew-php/issues/1940)を参考に再インストールしたら直った。という話。

## 環境

```bash
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.12.4
BuildVersion:	16E195


$ brew list | grep php
php-cs-fixer
php70
php70-mcrypt


$ php -m | grep mcrypt
## 無反応
```

## 手順

```bash:php70-mcryptをソースから再インストール
$ brew reinstall -fs php70-mcrypt
```

```bash:確認
$ php -m | grep mcrypt
mcrypt


## 表題のメッセージもでなくなりました。
```

## おわり

ここに至るまで php.ini に mcrypt のパスを書いたりなど色々やったのですが、最終的には再インストールが正解でした。

homebrew-php のスレ主ありがとう。

おわりです:whale2:

## 参考と注釈

* [Mcrypt PHP extension required.の対処方法 - Qiita]
* [install php70-mcrypt susses but not work](https://github.com/Homebrew/homebrew-php/issues/1940)
EC2を停止/起動したらネットワークに接続できなくなった

# 症状

すでに稼働中のEC2で作業をし、必要があったためEC2を停止/起動した。
すると、今まで動いていたデプロイコマンドが動かなくなった。

調べたところ、EC2から外部のネットワークに接続できなくなっていた。
具体的にはssh接続でEC2にログインし、以下のコマンドを実行しても一向に応答がない状態となってしまった。

```
$ ping www.google.co.jp
```

# 原因

このEC2は開発環境として使用していて、複数のdev環境が動いている。
それぞれのdev環境に固定IP（Elastic IP）を割り当てるために、複数のElastic IPをEC2に関連付けている。

EC2の停止/起動により、EC2のパブリックIPが変更されたのだが

なんと

**既に関連付けられていたElastic IPと同一のパブリックIPアドレスが割り当てられたのである。**

![add_text.jpg](https://qiita-image-store.s3.amazonaws.com/0/71267/2704ab6f-bf5f-3176-7688-d1d4ebf0025a.jpeg)

だからpingを打っても応答がない(循環していた？)状態になっていたんですね・・・。

# 対応
EC2の停止/起動で再度パブリックIPを割り当て直して完了。
これを機にElastic IPを新しく発行して、EC2の固定IPに割り当てました。

# 最後に
既に関連付けられているIPと同じIPがパブリックIPとして割り当てられることあがある、
なんてことが、まさか起きるとは思っていたなかったため
原因を探すのに時間がかかってしまいました:disappointed_relieved:
確率で起こりうることとはいえ、AWS側で何かしらのチェックが入っていることを期待してしまっていました。
C#で文字認識をする（導入）

#Tesseractを使って文字認識（OCR）
**インストール**
Tesseractの他にも使えそうなのはあった。
　　Tesseract.Net.SDK → 個人用の試用版だった
　　tesseract.net　→ よく分からなかった
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/174938/961207cf-4ec5-50fe-6ac6-c534ad3f5383.jpeg)

**言語データのダウンロード**
言語データを別途準備する必要がある。
英語：tesseract-ocr-3.02.eng.tar.gz
日本語：tesseract-ocr-3.02.jpn.tar.gz

#サンプルコード

```csharp
    class Program
    {
        static void Main(string[] args)
        {
            //言語ファイルの格納先
            string langPath = @"C:\tessdata";

            //言語（日本語なら"jpn"）
            string lngStr = "eng";

            //画像ファイル
            var img = new Bitmap(@"C:\Temp\test.jpg");

            using (var tesseract = new Tesseract.TesseractEngine(langPath, lngStr))
            {
                // OCRの実行
                Tesseract.Page page = tesseract.Process(img);

                //表示
                Console.WriteLine(page.GetText());
                Console.ReadLine();
            }
        }
    }
```

**画像ファイル**
![test.jpg](https://qiita-image-store.s3.amazonaws.com/0/174938/30d7df8f-de18-64e3-5249-ee631dd7f9fe.jpeg)
---
**結果**
![キャプチャ1.JPG](https://qiita-image-store.s3.amazonaws.com/0/174938/2a0c8a49-a1a8-959a-0eec-b9f52dc91204.jpeg)


#その他
あらかじめ文字を指定しておけば精度が上がるらしい。
```tesseract.SetVariable("tessedit_char_whitelist", "1234567890");```
学習機能もあるとのこと
jsdoでconvnetjs その7

#概要
線形回帰のプレイグランド、作って見た。
パーセプトロンの数と回数を設定。
時間とロスとグラフを表示します。

#写真
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/g/G/S/gGSV.jpg?t=1491993853)

#成果物
http://jsdo.it/ohisama1/gGSV
chef-clientのダウングレード

### 前置き

- Chef-Server11を使っているのだが、最近のOSでデフォルトで入るknifeだとエラーになるようになった
    - amazon linuxやCentOSで
    - Chef-client 13系以上がだめで、12系なら問題なし
    - あるいは、レシピの書き方によってもchef-client を古い目にしたいときがある

```
FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
ERROR: undefined method `inject' for nil:NilClass
FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

あるいは
Running handlers:
[2018-05-01T07:36:25+00:00] ERROR: Running exception handlers
Running handlers complete
[2018-05-01T07:36:25+00:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources would have been updated
[2018-05-01T07:36:25+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2018-05-01T07:36:25+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2018-05-01T07:36:25+00:00] FATAL: NoMethodError: undefined method `supports' for Chef::Resource::User::LinuxUser
など出る

```

### 解決

https://downloads.chef.io/
でChef-Client12.Xを選んでダウンロード


```console
# knife -v
Chef: 13.7.16
# yum remove chef
# cd /usr/local/src
適当なディレクトリでよい
# wget https://packages.chef.io/files/stable/chef/12.22.5/el/7/chef-12.22.5-1.el7.x86_64.rpm 
# rpm -ivh chef-12.22.5-1.el7.x86_64.rpm
# knife -v
Chef: 12.22.5
```

とりあえずよかった

### 懸念点など

- Chef-Serverをバージョンアップすればいいのだが、そもそChefやめてAWSの機能や、Ansibleに置き換え中なのでこのような対応になった
    - サーバ使い捨てデプロイを導入していくので、構成管理手法も変えざるを得ない
二要素認証はAuthy一択

最近、二要素認証を求められる事が非常に多いですが、携帯電話を買い換えると、またリカバリーコード入れ直しになったりしてめんどくさいですよね？

そこで、Authyを使えば、勝手にバックアップ取ってくれて、再接続すれば、すべてのにワンタイムパスワードが一発で復旧します。

もうGoogleの二要素認証は使わなくて良いですね。
Kotlin×DataBindingで「ｱｲｴｴｴ onClick() 呼ばれないﾅﾝﾃﾞ?!?!」となったときに確認すること

凡ミスをやってしまったので備忘メモ。👾

# DataBindingで`onClick()`実装

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="owner"
            type="com.shanonim.sample.MainActivity" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/button"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:onClick="@{() -> owner.onClickButton()}"
            android:text="@android:string/ok" />
    </RelativeLayout>
</layout>
```

クラス側で`onClickButton()`を書いてあげると、タップ時にメソッドが実行されます。

```kotlin
fun onClickButton() {
    Toast.makeText(this, "tapped", Toast.LENGTH_SHORT).show()
}
```

# `onClick()`が呼ばれない...😢
下記の実装では、ボタンをタップしても`onClickButton()`が呼ばれません。

```kotlin:MainActivity.kt
class MainActivity : Activity() {

    var binding: ActivityMainBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    }

    ...

```

# 【解決策】`binding!!.○○ = this`を忘れない🙅
xml側の`<variable>`で指定しているnameとViewを紐付けてあげないといけません。

```xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="owner"
            type="com.shanonim.sample.MainActivity" />
    </data>
```
であれば、

```kotlin
binding!!.owner = this
```
が必要です。

先ほどのActivityのコードを補足してみます。

```kotlin
class MainActivity : Activity() {

    var binding: ActivityMainBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding!!.owner = this
    }

    ...
```

これで無事にボタンがタップできるようになりました🎉
babelもflow-remove-typesもいらないFlow Comment Syntax

JavaScriptに型を付けてくれるflowですが、導入するにはbabel(とtransform-flow-strip-typesプラグイン)やflow-remove-typesを使って型注釈をコードから削除してJSとしてValidにする仕組みが必要になります。

ところが[Comment Types Syntax](https://flow.org/en/docs/types/comments/)を使うと、flowの型注釈を全てコメントの中に収めることができます。つまりコードをJSとしてValidに保ちつつ、型の恩恵を受けることが出来て最高っぽいです :sparkles: 

Comment Types Syntaxは2通りあり、 `/*:: */` と `/*: */` で、この中に型に関するコードを書きます。詳しくは[ドキュメント](https://flow.org/en/docs/types/comments/)を参照下さい。

Facebook謹製のIDEである[Nuclide](https://nuclide.io/)はComment Types Syntaxをシンタックスハイライトしてくれます。

![スクリーンショット 2017-04-12 19.39.37.png](https://qiita-image-store.s3.amazonaws.com/0/59312/f3ae7730-8aa5-a95c-a969-03868f96ccff.png)

本来ただのコメントになるはずの`/*:: */` と `/*: */` がシンタックスハイライトされてます。

コメントで囲む分だけ若干冗長にはなりますが、flow導入によるJSコンパイル環境の複雑化というデメリットをなくすことができるのでとても強力だと思います！