OmniAICreator/Qiita-1.07M huggingface dataset:
デブサミ2017、個人スポンサーの視点でレポート

# はじめに
Developers Summit 2017([デブサミ2017](http://event.shoeisha.jp/devsumi/20170216))が2017/2/16-17に開催されました。今回も個人スポンサーとして参加しましたので、取り留めなく私の視点でレポートしたいと思います。
次回の個人スポンサーが増えれば幸いです(汗)
# デブサミ個人スポンサーのメリット・デメリット
デブサミの個人スポンサーというのは、「デブサミの開催を個人で出資・応援していただける方のこと」です。デブサミは無料イベントなのですが、有料の代わりに色々な特典があります。
今年は去年から料金など少し変更になりました。今年の特典は、、、。

- フリーパス：事前登録なしにセッションの聴講ができます。セッション選択に迷う方には魅力的ですね。
- 優先入場：一般入場の前に入場できますので、待機列に並ばなくても良くなります。
- 専用受付：受付も別なので、待機列に（略）
- 電源・Wifi・テーブル付きの席：レポートとか内職（笑）とかするのに捗ります。
- スピーカーラウンジ利用：これは今年からです。スピーカーラウンジが使えるので、休憩する際に場所があるのは嬉しいですね。
- 弁当と飲み物：弁当は今年からです。会場の目黒雅叙園は、昼食が非常に不便&料金高いという問題があるのですが、一気に解決します。
- Tシャツ：これは２日間申込の方限定です。Tシャツは微妙な面もありますが、それはステータスという事で（汗）
- 翔泳社書籍30%割引：デブサミで書籍を沢山購入する方（私です）にはありがたいです。
- 公式サイト掲載：これもステータス（略）

今年は２日間で20,520円でした。昨年より値段が上がってますが、それに見合うメリットはあると思いました。

デブサミ参加へのバリアーとして、「登録に出遅れるとセッションが満席になる」というのがあるのです（個人的にもらう意見）が、これを解決できる方法として有効ではないか、と考えています。
要は、面倒な事を金で解決する（笑）のです。魅力的ですよね？
# デブサミの裏側をちょっと覗く
ということで、今年はスピーカーラウンジを使うことができたのですが、最初に入った時に感じたのは、、、**タコ部屋だなぁ**でした。考えてみれば、より良い発表をする為への準備とかする訳ですから、当たり前なのですが。
# デブサミ今年の特徴
今年のデブサミで去年から変わった点としては、

- 参加コミュニテイが大幅に変わった(IoT関連のみ)
- コミュニティの書籍販売が出来るようになった

かと思います。
昨年までは色々なコミュニティが参加していたのですが、展示場所が良くないこともあって微妙な感がありました(昨年はJGGUGブースに２日間居ました)。今年は展示場所のアクセスが改善された（書籍販売ブースに近い）こともあり、目につく機会があったのではないか、と思います。
また、今年はコミュニテイの書籍販売ができた事で、今までとは違うコミュニティが参加できて、デブサミの幅が広がったのではないかと思います。
# で、レポートは?
レポートは、他の方がまとめてくれると思いますので、個人的な思い（ポエム）を書きます。
## 16-B-7
スピーカーの市谷さんとはコミュニティに参加したこともありましたし、色々な場所で話を聞く事がありましたが、デブサミという場所で「思い」を聞くことができたのは良かったです。
また、黒田さん、新井さんの話も「思い」が詰まっていて良かったです。
## 17-B-7
スピーカーの原田さん・吉羽さんとは、勤め先でのワークショップの講師としてお世話になりましたし、それ以前にもイベントで絡みがありました。
今回は「ジョイ・インク」に関連するワークショップでしたが、貴重な経験をさせてもらいました。
実は、近くに座っていた方が「Yahoo!Japanのスピーカー」「ヴァル研究所のスピーカー(新井さん!?)」でした。ワークショップの中で話していて、自分では考えられない視点とかの「気づき」を得ることができて嬉しかったです。
# まとめ
デブサミ最高！次も参加しますよ。そして、何時かは貢献したい、、、。
# おまけ
デブサミ終わってホテルに移動する際に、途中まで原田さんと一緒でした。少し前までセッションのスピーカーの方と話ができるのは貴重ですよね？！
ModelState（モデル検証）のエラーを消す

通常は利用する事は無いですが、エラーチェック（モデル検証）が必要ない場面もあると思います。
以下の方法でModelStateのエラー情報を削除すれば、エラーがなかったことになるため、VIEWを表示したときにValidationMessageForやValidationSummaryにエラーメッセージが表示されなくなります。

```csharp:controllerに記述する。
foreach (var key in ModelState.Keys)
{
    ModelState[key].Errors.Clear();
}
```
C#erでもネイティブエンジニアでもないPHPerがXamarinでネイティブアプリを開発した話

# はじめに
c#を少しObjective-cを多少触ったことがあるPHPerな僕がXamarinを使用して
ネイティブアプリ開発した感想をまとめました。
個人的な意見もありますので参考程度に観ていただければと思います。

#背景
健康管理アプリをWeb、iOS、Androidでリリースしたいという案件の開発を
頂きましてネイティブアプリ開発を行うことになりました。
なぜXamarinを選んだかというと、
iOSとAndroidを別々に開発するのは改修コストがかかるというのと、
Objective-c、javaの経験者を雇うのは採用コストが高いという要望があり、
技術的挑戦をする意味でXamarinしかもXamarin.Formsを採用しました。

#Xamarinを採用してみての率直な感想
c#は描きやすくわかりやい言語で思い描いた設計をそのまま形にできる素晴らしいものでした。またXamarin.FormsはMVVMパターンが採用されており高凝縮に設計することができて非常に見通の良いコードに実装する事ができました。
**ただ・・・**
やはりまだまだ発展途上な技術でネイティブアプリを開発する上で、
大変なことはいくつかありました。

#Xamarinのとほほなところ・・・(個人的見解)
##描画の差異
Xamarin.Formsで共通のコンポーネントを使用しても、当たり前のようにiOSとAndroidで描画の差異が出ます。なので各OSごとにレンダリングを調整することなんて当たり前のようにやらなければいきません。Androidで正しく表示されるようにレイアウトを組み直すなんてことも普通にあります。またプラットフォーム依存する処理は各OS毎に実装する必要があります。
なのでカスタムレンダラー、DependencyServiceは避けては通れません。


##挙動の差異
描画の差異だけでなく挙動にも違いが多々あります。
例えばモーダルを表示して閉じた際に前のページのOnAppearingがiOSでは呼ばれるが、
Androidでは呼ばれないなど、またAndroidのみFrameのタップイベントで例外が発生するなどがありました。
なので各OSごとに挙動を合わせるように実装を工夫しなくてはなりません。


#Xamarinを使ってよかったところ
##コードの共通化と開発工数の短縮
iOSとAndroidで約70%以上はコードを共通化することができました。
UIはもちろんページやアプリのライフサイクル、からAPI通信部分とViewModelを共通化できたので、システム根幹部分はほぼ共通化することができました。
なので書くコード量が減り工数の短縮は出来たかと思います。

##シンプルかつ見通しの良い設計
個人的な見解ではありますがXamarin.Formsのイデオムは非常に解りやすいアーキテクチャになっているのでほぼ初見の人でも理解できます。
またc#のわかりやすさと書きやすさも合わさって見通しの良い設計にすることができるかと思います。

#まとめ
Xamarinはまだまだ発展途上な技術なので選定は考える必要がありますが、スピーディーかつ簡潔にハイブリッドアプリを実装することができる開発手段です。
またPrismなどのフレームワークを使用したらさらにモダンな設計にする事が可能です。
[JXUG](http://jxug.org/)などのコミュニティーが盛んになってきているので、
Xamarinと共に成長したいという気概があるのであれば面白い技術かと思います。
初心者Unity：bool型を使ったゲームフラグ管理もどき(備忘録)

超初心者投稿。
Boolをはじめていじってて偶然うまくいったのを忘れないように保管。

    bool[] stayflg = new bool[5];

    void Start() {
        for(int i = 0; i < 5; i++) { stayflg[i] = false; }
	}

	void Update () {

        if (Input.GetKeyDown(KeyCode.Space) && !stayflg[0]){
            stayflg[0] = true;
        }

        if (stayflg[0]){・・・以下略

このnew boolというのを忘れていた(知らなかった)らしく。
勘で入力していたらうまくいった。

今後このBool配列は二次配列にして、RPGとかアドベンチャーとかのゲームフラグ管理で役に立つかもしれんぬ。

もっといいやり方があるかもしれんけど、それは追々考えよう。
Linux や Ubuntu on Windows で file:/// のパス形式で cd する

# ブラウザで閲覧中のローカルファイルがあるフォルダに簡単に cd したい……

以前に[Ubuntu on Windows で Windows のフルパス名で cd する](http://qiita.com/kazinoue/items/9bcaa53b771e88725ff1) というネタを書いたのですけど、file:/// なパス指定でも同様に cd できると良いなあと思ったので、少し変更してみることにしました。 

実際に実行してみたのがこちらのスクリーンショット。

![image](https://qiita-image-store.s3.amazonaws.com/0/149350/5e372868-d926-fa3b-f41d-3363ab2533de.png)

こうなると、ブラウザでローカルファイルを開いている最中に、そのファイルのあるディレクトリで作業したい場合にコピペで cd できるわけですね。

このスクリーンショットは Bash on Ubuntu on Windows のものですが、今回実装した内容は普通の Linux でも使えます。自分の手元では Kali Linux で確認済みです。

## 実装
Windowsのパス名をUbuntu on Windowsのパス名に変換して cd することは前回の実装で出来ているのですが、今回の実装では file:///[ドライブ名]:/… を見つけたら Windows のパス名相当に変換する処理を付け足します。付け足すといっても今回作る処理が先に行われるようにします。

そうすることで、前回作成した部分がほとんどそのまま使いまわせます。

また、file:/// なパスにはURLエンコードされた文字を含む場合があります。たとえば、"Program%20Files" とか。これは当然ながらデコードしなければなりません。

このような処理と前回実装済みの処理との組み合わせにより、 URL形式の file:///[ドライブ名]:/… と、Windowsのフルパス形式の両方を Ubuntu on Windows の cd で利用できるようになるわけです。

あるいは、せっかくなので file:/// でドライブレターを含まない場合も扱えるようにしてみましょう。そうするとこれは同じ実装がネイティブな Linux や UNIX 環境でも使えます。macOS のターミナルでも多分動くはず。

実際の実装例はこちらです。前回同様に .bashrc あたりにこれを追記します。

```bash:.bashrcなどへの追加内容
# file:// や [drive_letter]:\... の入力文字列を UNIX のパス形式に変換する処理
__change_winpath2buwpath() {
	newpath=""
	local __inputpath="$1"

	# https://regexper.com/#%5Efile%3A%5C%2F%5C%2F(%5C%2F((%5BA-Za-z%5D%3A)%3F%5BA-Za-z0-9%20%5C-%5C.%5C%25%5C%2F%5C~%5C(%5C)%5C%3A%5D*))(%5B%23%5C%3F%5D.*)%3F
	if [[ $__inputpath =~ ^file:\/\/(\/(([A-Za-z]:)?[A-Za-z0-9 \-\.\%\/\~\(\)\:]*))([#\?].*)? ]]; then
	if [ "${BASH_REMATCH[3]}" == "" ]; then
			# 入力値がドライブレターを含まない file:/// のパス指定なら file:// と # 以降を削ってUNIXのフルパス相当にする
			__inputpath=$( printf '%b' "${BASH_REMATCH[1]//%/\\x}")
	else 
			# 入力値が file:///[A-Za-z]:/ のパス指定なら file:/// と # 以降を削ってWindowsのフルパス相当の文字列にする
			__inputpath=$( printf '%b' "${BASH_REMATCH[2]//%/\\x}")
	fi
	fi

	if [[ "$__inputpath" =~ ^([A-Za-z]):(.*) ]]; then
		# 入力文字列が Windows のフルパスならば
		# ドライブレターとディレクトリに分解する
		local __windows_driveletter=${BASH_REMATCH[1],}
		local __windows_path=${BASH_REMATCH[2]}


		# ドライブレターとパスを含めて Ubuntu on Windows 上でのパスにする
		# このときにドライブレターは小文字に変換し
		# バックスラッシュをスラッシュに置換している
		newpath="/mnt/${__windows_driveletter}${__windows_path//\\/\/}"
	else
		newpath="$__inputpath"
	fi
}

__cd() {
	if [ "$1" == "" ]; then
		# パラメータが未指定の場合は cd コマンドをパラメータ無しで実行する
		\cd
	else
		# Windowsのフルパスや file:/// を
		# Ubuntu on Windows のパスに変換する処理
		__change_winpath2buwpath "$1"

		# 指定されたパスがファイルならば、そのファイルのディレクトリを取得する
		# dirname で変換する方法もあるけれど、外部コマンドは極力避けたいので
		# シェル変数の展開で後方最短パターンの削除を利用する
		if [ -f "$newpath" ]; then
			echo "${newpath} is file."
			newpath=${newpath%/*}
			echo "remap to ${newpath}"
		fi

		\cd "$newpath"
	fi
}

# cd コマンドを __cd に置換する
alias cd=__cd
```

## そのうち追加する処理
> 入力値がディレクトリではなくファイルへのフルパスだった場合に、そのファイルが存在するディレクトリに対して cd できるようにすると、さらに便利なはず。
> 
> これは実際に cd する前に -d や -f でパスを検証し、必要に応じて入力値からファイル名部分を削るだけだからあっさり作れるハズ。

上記は実装済み。

## 参考資料
URLエンコードされた文字列をデコードする処理は下記ページの内容を参考にしました。
http://unix.stackexchange.com/questions/159253/decoding-url-encoding-percent-encoding
RSpecのフォーマッターの出力結果を任意のデータストアに保存できるgem rspec-storageを作った

最近、手元でRSpecを全部流すなんてことはあんまり無くなってきた。
CIサービス上で結果は確認できても、色々情報を収集したり加工したりしたい場合ローカルのファイルシステムに吐くより、S3とかGCSとかに吐ける方が何かと便利なことが多い。

というわけで、gemで何とかしてみた。
https://github.com/joker1007/rspec-storage

RSpec自体にこういう処理を差し込めるAPIが無いので、出来るだけメンテしやすい形でモンキーパッチを当てている。


こんな感じで使う。(GCSの場合はgs://)

```
$ rspec -r rspec/storage spec/example_spec.rb -f doc -f json -o s3://your-bucket/spec_result.json
```

パースして加工することを前提にするならjsonフォーマットで吐いておくのが良いだろう。

RSpecのCLIオプションをごりごり拡張するのはイマイチ筋が悪いと思ったので認証情報やリージョン情報は、基本的に環境変数経由かIAM的なものを利用することを想定している。

とりあえずS3とGCS対応のプロバイダーは書いたが、URLスキーマを決めてハンドリング方法を定義すれば、構造上何にでも転送できるはず。
RedisとかRDBに突っ込むプロバイダーも書けそうだが、自分では用途が無いので実装はしていない。
もし、そういう感じのことがしたい人が居たらPRいただけると助かります。
ScalaからTensorFlowのJava APIを呼びだすぞい

Googleが誇る機械学習ライブラリTensorFlow 1.0がリリースされましたね。
何が更新されたか覗いてみま…… Java API !?

> Experimental APIs for Java and Go

[Announcing TensorFlow 1.0](https://research.googleblog.com/2017/02/announcing-tensorflow-10.html)

Java APIが使えるということは、JVM言語であるScalaからも呼びだせるはずなので、早速やってみました :raised_hands:

# 準備

[tensorflow/tensorflow/java/README.md](https://github.com/tensorflow/tensorflow/blob/cf3a2356e81b09ee2f3b8048c1b84bb5d12a3a4e/tensorflow/java/README.md)
に従って、JARとネイティブライブラリをダウンロードして解凍して、配置するだけです。
Mac OS Xだとこんな感じ。

```
$ tree
.
├── build.sbt
├── jni
│   └── libtensorflow_jni.dylib
├── lib
│   └── libtensorflow-1.0.0-PREVIEW1.jar
└── src
    └── main
        └── scala
            └── Main.scala
```

# コード

ベクトルA (1, 2, 3)とベクトルB (4, 5 ,6)の要素積を計算するだけのテストコードです。

```scala:src/main/scala/Main.scala
import org.tensorflow._

object Main extends App {
  val graph = new Graph()
  val a = graph.opBuilder("Const", "a").
    setAttr("dtype", DataType.INT32).
    setAttr("value", Tensor.create(Array(1, 2, 3))).
    build().
    output(0)

  val b = graph.opBuilder("Const", "b").
    setAttr("dtype", DataType.INT32).
    setAttr("value", Tensor.create(Array(4, 5, 6))).
    build().
    output(0)

  val c = graph.opBuilder("Mul", "c").
    addInput(a).
    addInput(b).
    build().
    output(0)

  val session = new Session(graph)
  val out = new Array[Int](3)
  session.runner().fetch("c").run().get(0).copyTo(out)

  println(out.mkString(", "))
}
```

なお、[Graph](https://www.tensorflow.org/api_docs/java/reference/org/tensorflow/Graph)、[Session](https://www.tensorflow.org/api_docs/java/reference/org/tensorflow/Session)、[Tensor](https://www.tensorflow.org/api_docs/java/reference/org/tensorflow/Tensor)は明示的に`close()`を呼ばないとリソース解放されないようなので、きちんとしたコードを書くときは注意してください。


# 実行

```
$ sbt run -Djava.library.path=./jni
...
4, 10, 18
```

はい、ベクトルC (4, 10, 18)が計算できました。

# 感想

機械学習、とくにディープラーニングといえばPythonの文化が強く、静的型付け言語が好きな自分としてはちょっと歯がゆい思いをしていたのですが、こうやって手に馴染んだ言語を使えるとテンション上がります :heart_eyes:
もちろん、Deeplearning4jなど良いJavaライブラリもあるのですが、最新の学習モデルはTensorFlowで実装されることが多いので……。

機械学習の面倒さは、まずは前処理のデータ整形に依るところが大きくて、そこも合わせて一つのコードで書けると敷居がグッと下がる気がします。
Java APIはまだ最低限のものしか用意されていないみたいですが、これからどんどんリッチになってくれると嬉しいですね :joy: :joy: :joy:

# 環境

```scala:build.sbt
name := "tensorflow-scala"
scalaVersion := "2.12.1"
```
iRuby Notebookでグラフをインラインで描画する方法の調査（chunky_png編）

# はじめに

Jupyter Notebookはインタラクティブにスクリプトの開発ができる素晴らしい開発環境なのですが、iRubyとして動作させると少し機能に見劣りするところが無きにしも非ず。

とりわけ、グラフを描画する部分について、幾つかライブラリがあるもののエクスポートを行う場合には、受け取り側でも同じライブラリがないと閲覧することができないという状況で、少し不便。

[参考ライブラリ]
https://github.com/domitry/nyaplot
https://github.com/rdp/ruby_gnuplot

ということで、Pythonでmatplotlibを使った時のようにNotebookに保存できるグラフ環境が準備できないか調査してみましたので、その結果をまとめます。

# Pythonはどうなっているの？

Pythonでグラフを描画したNotebookをHTMLでエクスポートして、ソースを確認してみると、グラフの部分は以下のようになっていました。

```html:
<img src='data:image/png;base64,iVBORw0KGgoAA...中略...ErkJggg==' />
```

pngの画像データをbase64で変換し、テキストデータで保存しているようです。
では、Rubyで同じようにできるライブラリが無いか探してみます。

# chunky_png

https://github.com/wvanbergen/chunky_png

ピュアRubyのライブラリがあったので、インストールしてみます。

```sh:
$ gem install chunky_png
```

# 適当に線を描画して出力してみる

```rb:
require 'chunky_png'

width = 500
height = 200

png = ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)

png.line(0, 0, width, height, ChunkyPNG::Color.from_hex('#aa007f'))
png.to_blob
```

実行結果は...

```
"\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00...中略...\x00\x00IEND\xAEB`\x82"
```

見れません(汗)

少し調べてみると、IRuby.displayというのが使えそうだったので、以下のように追記してみます。

```rb:
require "base64"

src = 'data:image/png;base64,' + Base64.strict_encode64(png.to_blob)
IRuby.display "<img src='#{src}' />", mime: 'text/html'
```

![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/114240/092fee87-5121-18fc-48b4-b55139330f77.png)

できた！

# もう少し調べてみる

もっと簡単な方法がありました(汗)

```rb:
IRuby.display png.to_blob, mime: "image/png"
```

# グラフっぽいものを描画してみる

```rb:
require 'chunky_png'

width = 500
height = 200

png = ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)

png.line(0, 0, 0, height, ChunkyPNG::Color.from_hex('#aa007f'))
png.line(0, 0, width, 0, ChunkyPNG::Color.from_hex('#aa007f'))

y = [10, 20,  5, 30, 15, 50]

y_max = y.max()
y_min = y.min()
y_size = y.size

y_buff = y[0]

y_rate = height / (y_max - y_min)

(1..y.size-1).each do |val|
  x0 = width / y_size * (val - 1)
  x1 = width / y_size * val
  png.line(x0, (y_buff - y_min) * y_rate, x1, (y[val] - y_min) * y_rate, ChunkyPNG::Color.from_hex('#aa007f'))
  y_buff = y[val]
end

IRuby.display png.to_blob, mime: "image/png"
```

![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/114240/540cbba6-1fd1-7ba2-7378-bff80d5eaf27.png)

...それっぽい（汗）

このNotebookを別のパソコンにコピーして開いてみたら、実行結果をそのまま見ることができました(^-^)

ということは、これを利用してmatplotlibみたいなものを作ればいいのか...

さて、これからどうするかな〜(^_^;)
pythonで大数の法則

ギャンブルで儲けることができない絶対的な理由が「大数の法則」だそうです。
以下コトバンクより
>大数の法則とは、コイン投げを数多く繰り返すことによって表の出る回数が1/2に近くなど、数多くの試行を重ねることにより事象の出現回数が理論上の値に近づく定理のことをいう

これをpythonで実証してみます。

```large_num.py
#乱数生成用ライブラリ
import random
#数学計算用ライブラリ
import math

#試行回数を設定
max_try = int(input('最大試行回数を入力してください（10を入力値でべき乗) :\n'))
#パターンを設定
pattern = int(input('何分の1を計算するのか入力してください : \n'))
#理論的な確率を計算
theory = (1 / pattern) * 100
print(theory)

print('\n{0}通りの数のうち1が出る確率は理論上{1}%\n'.format(pattern,theory))
print('計算スタート!!\n')

for i in range(1,max_try) :
    #試行回数を設定
    try_num = pow(10,i)
    #countを初期化
    count = 0

    for x in range(try_num):
        #乱数生成
        dice = random.randint(1,pattern)
        #1を判定
        if dice == 1 :
            count += 1
    # 確率を計算
    result = (count / try_num) * 100
    # 結果を印字
    out = '{0}回で1が出る確率は{1}%  理論値との差は{2}%'.format(try_num,result,math.fabs(result - theory))
    print(out)
Docker for Macをインストールしてみた

# はじめに
「Dockerが、素晴らしい！」と、色々なところで、聞くようになったので、自分でも使ってみようと思い、まずはDockerをインストールすることにしました。
昨年に、Docker for Macなるものがリリースされたようですので、自分がインストールした手順を残します。

# 手順
## Docker for Macのダウンロード
Docker for MacをMacにダウンロードします。
サイトは、以下のURLです。
https://docs.docker.com/docker-for-mac/install/

* Stable channel
* Beta channel

の2つがあります。

今回は、安定版のStable channelをダウンロードしました。

![スクリーンショット 2017-02-17 20.13.01.png](https://qiita-image-store.s3.amazonaws.com/0/106843/8cef88c1-b0f1-a5c1-50fe-7db980410c85.png)

実行するといつも通りの画面が現れます。

## Dockerの起動
Dockerを起動すると、以下の画面が表示されます。「Next」をクリックします。
<img width="710" alt="スクリーンショット 2017-02-17 20.16.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/106843/1c5258d7-88c3-b726-3d6b-6111311afc19.png">

次の画面では、「OK」をクリックします。端末のパスワードを入力する画面が現れるので、入力します。
<img width="710" alt="スクリーンショット 2017-02-17 20.16.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/106843/2688d4a1-1739-d893-bc7b-ef6d5d12e592.png">

次は、上から画面が伸びてきます。「Got it!」をクリックします。
![スクリーンショット 2017-02-17 20.17.09.png](https://qiita-image-store.s3.amazonaws.com/0/106843/738729bd-b229-09c9-9206-9e8714fe4899.png)

上のバーに、Dockerアイコンが現れているので、クリックするとこんな感じのメニューがでてきます。
<img width="304" alt="スクリーンショット 2017-02-17 20.21.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/106843/5de7c052-7cb8-1bd5-0d54-1dbbc44fad98.png">

Dockerを無事に起動することが出来た模様です。

## Dockerの確認
[Get started with Docker for Mac](https://docs.docker.com/docker-for-mac/)というドキュメントがあるので、従ってみます。

```
$ docker --version
Docker version 1.13.1, build 092cba3

$ docker-compose --version
docker-compose version 1.11.1, build 7c5d5e4

$ docker-machine --version
docker-machine version 0.9.0, build 15fd4c7
```

バージョンの確認ができました。

## nginxの起動
nginxを起動してみます。
```
$ docker run -d -p 80:80 --name webserver nginx
```

ブラウザで、 http://localhost に接続してみると・・・。
![スクリーンショット 2017-02-17 20.32.53.png](https://qiita-image-store.s3.amazonaws.com/0/106843/708ca59d-578c-9af6-8f6e-03892103c5ce.png)

```
$ docker ps
```
で、Dockerのプロセスが確認できました。

nginxを止めるには、
```
$ docker stop webserver
```
です。

nginxを消すには、
```
$ docker rmi nginx
```
です。

# おわりに
今回は、インストールして、簡単な使い方を実行してみました。
今すぐ、有効利用できるわけではないですが、今後に向けた下準備はできたということで！
iOSでLÖVE

こんにちは、Love2DでiOSアプリをつくってHello World!してみたいと思います。

# ダウンロード
https://love2d.org/ からiOS sourceをダウンロードします。
<img width="874" alt="LÖVE_-_Free_2D_Game_Engine.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/5e92e00d-117a-8dd6-1294-855b380c3591.png">


# Xcodeで開く
先ほどダウンロードしたzipファイルを展開します。

展開したディレクトリに移動して以下のコマンドを入力します。

```zsh
$ open platform/xcode/love.xcodeproj 
```

環境によっては警告がでるかもしれませんが、気にしないでください。僕は気にしませんでした。
<img width="532" alt="スクリーンショット 2017-02-01 19.56.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/f648cb99-58fd-da58-b2bf-0e4505820aea.png">

# 実行する
targetをlove-iosに変更します。
<img width="184" alt="love_xcodeproj.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/d2a8f9ef-796f-2b87-5b5c-fc0718c4b8a5.png">

<img width="447" alt="love_xcodeproj.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/0912a1b0-26b0-e4a1-4562-29cb50111531.png">

targetをlove-macosxからlove-iosに変更してからBuild PhaseのCopy Bundle Resoucesを追加します。
<img width="880" alt="love_xcodeproj.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/eeedbc9c-0019-ea3c-0d6e-f121bed685af.png">

<img width="400" alt="スクリーンショット_2017_02_01_20_09.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/00d70d3b-8012-ecf6-b1ff-29e79972c796.png">

.loveファイルを選択します。作り方は[これか](http://qiita.com/xsota/items/e359200df7b6a30703a4)、[このへん](http://qiita.com/xsota/items/c8828bd76eafb24a3db4)をみてください。
<img width="518" alt="スクリーンショット_2017_02_01_20_11.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/2ba8324b-b575-fbac-ccf9-fade68215b53.png">

Finishをクリックして終わります。
<img width="730" alt="スクリーンショット_2017_02_01_20_13.png" src="https://qiita-image-store.s3.amazonaws.com/0/113692/6f431d8f-363c-43bd-306f-54076178229a.png">

あとはなんかさんかっけーのアイコンをクリックして実行するだけです。

こんな感じで実行されます。やったね！
![Screen Shot 2017-02-17 at 20.04.15.png](https://qiita-image-store.s3.amazonaws.com/0/113692/7bd96726-fd03-a6c3-8cad-9b2ab688fd2b.png)


# 最後に
YouTubeにチュートリアル動画上がってるので、これを見たほうがわかりやすいかもですね。
https://youtu.be/MsYanwcU42E

それではさようなら。
ロボットにノリの良い会話をさせたい - 会話におけるサブサンプションアーキテクチャ

これはただの妄想とアイディアです。考えがまとまりきらないうちから書いてます。
私は会話系の AI の専門家ではないので、「そんなの常識だよ」だったらすみません。

# 現状の音声対話 AI の辛さ
最近、ロボホンを使ってみたり、 某社の雑談ロボットのデモを見たりで、音声を使ったロボットとの対話や雑談を体験して、以下の部分が辛いなぁと感じました。

- 発話のタイミングの重要さ
    - 現在の技術では音声認識が間に合わず間が持たない
    - 対話はタイミングとノリがとても重要
    - 相手が話しているところに割り込むととても印象が悪い
- 声のトーンや速度の問題
    - 話者と話す速度が合っていないと会話はとてもストレスを感じる

つまり、音声の会話においては、会話の内容も大事ですがそれ以上にタイミングやノリのようなものが合っていないととてもつらいということです。



# 音声会話に必要なことの階層的構造
## 会話には階層構造があるのではないか
会話の空気感（タイミング、速度、トーン）を守ることは心地よい会話をするために「本能的なレベルで」必須であると感じました。人間じゃない動物だって、鳴き声の空気感を使ってその感情や危険を仲間に伝えているのです。

一方で、会話の「内容」というのは一段高級な機能であるように思われます。鳴き声に非常に複雑な意味をもたせ「会話」を行っているのは人間のみです。（たぶん。）

そして、前者は相手の会話に対して厳密なタイミングで行う必要がありますが、後者は実はタイミングはそんなに重要では無いように思えます。人間でも、間髪入れず内容のあるこたえを返せるのは頭のいい人だけです。頭の悪い人も「うーん、そうだね。それなら・・」といったように間をおいて解答できます。

この「うーん、そうだね。」によって前者のような会話の空気感を満たしつつ、後者の解答を作るまでの時間稼ぎをしています。

ここまで考えて思い出したのが、ロボットの行動に置けるサブサンプションアーキテクチャでした。

## サブサンプションアーキテクチャ
[サブサンプションアーキテクチャ](https://ja.wikipedia.org/wiki/%E3%82%B5%E3%83%96%E3%82%B5%E3%83%B3%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%BB%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)とは元々ロボットの行動のアーキテクチャで、複雑な振る舞いを多数の単純な振る舞いを行うモジュールに分割し、それらに階層構造を与えるものです。
![image](https://vantage-planning.qiita.com/files/6c56e5a9-38ba-3c15-de95-9e1ab7db8b20.png)
上の図から解るように、下層のモジュールは、それを行わないと死んでしまう、怪我をするような事象にたいして素早く対応します。一方で、上層はそのロボットが達成したい目的に対しての戦略をゆっくりと考えます。
下層のモジュールは素早く動きますが、上層の命令が優先されるため、一旦下層モジュールによって反射的に何かを避けたものの、あとから上層の命令で敢えてそこを突き進むといった行動が可能になります。

### 歴史
サブサンプションアーキテクチャの利点は、反応が早いことです。
サブサンプションアーキテクチャ以前のロボットは、センサから情報を読み取り、そこからロボットを取り巻く環境を計算して、最適な戦略を建て、行動を決定し、モーターを動かしていました。この方法だと、たしかに正確に動くもののものすごく動きや反応が遅いロボットができてしまったのです。
サブサンプションアーキテクチャの登場によって、危険の回避等素早く動くべきものが素早く行えるようになり、常に動き回るような動的なロボットが出てくるようになりました。

## サブサンプションアーキテクチャの会話への適用
サブサンプションアーキテクチャは会話に対しても当てはめることができそうです。
会話 AI にとって、最も避けるべきは会話をしている空気感の破綻です。これを避けつつ、内容のある会話を模索していきます。

- 上層(Explore)
    - 会話の長いコンテキストや、自身・相手の感情モデルを管理し、会話の方向性を決めます
        - 相手の感情モデルから自身の感情モデルの状態を決定します
        - 自身の感情モデルに従って声のトーンや発話の速さを決めます
    - 恐らく上層が直接発話をするというかは中層や下層に働きかける感じになります
- 中層（Wander）
    - 相手の発話に対して、何かしらの意味のある応答を生成し返します
- 下層（Avoid）
    - 相槌を打つ事により、返答のリズムをつくります
    - 相手の発話状態を監視して、相手の発話にかぶらない様にします
    - 現状の技術では音声認識に時間がかかる印象なので、このレイヤーは音声認識を経る前の段階で動く必要がありそうです

これにより、理想的には以下が得られるはずです

- リズム感のある会話
- 自分と相手の感情やテンションの同期
- 方向性のある会話

まあ、各レイヤーで十分なクオリティを作るのが大変難しそうですけどね！
logentriesにfluentdから簡単にデータを送る方法


logentriesにfluentdで集めたログから特定のものを送りたくて、試してみたが意外と苦戦したのでメモしておく

##結論

[fluent-plugin-out-https](https://github.com/kazunori279/fluent-plugin-out-https)で、logentriesの[Token TCP]で作ったエンドポイントにPOSTするのが一番簡単

※httpsでPOSTしたかったので、[fluent-plugin-out-http](https://github.com/ento/fluent-plugin-out-http)は使わなかった。。

##所感

- logentriesのドキュメントが中々読みづらく苦戦した
- ネット上にも簡単だから??かほとんど情報はない印象
- fluent-plugin-out-httpにuse_sslオプションがつくと一番いいなと思った。

##設定

1.プラグインを設置
[fluent-plugin-out-https](https://github.com/kazunori279/fluent-plugin-out-https)をcloneしてきて、out_https.rbを`/etc/td-agent/plugin/`配下に設置

2.こんな感じのconfigを書く

match句の部分は、適宜自分の環境に読み替える

```
<match *>
  type            http
  use_ssl         true
  include_tag     true
  endpoint_url    https://webhook.logentries.com/noformat/logs/[logentriesの画面が取得出来るtokenをset]
  http_method     post
  serializer      json
  rate_limit_msec 100
</match>

```

3.td-agentを再起動

4.logentries上で、ログが確認出来るはず

![Log_Sets_prd_waikiki_aplog___Logentries.jpg](https://qiita-image-store.s3.amazonaws.com/0/40850/462e6e25-1664-6d3d-ccd8-41b2c0ea802e.jpeg "Log_Sets_prd_waikiki_aplog___Logentries.jpg")

##その他にやってみたこと

###fluent-plugin-logentries

自分の知識が足りなかったのかもしれないが、軽くコード見たところエンドポイント/認証方法が古かったりしたように見えて自分の環境では使えなかった。。。


###ファイルを吐いて、logentriesエージェントでエンドポイントに送る

下記の構成でやろうとも検討したが、fluentdで完結したかったのでやらなかった。只、検証はして問題なくlogentriesにPOST出来る事は確認した。

http://qiita.com/cs_sonar/items/3879dffec076c6a60f31
UITableViewCellの高さを自動調整する

UITableViewCellの高さを自動調整させる方法をメモ。

##1. storyboardでViewControllerにTableViewを設置する
<img width="923" alt="スクリーンショット 2017-02-16 13.48.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/c4a31ea4-a8f2-421f-ff51-c7af25cf2829.png">

今回は、TableViewにTableViewCellを３つ配置。各セル内にラベルを置く。

##2. セル内のラベルに制約（上下左右のマージンを0）を設定
<img width="268" alt="スクリーンショット 2017-02-17 19.31.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/25f919c3-e240-d1ae-54e9-ea82c99ce279.png">

##3. ViewControllerの実装
ViewControllerは以下のように実装する。

```swift
import UIKit

//各TableViewCellのIdentifier
private let topCellID = "topCellID"
private let middleCellID = "middleCellID"
private let bottomCellID = "bottomCellID"

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet weak var mainTable: UITableView!
    
    static let cellIDs: [String] = [topCellID, middleCellID, bottomCellID]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
        mainTable.delegate = self
        mainTable.dataSource = self
        
        mainTable.estimatedRowHeight = 5
        mainTable.rowHeight = UITableViewAutomaticDimension
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // 行数
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return ViewController.cellIDs.count
    }
    
    // セル
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellId: String = ViewController.cellIDs[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId)!
        
        if cellId == topCellID {
            let label = cell.viewWithTag(100) as! UILabel
            label.text = "上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上上"
        } else if cellId == middleCellID {
            let label = cell.viewWithTag(100) as! UILabel
            label.text = "中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中中"
        } else if cellId == bottomCellID {
            let label = cell.viewWithTag(100) as! UILabel
            label.text = "下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下下"
        }
    
        return cell
    }
    
    // セクション数
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
}
```

ポイントは、viewDidLoadの以下の部分。

```swift
mainTable.estimatedRowHeight = 5
mainTable.rowHeight = UITableViewAutomaticDimension
```

これでセルの高さを自動的に調整してくれるようになる。

##4. こんな感じ
<img width="375" alt="Screen Shot 2017-02-17 at 19.54.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/b77d85e2-1b6d-19e0-640f-34a7ce0fa16b.png">
Riotでclickの挙動を確認してみた


いろいろと挙動を確認したので備忘録です。

## 通常のonclickからparent変数を使って親メソッドにアクセスする方法

### 通常

見たままです。

```js:parent.tag
<parent>
	<input type="button" value="button1" onclick={ clickButton1 }>

	<script>
		clickButton1() {
			alert('button1がクリックされました');
		}
	</script>
</parent>
```

### 子タグから親タグのメソッドにアクセス

parent変数を使用して親タグにアクセスができます。

```js:parent.tag
<parent>
	<input type="button" value="button1" onclick={ clickButton1 }>
	<child1></child1>

	<script>
		clickButton1() {
			alert('button1がクリックされました');
		}
		clickButton2() {
			alert('button2がクリックされました');
		}
	</script>
</parent>
```

```js:child1.tag
<child1>
	<input type="button" value="button2" onClick={ parent.clickButton2 }>
</child1>
```

### 孫タグから親タグのメソッドにアクセス

parent変数を使用して...はだめでした。

```js:parent.tag
<parent>
	<input type="button" value="button1" onclick={ clickButton1 }>
	<child1></child1>

	<script>
		clickButton1() {
			alert('button1がクリックされました');
		}
		clickButton2() {
			alert('button2がクリックされました');
		}
		clickButton3() {
			alert('button3がクリックされました');
		}
	</script>
</parent>
```

```js:child1.tag
<child1>
	<input type="button" value="button2" onclick={ parent.clickButton2 }>
	<child2></child2>
</child1>
```

```js:child2.tag
<child1>
	<input type="button" value="button3" onClick={ parent.clickButton3 }>
</child1>
```

実装したい場合は子タグから孫タグに対して情報を渡しすことでアクセスすることができるようになります。

```js:child1.tag
<child1>
	<input type="button" value="button2" onclick={ parent.clickButton2 }>
	<child2 onclick={ parent.clickButton3 }></child2>
</child1>
```

```js:child2.tag
<child1>
	<input type="button" value="button3" onClick={ opts.onclick }>
</child1>
```

上の例が子タグから孫タグへ〜という言い回しなのであまり用途は感じられませんが親タグのメソッドにアクセスする場合は、`parent`変数を使う以外にも情報を参照することで実装できるということがわかりました。

## onclickで引数を渡したい場合の方法

上の例でもそうですが基本的にイベント操作を行う場合は()をつけてしまうと即時実行されてしまうのでメソッド名のみ記述します。
しかしループ処理のなかでイベント操作を行う場合は引数を渡したくなると思いますのでそのときは`bind`を使って実装ができるようです。

```js:sample.tag
<sample>
	<p>
		<virtual if={selectItem}>
			{ selectItem }が選択されました
		</virtual>
		<virtual if={! selectItem}>
			項目を選択してください
		</virtual>
	</p>
	<ul>
		<li each={ item in items }>
			<a href="#" onclick={ clickItem.bind(this, item.id) }>{ item.name }</a>
		</li>
	</ul>

	<script>
		this.selectItem;
		this.items = [
			{ id: 1, name: '長崎市' },
			{ id: 2, name: '諫早市' },
			{ id: 3, name: '大村市' },
			{ id: 4, name: '佐世保市' },
			{ id: 5, name: '島原市' },
			{ id: 6, name: '雲仙市' },
			{ id: 7, name: '南島原市' },
			{ id: 8, name: '松浦市' },
			{ id: 9, name: '平戸市' }
		];

		clickItem(id, e) {
			e.preventDefault();
			let item = this.items.filter(i => i.id == id);
			this.selectItem = item[0];
		}
	</script>
</sample>
```

上の例では`clickItem(id, e)`というメソッドで引数とイベント情報を受け取るようにしています。
実際にonclick時の書き方は`{ clickItem.bind(this, id) }`のように`bind`を使うことでメソッドにアクセスることができます。
無駄にターミナル常駐型のタスクをサービス化してみた

gulpみたいなターミナルに常駐するタスクを実行するとき、
バックグラウンドで動かせたほうがずっとウィンドウ開かなくていいし、
仮想環境とかでも動かせるし便利だなと思って色々試したので書き残しておきます。

# 実行環境
vagrant 1.7.4(centos6.7)
VirtualBox 5.0.28

# やりたかったこと
だれもが1回は使ったことある`sudo service httpd start`のように`sudo service gulpd start`でずっとファイルの変更をwatchしてる状態をつくる。

# 背景知識

基本的に下記一式が必要

1.実行ファイル（コマンドそのものでバイナリになってるものが多い）
/usr/sbin

2.実行シェル(ここでstart/stop/restartといったサービスの管理を定義する）
/etc/init.d/~
/etc/rc.d/init.d/~

3.pidfile（サービスが利用するプロセスIDが記憶される、killする際のID指定に用いる）
/var/run/~

4.lockfile（サービス起動時に作成される、起動判定に用いる）
/var/lock/~

pidfileとlockfileがわかりにくいんですが、サービスをstart/stop/restartといったコマンドで管理するためのものだと思ってもらえればよいと思います。
startするときはlockfileが存在しなければタスクを起動し、存在すれば既に起動しているという文言を提示する、
stopするときはpidfileに書き込まれたプロセスIDを指定してプロセスをkillするといった具合です。

長くなりましたが下記がgulpdデーモン化の実装になります。

# 実装
pidfile,lockfileは所定の場所に設置済みとお考えください。
実行ファイルと実行シェルを作成します。

- 実行ファイル

gulpfileが置いてあるディレクトリまで移動しgulpコマンドを実行するだけのコマンドをgulpdとして定義しました。
/homeにgulpfileを設置しているので`cd /home`になってます。

```gulpd.sh
#!/bin/bash
cd /home
nohup gulp </dev/null &>/dev/null &
```
ここ勘違いしてたんですが、daemonで実行ファイルを動かせば勝手にバックグラウンドになると思っていたので、当初は3行目は単純に`gulp`とだけ書いてありました。ですが動かしたところいつまでたってもサービスが起動しない（watchがフォアグラウンドで動き続ける)ことから今回のような実装になってます。

- 実行シェル

長くなるので要点だけ書きます。

```gulpd.sh
#!/bin/bash
#
# gulpd       Startup script for the gulpd
#
# chkconfig: - 98 11
# description: gulpd
# processname: gulpd
# pidfile: /var/run/gulpd.pid
#
# Source function library.
. /etc/rc.d/init.d/functions

GULPD_LANG=${GULPD_LANG-"C"}

INITLOG_ARGS=""

gulpd=${GULPD-/usr/sbin/gulpd}
prog=gulpd
pidfile=${PIDFILE-/var/run/gulp.pid}
lockfile=${LOCKFILE-/var/run/gulp.lock}
RETVAL=0
STOP_TIMEOUT=${STOP_TIMEOUT-10}

start() {
        echo -n $"Starting $prog: "
        LANG=$GULPD_LANG daemon --pidfile=${pidfile} $gulpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}
stop() {
	status -p ${pidfile} $gulpd > /dev/null
	if [[ $? = 0 ]]; then
		echo -n $"Stopping $prog: "
		killproc -p ${pidfile} -d ${STOP_TIMEOUT} $gulpd
	else
		echo -n $"Stopping $prog: "
		success
	fi
	RETVAL=$?
	echo
	[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  restart)
	stop
	start
	;;
  *)
	RETVAL=2
esac

exit $RETVAL
```

# 所感
daemonコマンドって指定したタスクをバックグラウンドで実行してくれる便利な関数だと思っていたんですが、実際のところはバックグラウンドで実行されるタスクを管理するためのものなんでしょうか、時間がある時にfunctionsのdaemon関数を読みたいなと思いました。
この辺はシェル芸が達者な人にお話を聞いてみたい。。。。

というかただバックグラウンドでタスクを動かしたいだけなら```nohup sudo gulp </dev/null &>/dev/null &```を直接ターミナルに打ち込むだけで良かったりもします。
そんなこんなで色々書いてから気づいたので無駄もありましたが、start/stop等使えるので若干管理が楽になったと前向きに捉えることにします。

以上。
SQL ServerのUpdate文

## JOINを使用して更新する



```sql
UPDATE TableA
SET
a.col1 = b.col1
,a.col2 = b.col2
FROM TableA a
INNER JOIN TableB b ON a.id = b.id
```



UPDATE (Transact-SQL) : https://msdn.microsoft.com/ja-jp/library/ms177523.aspx#OtherTables

3-3 結合を伴うupdate文 : http://www.geocities.jp/oraclesqlpuzzle/sqlserver/sqlserver-3-3.html
早速、既存のEC2にIAMロールを付けてみた

うっかり IAM ロールを付け忘れて EC2 を起動してしまったので後から付与してみた。
実行例がなかったので覚え書き。

1. 事前準備

- - -

GUIでロールを作っておきます。下記コマンドの例では「role_waka」という名前のロールを使っています。
![image](https://qiita-image-store.s3.amazonaws.com/0/162653/47c5fed6-3fd0-430e-f306-be30110e4a8f.png)

　
　
2. ロールを付けるコマンド

- - -


```
aws --profile waka --region ap-northeast-1 ec2 associate-iam-instance-profile --instance-id i-XXXXXXXXXXXXXXXXX --iam-instance-profile Name=role_waka
```

[オプションの説明]
　--instance-id ：インスタンスID
　--iam-instance-profile ：Name=IAMロール名
　
　
3. 確認コマンド

- - -


```
aws --profile waka --region ap-northeast-1 ec2 describe-iam-instance-profile-associations
```
 
[表示例]

```
{
    "IamInstanceProfileAssociations": [
        {
            "InstanceId": "i-XXXXXXXXXXXXXXXXX",
            "State": "associated",
            "AssociationId": "iip-assoc-XXXXXXXXXXXXXXXXX",
            "IamInstanceProfile": {
                "Id": "XXXXXXXXXXXXXXXXXXXXX",
                "Arn": "arn:aws:iam::XXXXXXXXXXXX:instance-profile/role_waka"
            }
        }
    ]
}
```
　
[[Amazon Web Services ブログ] 既存のAmazon EC2インスタンスにIAM Roleがアタッチできるようになりました](https://aws.amazon.com/jp/blogs/news/new-attach-an-aws-iam-role-to-an-existing-amazon-ec2-instance-by-using-the-aws-cli/ "既存のAmazon EC2インスタンスにIAM Roleがアタッチできるようになりました")
numpyのallについて

# numpyのallについて

@shiracamus さんのコメントを参考にして[**こちら**](http://qiita.com/fujibo/items/79cae02f1065f6fee7aa)に新しく記事を作成したのでこちらを参照にしてください.

## はじめに
numpyのallとはnumpyの配列の要素が全てTrueであればTrueを, そうでなければFalseを返す関数です. ドキュメントは[こちら](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.all.html#numpy.ndarray.all).

numpyを用いた計算は非常に高速なので基本的にはnumpyで計算する方がpythonで直接記述するよりも高速なのですが, その部分をどうしても高速化したくなり色々試してみたところ, 限定的な条件であればそれを覆すことができてしまったので紹介したいと思います.

## 手法
手法としてはfor文で全ての配列要素にアクセスしてandで順に計算していくというものです. これをnumpyのallと比較します.
またnumbaを使用した時の時間も調べたいと思います.

## ソースコード
```python
import numpy as np
import time
import matplotlib.pyplot as plt
import sys

# allを使用
def func1(arr):
    return arr.all()

# and を for で使用
def func2(arr):
    tf = True
    for i in range(arr.size):
        tf = tf and arr[i]
    else:
        return tf

if __name__ == '__main__':
    if len(sys.argv) == 3:
        testsize, arr_size = map(int, sys.argv[1:])
    else:
        testsize = 10
        arr_size = 10
    # テストをする回数, 配列のサイズ
    print(testsize, arr_size)

    elapsed_time = []
    for i in range(testsize):
        # True と False の配列
        arr = np.random.randint(2, size=arr_size).astype(np.bool)
        start = time.time()

        func1(arr)

        end = time.time()
        elapsed_time.append((end - start) * 1e6)

    plt.plot(elapsed_time[1:], 'b', label='numpy all')

    elapsed_time = []
    for i in range(testsize):
        arr = np.random.randint(2, size=arr_size).astype(np.bool)
        start = time.time()

        func2(arr)

        end = time.time()
        elapsed_time.append((end - start) * 1e6)

    plt.plot(elapsed_time[1:], 'r', label='for')
    plt.xlabel('test size')
    plt.ylabel('elapsed time[us]')
    plt.legend()
    plt.show()
```
## 結果
### numba不使用
配列のサイズを10, テストする回数を10回とすると次の図のようになりました. for文を使用してandをしていった方が速くなっています.
![fig10_10.png](https://qiita-image-store.s3.amazonaws.com/0/145171/9f9b2911-f3c6-5c7f-63ea-5fa1d158009d.png)

配列のサイズを200, テストする回数を10回とすると次の図のようになりました. allの方が高速になってますね.
![fig10_200.png](https://qiita-image-store.s3.amazonaws.com/0/145171/6e17e650-002a-d664-50ef-0f88fc0c19be.png)

配列のサイズを大きくするにつれてfor文の方が遅くなってきます.
その様子は次の図でわかります. このパルス状に見えるものが何かは不明です. ここから環境にも依ることとは思いますが配列のサイズが100以下であればpythonでそのまま記述した方が高速になることがわかりました.
![fig_.png](https://qiita-image-store.s3.amazonaws.com/0/145171/f9425046-1207-912e-3278-6ec539462ae9.png)

### numba使用
numbaはJust In Time(JIT)コンパイルを行うので一番最初に関数にアクセスするのに時間がかかります. そのため一番最初のアクセスにかかる経過時間を除いてplotしています.すると図のような結果が得られました. 二回目のアクセスにもどうやら時間がかかるみたいです. 実行時間としては差がなくなったと言えるでしょう.
![fig.png](https://qiita-image-store.s3.amazonaws.com/0/145171/170f6c80-3518-0bff-45e9-d6bfb0277823.png)
配列がより大きい場合は次の図のようになります. numpyの方が高速になっています.
![fig__.png](https://qiita-image-store.s3.amazonaws.com/0/145171/caacaeb0-aa6a-f638-bb4a-369747c08c79.png)

## 結論
グラフをたくさん貼りましたが言いたいことは以下の２つです.
* **配列のサイズが小さい時はnumbaを使用しないという条件であればfor文を用いた方が高速**
* **numbaは高速化に貢献する**

## 最後に
あのグラフに現れるパルスは何だったのだろうか.
MacでAmazone Dashボタンで遊ぶ 自分用メモ

#Homebrewインストール

```console:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

1)Nodebrewをインストール

```console:
brew install nodebrew
```
2)Nodebrewをセットアップ

```console:
nodebrew setup
```
3)bash_profileにパスの設定を書き込む

```console:
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```
4)bash_profileを再読込し、追加したパスを有効にする

```console:
source ~/.bash_profile
```

#Node.jsをインストール

```console:
nodebrew install-binary stable
```
使用するバージョンを選択

```console:
nodebrew use stable
```
#dasherをcloneしてくる
https://github.com/maddox/dasher

足りないモジュールがあるので取ってくる

```console:
npm install -g npm-install-missing
npm-install-missing
```
#Amazone Dashボタンの設定
Amazoneアプリで設定を進め、注文する商品を選択する画面で右上の
✖ボタンを押してキャンセルしてください。
表示されるアラートはスルーで
#Amazone Dashボタンのmacアドレスを調べる

```console:
./script/find_button
```
amazone dashボタンを押して　Amazon Technologies Inc.と表示されるmacアドレスをメモ
cloneしてきたdasher/config/以下にconfig.json作成

```json:config.json
{"buttons":[
  {
    "name" : "ボタンの名前",
    "address": "さっきメモったmacアドレス",
    "url": "ボタンが押されたときに飛ぶURL",
    "method": "POST",
    "json": true,
    "body": {"text":"Hello"}
  }
]}
```

#dasherを起動

```console:
npm start
```

ボタンが押されるとコンソールにボタンが押された表示がされます
なんかエラー出たら取り合えすsudoつけとけばいいと思います

config.jsonのurlをIFTTTのMaker Eventのurl設定しておけば色々楽しめそうです
以上です
scikit-learn の "ValueError: Input contains NaN, infinity or a value too large for dtype('float64')." への対処方法

scikit-learn の StandardScaler を使用してデータの標準化を行う際、下記のエラーが出ることがある。

```python:input
from sklearn.preprocessing import StandardScaler

# 訓練データ（ pandas.DataFrame 型）
X = training_data()

# 標準化
sc = StandardScaler()
sc.fit(X)
```
```python:output
ValueError: Input contains NaN, infinity or a value too large for dtype('float64').
```

これを避けるためには、入力データからNaNや無限大を除去する必要がある。

例えば、下記のコードでXからNaNを一つでも含む列を削除できる。

```python
# X から NaN を含む列を削除する
X.drop(X.columns[np.isnan(X).any()], axis=1)
```

各機能説明

- np.isnan(X): NaNの要素はTrue、その他の要素はFalseの行列を得る
- np.isnan(X).any(): NaNを含む列はTrue、その他の列はFalseのリストを得る
- X.columns[np.isnan(X).any()]: NaNを含む列名を得る
- X.drop('col', axis=1): Xから列名がcolの列を削除する
postgresqlのpg_node_treeという型を解釈したい。した。

```sql:a.sql
-- Function: get_config(text)

-- DROP FUNCTION config(text);

CREATE OR REPLACE FUNCTION config(k text DEFAULT 'test'::text)
  RETURNS text AS
$BODY$
	DECLARE v text;
 
	BEGIN
		--
			EXECUTE 'SELECT val FROM config WHERE key = $1;'
			USING   k
			INTO    v;
		--
			return v;
	END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION config(text)
  OWNER TO todanano;
```

こんな関数を作る。引数はデフォルト値が設定されている。

pg_procをselectして、このデフォルト値を確認すると、以下の内容が得られる。

```
"({CONST :consttype 25 :consttypmod -1 :constlen -1 :constbyval false :constisnull false :location 118 :constvalue 8 [ 32 0 0 0 116 101 115 116 ]})"
```

これの読み解き方が分からない・・・。

最終的に欲しい内容は、この訳の分からないpg_node_treeという型のデータから、
DEFAULT ～の部分を作りたいだけ、、、。

うーん・・・。

と、悩んでいましたが、調べていたら自己解決しました。


上記内容を手作業で読み解くのは、かなり難しい（というか全然分からない）が、
以下の関数に対して、pg_procのoidを渡せば、勝手に解釈した内容を渡してくれる。

```
pg_get_function_arguments(pg_proc.oid);

以下の内容を得る。

"k text DEFAULT 'test'::text"

```


：）


psqlの\dとかではなくて、select文で関数の一覧を取得して、
それぞれのcreate文を得たい、というのが最終目的だったが、
以下の関数で、割とあっさり出てしまった・・・。うーむ。

```
pg_get_functiondef(pg_proc.oid);
```

ただ、これで得られる内容だけだと、なぜかコストの設定とか、言語何使うの？とか
出力してくれないので、pg_procテーブルを結局見ながら、そのあたりを追加する必要がある。
（そのまま実行できるクエリ吐いてくれぇ・・・・）
ボタンのようなリンクを作りたい...ので作ってみた

## 作りたいイメージ
↓こんなの
![save.png](https://qiita-image-store.s3.amazonaws.com/0/101848/4a577d8a-511f-aa11-7d0d-cc36461bf878.png)
クローム標準(?)っぽいボタンが作りたかった
ただしリンクで...:scream:

## ボタンのようなリンクで検索してみる
結構出てきた
![google.png](https://qiita-image-store.s3.amazonaws.com/0/101848/e6d88cd0-bafd-8bae-b250-33f5d18e6aca.png)

## 思ってるのと違う...
ホバーしたら色が変わったりと、かっこいいものが多く
みなさんが作っているボタン（リンク）と作りたいイメージが中々合致しない...

## なので作ってみた
作ったコードはこちら

```css:button_link
.button_link {
    border: 1px solid;
    border-color: #a6a6a6;
    padding: 4px;
    font-style: normal;
    text-decoration: none;
    color: black;
    background:-webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dddddd));
    background:-webkit-linear-gradient(top, #f6f6f6, #dddddd);
    background:-moz-linear-gradient(top, #f6f6f6, #dddddd);
    background:-o-linear-gradient(top, #f6f6f6, #dddddd);
    background:linear-gradient(to bottom, #f6f6f6, #dddddd);
}
```

## できたイメージがこちら
左がリンクで右がボタンです。
![button_link.PNG](https://qiita-image-store.s3.amazonaws.com/0/101848/7b196b35-3200-2b9d-7812-35387efc61a1.png)

ちなみに中のソースはこんな感じ
(今回はspanの中にリンクを埋め込む形で実現させました）

```html:
<span class="button_link">
    <a style="color:black;text-decoration: none;" href="hogehoge">保存</a>
</span>
&nbsp;
<button>保存</button>
```

### おまけ
上記はChromeをイメージしたボタンでしたが、FirefoxとIEも作ってみた

#### Firefox
左がリンクで右がボタン
![image](https://qiita-image-store.s3.amazonaws.com/0/101848/d0293626-8017-f4f5-8d78-d5dd6d697b3b.png)

```css:button_link_firefox
@-moz-document url-prefix() {
    .button_link {
        text-decoration: none;
        background: -moz-linear-gradient(top, #f1f1f1, #dddddd 50%, #d8d8d8);
        border-radius: 3px;
        border: 1px solid #707070;
        border-radius: 3px;
        color: black;
        font-family: Verdana;
        font-size: 13px;
        padding: 2px 7px 1.5px;
        text-decoration: none;
    }
}
```

#### ie-11
左がリンクで右がボタン
![image](https://qiita-image-store.s3.amazonaws.com/0/101848/96776848-52bc-50ef-b474-a7a274065692.png)

```css:button_link_ie11
.button_link {
    border: 1px solid;
    border-color: #6f6f6f;
    background-color: #dedede;
    padding: 3.5px 4px 0px 8px;
    font-size: 12px;
}
```

## まとめ
あくまで似たような...ものならそこまで時間かからずに作成できた
ただしクリックしたときのアニメーション（？）には対応していないので、今後暇ができたら改良する予定

ちなみに使用したツールやサイト様はこちら↓↓↓
[iromiru](http://higashi-dance-network.appspot.com/iromiru/)　画像から色コードを調べられるサイト
[CSS3 グラデーション（gradient）の指定方法](http://www.css-lecture.com/log/css3/css3-gradient.html)
[Chrome、Firefox、Safari、IEそれぞれのみに適用されるCSSハックの書き方まとめ](https://nelog.jp/css-hack-major-4-browzers)
UIButton覚書

#UIButton覚書

- 文字 + 装飾
- 画像
- 画像 (画像はそのままで色かえる）
- 画像 ＋　文字

※画像はPDF使ってます

![スクリーンショット 2017-02-17 18.38.42.png](https://qiita-image-store.s3.amazonaws.com/0/50839/b75e40ac-9cf5-10cc-0d5e-cd2990446374.png)

```
        /* 
         文字 + 装飾
        */
        let btn1 = UIButton(type: .custom)
        btn1.frame = CGRect(x: 50, y: 100, width: 80, height: 40)
        // 背景色
        btn1.backgroundColor = UIColor.orange
        // フォント
        btn1.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14.0)
        // 角丸
        btn1.layer.masksToBounds = true
        btn1.layer.cornerRadius = 3.0
        // 文字と文字色
        btn1.setTitle("ボタン", for: .normal)
        btn1.setTitleColor(UIColor.white, for: .normal)
        btn1.setTitle("ボタン", for: .highlighted)
        btn1.setTitleColor(UIColor.gray, for: .highlighted)
        self.view.addSubview(btn1)
        
        
        /*
         画像
         */
        let btn2 = UIButton(type: .custom)
        btn2.frame = CGRect(x: 50, y: 150, width: 40, height: 40)
        btn2.setImage(UIImage(named:"trashIcon"), for: .normal)
        btn2.setImage(UIImage(named:"trashIcon"), for: .highlighted)
        btn2.tintColor = UIColor.purple
        self.view.addSubview(btn2)
   
        /*
         画像 (画像はそのままで色かえる）
         */
        let btn3 = UIButton(type: .custom)
        btn3.frame = CGRect(x: 50, y: 200, width: 40, height: 40)
        btn3.setImage(UIImage(named:"trashIcon")?.withRenderingMode(.alwaysTemplate), for: .normal)
        btn3.setImage(UIImage(named:"trashIcon")?.withRenderingMode(.alwaysTemplate), for: .highlighted)
        btn3.tintColor = UIColor.purple
        self.view.addSubview(btn3)
        
        /*
         画像 ＋　文字
         */
        let btn4 = UIButton(type: .custom)
        btn4.backgroundColor = UIColor.lightGray
        btn4.frame = CGRect(x: 50, y: 250, width: 120, height: 50)
        btn4.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14.0)
        btn4.setTitle("ゴミ箱", for: .normal)
        btn4.setTitleColor(UIColor.white, for: .normal)
        btn4.setTitle("ゴミ箱", for: .highlighted)
        btn4.setTitleColor(UIColor.gray, for: .highlighted)
        btn4.layer.masksToBounds = true
        btn4.layer.cornerRadius = 3.0
        btn4.setImage(UIImage(named:"trashIcon")?.withRenderingMode(.alwaysTemplate), for: .normal)
        btn4.imageView?.contentMode = .scaleAspectFit
        btn4.imageView?.tintColor = UIColor.gray
        // タイトル位置の調整
        btn4.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -50.0, bottom: 0.0, right: 0.0)
        // イメージ位置の調整
        btn4.imageEdgeInsets = UIEdgeInsets(top: 10.0, left: -20.0, bottom: 10.0, right: 0.0)
        self.view.addSubview(btn4)

```
様々な言語における並行、並列処理(C,C++編)

##知識
並列処理(Parallel)と並行処理(Concurrent)

- 並行: 1CPU,マルチスレッド(同期)
- 並列: マルチCPU(非同期)

- 排他制御: あるデータに対し、特定スレッド内での処理が終わる前に、他のスレッドからアクセスできないようにする。

##実験
一度の命令でアクセスできない64bit整数型の変数を複数スレッドからアクセスしてみる


```c:pthread_test
#include "pthread.h"
#include <stdio.h>

void *func(void *p){
	printf("Passed: %d",*(short*)p);
}

int main(void){
	
	pthread_t pthread;
	short val = 2525;
	pthread_create(&pthread,NULL,&func,&val);
	pthread_join(pthread,NULL);
	printf("MAIN FINISHED");

	return 0;
}
```

pthreadsで簡単にマルチスレッド。

32bitCPUでLONGLONG型(64bit)に複数スレッドからアクセスしようとすると…

```c:longlongbreak
#include "pthread.h"
#include <stdio.h>
#define REPEAT 5000000

long long int a = 0;

void check(){
    if(a != 1 && a != -1){
	printf("LONG LONG VALUE HAS BROKEN!!!");
    }
}

void *func(){
    int i;
    for(i=0;i<REPEAT;i++){
	a=1;
	check();
    }
    printf("SUB FINISHED");
}

int main(void){

    pthread_t pthread;
    pthread_create(&pthread,NULL,&func,NULL);
    int i;
    for(i=0;i<REPEAT;i++){
	a=-1;
	check();
    }
    pthread_join(pthread,NULL);
    printf("MAIN FINISHED");

    return 0;
}
```
結果:
LONG LONG VALUE HAS BROKEN!!!SUB FINISHEDMAIN FINISHED

私の環境ではREPEAT回数を5000000回にした辺りから、値の破壊が発生する。
これは32BITCPUでは、一度の命令では64bit型データにアクセスできないからである。
これを防ぐために排他制御が必要。

排他制御を行うには、mutexを使う。

```c:mutex
#include "stdio.h"
#include "pthread.h"
#define REPEAT 50000000

pthread_mutex_t mutex;
long long int a = 0;

void check(){
	if(a != -1 && a != 1){
		printf("LOG LONG HAS BROKEN!");
	}
}

void *func_thread() {
  int i=0;
  for(i=0; i < REPEAT; i++){
    pthread_mutex_lock(&mutex);
    a = 1;
	check();
    pthread_mutex_unlock(&mutex);
  }
  printf("SUB FINISH");
}

int main(void) {
  pthread_mutex_init(&mutex, NULL);//mutexオブジェクト初期化
  pthread_t pthread;
  pthread_create( &pthread, NULL, &func_thread,NULL);

  int i=0;
  for(i=0; i < 10000; i++){
    pthread_mutex_lock(&mutex);
    a =-1;
	check();
    pthread_mutex_unlock(&mutex);
  }

  pthread_join(pthread, NULL); 
  pthread_mutex_destroy(&mutex);//mutexオブジェクト破棄
  printf("MAIN FINISH");

  return 0;
}
```

このようにすれば値破壊は起こらない。
> 引用: https://ota42y.com/blog/2015/06/18/c-thread/
...
雑談(乱入)用BOT「SPACE PIRATES」を作りました。

<img width="375" alt="IMG_9950.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/165911/45c0b64a-77eb-caea-0e99-68814c9c902c.png">

##BOT概要
LINEmessagingAPIを使った雑談(乱入)用BOTです。
LINE内のすべてのトーク(1:1トーク/グループ/トークルーム)に招待できます。
LINEといえばグループで会話することが多いと思うので、グループ内に招待しておくことで会話が楽しくなるようなBOTを目指して作りました。
もちろん1:1トークでの雑談対話APIを使ったBOTとの会話も可能です。

##主な機能
- 雑談
- 乱入 & 地図表示

##使い方
<img src="http://qr-official.line.me/L/CuwL_OR5JD.png">
QRコードから友達登録をお願いします。

スマホの人は下記からでも友達登録できます。
<a href="https://line.me/R/ti/p/%40ieu9286o"><img height="36" border="0" alt="友だち追加" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png"></a>

例えばこんな雑談が可能です。
<img width="375" alt="IMG_9948.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/165911/d4f9cabf-7616-8d5d-9cf0-c9de7af6b3f7.png">

乱入検知時
<img width="375" alt="IMG_9949.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/165911/7a464c6e-a996-5fe2-2490-395b1ce350c7.png">

特定の言葉の場合には反応し、世界地図で場所を教えてくれます。
ちなみに地図をタッチするとgoogle mapが開きます。

##乱入について
基本的には某宇宙海賊様のネタの場合に反応します。
また、世界の首都の座標データを[ASTI アマノ技研様のページ](http://www.amano-tec.com/download/world.html)よりお借りいたしました。
これにより約200の国名に近い言葉がメッセージ内に入っていた場合に容赦なく乱入可能になりました。
念のため日本の都道府県も対象にしました。
まだ検知率が低いので、今後なにか増やすかもしれません。

##モード
- サイレントモード
- トークモード

グループおよびトークルーム内にBOTを招待するとモードの切り替えができます。
モード名をそのままメッセージとして送信することでモード切替が行えます。

サイレントモードでは乱入検知のみを行い、雑談対話を行いません。
普段と変わらない会話の中に突然乱入されたい時に最適です。
グループやトークルームに招待した時の初期設定はこのサイレントモードです。

トークモードではメッセージに対して雑談対話APIを通して全レスします。
1:1トークの場合は常にトークモードになっています。

##雑談対話時の口調
- デフォルトキャラ
- 関西弁キャラ
- 赤ちゃんキャラ

雑談対話時のBOTの口調を変更できます。
この機能は後述の外部APIが提供している機能になります。

モードと口調は1:1トーク時のメニューからも変更出来ます。

##しりとり
雑談対話時に「しりとり」もしくは「しりとりしよう」というメッセージを送信するとしりとりモードになるようです。
この機能も雑談対話APIが提供している機能です。

##使用API
- NTT docomo 雑談対話API
- Google Static Maps

##問題点
- 雑談対話APIが返したメッセージも乱入チェックしているので、雑談対話APIが変な単語を覚えてしまうと無限ループっぽくなる仕様。
- 「タイ」「マリ」「滋賀」「三重」「奈良」などの文字数が少ないもののヒット率が高い
- グループおよびトークルーム内でBOT以外の入室があった場合にjoinイベントが飛んでくる(?)(確認中)

##その他、技術的なこととか
サーバはさくらのレンタルサーバを使っています。
基本的な構成はphpとnode.jsです。

メッセージイベント
↓
mecabで形態素解析してカタカナに変換
↓
正規表現で国名にマッチするかチェック
↓
マッチしたらnode.jsから指定時間後に返信するように指示
↓
マッチしなかったらそのままphpで返信

という流れです。

時間差でメッセージを送りたいがためだけにnode.jsを使いました。
node.js側ではsqlite3でリクエストを保存しながらsettimeoutで指定時間後にpostリクエストを返しています。
作り方が甘く、たまにメモリ不足(?)で落ちているときがあって、メッセージの順番が前後するときがあります。
もっといい方法があればどなたか教えてください。

また、Push APIは普通に使うと高額なため、このBOTはBot Award中の無料期間が終われば削除する予定です。

###雑感
LINEmessagingAPIはグループおよびトークルーム内のメンバーの情報やグループ内に何人いるとかグループ名とかが取得できないのが辛かった。
この辺が改善されればゲームなんかが作りやすくなりそう。

あと、1:1トーク画面じゃないとメニューが出てこないっていう仕様も辛い。
メニューを押してもメッセージ送信とかURL開くとかしか出来ないのでそこまで問題にならないのだけれど、せっかくPostback eventが実装されたのだからメニューとかImagemapからも使わせて欲しかった。

##最後に
ネタ的なBOTなので怒られそうな場合には即刻削除します。