OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでMarkdownからHTMLに変換する

DjangoやBottleでウェブアプリの開発をしていると、入力されたテキストに対してPythonでMarkdownのレンダリングをしたくなることがあります。そこで今回は[mistune](https://github.com/lepture/mistune)というOSSのパッケージを利用して、Python側でHTMLに変換することを試してみます。

### シンプルな使い方

mistuneのREADMEに書かれているサンプル通り動かすと、以下のようになります。ポイントとしては、通常のテキストの場合は段落ごとに`<p>`タグで囲われており、その中で強調表示や斜体などが展開されます。リスト表記などの場合は、対応するタグで囲われるという感じです。

```py
In [1]: import mistune

In [2]: mistune.markdown('I am using **mistune markdown parser**')
Out[2]: '<p>I am using <strong>mistune markdown parser</strong></p>\n'
```

```py
In [3]: txt = """段落1
   ...: 
   ...: 段落2"""

In [4]: mistune.markdown(txt)
Out[4]: '<p>段落1</p>\n<p>段落2</p>\n'

In [5]: txt = """- リスト1
   ...: - リスト2
   ...: - リスト3"""

In [6]: mistune.markdown(txt)
Out[6]: '<ul>\n<li>リスト1</li>\n<li>リスト2</li>\n<li>リスト3</li>\n</ul>\n'
```

またオプションとして、入力されたHTMLタグをエスケープするかどうかの`escape`(デフォルトではTrue)や、空白行を入れない改行の際に`<br/>`タグを含める`hard_wrap`というものがあります(デフォルトではFalse)。

### 自作のLexerとRenderを使う

さて、mistuneでは一通りのmarkdownの仕様に従った変換はデフォルトで提供されていますが、加えて独自の表記や記号に対してもルールを指定してHTML変換する機能もあります。

mistuneでは標準でhttp/httpsのリンク付与機能を提供していますが、他のftpやsmbなどのプロトコルには対応していません。ここでは例として、リンクに自動でaタグを付与する機能を追加してみます。

方法としては、Lexerに独自ルールの記載して、Rendererに対応する変換方法を指定するというものです。ここでは、LexerでftpやsmbのプロトコルのURLを正規表現で抜き出して、Rendererで前後に`<a>`タグを付与するということをしています。

```py
import re
from mistune import Renderer, InlineLexer


class DocumentLinkRenderer(Renderer):

    def document_link(self, link):
        return '<a href="{l}">{l}</a>'.format(l=link)


class DocumentLinkInlineLexer(InlineLexer):

    def enable_document_link(self):
        self.rules.document_link = re.compile(r'''^((https?|smb|ftp|file):\/\/[^\s<]+[^<.,:;"')\]\s])''')
        self.default_rules.insert(3, 'document_link')

    def output_document_link(self, m):
        text = m.group(1)
        return self.renderer.document_link(text)
```


使い方としては、`mistune.Markdown()`にカスタムのRendererとInlineLexerを指定します。


```py
renderer = DocumentLinkRenderer()
inline = DocumentLinkInlineLexer(renderer)
inline.enable_document_link()
markdown = mistune.Markdown(renderer, inline=inline)
    
markdown("markdown text")
```

実際に利用してみると、以下のようにftpのURLに対しても自動でリンクが作成されていることがわかります。

```py
In [20]: markdown("ftp://path/to/file")
Out[20]: '<p><a href="ftp://path/to/file">ftp://path/to/file</a></p>\n'
```

この機能を使えば、はてなキーワードみたいに特定の単語にリンクを貼ったり、RedmineやBacklogのチケットのように記事のIDとURLの紐付けを行うことができます。


### 参考

- [lepture/mistune: The fastest markdown parser in pure Python with renderer feature.](https://github.com/lepture/mistune)
- [Markdownから楽してフォーマット変換する方法 - Qiita](http://qiita.com/vh5150/items/26eeb0f3aaabfdb237f6)
- [Markdown Parsers in Python — Just lepture](http://lepture.com/en/2014/markdown-parsers-in-python)
[Unity][NCMB]横画面固定なのに縦画面でアプリが起動されてしまうときの対処法

横画面固定の設定(PlayerSettingsでAutoRotation, Landscape Right, Landscape Left)であるのに、端末を縦にしてアプリを起動すると、縦画面になってしまうというバグが発生した。

#症状
・上記の通り、端末を縦にしてアプリを起動すると、縦画面になってしまう
・縦画面のままゲームを進めるとレイアウトが崩れる
・起動後、すぐに端末を横向きにすれば画面も横になる
・横向きのまま起動すれば縦にはならない

#環境
・mac OS Sierra 10.12.1
・Unity 5.4.3f1
・デバッグ端末：DP-X1、Xperia Tablet Z4

#原因の特定経緯・対処法
・iOS版では問題ないことから、Android固有の問題である
・[NCMB](http://mb.cloud.nifty.com)を入れるまでは問題なかった

ということから、NCMBプラグインによって入れられたAndroidManifest.xmlがおかしいのではないかと考えた。

同様の症状を調べると、以下のものが該当した。
・[[Unity][Unity3d] Android で実行した時に設定している以外の向きに回転してしまう問題の解決方法](http://d.hatena.ne.jp/nakamura001/20160203)
・[App starts and then runs in landscape mode (Unity 4.2 - Android)](http://answers.unity3d.com/questions/503957/app-starts-and-then-runs-in-landscape-mode-unity-4.html)
・[[Android] Broken device orientation](https://forum.unity3d.com/threads/android-broken-device-orientation.428741/)

これらのサイトを参考にした結果、AndroidManifest.xmlで画面の向きを設定すれば良いことが分かった。

よって、NCMBによって入れられたAndroidManifest.xmlの一部を次のように改変した。

```xml:AndroidManifest.xml
        <!-- <meta-data android:name="smallIcon" android:resource="@drawable/comment_icon"/> -->
        <!-- UNITY PLAYER ACTIVITIES ( [WARNING] if use Prime31, edit 'com.nifty.cloud.mb.ncmbgcmplugin' to 'com.prime31' at android:name of 3 these activities) -->
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
            android:label="@string/app_name"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
            android:screenOrientation="sensorLandscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
```

まず、元のNCMBによるAndroidManifest.xmlにあった

```
<activity android:name="com.nifty.cloud.mb.ncmbgcmplugin.UnityPlayerProxyActivity"
```

を

```
<activity android:name="com.unity3d.player.UnityPlayerActivity"
```

と改変した。

また、<activity〜内に

```
android:screenOrientation="sensorLandscape"
```

を追記した。


以上の方法で対処することができた。


2016.12.13　追記
もしかしたら、Unity5.5で改善されてるかもしれない
関西ゲーム勉強会で「あんさんぶるスターズ！の運営について」というタイトルで発表しました

Happy Elements株式会社 カカリアスタジオ Advent Calendar 2016の8日目の記事です。
担当は「あんさんぶるスターズ！」グループの @kusakari です。7日連続で対応してくれた @nagizero お疲れ様でした＆ありがとうございました！

# はじめに

12月3日に新梅田研修センターで開催された[関西ゲーム勉強会](http://kgstudy.com/)で「あんさんぶるスターズ！の運営について」というタイトルで発表させて頂きました。

# 発表資料
- [あんさんぶるスターズ！の運営について](https://speakerdeck.com/kusakari/ansanburusutazu-falseyun-yong-nituite)

# 発表の概要
## 前半（47ページまで）

コンテンツディレクターの堤が、イベント運用時におけるコンテンツ制作の一通りの流れとポイントを説明しました。

## 後半（48ページ以降）

草苅が開発・運用について説明しました。
弊社ではクオリティーを上げるために、全社的にできるだけ小さなチームで開発するという方針なのですが、小さなチームで開発していると、あいまいなルールのまま、なんとなく開発が進んでいくことも少なくありません。
そのため、あんさんぶるスターズ！の開発チームでは、資料に書いたような形で、進捗と責任の可視化、そしてルールの明文化を行っています。こういうことを考えると、マイクロマネジメントになりがちなのですが、そうならないように注意して運用しています。
あんさんぶるスターズ！ではリリースから数ヶ月はバグが多かったこともあり、1PRにつき2人のレビュアーをアサインしていました。安定してきてからは開発速度を上げるために、重要なPRのみレビュアー2人としています。このように同じ運用でもフェーズに応じて柔軟にやり方を変えていくことも重要と考えています。
そういう意味では今のアプリやチームの状況に応じて柔軟に対応していくためにも、開発リーダーの設置や役割の明確化、状況の可視化やルールの明文化、などが役に立つと考えています。


# GitHubにreviewerの機能が追加

タイムリーなことに、本日、[GitHubにreviewerの機能が追加](https://github.com/blog/2291-introducing-review-requests)されました。これでreviewerをラベルで管理しなくても良くなるかもしれません。
ツールに運用を合わせていると、ときにはツールの機能追加によって運用が楽になる例もあるいうことで…

# おわりに

関西ゲーム勉強会のスタッフの皆様、見に来てくださった皆様ありがとうございました！非常に貴重な体験をさせて頂きました。
iTunes Connect　とApple Developer Program　走り書き

## ■iTunesConnect

・EnterpriseアカウントではiTunesConnectには入れない、
　基本的にiTunesConnectは配布用

・AppManager以上の権限がないと、Sandboxテスターは作れない。

・権限一式
![image](https://qiita-image-store.s3.amazonaws.com/0/17904/e6783b93-ea55-6c40-31a3-e3530661f86c.png)




## ■Apple Developer Program

メンバー権限では証明書のダウンロードはできない。
Team名・TeamIDはMembershipからみれる


・参考URL
　https://developer.apple.com/support/roles/jp/
SublimeText3でエスケープキーを押してもコンソールを表示させる設定

この記事は諸事情により、[このリンク先](https://sublimer.hatenablog.com/entry/2016/12/08/000000)に移行しました。
This article has moved to [this link](https://sublimer.hatenablog.com/entry/2016/12/08/000000) due to various reasons.
【ゲリラアドカレ】UE4ゲーム実装　進捗報告 3日目(進んでいくように見えるエフェクト)

 【非公式】C&M GAMESゲリラ Advent Calendar 2016 6日目の記事です。

FlashゲームをUE4で再実装するゲリラアドカレです。

クエスト画面でたくさんのソーシャルゲームでよく見かける、先に進んでいるっぽく見せる演出を実装します。

・注意
許可を取ってないので通常業務の空いた時間を利用して作成するため、作成中のゲーム、及びアドカレは完成保証がなければ、ゲーム自体もリリースされる保証も皆無なので、あんまり期待しないでください。

#演出の表示

ずばり、集中線を表示してカメラをズームさせるだけです。単純です。
オリジナルのクエストでやってることとは微妙に違いますが、先に進んでる感が出ればOKとします。

#集中線の表示

com04さんのTwitterを全力で頼らせて頂きました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">のーでぃんぐ <a href="https://t.co/5x6IMjKfvM">pic.twitter.com/5x6IMjKfvM</a></p>&mdash; com04 (@com04) <a href="https://twitter.com/com04/status/798904048141242368">2016年11月16日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

オリジナルで使用している集中線の画像素材を利用してマテリアルを組みました。

![マテリアル.png](https://qiita-image-store.s3.amazonaws.com/0/104377/2c478b59-b2d2-b5cb-3341-4cd8d4190188.png)

カメラのフェードインを呼び出すカスタムイベントを実装しました。

![カメラフェードイン.png](https://qiita-image-store.s3.amazonaws.com/0/104377/4c4f3d49-1030-072c-8326-e57b18f1b3d3.png)

このイベントを呼び出すため、UIのブループリントを修正しました。
ボタンを押した時に表示するようにしています。

![UI修正.png](https://qiita-image-store.s3.amazonaws.com/0/104377/3b2b24b5-85c9-0e99-a9ac-475a83b87271.png)

ボタンを一括で消すのをいちいちノードで書くのが面倒なため、関数を用意してつなげました。

![関数.png](https://qiita-image-store.s3.amazonaws.com/0/104377/fef78ad6-4945-2d91-4ed7-85f1ac7011b9.png)

メインのカメラBPが必要なため、レベルブループリントを修正しています。
![レベルブループリント.png](https://qiita-image-store.s3.amazonaws.com/0/104377/b22fb315-0e4d-6170-9dd2-d360c41f980b.png)

最後、セリフを表示しているCanvasのバインド関数を作成します。

画像ではセットされていますが、可視性の横のバインドというプルダウンからバウンド関数を新規作成します。
![バインド.png](https://qiita-image-store.s3.amazonaws.com/0/104377/e13af205-b9e0-ee26-b138-5a5dd62dd75e.png)

バインド関数を記載します。とりあえずボタンが消えたら無条件で消えるようにします。
![バインディング.png](https://qiita-image-store.s3.amazonaws.com/0/104377/8ea6b2fd-ece6-a48c-cf18-a2730464c2c1.png)

#先に進んでいるような演出

これで先に進んでいるような演出が出来ました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">com04さんが前に書いていた集中線ノードを全力でお借りしました。<br>おかげでソーシャルゲームでよく見る先に進んでいる風の感じが出ました <a href="https://twitter.com/hashtag/UE4Study?src=hash">#UE4Study</a> <a href="https://t.co/WLgKqvis8m">pic.twitter.com/WLgKqvis8m</a></p>&mdash; 荻野雄季＠クルーズから出荷された豚 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/806823892048191488">2016年12月8日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

次はエンカウント演出を出そうかなと考えています。
それが出来ればクエスト画面のプロトタイプとしては十分です。

あとはクエスト選択画面からクエストのレベルを呼び出す処理を実装後、最大の難関で工数が掛かる、バトル画面の実装に入ります。

……バトルの工数が足りない気がする。終わるかなぁ。
rubyの配列に非破壊的に値を結合する方法

配列に対して破壊的に追加する書き方は良く見るので、非破壊的に追加する方法がなかったので、書いておきます。

### 前提条件

```ruby
x = [1, 2, 3]
y = [4, 5]
```

### +
単純に+をする

```ruby
z = x + y
=> [1, 2, 3, 4, 5]
x
=> [1, 2, 3]
```

### dup
複製する

```ruby
z = x.dup.concat(y)
=> [1, 2, 3, [4, 5]]
x
=> [1, 2, 3]
```

### 代入する

```ruby
z = [x, y]
=> [[1, 2, 3], [4, 5]]
x
=> [1, 2, 3]
```

### *で展開する

```ruby
z = [*x, *y]
=> [1, 2, 3, 4, 5]
x
=> [1, 2, 3]
```

書き方によって後処理が変わる(flattenがいる)と思いますが、こんなもんでしょうか。

他に書き方を知っていれば、教えていただければと思います:bow:
AWS CLIメモ： SG作成

コンソール操作（通称：ぽちぽち）ではなく、AWS CLIでSG(Security Group)を作成するメモ

参考）
http://docs.aws.amazon.com/cli/latest/reference/ec2/create-security-group.html
http://docs.aws.amazon.com/cli/latest/reference/ec2/authorize-security-group-ingress.html
http://docs.aws.amazon.com/cli/latest/reference/ec2/authorize-security-group-egress.html

やるべきことは以下
1. SGを作成する ※所属するVPNを指定する必要あり
2. Inboundの許可設定追加
3. Outboundの許可設定追加


CLIコマンド例は以下

## SG作成

```
aws ec2 create-security-group --group-name [SG名] --description [説明] --vpc-id [VPC ID]
```

VPC名で管理したい場合に、VPC名からVPC IDへの変換をシェル芸で対応するならdescribe-vpcsコマンドと、jqを使って整形して取得できる。

```
VPC_NAME='my_vpc'
eval VPC_ID=$(eval "aws ec2 describe-vpcs |jq -r '.Vpcs[] | select(.Tags[].Value==\"${VPC_NAME}\") | .VpcId '")
```
※変数VPC_NAMEで指定したVPC名で、VPC IDを取得する例

SGにNameタグを付与したければ以下を追加

```
aws ec2 create-tags --resources [SG ID] --tags Key=Name,Value=[名前]
```

## Inbound設定
外部からSGへのアクセス許可設定

以下はFROMをSG IDで指定する例
※すべてのプロトコル対象の場合は--protocol all

```
aws ec2 authorize-security-group-ingress --group-id [対象のSG ID] --protocol all --source-group [アクセス許可する送信元SG ID]
```

IPアドレス指定するならオプション --source-group の代わりに --cidr を利用

```
--cidr 192.168.0.0/24
```



また、参考まで、SG名からSG IDに変換するには以下

```
aws ec2 describe-security-groups --filters Name=group-name,Values=[SG名] | jq -r '.SecurityGroups[].GroupId'
```


## Outbound設定

基本的には、Inboundの authorize-security-group-ingress を authorize-security-group-egress に変えるだけ。

### 注意点：VPCエンドポイント経由でS3へアクセスする場合

アウトバウンドに PrefixListId=pl-61a54008 を指定する必要あり

Prefix List IDを指定したい場合は --source-group の代わりに --ip-permissions

```
--ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,PrefixListIds=[{PrefixListId=pl-61a54008}]
```
※Prefix IDとは、宛先のAWSクラウド上のサービスを特定するためのIDで、AWSサービスのIPアドレス帯域をIDで指定できるもので、東京リージョンはpl-61a54008が該当。
VPCエンドポイント経由でS3バケットにアクセスする場合に、この帯域に対するアウトバウンドを設定しておく必要がある。

以下で詳細を確認できる。
```
aws ec2 describe-prefix-lists
```
Paper Plane xUI(PPx)のListFileとpecoの関係

pecoでは標準出力に一覧を選択して標準出力へ出す事ができ、対話的なフィルタ処理と言えます。
ここでは**(それぞれを使って感じた僕なりの)**用途の違いを解説したいと思います。

# pecoの例

## スクリプトで対話的な処理

例えば、何かスクリプトを実行中に対話的な処理を入れたいとなると、pecoの出番になります。
*※動作確認はcygwinのmintty上でしており、pecoを動作させるために[winpty](https://github.com/rprichard/winpty)をインストールしています。*

```sh:peco_test.sh
#!/bin/sh

while : ;do
  echo Paper Plane xUIを使いますか?
  sleep 2
  select=`echo -e "Hai\nYes\nNo" | peco`

  case $select in
  Hai|Yes)
    echo Welcome Paper Plane xUI!
    break
    ;;
  *)
    echo そんな、ひどい
    sleep 1
    ;;
  esac
done
```

上記のように、とても手軽に選択肢を作る事ができます、しかも入力では無いのでコーナーケースの考慮もある程度しなくても良く、例えばYesの場合に```"[Yy]([Ee][Ss])?"```という入力チェックをしなくても良くなります、また、複数選択の時も*に行くようになっています。

上記の場合は選択肢の為、[choコマンド](http://mattn.kaoriya.net/software/lang/go/20160603011620.htm)の方が適切かと思いますが、一例として紹介します。


## gitブランチを選択してcheckout

次はLinuxコマンドとの連携時にpecoを使う場合です、gitでcheckoutしたい時にブランチ一覧から選択したい時、

    $ git checkout `git branch | peco`

とすると、ブランチ一覧から選択してcheckoutをする事ができます[^1]、このコマンドをaliasにしていたり、グローバルaliasが使えるzshでブランチ選択部分だけをaliasにして汎用的にしている例を見かけます。

[^1]: カレントブランチに「\* 」が残ってますが、僕の場合は候補外の目印として残すようにしてます


# PPxの例

PPxでは後者の「gitで、選択したブランチをcheckout」のような部分に利用できます、前者のスクリプト内の対話的な処理はpeco(やcho)の方が良いでしょう。

## PPxでgitブランチを選択してcheckout

まずは、単にコマンドの実行結果をListFileに吐き出すだけのコマンド群を用意します、これは単純ですが、汎用的です。

「Shift+s」でコマンド実行結果をListFile化する
![command.png](https://qiita-image-store.s3.amazonaws.com/0/51728/78e87608-967e-8a90-4592-7f0b2b6bc77d.png)

ここでgit branchを実行

![git_branch.png](https://qiita-image-store.s3.amazonaws.com/0/51728/43e0707c-e24d-df5d-5caf-ca31f61acefd.png)

ブランチ一覧がエントリーとして表示されます。

この中からエントリーを選択してcheckoutをするために、[Paper Plane xUI(PPx)をgitのフロントエンドとして使う](http://qiita.com/wordijp/items/25491064932f36ec1943)で用意したcheckoutメニューを、カーソル上のエントリーが初期値となるように少し改造します。

「Shift+g, o」の初期値を変更
![git_checkout_entry.png](https://qiita-image-store.s3.amazonaws.com/0/51728/c1220d4c-c041-fd5b-5890-8f321520c2e9.png)

これで選択したエントリーへのcheckoutができます。


# ツール構成

## entry.js

選択した最初のエントリーを返します、%FC相当の事をやってるだけなんですが、%FCはListFile上だとフルパスを返すので、スクリプトとして用意します。

```js:entry.js
//! script

for (var items = new Enumerator(PPx.Entry); !items.atEnd(); items.moveNext()) {
	PPx.Result = items.item().Name;
	break;
}
```

## PPx設定

差分のみです[^2]。

[^2]: 「Shift+g」はエントリー以外の自分ルールがありますが「Shift+g, o」でエントリーを初期値にしています。これは初期値の「.」はすぐ入力出来るし、最初の一つだけしか使われないので「Ctrl+g」とは違う、なにより使い勝手が良く、という事でこうしました。

**※自身の設定が消えないように、適用前にバックアップを取るか、追加取り込みをしてください**
**※GitExtensionsやスクリプトのパスは自身の環境へと合わせて下さい**

```:PPX.CFG
KC_main	= {	; PPcメイン窓
\S	,
	*set dummy='command実行'
	*set CIN_LSTFILE=%'temp'\cin2listfile.tmp
	*set CMD=%"コマンド?"%{command%}
	%Obsq %'CMD' | ruby %0\script\shell\tolistfile.rb | nkf -Lw -s > %'CIN_LSTFILE'
	*jumppath %'CIN_LSTFILE'
}

M_menuCustomGit2	= {	** comment **
git check&out <target>	= 
	*set ENTRY=%*script(%0\script\entry.js)
	*set ARG=%"git checkout <target>(入力1/2)"%{%'ENTRY'%}
	%"git checkout <target>(Enterで実行2/2)"%{%}
	%OB git checkout %'ARG'
}
```

# 終わりに

身も蓋もないですが、今回のように利用頻度の高い場合は専用メニューを用意してもよいかと思います、こちらの方がListFileを中継せず、1アクションで済むためスムーズです。

```:PPx.CFG
M_menuCustomGit2	= {	** comment **
git check&out <branch> <PECO>	= %OB git branch | peco | xargs git checkout
}
```
herokuとphpでオウム返しlinebotを作る（Mac限定）

# 準備
1. homebrew をインストールする（brew updateしておこう）
2. heroku のアカウントを作成する
3. linebot のアカウントを作成する
4. herkou cli をインストールする => ```$ brew install heroku```
5. php をインストールする => ```$ brew install homebrew/php/php71```
6. composer をインストールする => ```$ brew install homebrew/php/composer```

```
以下のコマンドを自分のマシンで入力して、バージョンが表示されるか確認する
$ heroku version
$ php -v
$ composer -V

herokuにログインしておく
$ heroku login
```

# プロジェクトを作成する
以下のコマンドを実行する

```
$ mkdir sample-bot
$ cd sample-bot
$ touch composer.json && echo {} > composer.json
$ composer require linecorp/line-bot-sdk
$ vi index.php
```

```index.php
<?php
require_once __DIR__ . '/vendor/autoload.php';

$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient(getenv('CHANNEL_ACCESS_TOKEN'));
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => getenv('CHANNEL_SECRET')]);
$sign = $_SERVER["HTTP_" . \LINE\LINEBot\Constant\HTTPHeader::LINE_SIGNATURE];
$events = $bot->parseEventRequest(file_get_contents('php://input'), $sign);

foreach ($events as $event) {
  if (!($event instanceof \LINE\LINEBot\Event\MessageEvent) ||
      !($event instanceof \LINE\LINEBot\Event\MessageEvent\TextMessage)) {
    continue;
  }
  $bot->replyText($event->getReplyToken(), $event->getText());
}
```

```
$ git init
$ git add .
$ git commit -m "Initial commit sample-bot"

以下のコマンド後に表示されるURLをhttps://**********.herokuapp.com/をメモる
$ heroku create

$ git push heroku master
```

# linebot の設定

1. [ここ](https://business.line.me/ja/)にアクセスする。
2. 「アカウントリスト」>「ビジネスアカウントを作成する」>「MessageAPIを始める」でアカウントを作成する
3. 「アカウントリスト」から「LINE@MANAGER」にアクセスする
4. 「LINE@MANAGER」の左にある「アカウント設定」>「Bot設定」で「APIを使用する」を有効にする
5. 「Bot設定」の「リクエスト設定」で「webhook送信」を利用するに変更する
6. 続けて「詳細設定」の「自動応答メッセージ」を利用しないに設定する
7. 「保存」ボタンを押して、設定を保存する
8. 再度[ここ](https://business.line.me/ja/)の「アカウントリスト」から「 LINE Developers」を開く
9. 「QR Code」で自分のLINEアカウントのともだちにアプリを追加する
10. 「EDIT」ボタンを押し編集画面で、「Webhook URL」に先ほどメモったURLを入力し、「SAVE」する
11. 「Channel Secret」と「Channel Access Token」をメモる（表示されていない場合は「ISSUE」を押す）

# heroku 環境変数設定

```
$ heroku config:set CHANNEL_SECRET=メモったChannel Secret
$ heroku config:set CHANNEL_ACCESS_TOKEN=メモったChannel Access Token
```

# 試す
自分のスマホから追加したアプリにメッセージを送信してみて、オウム返しが帰ってきたら成功です
君の名は。 in C

C言語 Advent Calendar 2016 が12/1以降なんとなく繋がっているので、役に立たない小ネタで2度目の参加です。

# 突然ですが

C言語のプログラム中の「マクロ(macro)[^1]」と「関数(function)」に対して、全く **同じ名前** を使うことは可能でしょうか？

例えば `NAME` という名前のマクロと `NAME` という名前の関数を **同時に定義し**、それぞれを **呼び分ける** ことはできるでしょうか？

[^1]: 本記事で扱うマクロは、厳密には「関数形式マクロ(function-like macro)」と呼ばれる形式のものです。通常の「関数」との混同を避けるため、本文中では単に「マクロ」と表記します。


# 無理？

と思った？実現可能です。というか、無理だったらはなからこんな記事書きませんよね。

括弧`()`の力を使うことで、下記ソースコードのように記述できます。カギとなるのは B)関数の定義 と、D)関数の呼び出し の記述方法でしょうか。

```c:yourname.c
#include <stdio.h>

// A) マクロmacro_or_funcを定義する
#define macro_or_func(s) puts(s)

// B) 関数macro_or_funcを定義する
void (macro_or_func)(const char* s)
{
  // C) マクロmacro_or_funcを呼び出す
  macro_or_func(s);
}

int main()
{
  // D) 関数macro_or_funcを呼び出す
  (macro_or_func)("C");
}
```

特に B) はかなり特殊な書き方だと思います。私も[StackOverflowの質問と回答][so]を見るまでは知りませんでした。

いやぁ、C言語ってホントに[奥が深い][bk]ですねぇ。

[so]: http://stackoverflow.com/questions/13600790/
[bk]: http://0xcc.net/misc/bad-knowhow.html

# ちなみに
2016/12/12追記： 括弧`()`を使わない別解として、<del>高度な革新的技術による</del>マクロ`PREVENT_MACRO_SUBSTITUTION`を利用した技法もあります。

```c:yourname2.c
#include <stdio.h>
#define PREVENT_MACRO_SUBSTITUTION

// A) マクロmacro_or_funcを定義する
#define macro_or_func(s) puts(s)

// B) 関数macro_or_funcを定義する
void macro_or_func PREVENT_MACRO_SUBSTITUTION(const char* s)
{
  // C) マクロmacro_or_funcを呼び出す
  macro_or_func(s);
}

int main()
{
  // D) 関数macro_or_funcを呼び出す
  macro_or_func PREVENT_MACRO_SUBSTITUTION("C");
}
```

C++言語向けのBoostライブラリでは、同等の[`BOOST_PREVENT_MACRO_SUBSTITUTION`マクロ][boost.pp]が提供されています。

[boost.pp]: https://cpplover.blogspot.jp/2010/06/define-boostpreventmacrosubstitution.html

こんな汚いテクニックがどこで必要なのか？と思われるかもしれませんが、[一部の環境][minmax]では役に立つこともあります。歴史的経緯もあるし仕方ないよね。うん。

[minmax]: http://d.hatena.ne.jp/yohhoy/20120115/p1

# あとがき

本記事で紹介した内容に実用性はほとんどないでしょう。よほど特殊な事情でもない限り、マクロ名と関数名には異なる名前をつけるべきです。

あと、タイトルは数十秒考えて適当につけました。2016年に流行った映画に似ていますね。見てないけど。

---
ESLintをオレオレレベル設定してCIでだけ警告したりする

# ESLintでCIのときだけエラー警告してほしい

## おさらい：ESLint の標準的なレベル分け

ESLintでのレベル分けは３つ定義されている

http://eslint.org/docs/user-guide/configuring#configuring-rules

* `off`, `0` - オフ。何も警告しない
* `warn`, `1` - 警告するが、exit codeに影響を与えない（CIではコケない）
* `error`, `2` - 警告する。exit codeを1にする

## 問題：いい具合のレベル感がない

プロダクション環境でESLintをかけていると、`no-console`や`no-unused-var`など、「これproductionビルドまでにはエラーとして検出したいのだけど、開発中は見逃してほしい」みたいなのがたまにある。
（`error`にしてしまうとstorybookとかでエグくなって辛い等もあった）

ESLint自体のエラーレベルは三段階のみで、CLIからwarnがあってもexit codeを1で返すようなコマンドも見つからなかった（多分このへんはレベル管理をシンプルにしているからだと推測できる）


## 解決法：レベル分けの定数管理を利用してCI判定

reactの[`eslintrc.js`](https://github.com/facebook/react/blob/v15.4.1/.eslintrc.js)を見てみるとこのエラーレベルを定数定義していることがわかる

```js
const OFF = 0;
const WARNING = 1;
const ERROR = 2;
 :
 rules: {
    'accessor-pairs': OFF,
    'brace-style': [ERROR, '1tbs'],
 }
```

なるほど。そういうのもあるのか。

これを応用して、CIの場合だけWARNINGの挙動をエラー化させれば良い。circle-ci, travis-ciはどちらも`CI=true`という環境変数を設定しているので、これを利用する


```js
const ERROR = "error"
const WARNING = (process.env.CI == true) ? "error" : "warn"
const OFF = "off"

```

これでCI時のみ警告出来るようなった。

* https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables
* https://circleci.com/docs/environment-variables/

`process.env.CI`が使えないなら自前で変数設定してもいいんじゃないかと思う


```js
const ERROR = "error"
const WARNING = (process.env.STRICT_LINT == true) ? "error" : "warn"
const OFF = "off"

// こんな感じもアリだろう
// const WARNING = (process.env.STRICT_LINT == true || process.env.CI == true) ? "error" : "warn"



```

```json
{
  "scripts": {
    "lint": "STRICT_LINT=true eslint"
  }
}
```

# 応用編：意味付けでオレオレレベル設定をする

上記のレベルの定数管理を見て思いついてやってみてる案。

ESLintはレベル分割を最低限の挙動の違いだけをシンプルに分割している。

だが実は実務上だと「このルールなんでつけたんだっけ？」みたいなのもあって、もうちょっと意味を持たせたくなったりする。ということで色々細分化させてみたら良いんじゃないかと思いついている（逆にわかりづらくなったりするかもしれない）

だいたいこんなイメージ

```js
// no-evalとかコードの書き方が変わる禁止事項
const CRITICAL = "error"

// エラーなのだけどデバッグ時には無視していい警告だけする
const ERROR = (process.env.CI == true) ? "error" : "warn"

// たまに気が向いたら直すルール（無い方が良いかも？）
const WARNING = "warn"

// OFFはそのまま
const OFF = "off"

//// ここから読み手向けなど ////

// 「手で治すのめんどいけどfixableだったらつけとくか」的なルール。dev時は出さない
const FIXABLE = (process.env.CI == true) ? "error" : "off"

// おためしルール。きつかったらチームで相談しようね、という宣言
const TRIAL = "error"

// 本当はつけたいけど、直すの重くて妥協しているやつ。rubocop_todo的なやつに近いイメージ
const TODO = "off"
```

FIXABLEは結構「これなんでやったんだっけ」ってなるやつが多いので、結構いいと思っている。TRIALとTODOは思いついたものの使い所が無くて今のところ運用出来てない
enebular の INFOMOTION を他のサイトに貼り付ける

本投稿は、[enebular Advent Calendar 2016](http://qiita.com/advent-calendar/2016/enebular) の第8日目の記事です。

第1日目の記事や、enebular.com のチュートリアルをすすめることで、 enebular でグラフ（INFOMOTION）が表示されていると思います。

![image](https://qiita-image-store.s3.amazonaws.com/0/7046/48d8201a-a626-23e3-0a4c-325665946890.png)

実は、INFOMOTION は、HTMLとして他のサイトに貼り付けることができるんです！

やりかたはとても簡単。

グラフの右肩にある「share」リンクをクリックすると、ウインドウに貼り付け用のHTMLが表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/7046/143d8682-0781-528b-084c-65119a0dcfd6.png)

これを他のサイトのHTMLに埋め込むだけです！

※画像はローカルのHTMLです。

![image](https://qiita-image-store.s3.amazonaws.com/0/7046/d49dec6d-128a-9187-2ba3-2b03d0b1cabd.png)

INFOMOTION は部品ごとに `div` タグになっており、コンパーチブルに埋め込むことができます。ただ、既存のサイトに埋め込むときは、スタイルの競合があるかもしれないので、そこだけ注意が必要です。

**dateRangePicker**

```
<div id="enebular-daterangepicker"></div> 
```
![image](https://qiita-image-store.s3.amazonaws.com/0/7046/8df99daf-0804-bce2-64a4-7f663cd8db59.png)


**timeline**

````
<div id="enebular-timeline"></div>
```
![image](https://qiita-image-store.s3.amazonaws.com/0/7046/0febdbf2-2da7-78e1-84f9-d84a3bb330c4.png)

**graph**
```
<div id="enebular-graph"></div>
```

![image](https://qiita-image-store.s3.amazonaws.com/0/7046/9bc937ea-c208-5a35-814d-3590f683052e.png)

こんな感じです。それでは〜。
JavaScriptでハードをコントロールしよう

 [JavaScript Robotics Advent Calendar 2016](http://qiita.com/advent-calendar/2016/javascriptrobotics) の9日目の記事です　

今回コントロールするのは、Nefryです。
まずはNefryについて紹介していこうと思います。

# Nefryとは？

**フリスクサイズのIoTデバイス**でUSBに直接繋げられたり、Webページ上でWiFiの設定やESP8266の端末設定ができるようになっていたりとESP8266をより簡単に扱えるものになっています。

詳しくはLigブログで記事をいくつか載せていますのでご覧ください。

[自作したオリジナルIoTデバイス「Nefry」とインターネットを繋いでみた](http://liginc.co.jp/236620)

[Webサービス同士を連携できる「IFTTT」と自作IoTデバイスを繋いで生活を便利にしてみた](http://liginc.co.jp/263899)

>**[dotstudio](https://dotstud.io/projects/nefry-connect-internet/)さんにて販売中です！！**

![](https://qiita-image-store.s3.amazonaws.com/0/97208/95705e6e-e8e8-9f9d-6778-7de63860a01e.jpeg)　　


# RESTAPIでハードを扱おう

>dotstuidoさんのところで記事を公開しています。
**[URLを入れるだけ！REST APIでNefryを簡単に制御してみよう！](https://dotstud.io/blog/nefry-rest-api-tutorial/)**
![[URLを入れるだけ！REST APIでNefryを簡単に制御してみよう！](https://dotstud.io/blog/nefry-rest-api-tutorial/)](https://dotstud.io/img/blog/059/00_eyecatch.png)


今回はこちらで紹介したものをベースにすすめていきます！

## Nefryにプログラムを書き込もう

NefryでRESTAPIを扱うためにプログラムを書き込みましょう。

上の記事や環境構築の話を参考にしてArduinoIDEで書き込むことができますのでNefryにプログラムを書き込んでみましょう。
**(後日、プログラムをダウンロード出来るようにするので、いいねでも押してまた見てください。)**

```cpp:RestApi.ino
#include <NefryRESTAPI.h>
void setup() {
  NefryRESTAPI.begin();//REST APIを使うのに必要な初期化をおこないます。
}

void loop() {

}
```

書き込み終わったら次に進みましょう。
wifiの設定などもwebページから設定できるのでもしよければやっておきましょう。

## javascriptでコードを書こう

先ほどの設定でハードについては準備完了ですので、javascriptのコードを書いていきます。

今回のコードはすべてこちらにまとまっています。

>http://jsdo.it/wamisnet/63S4

<script type="text/javascript" src="http://jsdo.it/blogparts/63S4/js?width=465&height=496&view=screenshot"></script>

たとえば、バージョン情報についてはこちらをたたいています。

```js
$.post("http://192.168.4.1/api/version",
  "",
  function (data, textStatus, jqXHRn) {
    //リクエストが成功した際に実行する関数
      alert("Nefry Rest Api version: " + data.version);
  },
 "json"
);    
```

他には、NefryにはフルカラーLEDがついているのですが、それの制御をすることもできます！

```js
$.post("http://192.168.4.1/api/1.0/NefrysetLed",
  "r=255&g=0&b=0",
  function (data, textStatus, jqXHRn) {
      //リクエストが成功した際に実行する関数
      alert("Nefry Rest Api: " + data.mode);
  },
  "json"
);    
```

jsのコードは割とシンプルでNefryのAPIをjqueryでpostさせているだけですね。

### どんなAPIがあるの？

[dotstadioの記事](https://dotstud.io/blog/nefry-rest-api-tutorial/)によく使うAPIを掲載しています。

基本的な制御はそちらの記事を参照していただけるのですが、乗っていないものについても実装されてますので、ぜひぜひ[こちらのqiitaの記事](http://qiita.com/wamisnet/items/5483d14bf21cd3193ae0)をご覧ください。

## 動かしてみよう

jsdoitからNefryを制御しています。

<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">jsdoit(javascript)からNefryを制御してみた！ <a href="https://t.co/146jBE0pW4">pic.twitter.com/146jBE0pW4</a></p>&mdash; わみ (@wamisnet) <a href="https://twitter.com/wamisnet/status/806820023880687616">2016年12月8日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## まとめ

Arduinoが扱えなくてもjavascriptでうまい具合に制御できるので、ぜひためしてみてください！
JavaScriptを始めるに当たってのハマりポイント

はじめまして。BRIGHT VIEでサーバサイドのエンジニアをしている @lemonade14 です。

[BRIGHT VIE エンジニア Advent Calendar 2016](http://qiita.com/advent-calendar/2016/brightvie)の7日目の記事となります。

# 弊社の開発環境

弊社の最近の開発では、JavaScriptを中心とした技術でサービスの開発を行っています。

サーバサイドはNodeJS（ver6.0.0）、フロントエンドはAngularJS(1系)、アプリ側はSwiftを用いたWebViewで開発を進めています。

これまでJavaScriptと言えば、jQueryを中心としたUI構成やDOMのアクセス、
アニメーションの実行など簡単なものがメインでしたが、
近年のモダンな開発におけるJavaScriptは設計概念や言語仕様、パフォーマンスチューニングなど
JavaScriptのスキルもかなりレベルの高いものになってきていると感じています。


自分自身もここ1~2年ほど、JavaScriptのモダンな開発に着手し、
SPA（Single Page Application）での開発を続けてきましたが、
新規メンバーの参入やPHPなどのサーバプログラマーがJavaScriptを始めるにあたり、
「かなり苦労しているなぁ」とか「これ毎回教えているなぁ」と感じる部分について記載できればと思います。


# JavaScriptにおけるハマりポイント

## 非同期通信（Promiseについて）
PHPなどスクリプト言語をやられている方が
JavaScriptを始めた場合最初にあたる壁かと思います。

例えば下記のような処理

```
 1: function getLoginUser() {
 2:   return new Promise(function(resolve, reject){
 3:      // ここでDBアクセスなどでデータを取得したとるる
 4:      return resolve({loginCount:100});
 5:   });
 6: }
 7: 
 8: var staff = {};
 9: console.log('A');
10: getLoginUser().then(function(res){
11:   console.log('C');
12:   staff = res;
13: });
14: console.log('B');
15: console.log(staff.loginCount);
```

上記プログラムを実行した場合、PHP的な感じで行けば15行目のconsole.logでは、
「A -> C -> B -> loginCount:100」と表示されることを期待してしまいます。

非同期処理として処理がいつどのタイミングで実行されるのか、
Promiseの扱い方を理解するまで少し時間がかかるように感じました。

今回の例の場合だと「A -> B -> undefined -> C」と表示されます。

JavaScriptは上から順に処理を実行していくので、
9行目のconsole.logでAを表示した後に、
10行目のgetLoginUser()で処理のみ呼び出しを実施し、
14~15行目の処理が実行されます。
11~12行目は、getLoginUserの非同期処理が実施完了後、callbackで呼ばれるため、
14~15行目よりも後から実行されるという認識になります。


このあたりの非同期処理の基礎が身に付いてこれば、第一段階突破といった感じでしょうか。


## JSのシングルトンの扱い

JavaScriptには、クラスという概念が基本的には存在しないので、
新しくオブジェクトを作ればそれがシングルトンになります。

```
// アイテムのマスター情報と仮定
var Item = {
    name: 'アイテムA',
    point: 200,
  };
```


特に意識せずにオブジェクトを作成し、変数に入れて使い回しをしたときなどに
このあたりの仕組みを理解せずに利用しているとひどい目に合う場合があります。

上記例の場合で例えば下記のような販売する際には、アイテムの価格を100円にする
などの処理を入れた場合

```
// buyItemは販売用のアイテムとする
var buyItem = Item;
console.log(Item);
console.log(buyItem);
// 販売するアイテムは100円で割引した価格とする場合
buyItem.point = 100;
console.log(Item);
console.log(buyItem);
```

上記結果としては、

```
Object {name: "アイテムA", point: 200}
Object {name: "アイテムA", point: 200}
Object {name: "アイテムA", point: 100}
Object {name: "アイテムA", point: 100}
```

となり、buyItemのpointの値を変化しただけなのに、Itemのオブジェクトの中身も書き換えられてしまいます。

これは、同一メモリ領域に保存されているデータを参照しているため書き換え処理が発生しております。
そのため、データの書き換えなどを行う際には、
シングルトンの構造把握及びディープコピーの実施などを実施し、
マスターデータとなる実データを扱う場合には要注意となります。



## JavaScriptはシングルスレッド

非同期通信を走らせたとしても基本的にはJavaScriptはシングルスレッドで実行しています。
そのためUIの描画やDOM操作、アニメーションなどJSの処理に時間がかかる処理と
ロジックとして処理をゴリゴリ書く処理を並行して実行することが出来ず、
パフォーマンス面で影響が出る可能性があります。

最近では、ServiceWorkerを利用することでメインスレッドとは別で処理を実行できるようになるので
マルチスレッドっぽく並列で処理の高速化を目指した開発するにはServiceWorkerの利用がおすすめです。


## 最後に

まだまだプロトタイプチェーンやビルド周りの整備、ES2016やTypeScriptなど出せばキリがない部分ですが、
実践的に最初のステップをこえるためには上記知識は必要なのではないかと感じています。

自分たちの技術を高めていくことは、お客様や利用してくれる皆様に
より良いサービスを提供していけることにつながるため、
引き続き日々勉強を心がけて頑張っていけたらなと思います。
kubeadmが何をやっているのかみてみた

この記事は[Kubernetes Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kubernetes) 8日目の記事です。

# サクッとクラスタを組みたい！
マルチノードでのKubernetesクラスタを構築する方法はいろいろありますが、王道的な方法がなく、いろんな方法で皆さん構築されてるかと思います。
Version 1.4からkubeadmという大抵の環境で簡単にクラスタ構築できる仕組みが入りました。詳しい方法は、[こちらの記事](http://qiita.com/tkusumi/items/5908c91807107551e796)が参考になります。
まだalphaなので、本番投入するには怖い感じなのですが、何をしてくれているのかコードを読んでみました。

(とくにCSR周りが怪しいので、間違いがあれば、ご指摘お願いします)


# マスターの設定 (kubeadm init)

#### ノードの状態確認
ノード自身のIPアドレスが自動検出されます。
また、必要なサービスがインストール済みか、ポートが空いているか事前に確認します。[このあたり](https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/preflight/checks.go)のコードのRunInitMasterChecksあたりにチェック内容があります。


#### Manifestファイル作成
K8sの各コンポーネント(API Server, Controller manager, Scheduler)のマニフェストファイルを`/etc/kubernetes/manifests`配下に作成します。etcdのエンドポイントを指定しなかった場合、これも作成します。

#### PKI assets作成
K8sで使われる鍵やCAなどを`/etc/kubernetes/pki`にサクッと作ってくれます。opensslコマンド叩かなくていいです。

#### クライアント用設定/接続確認
`/etc/kubernetes/admin.conf`を作成した上で、作成したAPI serverに接続確認を行います。マスターにあるはずの3コンポーネントがあるかどうか確認したり、ダミーのPodをデプロイしてみて稼動確認までやってくれます。

#### kube-discovery立ち上げ
クラスタ情報をjoinしてくるノードに返すために、kube-discoveryなるものを立ち上げます。デフォルトでは9898ポートで待ち受けます。

```
$ kubectl get deploy kube-discovery --namespace=kube-system
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-discovery   1         1         1            1           1d
```
ノードがjoinするときにJWS(JSON Web Signature)を使ってクラスタ情報の署名をしています。その際に使うBearer TokenやAPI serverのエンドポイント、クラスタ用のCAをSecretとして保存します。

```
$ kubectl describe secret clusterinfo --namespace=kube-system
Name:		clusterinfo
Namespace:	kube-system
Labels:		<none>
Annotations:	<none>

Type:	Opaque

Data
====
ca.pem:			1025 bytes
endpoint-list.json:	25 bytes
token-map.json:		29 bytes
```

#### kube-proxy, kube-dns立ち上げ
kube-proxyはDaemonSet、kube-dnsはDeploymentで。kube-dnsのレプリカ数は1なのでこのノードが落ちたらDNSも落ちます。

#### 接続用情報表示

```
kubeadm join --token <tokenID>.<token> 192.168.0.2
```

無事に構築できるとこのクラスタにjoinするためのコマンドが表示されます。トークンはdotをセパレータとして前半がtokenID、後半がtokenとなります。

# ノードの追加 (kubeadm join)

ということでjoinしてみます。

#### ノードの状態確認
マスター構築時と同じようにサービスの状態確認が行われます。

#### クラスタ情報取得
マスターノードに立ち上げられたkube-discoveryに対して、tokenIDをパラメータとしてクラスタ情報を要求します。
kube-discovery側では、先に作成されているはずのSecretを参照してtokenIDに紐づくtokenがあるか確認します。あった場合は、API serverのエンドポイント情報、クラスタのCAを返します。
返ってきたクラスタ情報はtokenをキーとしてJWSで署名されています。joinする側はそれを検証して、そのエンドポイントに対してアクセスします。

#### TLSのセットアップ

Certificates APIに対してCSRを投げて、kubeletがAPI serverにアクセスするための証明書を受け取ります。CSRは以下のコマンドで確認可能です。

```
$ kubectl get csr
NAME        AGE       REQUESTOR          CONDITION
csr-xxxxx   1d       kubeadm-node-csr   Approved,Issued
$ kubectl describe csr csr-xxxxx
```

[ドキュメント](http://kubernetes.io/docs/admin/master-node-communication/#kubelet-tls-bootstrap)によると証明書は1年間有効(というか使用している[ライブラリ](https://github.com/cloudflare/cfssl/)のデフォルト値)です。期限きれる前に更新しないといけないはずなんですが、どう更新すればいいんでしょうね…

最後に`/etc/kubernetes/kubelet.conf`に設定を書き込んで終わりです。

# で、本番に使えそうなのか

テスト環境用に構築するのだとものすごく楽にできるのですが、本番で使おうとすると結局いろいろ設定しなおさないといけないのでオススメできないです。ただ、ちゃんと証明書もきちんとセットアップしてくれるので、どのようにKubernetesをセットアップするべきかというサンプルとしては面白いと思います。
S3からGCSへのコピーについて

この記事は [Recruit Engineers Advent Calendar 2016](http://www.adventar.org/calendars/1617) の8日目の記事です。

## はじめに
RLSの@byaです。本記事では、S3からGCSへコピーについて書きます

## 送る方法

GCSへ送り方が２つあるが、以下のような使い方が分かれる

* When transferring less than 1 TB of data, use [gsutil](https://cloud.google.com/storage/docs/gsutil).
* When transferring more than 10 TB of data, use [Storage Transfer Service](https://cloud.google.com/storage/transfer/).
* For between 1 and 10 TB of data, use either gsutil or Storage Transfer Service.

### 大きな違い

<img width="770" alt="Screen Shot 2016-12-08 at 19.07.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/72573/9471a86c-6251-1c80-3458-c7c6aa4aa74c.png">


## Cloud Storage Transfer Serviceで転送する

### 参考ページ

* https://cloud.google.com/storage/transfer/

### インターフェース

* Creating and Managing Transfers with the Console
* Creating a Storage Transfer Service Client
    * Python
    * Java
* Storage Transfer Service API

### 実験

データ内容 | ファイル数 | サイズ | コスト時間 | インターフェース
--- | --- | --- | --- | ---
圧縮された(*.gz)・ ログデータ |	16562 |	591.31GB | 11:48:48 ~ 13:18:40 (90分) |	Web UI console

### 課題

上記の実験から早いことが分かるが、APIを時間単位で呼ぶと、API制限にひっかかる

## "gsutil cp" コマンドで転送する

[gsutil](https://cloud.google.com/storage/docs/gsutil) はCLIツールです。ですので、サーバーが必要になります。今回は、「クラウド別による転送・CPUによる転送・Memoryによる転送」で実験してみました。


### クラウド別による転送

以下の環境で行いました！

環境	| cpu	| memory	| os
---| ---| ---| ---
local (docker)	| 2 CPU	| 2 GB	| Centos 7
[GCE](https://cloud.google.com/compute/)	| 4 vCPUs	| 16 GB	| Debian 8
[EC2](https://aws.amazon.com/jp/ec2/)	| 4 vCPUs	| 16 GB	| Centos 6.6
fha (独自サーバー)	| 4 CPU	| 8 GB	| Centos 6.5

実験

データ：圧縮された(*.gz), ログデータ 

ファイル数	| サイズ	| オプション| 	local| 	fha| 	EC2| 	GCE
---| ---| ---| ---| ---| --- | --- 
1 | 132.1 MiB | 	-m cp -r| | 1m19.628s| 1m2.164s| **0m22.274s**
48 | 	3.4 GiB	| -m cp -r| | 7m0.263s| 2m13.449s| **1m50.913s**
96 | 	6.3 GiB	| -m cp -r| | 11m51.083s | 4m39.063s| **3m4.146s**

### CPUによる転送

CPUの個数を色々変えて転送してみます。

環境：GCE （memory = 8 gb, zone = asia-northeast1-a）
データ：圧縮された(*.gz), ログデータ 

ファイル数	 | サイズ	| オプション	| CPU = 1	| CPU = 2	| CPU = 4	| CPU = 8
---| ---| ---| ---| ---| ---| ---
1	| 	132.1 MiB| 	-m cp -r| 	0m19.914s| 	0m20.266s| 	**0m20.632s**| 	0m21.392s
48	| 3.4 GiB| 	-m cp -r| 	2m56.895s| 	2m14.262s| 	**1m49.925s**| 	2m4.989s
96	| 	6.3 GiB	| -m cp -r	| 4m51.639s	| 4m6.444s	| **3m0.520s**	| 3m37.409s

### Memoryによる転送

CPUの容量を色々変えて転送してみます。

環境：GCE （ cpu = 4 , zone = asia-northeast1-a）
データ：圧縮された(*.gz), ログデータ 

ファイル数 | 	サイズ	| オプション| 	メモリ=4gb| 	メモリ=8gb| 	メモリ=16gb| 	メモリ=26gb
---| ---| ---| ---| ---| ---| ---
1	| 	132.1 MiB| 	-m cp -r| 0m20.650s| 0m20.718s| 0m21.316s| 0m21.220s
48	| 	3.4 GiB	| -m cp -r| 2m2.060s| 1m57.305s| 1m50.478s| 2m6.267s
96	| 	6.3 GiB	| -m cp -r| 3m10.678s| 3m19.626s| 3m2.745s | 3m15.855s

## まとめ

* [Storage Transfer Service](https://cloud.google.com/storage/transfer/)は速度は早いが、API制限がある
*  [gsutil](https://cloud.google.com/storage/docs/gsutil)は、環境の影響によって速度が異なる。第三の環境で実施すると遅い(fha/local)。AWS or GCP のサーバーなら大丈夫が、GCPがベッター
* CPU増加で速度改善が見込めるが、おおよそで4CPUあたりが適正値
* Memoryの影響があまり見えなかった
Selenideでテストコードを書いてみた

# はじめに

E2EテストをSelenideで実装していたので、簡単に使い方のメモを残しておきます。

# Selenideとは

* WebページをUIテストのためのSeleniumをWrapperしたJavaライブラリ
* ブラウザの設定などはライブラリ内でデフォルトを設定している
* 公式サイト(http://selenide.org/)

# UIテストの流れ

UIテストの大まかな流れとしては以下の順番になります。
1. ページを表示
2. 画面操作
3. 結果を確認

UIテストの流れをSelenideでコード化すると以下の通り

```java
    Selenide.open("URL");  // ページを表示
    Selenide.$("#textarea").setValue("Hello World");  // テキストエリアに文字を挿入
    Selenide.$("#button").click();  // ボタンをクリック
    Selenide.$("#result")shouldHave(text("Success!")); // 結果を確認
```

# とりあえず動かしてみる

* 実装環境
    * IntelliJ Idea15
    * Java8

* 事前準備
    * gradle.dependenciesにSelenideライブラリを追加

    ```txt 
    dependencies {
      testCompile 'com.codeborne:selenide:4.1'
    }
    ```

    SeleniumやWebDriverなどの依存関係があるライブラリもインストールされる。

* サンプルソース

```java
    import com.codeborne.selenide.Selenide;


    public class SampleTest {
        public void test() {
            Selenide.open("http://example.com");
            Selenide.$("input[type=textarea]").setValue("Hello World!");
            Selenide.$("input[type=button]").click();
        }
    }
```

実行してみると、Firefoxが起動され、`Selenide.open("URL")`で指定したWebページにアクセスされました。

* 他に画面操作に関するAPI

    ```java
    Selenide.refresh();
    Selenide.close();
    Selenide.doubleClick();
    Selenide.hover();
    Selenide.submit();
    ```
 


# テストコード

Selenideでアサーション用のメソッドも提供されている。

```java
    import com.codeborne.selenide.Selenide;
    import com.codeborne.selenide.Condition;


    public class AssertionTest {
        public void test() {
            Selenide.open("URL");
            Selenide.$("input[type=textarea]").setValue("Hello World!");
            Selenide.$("input[type=button]").click();
            Selenide.$("img").should(Condition.disappear);
            $("#message").shouldHave(text("Hello World!"));
        }
    }
```


JUnitでもアサーションをすることが可能

```java
    import com.codeborne.selenide.Selenide;
    import org.junit.Test;

    import static org.hamcrest.CoreMatchers.is;
    import static org.junit.Assert.assertThat;

　　　　　　　　＠Test
    public class AssertionTest {
        public void test() {
            Selenide.open("URL");
            String browserTitle = Selenide.title();
            assertThat(browserTitle, is("Title"));
   
            Selenide.$("input[type=textarea]").getText();
            assertThat(textArea, is(""));
            Selenide.$("input[type=textarea]").setValue("Hello World!");

            Selenide.$("input[type=button]").click();
            Selenide.$("img").should(Condition.disappear);

            $("input[type=textarea]").shouldHave(text("Hello World!"));
        }
    }
```

# 実装中にハマったこと

* あるWebページから呼び出した子ウィンドウ内のCSS要素を取得できなかった

    → `Selenide.open()`から別ウィンドウを呼び出す際に`Selenide.switchTo.window(index)` で操作対象のウィンドウを切り替える必要があった。

* UIテストで使用するブラウザに対するオプション設定がSelenide内ではできなかった

    → 自分でWebDriverを用意して、`DesiredCapabilities`からオプション項目を設定し、WebDriverを起動する必要があった。(このあたりは調べきれていないので、正しいかどうか不明)

# 感想
WebDriverの設定やブラウザの操作(テスト終了後に閉じる、接続のタイムアウト)などは、Selenide側の初期処理や設定値が適用されるので、実装時には考慮しなくて済み、テストコードの作成に注力できると感じました。
Selenium側で要素のxPathを取得してブラウザ操作するより、jQueryライクにCSSセレクタで要素を指定できるので、テストコードの作成は実装が楽でした。
まだまだ触りたてなので、間違ったやり方やよい実装方法などあれば教えてください。
モデルのメソッドを利用してjson化したい

内部APIを作成しているときに、ふとモデルのメソッド実行したいなと。


```ruby

class User < ApplicationRecord
  def name
    first_name + last_name
  end
end

```

こんな感じのメソッドがあったとして、nameをjsonで返したい！

簡単にできます。

```ruby

User.all.limit(5).as_json(methods: [:name])

=begin

# 結果
 [
  {
    "id"   => 1,
    "name" => "テスト太郎",
    ~~
  },
  ~~
 ]

=end

```

すんなりできたので感動した!!

参考:
http://stackoverflow.com/questions/10821138/custom-model-method-that-should-be-included-in-json-serialization
Hyperloop 2.0の設定・iOS初級編

いきなりですが、今年はあんまりモジュールを書いていません。それだけありもので十分になってきたということでもあるのですが、それより何よりProアカウントを買ったのでHyperloopが使えるため、ちょっとした広告SDK程度のことならあまり気にしなくてもいいようになってきたのが大きいです。

それに、SDKに同梱されるモジュール自体も結構増えているんですよね。Httpsとか、CoreMotionとか、Geofence、NfcにSafariDialog、TouchIdからURLSessionなんてのもありますのでいつか紹介したいと思います。そう、（一部は）Proアカウントならね。

Hyperloopを使ってる人ってどれくらいいるのかわかりませんが、個人的に細々と使っています。本当はベータ版の時に作ったSocket.io（1.4以降に対応）を紹介しようと思ったのですが動かなくなったので、直すついでに調べた設定方法を説明していきます。

Hyperloopを利用するプロジェクトの作成は、CLIからはとても簡単です。質問にYと答えるだけな上にデフォルトの回答がYだからです。（そう、Proアカウントならね）

```bash
$ appc new
Appcelerator Command-Line Interface, version 6.0.0
Copyright (c) 2014-2016, Appcelerator, Inc.  All Rights Reserved.

? What type of project are you creating? Native App (app)
? Which SDK would you like to use? Titanium SDK (JavaScript)
? What's the project name? HyperloopTest
? What's your application id (example: com.myapp)? app.test
MobileWeb platform has been deprecated and will be removed in 7.0.0.
? Would you like to enable native API access with Hyperloop for this app? Yes

*** new completed. ***
```

生成されるtiapp.xmlにはもうモジュールが追加されています。

```xml
  <modules>
    <module platform="android">hyperloop</module>
    <module platform="iphone">hyperloop</module>
    <module platform="commonjs">ti.cloud</module>
  </modules>
```

もちろんPluginもロードされています。

```xml
  <plugins>
    <plugin version="1.0">ti.alloy</plugin>
    <plugin>hyperloop</plugin>
  </plugins>
```

それから、ビルド時にこちらの方がいいよとメッセージにあったので、iOSディレクティブにJSCoreを使うよう指定します。

```xml
<ios>
    <use-jscore-framework>true</use-jscore-framework>
```

さあ、準備ができました。

そこで、本日これから作成するのは、CallKitに対応した新しいTwilioのiOS SDKです。そう、まだベータ版で本家のChangelogにはさっぱり何も書かれていないのになぜか日本のTwilioのChangelogにはバッチリ載ってる（ので見落としていました！）、iOS 10以降の機能VoIP Pushなどに追随した新しいSDKです。急に話が大きくなって自分でもびっくりですが、大きな車輪は一度回し始めたらなかなか止まらないものです。気にせず先に進みます。

Twilio SDKの中身はframeworkになっているので、これをプロジェクトに設置します。ここからいきなりカスタマイズしてしまいます。サードパーティーのライブラリなどを利用する場合は`appc.js`という設定ファイルを用意します。

```js
module.exports = {
  hyperloop: {
    ios: {
      xcodebuild: {
        frameworks: [
          'CallKit',
          'PushKit'
        ]
      },
      thirdparty: {
        'TwilioVoiceClient': {
          source: ['src'],
          header: 'src',
          resource: 'src'
        }
      }
    }
  }
};
```

プロジェクトのディレクトリ直下にsrcというディレクトリを置いて、そこに`TwilioVoiceClient.framework`をコピーすればOK。他にもCallKitやPushKitのような組み込みのフレームワークを使いたい場合はxcodebuildプロパティに設定します。

JSのプログラム内ではObj-Cの`import`の代わりにrequireを利用します。

```js
var tvc = require('TwilioVoiceClient');
```

これで呼び出しが可能になりました。あとはフレームワークの流儀に乗っ取って作っていくだけ、なのですが、Delegateの指定などはObj-Cのクラスを生成することで対応しなければいけないようです。

https://github.com/appcelerator/hyperloop-examples/blob/master/app/lib/ios/subclasses/locationmanagerdelegate.js

うん、ちょっと今日はまだ仕事が忙しくてそこまで書けてないんだ！また続きを書くね！いや近所のおじさんのお誕生日に呼ばれちゃってさ、じゃあね！
DeepLearningってそもそもどういう問題なのか勉強してみた

# はじめに #

この記事は、DeepLearning初心者が自分の理解の助けとするために、書いた記事です。
要するに一切の前提知識がないまま書かれているので嘘かもしれませんし。間違っている可能性があります。

小学生的に言えばDeepLearningの本を読んで分かったこと。と言った感じの記事です。

# DeepLearningは答えを推定する問題ではない #

DeepLearningが一つのバズワードになってます。
で、僕も流行に乗っちゃうぞーってことで「ディープラーニング 入門」でぐぐってみたわけで…

こんなのとか
[いまさら聞けないDeep Learning超入門（1）](http://www.atmarkit.co.jp/ait/articles/1510/27/news008.html)

こんなのとか
[そもそもディープラーニングとは何か？](https://thinkit.co.jp/story/2015/08/31/6364)


つまりDeepLearningとは何か知らないけどたくさんの入力で学習して答えが未知の$x$に対して正しい推定値$ \hat{d} $を推定する問題なんだな。
と思いました。

で、じゃあ数理モデルは？といったところなかなか情報がなかったので本買って読んでいるのですが。
実はDeepLearningというか学習というのは**入力の答えを推定する問題ではない**ということを理解しました。
それは、結果であって目的ではないです。

じゃあ目的は？というのがこの記事の本論です。

# DeepLearningの目的 #

DeepLearningの目的が**入力の答えを推定する問題ではない**のだとしたら、何なのでしょうか。
僕の理解としては一言で言えば**入力の答えを推定するための関数（手続き）を構成する問題**です。

なんていうことでしょう。学習というのは推定するのは答えではなかったのです。
推定器や復号器の構成問題と理解したほうが良かったのです。

続けて、一体どういう問題なのかという話。

# DeepLearningのモデル #

さて、少し調べていくとこんな感じの図がある。
(graphvizで下付き文字作る方法あればお教えて下さい…)

これについて理解していきます。

![dl1.png](https://qiita-image-store.s3.amazonaws.com/0/77177/b4b18952-b1f0-1349-4784-dbf412030630.png)


ここでは、よく見るたくさんの手書きの数字の画像を0～9に振り分ける問題を考えることにします。
（以下暗黙で$\bf{x}$も$\bf{y}$いい感じに次元を拡張して議論します。他の文字も同様に…）

## 入力xと出力yの理解 ##

まず$\bf{x}=(x_{1},x_{2},x_{3},...)$これはもちろん入力ここで言う手書き画像に当たり、
学習中はこれに正解$d$を人間が教えます。つまり学習中は$(\bf{x},d)$のペアを入力していく形になりますね。

次に$\bf{y}=(y_{1},y_{2},…)$これは$d$が$i$である確度、要するに$y_{i}$が大きければ大きいほど$d$は$i$と推定される。
以下$y_{i}$は正規化されていることにします。つまり$ \sum_{i} y_{i} = 1 $としましょう。

ここまでで、学習の目的は任意の$(\bf{x},d)$を入力したときに正しく$y_{d}$が1に近づき$y_{i} (i \neq d)$が0に近づくようにしたい。

人間が1と書いた画像$x$を入力した時は$\bf{y}=(0,1,0,0,0,0,0,0,0,0)$になって
人間が2と書いた画像$x$を入力した時は$\bf{y}=(0,0,1,0,0,0,0,0,0,0)$になって…
となって欲しいということがわかってきました。(あくまで理想)

じゃあどうやって近づけるかということが問題になってきますね！
ここを理解すれば、DeepLearningって何ということの理解になる！はず！

## パラメータベクトルwの理解(大事) ##

ここでどうやって学習するのかをイメージします。
上の図で四角で囲ったノードは推定のためのノードです。
ここで何が行われるのかを理解していきます。

まずnode$i$に入ってきた$\bf{x}$から以下のように$u_{i}$を求めます。

```math
u_{i} = \bf{x}\cdot\bf{w}_{i}+b
```

要するに$\bf{w}_{i}$との内積取っていい感じにするためのバイアス$b$を足します。

更に学習を設計するときに決めた(活性化)関数$f_{i}$を$u_{i}$に適用してこのノードの出力$z_{i}$を決定します

```math

z_{i}=f_{i}(u_{i})

```

# yの決定 #

ここまででノードの計算方法がわかりました。
今回はノードが1層しかないので各$z_{i}$を正規化して最終出力$\bf{y}$を得ます。

そして各$y_{i}$の中で最も大きい$y_{i}$が$y_{\hat{d}}$であったとき推定する答えが$\hat{d}$となるわけです。
でこれが$\hat{d}=d$なら完璧！最高！

ふう、わかったぞ

# DeepLearningの目的 #

ここまでで僕達が自由に決めることのできるパラメータが分かります。

それは各ノードの$\huge{\bf{w}}$ですね。（あとバイアス$b$）

ということは学習の目的は、この$\huge{\bf{w}}$を決定することです。
これでこの記事の結論がでました。

ということは学習の目的は、$\huge{各ノードの\bf{w}を決定すること}$。

# おまけ #

今回は1層だけなのでDeepLearningではないのでちゃんとDeepLearningな図

![dl2.png](https://qiita-image-store.s3.amazonaws.com/0/77177/7e8482b9-12ce-67f2-3f79-86790e9ca36a.png)

で、どうやって学習するかって？
勉強中…
エクセルを使いこなそう①

下請けCOBOLERとして生きていた頃のノウハウ Advent Calendar 2016の６日目の記事です。


###レガシーな現場では全てがエクセルで作られる

COBOLの下請け現場ではエクセルを使いこなす力が重要になります。



・無駄にでかくて見づらい表はまずは、ヘッダー部分を固定する
・空白しかない行、灰色に塗られた行はグループ化でたたみ込む
・印刷する際はなるべくA4一枚に収まるように、余白の削除等を行う

このような作業をして、なるべく、自分の目に見える範囲で必要なものが見えるようにしましょう。


注意点としてはそういう状態で勝手に保存すると気を利かせたつもりでも怒られるかも知れません。

あくまでも自分のローカルでだけそう言う形にして、共有ドライブへの保存はしないように気をつけましょう。
Cognos BI レポート表示を自動リフレッシュする

Cognos BIで、刻一刻と更新されるデータをリアルタイムにレポートに表示できないか、というご相談を良く受けます。

基本的にHTML Itemに定期的にレポートを再実行するJavaScriptを仕込むしかないのですが、実装をご紹介します。

**自動反映イメージ**

レポート実行初期イメージ
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/0899ab72-dcbc-2aca-51d9-21871478170b.png)

裏のデータベースのデータ更新
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/2e94f5a8-3e93-a2bf-cb19-ff5863c53e5f.png)

5秒に一回、レポートが再実行される
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/22f50e11-05b2-3197-b775-81a517b3732d.png)

レポートに反映された結果
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/4df69614-4dfa-7cb9-9237-152257b3849a.png)


という動作で、リアルタイムではないのですが、5秒に一回リフレッシュは可能です。

**実装方法**
レポート中にHTML Itemを置いて、以下のコードを記載下さい。

\<script type="text/javascript"> 
var intval; 
var fW = (typeof getFormWarpRequest == "function" ? getFormWarpRequest() : document.forms["formWarpRequest"]); 
if ( !fW || fW == undefined)   
{
fW = ( formWarpRequest_THIS_ ? formWarpRequest_THIS_ : formWarpRequest_NS_ );
} 
var preFix = ""; 
if (fW.elements["cv.id"]) 
{
preFix = fW.elements["cv.id"].value;
}     
var nameSpace = "oCV" + preFix; 
if(intval!="") 
{
self.clearInterval(intval); 
intval="";
} 
self["RunReportInterval"] = self.setInterval( nameSpace + ".getRV().RunReport()",'5000' );
intval = self["RunReportInterval"]; 
\</script>


**参考文書**
こちらを参考にしています。IE11やCognos Analytics、Cognos BI 10.2.2でも動作確認済みです。
**JavaScript: Setting reports to auto refresh in Cognos Viewer with IE 6 or 7**
http://www-01.ibm.com/support/docview.wss?uid=swg21342426

こちらのTechnoteもあるのですが、動作がイマイチ安定しませんでした。ご参考まで。
**Prompt API - Auto refresh a report in the Browser / Web with a timed interval**
http://www-01.ibm.com/support/docview.wss?uid=swg21646893
頑張ってハックしたら多方面からお叱りを受けた話

この記事は[おうちハック Advent Calendar 2016](http://qiita.com/advent-calendar/2016/ouch-hack)7日目の記事です。（遅刻ゴメンなさい・・！）

「マイコンボードってなに？」というIoT超々初心者のウェブエンジニアがやっちまった話をします:raised_hands: 

## ことの発端
[IoTLT](https://iotlt.connpass.com/)というIoTの成果物を持ち寄るイベントで、がじぇるねの方に「使ってください！」とマイコンボードをいただきました。
<img width="359" alt="スクリーンショット 2016-12-08 19.12.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/119003/1644f986-939d-9ea5-e99e-460a5791ffc6.png">

マイコンボードを見るのはこの時が初めて！

* Webコンパイラでかけるよ
* 有線LANが直接させるよ

という初心者向けなボードをいただいたようです。
ピンクでなんか可愛いくらいしか正直わからなかった。

## 実現したかったこと
「お風呂が溜まったら知らせてくれる装置」
![スクリーンショット 2016-12-08 12.54.39.png](https://qiita-image-store.s3.amazonaws.com/0/119003/38753c66-c8bd-4ee4-cd85-21b93c77981b.png "スクリーンショット 2016-12-08 12.54.39.png")


身近なIoTといえばおうちハックなので、ずっと困っていたことを解消することにしました。

* 水はセンサー+マイコンで割となんとかなりそう
* とりあえず有線LANでサーバに飛ばせそう
* 給電もとりあえずなんとかなる

これは結構サクッといけるのでは・・！？という楽観的な見通し。

## 実装
![スクリーンショット 2016-12-08 12.52.11.png](https://qiita-image-store.s3.amazonaws.com/0/119003/50dc25d7-d084-ea32-8e99-e07b2dabd0d8.png "スクリーンショット 2016-12-08 12.52.11.png")


GROVE水センサー + GR-SAKURA + Node.JS + Milkcocoaで実装。
マイコンへの書き込み自体はWebコンパイラでとっても簡単:raised_hands: 

## 完成品
サクッと完成したものがこちら。
![スクリーンショット 2016-12-08 12.57.48.png](https://qiita-image-store.s3.amazonaws.com/0/119003/02d147cb-191e-c36d-1455-eb3301ee02ee.png "スクリーンショット 2016-12-08 12.57.48.png")
※真似しないでください。

## めちゃくちゃ怒られた
この装置、先述のIoTLTで発表したのですが。
有識者の面々に「君死にたいんか」とお叱りを受けました:innocent:

もちろんマイコンボード程度で感電死はさすがにないと思うのですが、マイコン・センサ・Macもろもろ「やばい」状態ですよね。

ちなみに家のLANポートの関係から有線LANはこんな感じ。最凶アイテム10mLANケーブル。
<img width="635" alt="スクリーンショット 2016-12-08 19.26.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/119003/8dfbd199-fb4d-9e17-dd3a-ba80f669d919.png">


## まとめ
そういえば電気と水ってやばいなあって言われたらわかるのですが、誰も「防水大事！」とか「むき出しはないわ」とか教えてくれなかった・・！（常識）

IoTって実装部分以外での参入障壁、結構あると思います（´・ω・｀）
未だに秋葉原で部品買うのめっちゃ怖いし。。（全員玄人に見える）

大変お叱りを受けたハックとはなりましたが、これをきっかけに有識者の面々からたくさんのアドバイスをいただくことができました:bow:
そして有識者の皆様、初心者に常識は通用しないのでどうか生暖かくご指導ください:bow::bow:

でも、楽しいからとりあえず死なない程度にやってみようず ＼(^o^)／

<iframe src="http://www.slideshare.net/YukaTokuyama1/slideshelf" width="615px" height="470px" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:none;" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>