OmniAICreator/Qiita-1.07M huggingface dataset:
SQLite よりもサクッと扱える NeDB さん！

経緯
====

Node.js を使っていて、ちょっとDB使いたいなーと思うこと、ありますよね。
で、 ```npm install sqlite3``` とかやろうとするわけですよ。
そんで、Pythonとか入れてないから node-gyp で **ERR** になるわけですよ。

JavaScript 使いとしては node-gyp のめんどくささはとてもつらいです。
Python 2 と 3 の戦争に巻き込まれるのは御免ですしネイティブのビルドなんてまっぴらなんです。

なので、 Node.js で SQLite のようにアプリに内蔵してサクッと使える DB を探したところ、出てきたのが NeDB でした。

NeDB
====

https://github.com/louischatriot/nedb/

SQLite やだーして出てきた NeDB さん。

どういう DB かというと、 **組み込みで、永続化でもインメモリでも使えて、Node.js・nw.js・Electron・ブラウザーで動く 100% JavaScript でバイナリ依存が一切無い** とのことです。
APIはMongoDBのサブセットで、十分に速いそうです。 ([公式文章](https://github.com/louischatriot/nedb/)ほぼそのまま訳)

インストールは超簡単で、 Node.js ならほかの依存ライブラリと同様に
```npm install nedb --save```
するだけです。

使い方もサクッとやりたいことだけできます。

```
import * as Datastore from "nedb";

let db = new Datastore({ filename: "nedb.db", autoload: true });
db.insert({ hoge: "hoge", fuga: "fuga" }); // 適当なオブジェクトを保存
db.findOne({ hoge: "hoge" }, (err, document) => {
    console.log(document); // 保存したオブジェクトが取り出せる
});
```

実際に使ってみたものが[こちら](https://github.com/progre/mitaqiita)になります。
Qiita の新着1万件の文字数 / ストック数を調べる簡単なプログラムですが、Qiita API のリクエスト結果を NeDB にガシガシ溜め込んで、再実行したときのリクエストを節約してみました。

こんな感じで、 NeDB は DB をサクッと使いたいときにとても便利なのではないでしょうか。
Ubuntu16.04LTSにCUDA7.5とcuDNNとCaffeをインストール

## CUDAのインストール
まずは「ソフトウェアとアップデート」の「追加のドライバー」からNVIDIAのドライバをインストールする．
バージョンが分かっていれば自分で，

```
sudo apt-get install nvidia-361
```
とかやってもOK．

NVIDIAのサイトには16.04版はまだ無かったので，今回はパッケージからインストール

```
sudo apt-get install nvidia-cuda-toolkit
```

## cuDNNのインストール
NVIDIAのサイト(https://developer.nvidia.com)からcuDNNをダウンロード．
ダウンロードするためには開発ユーザ登録が必要です．登録が完了するまでに1,2日かかります．

ダウンロードしてきたcudnn-7.0-linux-x64-v4.0-prod.tarを展開して，include/cudnn.hを/usr/includeの下にシンボリックリンク．同様にlib64/以下のファイルも/usr/libの下にシンボリックリンク．
(コピーするとあとで入れ直すときに面倒なので，シンボリックリンクにしておきました．)

```
cd ~
tar xf cudnn-7.0-linux-x64-v4.0-prod.tar
cd /usr/include ; sudo ln -s ~/cuda/include/cudnn.h .
cd /usr/lib ; sudo ln -s ~/cuda/lib64/* .
```

## caffeのソースコードのダウンロード
```
sudo apt-get install git
mkdir tmp; cd tmp
git clone https://github.com/BVLC/caffe.git
```

## 必要なパッケージの取得
~/tmp/caffe/docs/install_apt.mdに色々書いてあるので基本的にはそれを守っていれば大丈夫

```
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
```

pycaffe用

```
cd ~/tmp/caffe/python
for req in $(cat requirements.txt) ; do pip install $req ; done
```

## CMakeLists.txtの修正
このままmakeするとmemcpy関係でコンパイルエラーが出るので，~/tmp/caffe/CMakeLists.txtを編集．
ファイル内の
```set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall")```
を，
```set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORCE_INLINES -fPIC -Wall")```
と変更する．

## make
```
cd ~/tmp/caffe
mkdir build; cd build
cmake -D CMAKE_INSTLL_PREFIX=適当な場所 ..
make -j
make runtest
make install
```

## PATHとか
~/.bashrcあたりに以下を追記しておきます．

```~/.bashrc
export CAFFE_HOME=caffeをインストールした場所
export PATH=${CAFFE_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=${CAFFE_HOME}/lib:${LD_LIBRARY_PATH}
export PYTHONPATH=${CAFFE_HOME}/python:${PYTHONPATH}
```

追記後はsource ~/.bashrc を忘れずに．
Apple Developer Programの登録住所の変更方法


引越しにより住所が変わり， **Apple Developer Program**の登録住所を変更しようとしたときのメモ(2016年5月の情報です)

# 手順
するべきことは，大きく分けて2つです．

* 登録情報の更新要求
* 身分証明書のアップロード


## 登録情報の更新要求

まずは[Member Center](https://developer.apple.com/account/)へアクセス．

その後，左サイドバーの **Program Resources**メニューから **Membership**を選択します．

![01.png](https://qiita-image-store.s3.amazonaws.com/0/35230/e5a1290e-00a4-63a9-2c91-f9c507935829.png "01.png")

そうすると **Membership Details**が表示されるので，下端の **Need to edit this information?**を選択します．

![02.png](https://qiita-image-store.s3.amazonaws.com/0/35230/ae336cfa-4a50-4ebb-a0d4-e39c3cf7337d.png "02.png")

**Editing Your Membership Information**というポップアップが表示されるので，2つあるリンク先の初めの方 **Provide your updated information**を選択します．

![03.png](https://qiita-image-store.s3.amazonaws.com/0/35230/9d897423-3a0c-eb9c-be4d-12590881ad51.png "03.png")

表示されたフォームに入力していきます．

![04.png](https://qiita-image-store.s3.amazonaws.com/0/35230/98543e76-ae12-3c4a-64c7-d80a201ace65.png "04.png")

**Region**には日本国内在中なら **Japan(日本語)**を選択します． **Enter your updated information**には新住所を英語で記述します．この際，英語住所への変換に[JuDress](http://judress.tsukuenoue.com/)というサイトを利用しました． **Reason for update**には更新理由を記述します．「I moved.」という旨のことを書いておけばいいかと思います．

営業状況にもよりますが，0〜2日ほどでAppleさんからメールが来ます．


## 身分証明書のアップロード
Appleさんからのメールは日本語でした．おそらく， **Region**で選択した国の言語でメールが送られるものだと推察します．

メールにて，指定のURLのアップローダへ身分証明書をアップロードするよう要求されます．同時に，アップロードが完了したら，その旨と英語の新住所をメールで改めて返信するよう要求されます．

身分証明書として有効なものは次の通りです．自分は運転免許証をスマフォで撮影したJPEGデータを使用しました．

1. 新しい住所を示す、公的に発行された身分証明書のコピー
1. 郵便局に提出した住所変更届け

アップロードは基本 **Safari**で行うようにしてください．なお，アップロードする際，オプションでデータの説明を入力するフォームがあるのですが，そこを日本語で書くとエラーが発生し，アップロードを完了できませんでした．説明を入力するなら **英語**で．

と，ここで問題が，自分は運転免許証の，新しい住所情報が追記された裏面のみをアップロードしたのですが，Appleさんから「住所の確認はとれたけど，本人確認もするので表面も改めてアップロードしてね」という旨のメールが届きました．

メールに従い，改めてアップロード．晴れて登録住所の更新が完了しました🎉🎉🎉🎉
まっさらなUbuntu16.04LTSにOpenCV3.1とopencv_contribをインストール


※[2017/05/24] ソースコードの修正が不要になったので修正

GWで少し時間がとれたし，Ubuntu16.04LTSがリリースされたので手元のマシンにインストールしてみました．

## パッケージの更新
```
sudo apt-get update
sudo apt-get upgrade
```

## ソースのダウンロード
```
sudo apt-get install git
cd ; mkdir tmp ; cd tmp
git clone https://github.com/Itseez/opencv
git clone https://github.com/Itseez/opencv_contrib.git
```
ダウンロードに時間がかかるのでコーヒーでも飲みながら待つ．

## CUDAのインストール
NVIDIAのグラボを詰んでるマシンなので，CUDAもインストールしておきます．

## OpenCVのビルドに必要なパッケージのインストール
```
sudo apt-get build-dep opencv
```
でいけますが，まっさらなUbuntuだとソースが指定されていないぞと怒られるので，/etc/apt/sources.listの以下の行のコメントを外しておきます．
```deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial universe```
ついでに
```sudo apt-get update```
してから，改めて
```sudo apt-get build-dep opencv```
します．
ここでnvidia-opencl-devが入っているとパッケージが削除されてocl-icd-opencl-devが代わりに入るので，nvidia-opencl-devを再度インストールしました（これでいいのかは自信なし）．
```sudo apt-get install nvidia-opencl-dev```

不要かもしれないけどVTKとGlogをインストール．
```sudo apt-get install libvtk6-qt-dev libgoogle-glog-dev```

## CMakeLists.txtの修正
このままmakeするとmemcpy関係でコンパイルエラーが出るので，~/tmp/opencv/CMakeLists.txtを編集して，先頭に以下を追加
```set(CMAKE_CXX_FLAGS "-D_FORCE_INLINES ${CMAKE_CXX_FLAGS}")```

## make
```
cd ~/tmp/opencv
mkdir build ; cd build
cmake -D WITH_TBB=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ ..
＃CUDAインストールしてたので実際は，
cmake -D WITH_CUBLAS=ON -D WITH_TBB=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ ..
make -j
sudo make install
```
makeには時間かかるのでおやつでも食べに行きましょう．

<!--
おやつから帰ってくると，
opencv_contrib/modules/tracking/include/opencv2/tracking/onlineMIL.hppの57行目でエラーが出て死んでます．
どうやらsignマクロが悪さをしているようなので，onlineMIL.hppの57行目の
``` #define  sign(s)  ((s > 0 ) ? 1 : ((s<0) ? -1 : 0))```
を
``` #define  sign2(s)  ((s > 0 ) ? 1 : ((s<0) ? -1 : 0))```
とでもしておいて，
opencv_contrib/modules/tracking/src/onlineMIL.cpp 310行目と339行目で呼び出されているsign関数を先ほど変更した関数名(sign2)にする．

改めてmake

```
make -j
sudo make install
```
-->

使用例はまたそのうちに．
Docker Private Betaを使ってみた。

Qiitaはずっと見てるだけの人でしたが、最近暇ができたのでアップロードしてみます。ちなみにPC初心者です。Officeすらまともに触れません。
自分のメモ用に
まだ構築途中
# インストールしてみる
Macなんか持ってないんでWindowsで
自分の仕事用ノートPCにWorkstation Pro を入れてその中にWindows10 Insider previewを構築(Bashも使ってみたいんで)

## For Windowsをインストール
メールのURLからダウンロード
InstallDocker.msiを起動してインストール
とりあえず一回目は失敗した。
スクショも撮り忘れていろいろダメダメな状態。
### 一回目
1. Hyper-Vを有効にしていなかったので、有効にしますかとメッセージが表示したのでYes。
2. その後、再起動するとアクセストークン入力してねとメッセージが表示したのでコピペ
3. その後何故か起動しない。。。VMゲストの仮想化を有効にするの忘れてた。有効にしてくる。
4. 再起動したら、BSOD(マジカヨ)
5. 何回か自動で再起動してたらOS立ち上がったけどDockerがうんともすんともいわないのでのでやり直しすることに(エラーすら吐かねー)
スナップショットも撮り忘れてまた一から構築とか＼(^o^)／グダグダすぎる。

### 二回目
構築し直してきたよ。
先にVMゲストの仮想化を有効にしてきた。
結局起動しない。
![Docker-bug1.png](https://qiita-image-store.s3.amazonaws.com/0/72117/7aeed5ed-3fe4-df8b-c88e-8fdbe33fa3f9.png)
初期化が一向に終わらないのはなんでだろう。
普通に自分のPCに入れてみたいけど、Workstationとの兼ね合いもあるから微妙だな。。。

### 三回目
展示会などで忙しくしばらく触っていなかったがやっと起動した。
Window10を再構築、今度はInsider Previewではなくビルド10586で行いました。
普通にインストールして普通に起動した。
なんの障害もなく普通に動いたことに感動。
これでとりあえずDockerを勉強しますか。
後はお家に帰ってMacで試してみます。
SQLでカスタムフィールドに入っている日付形式を変更する

# はじめに
WordPressのカスタムフィールドで扱う日付形式を変更する必要がありました。
現在は年月日が一続きになっている、`yyyymmdd`という形式でした。
システムの変更に伴い、ソートや比較のやりやすい、`Y-m-d`形式に統一することになりました。
この変更をSQLで行いました。

# 現在と目標

WordPressのカスタムフィールドに入っているデータを確認します。

```sql
select *, DATE(meta_value) from wp_postmeta
where meta_key = 'openday'
      and DATE(meta_value) is not null
```

<img width="505" alt="Screen Shot 2016-05-06 at 5.03.26 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/f446142f-1056-3d43-d625-36d9becc22cd.png">



`where DATE(meta_value) is not null`とすることで不正な値をフィルタできます。

# UPDATE

これをUPDATE文にかけます。

```sql
update tm_postmeta
set meta_value = DATE(meta_value)
where meta_key = 'openday'
and DATE(meta_value) is not null;
```

うまくいきました。


# その他
作業はIntelliJ (PHPStorm)のDatabaseツール(?)にて行っていたのですが、`[22001][1292] Data truncation: Incorrect datetime value: '1'`というエラーが出てしまってうまく更新できませんでした。
SELECTはうまく通りますがUPDATEが通りません。

<img width="476" alt="Screen Shot 2016-05-06 at 5.19.45 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/c159eed5-ae90-4cb5-c7cc-4f7b9db7a496.png">



調べてみたところsql_modeを変更すると良い、という記事もありましたがうまく行きません。ケースが違うようです。

> http://qiita.com/kamesennin/items/72ec28d9194f0d52c15a

```sql
SELECT @@GLOBAL.sql_mode;
set @@global.sql_mode=NO_ENGINE_SUBSTITUTION;
```

自分の中の結論として、推測ですがどうやらDatabase接続プラグインの不具合のようです。Java系でよくあるエラーメッセージのようで、ツール側の問題かと思われました。

他のSQLツールで実行したところうまくいきました。
Express-generator使ってElectronが動かなかったとき

# 問題
Express-generatorでgenerateしたプロジェクトでElectronを起動したときにうまく起動しない。

# 対策
package.jsonに"main": "./app.js"を追加したらできた。

```package.json
{
  "name": "CommentViewer",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "main": "./app.js",
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.13.1",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0",
    "cheerio": "^0.20.0",
    "electron-packager": "^7.0.1",
    "electron-prebuilt": "^0.37.7",
    "pug": "^2.0.0-alpha6",
    "pug-cli": "^1.0.0-alpha1",
    "request": "^2.72.0"
  },
  "devDependencies": {
    "electron-debug": "^0.7.0"
  }
}

```

mainに追加してくれないのね・・・ジェネレータさん(´・ω・`)
AndroidでBLEのデータ通信を実装するときの参考

# 参考記事
- [Bluetooth Low Energy（BLE）/ iBeaconとは](http://qiita.com/miyatay/items/4d4ce4ccd7905ddc0144) - 特にGATTについて見ておく。
- [やはりお前らのAndroidのBLEが不安定だという認識は間違っている](http://www.slideshare.net/youten_redo/android-ble-stability)
- [AndroidのBLEでCharacteristicsのRead/Writeサンプルを作ってみた] (http://greety.sakura.ne.jp/redo/2013/11/androidblecharacteristicsreadwrite.html) - Read/Writeの実装の参考になる。
- [【連載】Bluetooth LE (5) Android 4.3 で Bluetooth LE 機器を使う](http://blog.fenrir-inc.com/jp/2013/10/bluetooth-le-android.html) - Notificationの実装の参考になる。
- [googlesamples/android-BluetoothLeGatt](https://github.com/googlesamples/android-BluetoothLeGatt) - googleのサンプルだが、あまりイケてない
- [ArduinoとAndroid端末をBLE(Bluetooth4.0)でつないでみる](http://www.robotsfx.com/robot/img/radio/BLESerial/BLESerial_how5.html)
- [Apple Media Service(AMS)を使ってAndroid WearからiPhoneのメディアを操作する話](http://shiitakeo.hatenablog.jp/entry/2015/07/26/224600)

# BLE端末のスタブ

AndroidでBLEアプリを作る場合、対応するBLE端末を用意する必要があります。
これにはiPhoneアプリのLightBlueが一番よいと思います。
仮想Peripheralの作成や、近くのPeripheralの検索などが出来ます。

## サンプルコード

### BLEのデバイスアドレスから、BluetoothDeviceのインスタンスを取得する

~~~java
  BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
  BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
  BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
~~~

参考: http://stackoverflow.com/questions/16902500/connect-to-device-with-bluetooth-address-on-string
Googleの一般物体認識NN, Inception-v3 を Tensorboard で可視化してみた

Tensorboard で Google の一般物体認識ネットワーク Inception のグラフを見る方法
======================================================================

2015年に公開されたGoogle の一般物体認識NN, Inception-v3 の[学習ライブラリが公開された](http://googleresearch.blogspot.jp/2016/03/train-your-own-image-classifier-with.html) ようなので、理解を深めるために Tensorboard でネットワークを可視化してみた。

# 前提条件

* Python (version 2.7.10)
* Tensorflow (version 0.8.0)

# 手順

1. 下準備(ワーキングディレクトリの作成)

```sh
$ mkdir /tmp/imagenet
$ cd /tmp/imagenet
```

2. トレーニング済みの Inception ネットワークをダウンロード

```sh
$ wget http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
$ tar xzvf inception-2015-12-05.tgz
```

3. トレーニング済みのInceptionネットワークからグラフ構造をダンプ

* ダンプスクリプトの設置

```
$ vi dump.py
```

```python
import os
import os.path
import tensorflow as tf
from tensorflow.python.platform import gfile

INCEPTION_LOG_DIR = '/tmp/inception_v3_log'

if not os.path.exists(INCEPTION_LOG_DIR):
    os.makedirs(INCEPTION_LOG_DIR)

with tf.Session() as sess:
    model_filename = '/tmp/imagenet/classify_image_graph_def.pb'
    with gfile.FastGFile(model_filename, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        _ = tf.import_graph_def(graph_def, name='')
    writer = tf.train.SummaryWriter(INCEPTION_LOG_DIR, graph_def)
    writer.close()
```

* グラフをダンプ

```sh
$ mkdir /tmp/inception_v3_log
$ python dump.py
```

4. Tensorboard でグラフを確認

* Tensorboard 起動

```sh
$ tensorboard --logdir /tmp/inception_v3_log/
```

* `http://localhost:6006/` にアクセス

# 参考資料

* https://www.tensorflow.org/versions/r0.8/tutorials/image_recognition/index.html
* https://github.com/tensorflow/tensorflow/issues/1287

# 表示例
![inception表示例.png](https://qiita-image-store.s3.amazonaws.com/0/94564/e15f1025-647b-3f14-f345-555c47170d88.png)
swiftでUIColorではなくCGColorを使いたい時

# 問題


UIButtonの枠線の色を指定する際に

```swift
button.layer.borderColor = UIColor.greenColor()
```

のようにすると

``` 
cannot assign value of type "UIColor" to type "CGColor?"
```

というエラーで怒れました。

これは、

「ボタンのボーダーカラーにはCGColorは使えるけど、UIColorは使えないよっ！」

ってことなので、CGColorの型を使う必要があります。

# 解決策

こんなときは

```swift
button.layer.borderColor = UIColor.greenColor().CGColor
```

として、後ろに`.CGColor`をつけるだけで解決できました！！！
zsh と peco による私のディレクトリ移動


似たようなものはいっぱいあるけれど、zsh と [peco](https://github.com/peco/peco) を使った私のディレクトリ移動。

`z <dir name>`

- [tab] でディレクトリ一覧からディレクトリ名を補完
- ディレクトリ名が一致したら一気に移動
- ディレクトリが部分的に一致したら peco で選ぶ

![peco_cd.png](https://qiita-image-store.s3.amazonaws.com/0/63210/49a4b1a1-68d1-f41b-3518-664b9f75958c.png "peco_cd.png")


`peco` とは "Simplistic interactive filtering tool"

```bash
% brew install peco
```

`~/.zshrc` に `z` コマンドを書く。

```bash
autoload -U compinit; compinit

function _z {
  compadd `cat $HOME/.peco/z-paths | sed 's|.*/||'`
}

compdef _z z

# z <dir>
# z add . : add current directory to directory list
# z edit  : edit the directory list with $ZEDIT

function z() {
  local PCD_FILE=$HOME/.peco/z-paths
  local PCD_RETURN
  local ZEDIT=${EDITOR:-emacs} # set your favourite editor

  if [ $1 ] && [ $1 = "add" ]; then
    # z add <dir>
    if [ $2 ]; then
      local ADD_DIR=$2
      if [ $2 = "." ]; then
        ADD_DIR=$(pwd) 
      fi
      echo "Adding $ADD_DIR to $PCD_FILE"
      echo $ADD_DIR >> $PCD_FILE
    fi
  elif [ $1 ] && [ $1 = "edit" ]; then
    # z edit
    $ZEDIT $PCD_FILE
  elif [ $1 ] && [ $1 = "." ]; then
    PCD_RETURN=$(/bin/ls -F | grep /$ | sort | peco)
  elif [ $1 ]; then
    # z <dir> unique matching
    local GREP_RETURN
    local grepcmd="cat $PCD_FILE"
    for pat in $*
    do
      grepcmd="$grepcmd | grep -e '/$pat'"
    done

    grepcmd=`echo $grepcmd | sed "s/'$/\$'/"`

    GREP_RETURN=`eval $grepcmd`
    echo "grep return = $GREP_RETURN"

    if [ `expr "$GREP_RETURN" : '.*'` -ne 0 -a \
	 $(echo $GREP_RETURN | wc -l) -eq 1 ]; then
      # unique match
      PCD_RETURN=$GREP_RETURN
    else
      PCD_RETURN=$(cat $PCD_FILE | sort | peco --query "$*")
    fi
  else
    PCD_RETURN=$(cat $PCD_FILE | sort | peco)
  fi

  if [ $PCD_RETURN ]; then
    echo $PCD_RETURN
    cd $PCD_RETURN
  fi
}
```

まずは

```zsh
% mkdir ~/.peco
% touch ~/.peco/z-paths
```

私は一覧に追加したいディレクトリを手動で追加している

```bash
% z add .
```

もし、$HOME以下全部を自動的に登録したければ find など

```bash
% find $HOME -type d > ~/.peco/z-paths
```


ディレクトリ一覧をみたり編集するには

```bash
% z edit
```




### 参考
zshの関数などのネタ元は忘れてしまいました(_ _)。
AWS SDK for Javaで、Scala 2.11ビルドのSparkアプリを実行するStepを追加する


現時点(2016/05/06)だと、Spark on EMRに入ってるSpark assemblyはScala 2.10でビルドされているため、Scala 2.11で書いたアプリをEMRで実行する際はひと工夫必要です。

こちらの記事にて、masterノードにsshで入って`spark-submit`する方法が紹介されていますが、ここではAWS SDK for Javaでstepを追加する方法をメモしときます。

- [EMR上でScala2.11ビルド版のSparkを動かす](http://qiita.com/uryyyyyyy/items/e9ec40a8c748d82d4bc4)

まあほぼ[AWSのドキュメント](http://docs.aws.amazon.com/ja_jp/ElasticMapReduce/latest/ReleaseGuide/emr-spark-submit-step.html)に書いてあるままです。

## 準備

上記記事を参考に、

- bootstrapアクションでJava8をインストールしたクラスタの用意
- Scala 2.11でビルドしたSpark assemblyの用意(`s3://path/to/spark-assembly`に置いたものとします)
- 適当にSparkアプリ作ってfatJarにしておく(`s3://path/to/your-app`に置いたものとします)

をやっときます。

## Stepを追加するコード

個人的趣味で、Scalaで書きます。

```scala:Main.scala
package com.example

import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.regions.{Regions, RegionUtils}
import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduceClient
import com.amazonaws.services.elasticmapreduce.model._

object Main {
  def main(args: Array[String]): Unit = {
    val credentials = new BasicAWSCredentials("your access key", "your access secret")
    val emrClient = new AmazonElasticMapReduceClient(credentials)
    emrClient.setRegion(RegionUtils.getRegion(Regions.AP_NORTHEAST_1.getName))

    val hadoopStepConfig = new HadoopJarStepConfig()
      .withJar("command-runner.jar")
      .withArgs("spark-submit",
        "--master", "yarn-cluster",
        "--conf", "spark.yarn.jar=s3://path/to/spark-assembly",
        "--class", "com.example.Main",
        "s3://path/to/your-app")

    val stepConfig = new StepConfig()
      .withName("step-example")
      .withActionOnFailure(ActionOnFailure.CONTINUE)
      .withHadoopJarStep(hadoopStepConfig)

    val jobFlowRequest = new AddJobFlowStepsRequest()
      .withSteps(stepConfig)
      .withJobFlowId("your cluster id")

    val jobFlowResult = emrClient.addJobFlowSteps(jobFlowRequest)
    println(s"stepIds: ${jobFlowResult.getStepIds}")
  }
}
```

実行すると、ちゃんとStepが作成されました。

```bash
$ sbt run
stepIds: [s-xxxxxxxxxx]
```
Rspec + Capybara | <select value=""> の value を指定して選択状態にする 


こういうセレクトボックスがあって、Banana を選びたい時。

```html
<select name="fruits">
  <option value="Apple">りんご</option>
  <option value="Banana">バナナ</option>
</select>
```

以下でOK。

```rb
find("option[value='Banana']").select_option
```

参考: http://stackoverflow.com/questions/20134085/how-to-select-option-in-drop-down-using-capybara

# 問題

```rb
find("option[value='#{result_match}']").click
```

じゃ無理だった。

たぶんバージョンによるのだろう。
「セレクトボックスなのに `click`」って分かりづらいし。

参考: http://stackoverflow.com/questions/12265174/select-an-option-by-value-not-text-in-capybara

# 注意

ユーザーから見えない「HTMLソースコード」基準のこのやり方は、通常は良くない。

普段は「外から見えるものだけ」を基準に、

```rb
select 'バナナ', from: 'fruits'
```

って書いた方が良い。

# 環境

- capybara (2.5.0)
- rspec (3.4.0)
- rspec-rails (3.4.2)



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
Oracleに対話形式でさくっと接続するbatプログラム

##OracleにSQL*Plusでさくっと接続したい

Oracleに接続して何らかの作業をする際、sqldeveloperなどのGUIツールは重くて嫌いなので、基本的にSQL*Plusを利用します。ただ、開発用、検証用、ステージング用･･････etc、とサーバが複数あり、さらにスキーマも複数あるせいで、TNS サービス名とアカウントの組み合わせを忘れがちだったので、対話形式で指定のOracleインスタンスにさくっと接続できるbatファイルを作成します。

##Oracle接続バッチツール

batファイルを実行後、接続先を番号で指定することで、番号に紐付くスキーマとインスタンスに接続するプログラムです。
検証用、ステージング用といったデリケートなサーバに接続する際には、コマンドプロンプトのタイトルや背景色が目立つように変更して、ヒヤリハットを防止します。

```bat:oralce_conn_sample.bat
@echo off
echo /*****************************************************************/
echo /*  ■Oracle接続バッチ                                             */
echo /*     1)サーバ：開発         SID：db1 スキーマ：user1             */
echo /*     2)サーバ：検証         SID：db1 スキーマ：user1             */
echo /*     3)サーバ：ステージング　SID：db1 スキーマ：user1             */
echo /*****************************************************************/

rem 番号を入力
echo.
set /p DB_SERVER="接続先を番号で指定してください >> "
rem 番号で指定した設定関数を実行
call :%DB_SERVER%
rem 接続関数を実行
call :CONNECT

rem 接続先の設定関数
:1
rem ユーザ名
set USER_NAME=user1 
rem パスワード
set PASSWORD=passwd1
rem TNS名
set TNS_NAME=db1.dev
rem タイトル
set TITLE_HEAD=開発環境
rem 背景色
color 1F
exit /b

:2
set USER_NAME=user1
set PASSWORD=passwd1
set TNS_NAME=db1.verify
set TITLE_HEAD=★★検証環境★★
color 5F
exit /b

:3
set USER_NAME=user1
set PASSWORD=passwd1
set TNS_NAME=db1.staging
set TITLE_HEAD=★★ステージング環境★★
color 5F
exit /b

rem 接続関数
:CONNECT
rem スクリプトを実行し易いように、SQLスクリプトファイルを配置しているディレクトリに移動
cd C:\app\sqlplus
title %TITLE_HEAD%　%USER_NAME%@%TNS_NAME%
sqlplus %USER_NAME%/%PASSWORD%@%TNS_NAME%
exit /b
```
ZabbixのUserParameterでうまくawkが効かない時cutを使ってみる

# 概要

ZabbixのUserParameterのなかで、awkが使えなかった

# まとめ

cutを使ってみる。

# 経緯

区切り文字が空白(0x20)であることは ***hexdump -C*** で確認した。

```
| awk '{print $$3;}'
```

これがうまくうごくとおもっていたのだけど、うまくいかなった。
区切り文字***-F ' '***も変えてみたつもりなのだが、うまくいかなかった。

そこで以下のようにしてみた。
```
| cut -d\  -f3
```
webpackでrequireやimportのパスのrootを指定する

# 何ができるか
```js
var Hoge = require("./Hoge.jsx");
import Fuga from "./common/Fuga.jsx";
```
って書いてたのを

```js
var Hoge = require("Hoge.jsx");
import Fuga from "common/Fuga.jsx";
```
って書けるようになる

# やり方
```js
var path = require('path');

module.exports = {
  //....
  resolve: { root: [ path.resolve('./front') ] }, // rootにしたいパスを指定
  //....
};
```
[本家サイト](http://webpack.github.io/docs/configuration.html#resolve-root)

# 何が幸せか
ディレクトリをリファクタリングしたくなった時に、「呼び出しファイルからの相対パス」で記述していると、リファクタリングが面倒になる。
これやっといてルートからの相対パスで書いておけば一括置換できる。

# 弊害
### hyperclick
~~[atomでjsでimportしたファイルにジャンプする](http://qiita.com/193/items/0e01e3fc00685b0fd262)
にも書いたけど、hyperclickで辿れなくなる。解決策は[atomでjsでimportしたファイルにジャンプする](http://qiita.com/193/items/0e01e3fc00685b0fd262)に書いてある。キモいけど。~~

神修正により問題なし
https://github.com/AsaAyers/js-hyperclick/pull/32

## eslint-plugin-import
に怒られる。でもこいつなくても、どうせビルドでめっちゃ怒られるから、

```yaml:.eslintrc
rules:
  semi: 0
  import/no-unresolved: 0
```
で黙らせた。
mapping in elasticsearch


## 検索エンジンを取り巻く7つの技術（前提知識）
1. トーカナイザ
    * 検索エンジンに文書をインデックスするために、入力文書内の文を単語に分割するコンポーネント
        1. 単語単位のトークナイザ(形態素解析器)
        2. （文字）N-gram トークナイザ
        3. 単語単位＋（文字）N-gram トークナイザ
2. 言語同定器
    * 入力文字列から言語を同定する機能を提供する
3. 単語の正規化器＆文字ノーマライザ
4. ストップワード
5. コンテンツ抽出
6. ランキングの調整
7. クローラ

※[ビッグデータ処理の常識をJavaで身につける](http://www.atmarkit.co.jp/ait/articles/1111/18/news148.html)

## what is mapping in elasticsearch ?
検索エンジン（ES）に、検索対象文字列を、どういったトーカナイザ（解析）で、検索可能かといった定義をすること

※意訳してみたが・・・

要は、スキーマ定義。

また、基本的には、mappingは必須ではない。

### steps
1. mappings property 定義
2. analysis property 定義

### mapping property
> Elasticsearch のスキーマ定義では、mappings プロパティ以下で type で扱うプロパティ名（MySQLでいうカラム名）とそのデータ型、アナライザー（後述）を設定します。mappings は、MySQL でいう create table の際にカラム名とそのデータ型を指定するのに近い感じ

### analysis property
> filter はストップワードの指定、tokenizer は利用するトークナイザーを N-gram にするか形態素解析にするかの指定などを行い、analyzer は filter と tokenizer を組み合わせて独自のアナライザーを作成します。それぞれ、複数の filter, tokenizer, analyzer を定義することが可能

```code:json
{...
  "analysis" :
    "filter" : ... ,
    "tokenizer" : ... ,
    "analyzer" : ... }
```

`それぞれ、複数の filter, tokenizer, analyzer を定義することが可能`

## when/how should mapping ?
1. create index 
2. put mapping API

以下は[公式](https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-get-mapping.html)より重要そうなところを抜粋

### create index
```code:yaml
$ curl -XPUT 'http://localhost:9200/twitter/' -d '
index :
    number_of_shards : 3 
    number_of_replicas : 2 
'
```
```code:json
$ curl -XPUT 'http://localhost:9200/twitter/' -d '{
    "settings" : {
        "index" : {
            "number_of_shards" : 3,
            "number_of_replicas" : 2
        }
    }
}'
```
※どちらもindexプロパティはなくてもいい
※各yaml/jsonを用意して食わせるでもOK

### put mapping API
```
$ curl -XPUT 'http://localhost:9200/twitter/_mapping/tweet' -d '
{
    "tweet" : {
        "properties" : {
            "message" : {"type" : "string", "store" : true }
        }
    }
}
'
```

### multi index 
```
$ curl -XPUT 'http://localhost:9200/kimchy,elasticsearch/_mapping/tweet' -d '
{
    "tweet" : {
        "properties" : {
            "message" : {"type" : "string", "store" : true }
        }
    }
}
'
```

### all option
`PUT /{index}/_mapping/{type}`

* {index}

   * blank | * | _all | glob pattern | name1, name2, …

* {type}
   * Name of the type to add. Must be the name of the type defined in the body.

> Instead of _mapping you can also use the plural _mappings

＝＞ `_mapping`でも`_mappings`でもOK


# ref
* [elasticsearchとSQL対比しながら理解](http://qiita.com/kieaiaarh/items/5ea4e8a188bd9814000d)
* [Elasticsearchチュートリアル - 不可視点](http://code46.hatenablog.com/entry/2014/01/21/115620)
Tokyoリージョンに3 AZほしい〜H/Aなetcd on CoreOSクラスタのメンテンナンスを自動化したい

Kubernetesクラスタを運用するということは、etcdクラスタも運用することになりますよね[^1]

[^1]: AWS etcd Serviceこないかなぁ〜〜

ところが、H/Aなetcdクラスタを楽に運用するためにはどうしたらいいのか、というまとまった情報がなかったので、ここに書いていきます。

## TL;DR;

色々調べたり読んだりした結果、英語が大丈夫なら以下のブログを読むのが一番よいと思いました。
[Building a Robust etcd cluster in AWS · crewjam.com](https://crewjam.com/etcd-aws/)

## etcdにおけるH/Aとは?

* 最低でも読み書きがNetwork Parittionに耐えられるように1 node * 3リージョンの構成で、5、7、9のようにどう障害が起きてもスプリットブレーンにならないノード数

## メンテナンスとは?

* CoreOSの自動アップデート
    * あえて無効化しなければ、設定したタイミングで自動リブートされる
        * 自動リブートのときにダウンタイムが発生しないようにしたい
* etcd自体の更新
    * CoreOSに含まれるetcdを起動するなら、CoreOSの更新と一緒にアップデートされるはず
    * なので↑と一緒
* etcdのバックアップ・復元
    * 全ノードが落ちることがあったら、データを全消失させる以外に、バックアップから復元する方法がある
* スケールアウト
    * 読み書きが追いつかなくなった場合に、安全にノード数を増やしたい
    * 安全とは
        * スケールアウト中にネットワーク障害が発生してもスプリットブレーン状態にならない

## そもそもetcdクラスタの安全なスケールイン手順は?

おおまかにいうと、リーダーでなくしてからノードをquorumから削除する。そのためには、現在のクラスタから削除する＋ディスカバリ対象にならないようにDiscovery Endpointからも削除する。

* `etcdctl member list`でノードIDを知る
* リーダーを削除したい場合は、まず他のノードをリーダーに昇格させる
* `etcdctl member remove NODE_ID`で対象ノードをquorumから削除する
* `etcdctl member list`でノードが削除されてることを確認する
* `etcdctl cluster-health`でクラスタが正常に稼働してることを確認する(確認した限り、リーダーを削除してしまうと、cluster-healthが返ってくるのにleader election timeout時間分かかる気がするので、cluster-healthの応答がすぐ返ってこなかったら、手順が間違ってたことになる)
* etcd discovery endpointを使ってる場合(=`MonsantoCo/etcd-aws-cluster`とかを使ってない場合)
    * `curl -XDELETE https://discovery.etcd.io/DISCOVERY_ID/ノードID`でノードを削除
    * `curl https://discovery.etcd.io/DISCOVERY_ID`でノードが削除されてることを確認

参考: [kocho/etcd-operations.md at master · giantswarm/kocho](https://github.com/giantswarm/kocho/blob/master/docs/etcd-operations.md)

リーダーを起動しているノードの場合、書き込みが一時的にできなくなる状態を避けるためには、ノードがシャットダウンされる前にリーダーを他のノードに譲りたい。

[etcd live cluster reconfiguration on CoreOS](https://coreos.com/etcd/docs/latest/etcd-live-cluster-reconfiguration.html)

[CoreOS, AWS, Fleet issue - Google グループ](https://groups.google.com/forum/#!topic/coreos-user/hSDU7NnKhuo)

## quorum

上の手順の前提は、ノードが一つ落ちたくらいではスプリットブレーンの危険もなく、かつ合意が形成できるようなノード数を保つ、またはquorumを下回らないようにする、ということです。

etcd界隈だと冒頭で紹介したcrewjamさんのブログ記事や、CoreOSの公式ドキュメントあたりにしか明確に書かれてない気がするのですが、例えばそもそも２ノードのetcdクラスタだと、quorumが1なのでネットワーク障害等でそれぞれのノードが自分をリーダおと思い込んで書き込み要求を受け付けてしまって、ネットワーク障害から復旧したときにリーダー同士のデータ不整合で自動復旧ができなくなってしまいます。

単一のノード障害でquorumを下回らない、かつネットワーク障害等でスプリットブレーンが起きないノード数を選ぶことは、書き込みのコミットにquorumが必要なElasticsearchなどでも重要視されています。

[How many nodes should an Elasticsearch cluster have?](http://cpratt.co/how-many-nodes-should-an-elasticsearch-cluster-have/)

etcdの場合、例えば単一AZの障害に耐えたいなら、最低３ノードを別々のAZやRegionに置く必要があります。

仮にap-northeast-1aに２ノード、ap-northeast-1bに1ノードおいたとき、1aが落ちると書き込みが完全にできなくなります。1bにいる１ノードがリーダーになるために合意を募っても、quorum=2以上の合意は得られず、結果quorumが必要な書き込みもコミットできないからです。

## 参考

[xuwang/aws-terraform](https://github.com/xuwang/aws-terraform/tree/master/modules/etcd)
など
Youtube Live でストリーミングを配信する

こんにちは。エクセルソフトの田淵です。

JXUGC とかでストリーミング配信をする際に、やっと良い感じの事前準備や設定がわかりましたので、共有します。

[Japan Xamarin User Group のイベント](http://jxug.connpass.com/) では、ストリーミングを行う際に [Youtube ストリーミング](https://www.youtube.com/channel/UCtmSdXmQWhBIiLuq3Xo3hLQ) を使用しています。最初は Ustream を使用していたのですが、無料プランでは 3か月しか動画が保存できないという謎な仕様が追加されたので、乗り換えました。本エントリーでは、Webcam で Youtube ストリーミングを快適に配信する方法をご紹介します。

## 必要なハードウェア

- ノートパソコン（Web カメラの関係で USB 3.0 付が良いです。）
- Web カメラ（USB 3.0 の HD が撮れるやつが良いです。）
- 太い帯域
- 三脚（低い位置からだとスクリーンが斜めっちゃうのでできれば合ったほうが良いです。）

## Youtube クリエイターツール

クリエイターツールは Youtube にログインして、右上のメニューから［クリエイターツール］をクリックするとアクセスできます。

アクセスしたら、左のメニューから［ライブストリーミング＞イベント］をクリックします。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/be5b50b0-1244-c698-6f39-a650d35d1719.png" width="450px" />

イベントページの右上の［新しいライブイベント］ボタンをクリックします。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/6286c697-d827-3d7a-a1ea-67cb40709ea2.png" width="450px" />

タイトルや Twitter と連携するか？などの情報を入力して［保存］をクリックします。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/0cc5f257-2071-1f61-a517-16d177678d13.png" width="450px" />

取り込み設定画面に移動するので、［取り込みの基本設定］から［720p］か［1080p］を選択します。（私が使用している [Logicool HD Pro Webcam C920](http://www.logicool.co.jp/ja-jp/product/hd-pro-webcam-c920) は 1080p 対応なのですが、パソコンの USB バスの帯域が足りないとかで 720 が最高みたい。もう少し良いノートで配信すれば 1080p 行けるかと。）

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/1728bcd0-7e5d-d05f-9562-8659e6582ba7.png" width="450px" />

配信開始日時の設定ですが、Wirecast から配信する際に強制的にイベント開始ができるので、大まかに設定するだけで大丈夫です。

Youtube 側はこれで終了です。

## Wirecast の設定

[Wirecast](http://telestream.net/wirecast/overview.htm) のサイトから、Trial をダウンロード、インストールします。ユーザー登録だけすると、Free 版が使用できます。私もフリー版を使用しています。

インストール後、起動しましょう。

下がレイヤーペインですが、Free 版では 1つしか使用できません。最初に幾つか登録されている［ショット（画面設定のことみたいです）］はすべて削除して、［＋］アイコンから、マシンに接続している Web カメラを選択してショットを作成します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/6a67c2a4-91b4-fa02-ff39-b73793c4e71a.png" width="450px" />

作成したショットを選択すると、上のプレビューペインに動画が表示されるのを確認し、ショットの右下にある歯車アイコンから［ソースを変更］と［オーディオの変更］で Web カメラが選択されていることを確認しましょう。

続いて、メニューから［配信＞配信の設定］をクリックします。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/a2beb9ec-a345-ec1c-32a8-5080d984c8ed.png" width="450px" />

ここで、エンコードをお持ちの環境によって、［720p Recommended］か［1080p Recommended］かを選択しましょう。

この画面は既に認証が完了していますが、新規に起動した場合は［認証］ボタンから利用している Youtube アカウントを指定してください。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/74ed82f2-db8a-a5dc-15a1-5cc0fbc7633e.png" width="450px" />

認証が完了すると、［Event］のドロップダウンから先ほど Youtube で作成したイベントが表示されるはずです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32453/4156bbe2-e7ad-4ba3-32f9-8961a952e4f4.png" width="450px" />

後は配信するイベント選択して、ダイアログを閉じ、［ストリーム］ボタンから配信を開始できます。

> Wirecast 側でイベントを作成する機能もあるようなのですが、エラーになってしまうので、事前に Youtube 側でイベントを作成する方法をお勧めします。（事前にイベントを用意しておくこともできますし。）

## まとめ

勉強会のストリーミング配信は Youtube がお勧めです。Wirecast を使用することで、高品質な配信を実現できます。Youtube アカウントと Twitter アカウントを紐づけておけば、配信開始と同時にツイートすることもできて非常に便利です。

以上です。
DockerコンテナにNFSボリュームをマウントする---Netshare Pluginを使ってみる

# 

[Netshare Plugin](https://github.com/gondor/docker-volume-netshare)を使うとDockerコンテナにNFSボリュームをマウントすることができます。このプラグインを使えると様々な用途(特にDocker Swarm上)で活用できそうなので、以下に手順を残しておきます。

## Vagrantでテスト用の環境を作る

```
vagrant init ubuntu/trusty64
sed -i -e "s/.*192.168.33.10.*/  config.vm.network \"private_network\", ip: \"192.168.33.10\"/" Vagrantfile
vagrant up
vagrant ssh
```
> **NOTE:** この例では192.168.33.10というアドレスを使ってNFSボリュームをシェアする環境を作ります。また、手順を短くするためにNFSサーバーもDockerも同じVMにインストールすることにします。


## Docker EngineとNFSサーバーをインストールする
```
# Dockerをインストールします
curl -fsSL https://get.docker.com/ | sh

# NFSサーバーをインストールして/exportsというディレクトリをシェアする設定を加えます
sudo -i
aptitude install nfs-server
mkdir /exports
echo "/exports 192.168.33.0/24(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
/etc/init.d/nfs-kernel-server start
```

### Netshare PluginをインストールしてコンテナにNFSボリュームをマウントする

```
# Netshare Pluginをインストールします
wget https://github.com/gondor/docker-volume-netshare/releases/download/v0.16/docker-volume-netshare_0.16_amd64.deb
dpkg -i docker-volume-netshare_0.16_amd64.deb
service docker-volume-netshare start

# コンテナを作ってNFSボリュームをマウントします
docker run --rm --volume-driver=nfs -v 192.168.33.10/exports:/mount -it ubuntu

# 確認します
root@934060cad02a:/# touch /mount/file1
root@934060cad02a:/# touch /mount/file2
root@934060cad02a:/# exit
ls /exports
file1 file2
```
> **NOTE:** `touch /mount/file1`がハングする場合はVMを`reboot`してからもう一度試してみてください。その場合は`service docker-volume-netshare start`をお忘れなく。。。

また、もちろんのことですが、下記のようにサブディレクトリをマウントすることもできます。

```
mkdir /exports/server1
docker run --rm --volume-driver=nfs -v 192.168.33.10/exports/server1:/mount -it ubuntu
root@72ac425831d1:/# touch /mount/test1
root@72ac425831d1:/# exit
root@vagrant-ubuntu-trusty-64:~# ls /exports/server1
test1
```

また、Netshare PluginはAWS EFSやCIFSもマウントできるようなので、ご興味のある方は下記リンクへどうぞ。

## 参考リンク
- [gondor/docker-volume-netshare](https://github.com/gondor/docker-volume-netshare)
rails params id missing

http://stackoverflow.com/questions/30943089/missing-params-when-updating-only-single-attribute-in-rails

```rb
get '/custom_description/edit' => 'custom_description#edit'
post '/custom_description/edit' => 'custom_description#edit'
```

to

```rb
get '/custom_description/edit/:id' => 'custom_description#edit'
post '/custom_description/edit/:id' => 'custom_description#edit'
```
Selenium(Java)でHTML要素が見つかるまで待機する処理

#SeleniumでHTML要素が見つかるまで待機したい
会社で勤怠管理のWebシステムを利用していますが、毎日、手動で入力するのが面倒くさかったのでSelenium(Java)で自動入力するツールを作りました。その際、画面遷移の完了を判断するために、あるHTML要素が見つかるまで待機する処理を作るのに一番、手こずったので内容をメモします。

##Strategyインタフェースを作成
ただ待機するだけではなく、画面によっては見つからなかったら再度、ボタンをクリックするようなことがしたかったので、「どのように待つか」というアルゴリズムを入れ替えられるようにStrategyパターンで作ります。

```java:java
public interface HtmlElementStrategy {
	public boolean isFindElement();
}
```

##Contextを作成
HtmlElementStrategy#isFindElementがtrueになるまで待機する処理。
waitTimeに待機時間、timeoutCntに待機回数を指定。

```java:java
public class HtmlElementContext{
	public static void waitUntilFindElement(long waitTime, int timeoutCnt,
			HtmlElementStrategy t) {
		for (int i = 0;; i++) {
			try {
				if (t.isFindElement()) {
					// 要素が見つかったらループを抜ける
					break;
				}
			} catch (NoSuchElementException e) {
				if (i > timeoutCnt) {
					// timeoutCntを超えたら例外を投げる
					throw e;
				}
			}
			try {
				// waitTimeの間、待機する
				Thread.sleep(waitTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
```

##クライアントを作成
実際の使用例。
HtmlElementContext#waitUntilFindElementを呼び出す際に、Strategyを実装する。

```java:java
HtmlElementContext.waitUntilFindElement(1000, 30,
		new TeamSplitStrategy() {
			// Strategyの実装
			@Override
			public boolean isFindElement() {
				if (driver.getTitle().contains("HTML要素名")) { 
					// 画面のタイトルが見つかった
					return true;
				}
				// リンクをクリック
				driver.findElement(By.linkText("HTML要素名")).click();
				return false;
			}
		});
```

##WebDriverWaitクラスを使えばよかった
この記事を書いている最中、SeleniumライブラリのWebDriverWaitクラスを使えば、わざわざ上記のような処理を自作しなくても済むことに気付いてしまいました。

```java:java
// Waitオブジェクト作成
Wait<WebDriver> wait = new WebDriverWait(driver, 30);

// 待機条件を実装
ExpectedCondition<Boolean> waitCondition= new ExpectedCondition<Boolean>() {
	public Boolean apply(WebDriver driver) {
		driver.findElement(By.linkText("HTML要素名")).click();
		return driver.getTitle().contains("HTML要素名");
	}
};

// 条件を満たすまで待つ
wait.until(waitCondition);
```

つまり、車輪の再発明をする前に、APIを確認しようねというお話でした･･････。
Macでデュアルキーボードを動かす

#目的
セパレートキーボードにしたいけど、Macのキーボードが気に入ってるので、
できればそのままの使い勝手を維持したい！

![KB800PB-us.jpg](https://qiita-image-store.s3.amazonaws.com/0/16981/789d39e5-5eba-a313-5b7a-cd4d11cffdd3.jpeg)

#やりかた
##１．Apple Wireless Keyboardを２つ用意する
![Mac Bluetooth Keyboard for Separate.png](https://qiita-image-store.s3.amazonaws.com/0/16981/cde12b8e-0a8c-01fa-a6a3-a415e6eeaedb.png)
##2.２つともつなぐ
※このままだと左右のキーボードが連携とれないため、左でShiftおしながら、右でiとか押してもIにならない
##3.Karabinerをインストールする
https://pqrs.org/osx/karabiner/index.html.ja

インストールするだけで左右のキーボードの対応付けがされる！

ただし、このままだと、キーを押しっぱなしにした時に少し違和感があるので、
リピート設定を下記のようにするとすると幸せになれます。
![スクリーンショット 2016-05-06 14.35.47.png](https://qiita-image-store.s3.amazonaws.com/0/16981/1fae8100-dd38-76a1-95ce-0f86a86cc409.png)

#この後やりたいこと
正直ぶった斬りたい
![MC184JA.jpg](https://qiita-image-store.s3.amazonaws.com/0/16981/b354cb5b-7612-2d2c-d9a3-d43fbeca6d05.jpeg)
こうして、
こう
![Double Axe.png](https://qiita-image-store.s3.amazonaws.com/0/16981/5e9c038a-722c-b7ea-f437-6f83a3b508c0.png)
Double Axe!

以上

#その後・・・ (2016/06/14追記)
キーボードにマキ割りダイナミックするのが面倒だったので、
このように運用してます。結構快適です。

![13151967_1200745913269168_7710485515075821549_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/16981/caa3aa82-3fa7-b645-ecfe-00cd668269fc.jpeg)
こいつをチョキチョキして

![13103339_1200740723269687_3968313868431183028_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/16981/3abcf04a-9837-476a-4d87-794c90e886a0.jpeg)
こんな感じ。

でもいつかはDouble AxeにしてDiablo倒すんだ・・・！

(*´ω｀*)ノシ
Swiftでgoo.glの短縮URLを生成するやり方

#開発環境
ElCaption 10.11.4
Swift2.2
Xcode7.3

#事前準備
APIキーを取得する必要があるのですが<a href="https://syncer.jp/how-to-make-shoten-url" target="_blank">PHPで短縮URLを作成する方法まとめ(全7サイト)</a>に取得方法が書いてあるのでここでは割愛します。

#コード
<a href="http://qiita.com/sushichop/items/ac4ae99b905ce523c2fe" target="_blank">SwiftでHTTPリクエストする</a>の記事を参考にコードを作成しました。
ここでは、緯度経度を指定したGoogleMapのURLをサンプルとして利用しています。
(取得したAPIキーを書き換えるのを忘れずに!)

```swift:ViewController
class ViewController: UIViewController {
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        postAsync()
        
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    // HTTP-POST
    func postAsync() {
        
        let apiKey = "APIキーをここに入力してください"
        // create the url-request
        
        //アプリごとにキーは生成しないといけない
        let urlString = "https://www.googleapis.com/urlshortener/v1/url?key=" + apiKey
        let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
        
        // set the method(HTTP-POST)
        request.HTTPMethod = "POST"
        // set the header(s)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        // set the request-body(JSON)
        let params: [String: AnyObject] = [
            "longUrl":"http://maps.google.com/maps?q=35,139&ll=35,139"
        ]
        
        do {
            request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.init(rawValue: 2))
        } catch {
            // Error Handling
            print("NSJSONSerialization Error")
            return
        }
        
        
        // use NSURLSessionDataTask
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
            if (error == nil) {
                let result = NSString(data: data!, encoding: NSUTF8StringEncoding)!
                print(result)
            } else {
                print(error)
            }
        })
        task.resume()
        
    }
    
    
}

```
#結果
idを指定してあげれば、短縮URLが取得できます。

```
{
 "kind": "urlshortener#url",
 "id": "http://goo.gl/rV3xdk",
 "longUrl": "http://maps.google.com/maps?q=35,139&ll=35,139"
}
```
MacのTerminalでCOMポート通信

MacのTerminalでCOMポートを使った通信ができます。

## COMポートの一覧を取得

~~~
$ ls -l /dev/tty.usb*
crw-rw-rw-  1 root  wheel   31,   4 May  6 14:19 /dev/tty.usbserial-Disabled
~~~

## 接続する

~~~
$ screen /dev/tty.usbserial-Disabled 
~~~

## 切断する

Control-a Control-\

## その他のコマンド

manを参照して下さい

~~~
$ man screen
~~~

# その他

screenではなくminicomというツールを使う方法もあるようです

- [Mac OS X Mountain Lion で RaspberryPi とシリアル接続する](http://cat-s-tail.blogspot.jp/2013/10/Mac-OS-X-Mountain-Lion-RaspberryPi-serial.html)

# 参考

- [MacでのCOMポートの使い方](http://nishi-monodukuri.blog.eonet.jp/default/2014/04/maccom-ee51.html)
- [screenコマンドのマニュアル](http://ss64.com/osx/screen.html)
Node.jsとExpressとPugを利用する設定方法

# 目的
Node.jsを利用したアプリケーションを作る際の一通りの流れのメモ

# 環境
- node 4.4.3
- npm 2.15.1
- Windows 8.1

# 環境構築
まずプロジェクト用フォルダの作成を行います。

```bash:commandprompt
mkdir Hoge
```

## Express-generatorを利用
Expressはルーティング機能が入っているモジュールです。Express-generatorでは、プロジェクトのひな型をジェネレートしてくれるのでそれを利用します。

```bash:commandprompt
npm i -g express-generator
```
次に、ジェネレータでプロジェクトのひな型を作成します。
`--git`は.gitignoreを作成してくれます。注意として、Hogeの一つ上の階層で以下のコマンドを実行しなければなりません。また、テンプレートエンジンはデフォルトではjadeになります。私はpug(旧jade)を利用するのでそのままテンプレートエンジンはjadeにし、後で拡張子を変えます。

```bash:commandprompt
express --git Hoge
```
## package.jsonの変更
ここの章に関しては、人それぞれ作りたいで内容が変わるので一例としてみてください。私の場合は、electronで何かしようと思っていたので、electronが入っています。また、pug(旧jade)を利用するのでpugも入れています。

```js:package.json
{
  "name": "CommentViewer",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.13.1",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0",
    "cheerio": "^0.20.0",
    "electron-packager": "^7.0.1",
    "electron-prebuilt": "^0.37.7",
    "pug": "^2.0.0-alpha6",
    "pug-cli": "^1.0.0-alpha1",
    "request": "^2.72.0"
  }
}
```
その後、`npm i`で必要なモジュールを入れていきましょう。

```bash:commandprompt
cd Hoge
npm i
```

## views内のファイルの拡張子の変更
viewsの中にある*.jadeファイルをすべてpugにします。

```bash:commandprompt
cd views
mv error.jade error.pug
mv index.jade index.pug
mv layout.jade layout.pug
cd ..
```
## app.jsの変更
次に、app.jsに記述されているview engineをjadeからpugに変更します。

```js:app.js(before)
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
```
を以下に変更

```js:app.js(after)
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
```
## サーバの起動
次に、サーバの起動を行います。

```bash:commandprompt
npm start
```
起動後は以下のURLにアクセスすると以下の図が表示されると思います。

http://localhost:3000/

![1.png](https://qiita-image-store.s3.amazonaws.com/0/116983/e7d8dac4-7198-f456-1ad0-87eb8e2be9aa.png)
特定の端末でGoogle Mapsを正しく表示できない場合はライトモードを使うと良かった


# 概要
Google Maps Android APIを使用してGoogle Mapsを表示する場合に、特定の端末で以下のような黒い領域が出現(スクリーンショットでは映らない)し、Google Mapsを上手く表示できない場合に対処したのでメモ。

![qiita_20160506.png](https://qiita-image-store.s3.amazonaws.com/0/43438/c2c3ce56-fb49-1075-de79-ad4cab9bcdef.png "qiita_20160506.png")

# 対処方針

## 問題が発生する端末
手元の検証端末のうち以下の2端末で現象が再現した。

|端末|OSバージョン|
|:--|:--|
|[Disney Mobile on docomo N-03E](http://www.n-keitai.com/n-03e/)|4.0.4|
|[GALAXY S II SC-02C](http://www.samsung.com/jp/consumer/mobilephone/smartphone/docomo/SGH-N033LKNDCM)|4.0.3|

さらに複数の端末での検証は、時間的な問題で不可能だったのでこの2例で判断。比較的古い端末で発生している点、特定のOSのバージョンで発生していない点から判断し対策を取ることにした。

## 地図の表示方法の変更

[Google Maps Android APIのドキュメント](https://developers.google.com/maps/documentation/android-api/intro)を確認すると、ライトモードという表示方法が用意されていた。

* https://developers.google.com/maps/documentation/android-api/lite

Google Mapsをライトモードで利用するとビットマップ画像で表示できる。通常モードとライトモードでの機能の差は[ドキュメントで確認](https://developers.google.com/maps/documentation/android-api/lite#api)できる。

## 対処方法

特定のOSバージョンを閾値としてそれ未満のバージョンの場合にライトモードを使用してGoogle Mapsを表示する。今回は閾値にするバージョンをKitKatに指定した。

# 実装

GoogleMapOptionsにライトモードを使用するかを指定するメソッドがあるのでOSバージョンによって切り替える。

```java

// OSバージョンによってライトモードを使用するか設定
GoogleMapOptions options = new GoogleMapOptions();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    options.liteMode(true);
} else {
    options.liteMode(false);
}

// SupportMapFragmentのインスタンスを取得する際にGoogleMapOptionsを引数として渡す
SupportMapFragment mapFragment = SupportMapFragment.newInstance(options);
mapFragment.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(GoogleMap googleMap) {
      // 各種設定
    }
});

// MapFragmentを表示
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.map, mapFragment);
ft.commit();
```

# 結果
Disney Mobile on docomo N-03E、GALAXY S II SC-02Cの2端末で現象が再現しないことを確認した。また、その他の端末でも問題は発生していない。
Ruby | 複数のハッシュに共通するキーを調べる

`keys` と `&` を使えば良い。

## 例1

次は、両方のハッシュが `b:` と `c:` のキーを持っている場合。

```rb
{ a: nil, b: nil, c: nil }.keys & { b: nil, c: nil, d: nil }.keys

# => [:b, :c]
```

## 例2

三個以上のハッシュにも使える。

次は、どのハッシュも `c:` のキーを持っている場合。

```rb
{ a: nil, b: nil, c: nil }.keys & { b: nil, c: nil, d: nil }.keys & { c: nil, d: nil, e: nil}.keys

# => [:c]
```

# 環境

- ruby 2.3.0



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
JupyterでRの環境を整える（Mac OS X）

以前の記事（[Rをノートブック形式で利用する](http://qiita.com/sbtseiji/items/876d2618702416892f7f)）で取り上げた，jupyterでRを使用するための環境構築の手順を，新規インストールが必要になった場合などの自分用の備忘録として記載しておきます。

# jupyterのインストール
自分の環境では，pythonのモジュールはpipをしているので，jupyterは次の手順でインストールします。[jupyter](http://jupyter.readthedocs.io/en/latest/install.html)のサイトにある手順にそってjupyterをインストールします。今は3.x系をメインに使用しているので，3.x系python用にインストールします。

```
pip3 install jupyter
```

もし，すでにipython（jupyterの旧名称）がインストールされている場合，このままではうまく動かないことがあります。その場合には，
```
pip3 install -U jupyter
```
として，ipythonをjupyterに更新します。

# Rの設定
## Rのダウンロードとインストール
当然ですが，Rをインストールする必要があります。[R Project](https://www.r-project.org)のページからRのディスクイメージをダウンロードしてきてインストールします。

## パッケージのインストール
Rのインストールが終わったら，[IRkernel](http://irkernel.github.io)のページにある手順に従い，必要なパッケージをインストールします。

（R.appではなく）*ターミナルで* Rを起動し（つまりターミナルのコマンドプロンプトに`r`と入力して起動する），利用するレポジトリを設定した上で，パッケージをダウンロードしてインストールします。

```r
options(repos="https://cran.ism.ac.jp")
install.packages(c('rzmq','repr','IRkernel','IRdisplay'),
  repos = c('http://irkernel.github.io/', getOption('repos')))
```

## Rカーネルのインストール
パッケージのインストールが終わったら，最後に**Rのコマンドラインで**以下を実行します。

```r
IRkernel::installspec()
```

上記を実行して，

```
[InstallKernelSpec] Installed kernelspec ir in /Users/***/Library/Jupyter/kernels/ir
```
のように表示されたらRを`quit()`で終了します。

# Jupyterの起動
jupyterを起動するには，ターミナルでjupyter用のホームにしたいディレクトリに移動し，

```
jupyter notebook
```

とするだけです。
これで，ホーム画面から「new」を選択してノートを作成する際に「python3」と「R」を選択できるようになっているはずです。
Ruby hashから完全一致したkeyを取り出す方法(正規表現)

ハッシュからkeyを取り出す時に完全一致したkeyのみ取り出す方法のメモ。

```hoge.rb
hash = {name: 'hogehogeko', first_name: 'hogeko', last_name: 'hoge'}
full_name = hash.select{|k, b| k.match(/name/)}
p full_name
```

nameを含むkeyを全てを取ってきてしまう。

```{:name=>"hogehogeko", :first_name=>"hogeko", :last_name=>"hoge"}```

```hoge.rb
hash = {name: 'hogehogeko', first_name: 'hogeko', last_name: 'hoge'}
full_name = hash.select{|k, b| k.match(/^name$/)}
p full_name
```

^と$で先頭と末尾を指定してあげる。

```{:name=>"hogehogeko"}```

これでOK。
中国wechat（微信ウェイシン）の公式アカウントの説明と比較


# wechatの紹介
　日本で最も使われているソーシャルチャットアプリと言えば、それはもちろん「LINE」です。
　中国でよく使われるソーシャルチャットアプリは「wechat（微信ウェイシン）」です。「LINE」と同じ無料メッセージと通話機能を持ち、アクティブユーザー数も4億人以上います。

WeChat（微信）の月間アクティブユーザ数が4億6800万人に届くも成長率は急減速
http://thebridge.jp/2014/11/wechat-468-million-active-users-q3-2014
WeChat（微信）のユーザ数が6億人を突破
http://thebridge.jp/2013/10/wechat-reportedly-surpassed-600-million-users


> 引用：http://www.bravesoft.co.jp/blog/archives/1194

# wechatの公式アカウント

　企業のマーケティングツールとしても欠かせない存在になってきており、既に公式アカウント保有企業は３００万社を超えています。

　公式アカウントは、微信公衆号(微信公众号)といいます。この機能は、微信公衆平台(公众平台)と呼ばれるプラットフォームに設置されています。
　アカウントの開設は、誰でも無料で可能です。詳しくみていくと、3種類のアカウントが存在します。

- 購読版(订阅号)
- サービス版(服務号)
- 企業版(企業号)

![0eb30f2442a7d933b5d4b41caa4bd11373f00164.jpg](https://qiita-image-store.s3.amazonaws.com/0/108473/e0644317-44b6-1031-b773-96bb260ff685.jpeg)


# 三種類公式アカウントの比較
`  `

| 種類 | 用途 | 適用対象 | プッシュ通知制限| フォーロー条件 | メニューのカスタマイズ | 高級API利用（基本情報取得など） | メッセージ表示位置 |
|:-----------|:-----------|:-----------|:-----------|:-----------|:-----------|:-----------|:-----------|
|購読版    |情報伝播    |個人、媒体、企業、政府など |1通/日             |  誰でも  |認証必須（1000人のフォロワー以上）|  利用不可 |  チャットリストの購読フォルダに |  
|サービス版|サービス提供|媒体、企業、政府など       |4通/月             |  誰でも  |認証不要 |  認証必須（1000人のフォロワー以上）|  チャットリスト |  
|企業版    |生産運営管理|媒体、企業、政府など       |無制限（1000通/分）|  事前に設定するメンバー限定<br>※メンバーはwechatIDとメアド/携帯電話で認証する | 認証不要 |  認証必須（1000人のフォロワー以上）| チャットリスト|
今更ながら「フカシギの数え方」

[「フカシギの数え方」](http://www.miraikan.jst.go.jp/sp/medialab/11.html)に出てくる，$n \times n$のマス目を一度通った場所を通らないように左上から右下まで移動する経路の組み合わせを数え上げる問題。この自己回避歩行（self-avoiding walk）のもっとも基本的な処理，つまりおねえさん式にすべての組み合わせをひたすら数え上げる処理をpythonで作成してみました。

ただしあくまで作成してみただけであり，動画にもある通り，マス目の数が増えると組み合わせの数は膨大になるのでこのスクリプトはまったく実用的ではありません（まともな用途には[Graphillion](https://github.com/takemaru/graphillion/wiki)などを使いましょう）。

#### スクリプト

```py3
def saw(n, path):
    if -1 in path[-1] \
     or n in path[-1] \
     or path[-1] in path[:-2] : return 0 

    if path[-1]==(n-1,n-1) : return 1

    return saw(n,path+[(path[-1][0]+1, path[-1][1]+0)]) \
         + saw(n,path+[(path[-1][0]-1, path[-1][1]+0)]) \
         + saw(n,path+[(path[-1][0]+0, path[-1][1]+1)]) \
         + saw(n,path+[(path[-1][0]+0, path[-1][1]-1)]) 

n = 5
print(saw(n,[(0,0)]))
```

#### 出力結果

```
8512
```

`saw`（self-avoiding walk）関数には，縦または横のノードの数（*四角形の数+1*）と，起点の座標を与えます。なお，起点座標は，「*起点座標のタプルを含んだリスト*」の形で与えます。

`saw`関数の中身は，

* 最新座標（リストの最後部）が「*マス目の範囲外*」か「*すでに通った場所*（リストの中に存在する座標）」であれば`0`
* 最新座標（リストの最後部）が「*目的地*（タプル`(n-1, n-1)`で表される座標）」であれば`1`

として，最新座標をそれぞれ縦横に1つずらした座標をリストに追加しながら`saw`を再帰し，戻ってきた数値を合計しています。つまり目的地にたどり着いて`1`が返ってきた経路の数を合計値として求めていることになります。