OmniAICreator/Qiita-1.07M huggingface dataset:
uGUIで禁則処理する

##uGUIで禁則処理する

禁則処理とは？
[禁則処理 - Wikipedia](https://ja.wikipedia.org/wiki/%E7%A6%81%E5%89%87%E5%87%A6%E7%90%86)

日本語を表示する上で、ほぼ必須である禁則処理ですが、uGUIのTextでは、禁則処理が行われません。

よって、自前で実装…………しません。

こちらを使います！
[tsubaki/HyphenationJpn_uGUI: uGUIでの禁則処理](https://github.com/tsubaki/HyphenationJpn_uGUI)

(オリジナルはこちら[inoook/HyphenationJpn_uGUI: uGUIでの禁則処理](https://github.com/inoook/HyphenationJpn_uGUI))

uGUIのTextのついてるオブジェクトに、このスクリプトをアタッチ。

このようになっていたものが
<img width="521" alt="uGUIText" src="https://qiita-image-store.s3.amazonaws.com/0/46278/f8035f6d-fb60-9c7a-8e4e-6cece29defc1.png">
このように！
<img width="521" alt="HyphenationJpn" src="https://qiita-image-store.s3.amazonaws.com/0/46278/c418245d-c993-1cdc-aec0-59bb212e209d.png">

分かりづらいかもしれませんが、しっかり禁則処理が行われています。

以下のようなプログラムで、スクリプト上から文字を変更することができます。

```C#:Sample.cs
using UnityEngine;

public class Sample : MonoBehaviour {
	void Start()
	{
		var m_Text = GetComponent<HyphenationJpn>();
		m_Text.GetText("好きな文字");
	}
}
```

で、本題。
## なぜGet…？
uGUIのTextでは、文字を変更するときは

```C#:Sample.cs
using UnityEngine;
using UnityEngine.UI;

public class Sample : MonoBehaviour {
	void Start()
	{
		var m_Text = GetComponent<Text>();
		m_Text.text = "好きな文字";
	}
}
```

のようにtextプロパティを用います。
が、こちらでは```GetText(string s)```
というメソッドを用います。

なぜ、Get…？
ちなみにオリジナルでは

```C#:HyphenationJpn.cs(オリジナル)の一部
void UpdateText(string str)
{
	// update Text
	Text textComp = this.gameObject.GetComponent<Text>();
	textComp.text = SetText(textComp, str);
}

public void SetText(string str)
{
	text = str;
	UpdateText(text);
}
```

```SetText(string s)```
なぜでしょう…(答えを持っている人は教えてください…)

プロパティがいいなあと思って、以下のような実装に変更。

```C#:HyphenationJpnFixed.cs(改良後)の一部
[TextArea(3, 10), SerializeField]
private string m_Text;
public string text
{
	get { return m_Text; }
	set {
		m_Text = value;
		UpdateText(m_Text);
	}
}
```

これでuGUIと同じ！

```C#:Sample.cs
using UnityEngine;

public class Sample : MonoBehaviour {
	void Start()
	{
		var m_Text = GetComponent<HyphenationJpnFixed>();
		m_Text.text = "変更したい文字";
	}
}
```

で、次の話
## プロパティでどこまで処理する…？

これで便利！と思ったのですが、先輩に
「(プロパティで処理するには)やりすぎ…」
と言われてしまいました…

上では見せていませんが、実際にSetする過程で、以下のような処理が行われています。

```C#:HyphenationJpnFixed.cs
[TextArea(3, 10), SerializeField]
private string m_Text;
public string text
{
	get{ return m_Text; }
	set{
		m_Text = value;
		UpdateText(m_Text);
	}
}

private Text _Text{
	get{
		if( _text == null )
			_text = GetComponent<Text>();
		return _text;
	}
}
private Text _text;

void UpdateText(string str)
{
	// update Text
	_Text.text = GetFormatedText(_Text, str);
}

string GetFormatedText(Text textComp, string msg)
{
	// かなり大きめの処理なので省略…
}
```

プロパティはGetter, Setterメソッドを定義できますよね。
なんでもできるのですが、Getterは値の取得、Setterは値の代入をするところ。軽い気持ちで何度もGet, Setできねばならないでしょう。
では、Getter, Setterではどのくらいの処理まで行うべきなのでしょうか…？

次回、プロパティのGetter, Setterではどのくらいの処理を行うべきか…？に続く…

(ちなみに、プロパティに書き換えたものは、結局使いませんでした… )

## 2/9 補足
[uGUIで禁則処理する の続き - Qiita](http://qiita.com/ma_sh/items/93fa1c20137c48e08794)

## 参考URL
[UnityのuGUIのテキスト表示機能について解説してみる - テラシュールブログ](http://tsubakit1.hateblo.jp/entry/2014/12/28/135446)
【AWS】Amazon Lexさわってみた


ちょっと気になったので、`Amazon Lex` を触ってみた。
やったことを簡単にキュレーションします。
https://aws.amazon.com/jp/lex/

---

# 0. Amazon Lexとは

- 音声やテキストを使用した会話型インタフェースする提供するサービス
- 自動音声認識（ASR）という音声をテキストに変換できる
- テキストの意図を理解するために自然言語理解（NLU）が使える
- 会話型アプリケーションを構築できる
- 対話ボット（チャットボット）が簡単に構築可能
- 料金システムは、従量課金制
- 東京リージョンは未対応（2017/02/04現在）

# 1. メリット

- 簡単に使用できる
- コンソールから直接、ビルド、テスト、デプロイができる
- モバイルデバイスやWebアプリケーション、FBメッセージンジャなどにパブリッシュ(※1)できる
- 管理など特別意識する必要ない（ハードウェアのプロビジョニングなど）
- 他のAWSサービスとの組み込み統合が可能
- コスパがいい
- 無料利用枠でも使用できる

----


★プレビュープログラムに申請中。
★つづきはまた今度。。。

----

# 参考文献（2017/02/04現在）
※1 : http://e-words.jp/w/%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%B7%E3%83%A5.html
Linuxのユーザパスワードをコマンドラインで設定

## Linuxのユーザパスワード
1行Tipsです。
Linuxでユーザにパスワードを設定する時、毎回パスワードを2回入力しなくてはならなくて面倒 ＆ 入力が表示されなくてタイプミスがわかりづらいですが、以下のコマンド一発でパスワードを設定できます。

```
sudo echo "p@ssw0rd" | passwd --stdin user01
```

![2017-02-04_passwd.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/d57ecf89-eff6-a69d-c82b-02a04f894d18.png)
Macで作られる._DS_Storeや._*ファイルをもろもろ削除するpythonスクリプト

#使い道
ポータブルHDDやUSBメモリーをMacに接続した後にWindowsやLinuxに接続すると、
.DS_Storeや既存ファイルのメタファイルっぽい._[既存ファイル名]達が大量に作られているのに気づく。
このファイル達はファイルシステムのセクタサイズより小さいため、数千ファイルあると数GB無駄になったりしていまう。まさに、そうなっていた。

Linuxであれば```find . -name "._*" -exec rm -f {} \;``` などで削除できそうだが、
Windowsのexplorerで._*で検索して削除しようとしても、._*ではない普通のファイルやディレクトリが引っかかってしまい非常に削除しにくい。

そこで困っている人と自分向けに簡単にpythonでスクリプトを組んでみた。
なお、厳密なファイルチェックなどは行っていないので消えてはいけないファイルが消える可能性もゼロではないため、このスクリプトのご利用は自己責任でお願いします。

```py
import os
import sys
import shutil

def deldirs(baseDir):
  print "Start " + baseDir
  ds = [baseDir]
  while True:
    if len(ds) == 0:
      print "Finished!!"
      break
    # Pop next target dir
    d = ds.pop(0)
    # Delete file
    fs = os.listdir(d)
    for fn in fs:
      fp = d + "/" +fn
      if fn[:2] == "._" or fn == ".DS_Store":
        if os.path.isfile(fp):
          print "Del File " + fp
          os.remove(fp)
      #elif os.path.isdir(fp):
      #    print "Del Dir " + fp
      #    shutil.rmtree(fp)

if __name__ == "__main__":
  if len(sys.argv) != 2:
    print "Usage: delmacfile.py TARGET_DIR"
    exit(1)
  baseDir = sys.argv[1]
  if os.path.isdir(baseDir) == False:
    print "Please arg1 is a TAGET_DIR"
    exit(2)
  deldirs(baseDir)
```

Windowsコマンドでやる方法もありそうだがPython好き向けということで。
MeCabをPython3.5から使う

# MeCabインストール
日本語のテキストマイニングを行うときのお供、形態素解析ソフトウェアMeCabをインストールします。
http://taku910.github.io/mecab/#download

意外とドハマリすることの多いMeCabのインストール方法です。
CentOS7.3、Python3.5の環境でMeCabをインストールすることを目指します。
私は手順を確立するのに1日かかりました（笑）


## 事前設定：必要なパッケージのインストール
OSにログインし、まずはrootユーザになります。
```
sudo su - 
cd ~
```

以下、rootユーザで操作を続けます。

MeCabの動作に必要なパッケージをインストールします。

```
yum -y install git gcc-c++
```


## MeCabパッケージをGit Cloneでダウンロード
MeCabをGitから落としてきます。
https://github.com/taku910/mecab

また、今回の作業は/opt/で行いますが、ディレクトリは環境と好みで選んでください。

```
cd /opt/
git clone https://github.com/taku910/mecab.git

```

## MeCabのインストール
/opt/にダウンロードしたMeCabをOSにインストールします。

```
cd mecab/mecab
./configure  --enable-utf8-only
make
make check
make install

```

## /usr/local/lib/libmecab.so.2.0.0へのリンクを設定
自動ではモジュールにリンクされないので、以下を実行します。

```
echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

```

## IPA辞書のインストール
https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM　
↑かからダウンロードします。
ただし、wgetできないため、ブラウザでダウンロードし、CentOSの/opt/ディレクトリに配置します。

```
cd /opt/
tar zxfv mecab-ipadic-2.7.0-20070801.tar.gz
cd mecab-ipadic-2.7.0-20070801
./configure --with-charset=utf8
make
make check
make install

```

これでOSからMeCabを使う準備はできました。

## MeCabをPythonへバインディングする
MeCabをOSにインストールしただけだと、Pythonから使うことはできません。
以下でPythonにMeCabをインストールします。

```
sed -i 's/ return string.split (cmd1(str))/return cmd1(str).split()/g' /opt/mecab/mecab/python/setup.py

python /opt/mecab/mecab/python/setup.py build
python /opt/mecab/mecab/python/setup.py install

pip install mecab-python3
```

これでPython3.5からMeCabを使う準備ができました。

## PythonからMeCabが使えることを確認

早速試してみましょう。

```
python
import MeCab
m = MeCab.Tagger ("-Ochasen")
print (m.parse ("私はメカブと申します。カラスではありません。昨日、帰宅途中に財布を落として探して回りました。Oh No!"))
```

こんな感じです。

![2017-02-04_mecab.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/f3b6244c-928d-9ac9-6420-3289a130ea65.png)
railsでaxiosを使用してpostする

railsでajax通信しようとすると、大概`Can't verify CSRF token authenticity
`で怒られると思います。

axiosでいきなりpostすると、こんなログが発行されいると思います。

セキュリティ上、変なデータ送信されないようにしているので、仕方ないですね。

## CSRF tokenの発行場所

では、普段のjqueryではなぜ意識せずに使用できていたのか？

それは下記のように`meta name`に設定しているからです。

```
<meta name="csrf-token" content="F6dek0xG3Kl/8fc8wlAdAdwWNgBhJ/O8da3ziVQG5y9yOxO7QUS8QVbro9+pLYF9/+qkHXQtrSwIcUteffGd1A==" />
```

https://github.com/rails/jquery-ujs/search?utf8=%E2%9C%93&q=csrf

これを`$.ajax`を使用するときは勝手に設定してくれていたわけです。

それが外れたので、エラーになってます。

ということは、きちんと設定すれば行けます。

## 設定方法

```
axios.defaults.headers['X-CSRF-TOKEN'] = $('meta[name=csrf-token]').attr('content')
```

これを加えることで、headersに値を設定することができます。

参考

http://qiita.com/dakatsuka/items/071313e9dd07d9ec15e4

http://r7kamura.hatenablog.com/?page=1475914566

https://github.com/mzabriskie/axios
Python 3.5でKerasモデルを可視化

## 目的

Python3.5、Anaconda4.3環境を使用しています。
Kerasで作ったLSTMモデルをJupyter Notebook上でpydot　＋　Graphvizで可視化する際の手順です。
OSはCentOS7.3です。

ここにKerasのモデルを可視化する方法が書いてあるのですが、必要なパッケージ含めて解説します。
https://keras.io/visualization/

# 手順
1. yumでOSにgraphvizをインストール。
2. pipでpydot、graphvizをインストール。
3. Jupyter Notebookでモデルを可視化してみる。


## yumでOSにgraphvizをインストール
Graphviz自体はPythonと関係ないパッケージです。
http://www.graphviz.org/About.php

CentOSに限らず、OSで動作するものなので、まずはインストールします。
`sudo yum -y install graphviz`

## pipでpydot、graphvizをインストール
Pythonでgraphvizを使ってモデル可視化するためにはpydotとgraphvizが必要です。
こちらのgraphvizはOSパッケージのPythonラッパーになります。

`pip install pydot graphviz`

これでインストールできましたが、可視化するために、環境によっては以下が必要になるかもしれません。

`pip install pydot3 pydot-ng`

## Jupyter Notebookでモデルを可視化してみる
Jupyter Notebookを起動して、KerasでLSTMモデルを書きます。
今回はここのモデルを転用します。
http://machinelearningmastery.com/sequence-classification-lstm-recurrent-neural-networks-python-keras/


```python
import numpy as np
import pydot
from keras.datasets import imdb
from keras.models import Sequential
from keras.layers import Dense, LSTM
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence

from keras.utils.visualize_util import model_to_dot 
from IPython.display import SVG

np.random.seed(7)
top_words = 5000
(x_train, y_train), (x_test, y_test) = imdb.load_data(nb_words=top_words)

max_review_length = 500
x_train = sequence.pad_sequences(x_train, maxlen=max_review_length)
x_test = sequence.pad_sequences(x_test, maxlen=max_review_length)

embedding_vector_length = 32
model = Sequential()
model.add(Embedding(top_words, embedding_vector_length, input_length=max_review_length))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam',　metrics=['accuracy'])
# ここでモデルを可視化する。
SVG(model_to_dot(model).create(prog='dot', format='svg'))

model.fit(x_train, y_train, validation_data=(x_test, y_test), nb_epoch=3, batch_size=64)
scores = model.evaluate(x_test, y_test, verbose=0)
print ("accuracy: %.3f%%" % (scores[1]*100))
```

これで↓のようにモデルを可視化できます。
![2017-02-04_graphviz.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/7805d7bb-db93-f9a2-bf23-71c96d75ff49.png)
reboot時にBIOSに入るようにする

UEFIになっているとBIOSには入れなくて困っていたのだけれど，[ここ](http://superuser.com/questions/519718/linux-on-uefi-how-to-reboot-to-the-uefi-setup-screen-like-windows-8-can)に方法が書いてあった．

```bash
systemctl reboot --firmware-setup
```
CentOS7にComposerをインストールする

##Composerとは
PHPのパッケージ管理システムである。

##なぜ使うのか
パッケージ管理システムがない環境では、メンバーがそれぞれ必要なライブラリの公式サイトにアクセスしたり、yumを使ったり、zipファイルをダウンロードしたりし、ローカルに展開します。
パッケージ管理システムはそれらを個人の裁量に依存せずに導入できる仕組みを提供します。

パッケージ管理システム自体のインストールが必要だったり、使い方の理解が必要だったり、学習コストは必要ですが、それよりはメリットの方が大きいので今時のPHPプロジェクトでは必要とされています。

Composerを使えば、コマンド一発で必要なパッケージをすべてインストールでき、依存関係にあるパッケージも自動的にインストールしてくれます。

##インストール手順
ComposerのインストールにはPHPが必要です。PHPがインストールされてない方は先にPHPをインストールしてください。
http://qiita.com/inakadegaebal/items/b57cf10339978d638305


「composer-setup.php」をダウンロードします。wgetなどのコマンドでも大丈夫ですが、公式サイトに紹介されている方法を取ります。

```
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
```
問題ないはずですが、有効なものかチェックします。「Installer verified」と表示されたら問題ないです。

```
# php -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
```
ダウンロードした「composer-setup.php」を実行し、インストールします。これで、「composer.phar」ファイルが出来上がります。

```
# php composer-setup.php
```
実行が終わったら「composer-setup.php」は不要なので削除します。

```
# php -r "unlink('composer-setup.php');"
```
Globallyに使うため、「composer.phar」を「/usr/local/bin/」の直下に移動させます。これでどこでも「composer」コマンドが使えるようになります。

```
# mv composer.phar /usr/local/bin/composer
```
確認

```
$ composer
```

※composerコマンドはrootユーザーでは使わないことが推奨されています。
https://getcomposer.org/doc/faqs/how-to-install-untrusted-packages-safely.md
python から Dlib 呼んで 顔のパーツ認識。

dlibというライブラリ?がある事を知ったので、試してみることに。
言語は python で。

# 環境を作る
## mac ports の入れ直し。
macOS 10.12(Sierra)にアップデートした際、MacPorts を入れ直ししてなかったんで、アンインストールしてから、10.12用をインストールした。

1. MacPorts のアンインストール
アンインストールの手順参照先
https://guide.macports.org/chunked/installing.macports.uninstalling.html

2. アンインストール後、macを再起動。

3. MacPorts のインストール

インストール手順
https://guide.macports.org/chunked/installing.macports.html

4.インストールの確認
`$ port version`
`Version: 2.4.0`


## pythonの確認とインストール
まず、python の環境を確認した後、version 2.7 のpythonをインストールする

1.現在実行しているpythonのパスを以下のコマンドで確認(☆)
`$ which python`
`/usr/bin/python`
OSがインストールしたpythonにパスが通っている。

2.MacPortでpython(2.7)をインストール。
`$ sudo port install python27`
依存関係からpython以外にもインストールが必要なものがあるみたいなんで、"Y"を入力。(Enterでも可)

3.pythonを切り替える
select で python の切り替えを行う。
`$ sudo port select --set python python27`

4.パスとバージョンの確認
`$ which python`
`/opt/local/bin/python`
(☆)で確認したパスが/opt/local/binに変わっている。

合わせて、バージョンも確認。
`python --version`
`Python 2.7.10`

# X のインストール
Xをインストール
http://www.xquartz.org
から落としてきてインストール。

## dlibのインストール
dlib のサイト http://dlib.net からダウンロード 
wget http://dlib.net/files/dlib-19.2.tar.bz2

sudo python setup.py install

# サンプルの実行
・・・その前に。
私の環境では、dlibのサンプル(face_detector.py)を実行した際に、パッケージが無いよと怒られた。

調べたら、どうやら これの事らしい。
http://scikit-image.org

portsのリストから探して、インストールすることに。
`sudo port install py-scikit-image`

インストール時のメッセージで、以下を実行しなさい。
的な事を言われたので、おまじないとして実行。
`$ sudo port select --set cython cython27`

念のため、select で確認。
`$ port select cython`
`Available versions for cython:`
`	cython27 (active)`
`	none`

サンプルの face_detector.py　が動いたんで一旦ここでおしまい。

次はwebカメラ(FaceTimeカメラ)からリアルタイムで顔のパーツ認識をさせてみようかと考えています。
PNG画像のファイルサイズを小さくする

スマートフォンアプリを作っていると、偉い人から「アプリの容量でかいよー、小さくしてー」なんて言われちゃったりしてさてどうしようかということになることがしばしばあります。
そんなときはまず使っていない画像や動画等のリソースを削除するのはもちろん、コンパイルの最適化オプションを上げてみたりしてなんとかがんばるのですが、努力にも限度があります。
なんで、PNG画像を再圧縮することで容量を小さくしてみるのが良いでしょう。
デザイナーがPhothoshopで作ったPNGファイルをアプリにそのまま組み込んでいる場合は、PNG画像を再圧縮することでサイズを小さくすることが期待できます。

## PNGの最適化ツール

PNGの最適化ツールには、可逆圧縮の[Pngcrush](https://pmt.sourceforge.io/pngcrush/)や[OptiPNG](http://optipng.sourceforge.net/)、非可逆圧縮の[pngquant](https://pngquant.org/)といったものがあります。
その中で高い圧縮率を誇る[zopflipng](https://github.com/google/zopfli)を使ってみます。

## zopfli とは

zopfliは2013年にGoogle社が発表した新しい圧縮アルゴリズムです。
PNGに使われていたdeflateという圧縮アルゴリズムよりも数%の改善を見込めるアルゴリズムですが、圧縮にむっちゃ時間がかかります。

zopfliはdeflate互換なので、zopfliで圧縮したPNGも従来のPNGビューアで表示できます。

## インストール (Mac)

HomeBrewからインストールできます。

```
brew install zopfli
```

## 使ってみる

### 基本的な使い方

```
zopflipng input.png output.png
```

### 上書きする

```
zopflipng -y input.png input.png
```

`-y` オプションは上書き時に問い合わせしなくなるだけなので、なくてもかまいません。

### もっと圧縮する

```
zopflipng -m input.png output.png
```

`-m` オプションを指定すると、圧縮率が高くなります。かわりに圧縮に時間がかかります。

### とりあえずディレクトリ以下にあるPNGファイルを全部圧縮してみる (Mac/Unix)

```
find your/image/directory -iname "*.png" -exec zopflipng -m -y '{}' '{}' \;
```

## 結果例

あるiOSアプリの3MBにおよぶPNG画像群に対してzopflipngで圧縮したところ、PNG画像のサイズがおよそ **30%減** になりました。
OptiPNGの `-o 7` オプションで圧縮した際にはおよそ **10%減** だったのに比べるとzopflipngが優秀なのがわかります。
Photoshopで作ったPNG画像をそのまま使っている場合には効果が高そうです。
クライアントサイドJavaScript(DOM)の基本知識まとめ(2)

##イベントハンドラー/イベントリスナーについてまとめ

###イベントドリブンモデル
クリックされた時やページがロードされた時など、イベントが発生した時に処理を実行するプログラミングモデル。

###イベントハンドラー/イベントリスナー
イベントに対応して処理内容を定義する関数

###イベントの発生で処理を実行させるには以下のことを定義しておく必要がある。

- どの要素でイベントが発生したか
- どのイベントを発生させるか
- どのイベントハンドラー/イベントリスナーに関連付けをするのか

これらの定義をおこなう方法にはonXxxxxを利用する方法とaddEventListener("Xxxxx")を利用する方法があるが、できるかぎりonXxxxxは利用せずaddEventListener("Xxxxx")を利用する。
onXxxxxによるイベントハンドラーの設定には一つ問題があり、同一の要素/イベントに対して複数のイベントハンドラーを関連付けできないので、再代入で上書きされてしまう。

###onXxxxxイベント

```javascript:onXxxxxによるイベントハンドラーの登録(1)
   window.onload = function(){statements};
   //windowオブジェクトで発生したloadイベントに対してstatements処理を関連付けさせる
```

イベントハンドラー（関数）は別に定義することも可

```javascript:onXxxxxによるイベントハンドラーの登録(2)
   function getTriangle(base,height){
     console.log( base * height / 2);
   };

   window.onload = getTriangle(5,2);
   //ページ読み込みと同時にgetTriangle関数を実行
```

onXxxxxによるイベントハンドラーの登録で複数のイベントハンドラーを登録しようとすると上書きされてしまう。

```javascript:onXxxxxによるイベントハンドラーの登録(3)
   window.onload = function(){
     alert('登録1');
   };

   window.onload = function(){
     alert('登録2');
   };
   //複数のイベントハンドラーをonXxxxxで登録しようとすると後から登録した方で上書きされてしまう。
   //この例だとページ読み込み完了後にアラートされるのは'登録2'の方のみ
```

###addEventListener("Xxxxx")イベント
上のような問題があるため、極力addEventListener("Xxxxx")の方を使う。イベントリスナーは同一要素の同一イベントに対して複数の処理を関連付けできるイベントハンドラーという理解でok。
onXxxxxがイベントを代入しているというイメージに対してaddEventListener("Xxxxx")はイベントを登録しているというイメージ。

```javascript:addEventListener("Xxxxx")によるイベントリスナーの登録(1)
   window.addEventListener("load",function(){statements},false);
   //windowオブジェクトで発生したloadイベントに対してstatements処理を関連付けさせる。
```

addEventListener("Xxxxx")であれば複数のイベント登録ができる。

```javascript:addEventListener("Xxxxx")によるイベントリスナーの登録(2)
   window.addEventListener("load",function(){
     alert('登録1');
   },false);

   window.addEventListener("load",function(){
     alert('登録2');
   },false);
   //ページ読み込み完了後に'登録1'と'登録2'が登録した順に両方アラートされる。
```

また、loadイベントはDOMContentLoadedで書き換えることができる。loadイベントがコンテンツ本体とすべての画像がロードされたところで実行されるのに対し、DOMContentLoadedイベントはコンテンツ本体がロードされたところで実行、つまり画像ロードを待つことなく実行できるので、loadより早いタイミングで実行できる。
よってDOMContentLoadedを利用した方が幸せ。
画像の読み込みが必要な場合はloadを利用。

```javascript:addEventListener("Xxxxx")によるイベントリスナーの登録(3)
   document.addEventListener("DOMContentLoaded",function(){
     alert('Hi');
   },false);
   //documentオブジェクトの読み込み完了後に'Hi'をアラート
```

###参照
[旧石器時代のJavaScriptを書いてる各位に告ぐ、現代的なJavaScript超入門 Section1 ～すぐにでも現代っぽく出来るワンポイントまとめ～](http://qiita.com/gaogao_9/items/ec2b867d6941173fd0b1#on%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E6%A5%B5%E5%8A%9B%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84-no_good)

[JavaScript本格入門　山田祥寛　著](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/477418411X/ref=sr_1_1?ie=UTF8&qid=1486178808&sr=8-1&keywords=javascript)
jquery.tabledit jqueryその場で編集 inplaceeditor

これが一番使いやすいのでメモ

http://markcell.github.io/jquery-tabledit/

```js

<? $this->start('script');//script or css?>

    <script src="/js/jquery.tabledit.min.js"></script>

<script>

    $(function () {
        $('#example1').Tabledit({
            url: '/hoges/table_ajax/99/',
            columns: {
                identifier: [0, 'id'],
                editable: [[1, 'nickname'], [2, 'firstname'], [3, 'lastname']]
            },
            onAjax: function(action, serialize) {

                //Ajax開始時
                console.log('onAjax(action, serialize)');
                console.log(action);
                console.log(serialize);
            },
            onSuccess: function(data, textStatus, jqXHR) {


                console.log('onSuccess(data, textStatus, jqXHR)');
                console.log(data);
                console.log(textStatus);
                console.log(jqXHR);
            },
            buttons: {
                edit: {
                    class: 'btn btn-sm btn-default',
                    html: '<span class="glyphicon glyphicon-pencil"></span>',
                    action: 'edit'
                },
                delete: {
                    class: 'btn btn-sm btn-default',
                    html: '<span class="glyphicon glyphicon-trash"></span>',
                    action: 'delete'
                },
                save: {
                    class: 'btn btn-sm btn-success',
                    html: '保存'
                },
                restore: {
                    class: 'btn btn-sm btn-warning',
                    html: 'Restore',
                    action: 'restore'
                },
                confirm: {
                    class: 'btn btn-sm btn-danger',
                    html: '削除'
                }
            }
        });
    });

</script>

<? $this->end(); ?>


    <div role="tabpanel" class="tab-pane fade active in" id="table1">
        <div class="table-responsive">
            <table class="table table-striped table-bordered" id="example1">
                <thead>
                <tr>
                    <th>#</th>
                    <th>Nickname</th>
                    <th>Firstname</th>
                    <th>Lastname</th>
                </thead>
                <tbody>
                <tr id="1">
                    <td>1</td>
                    <td>markcell</td>
                    <td>Celso</td>
                    <td>Marques</td>
                </tr>

                <tr id="2">
                    <td>2</td>
                    <td>markcell</td>
                    <td>Celso</td>
                    <td>Marques</td>
                    </tr>

                </tbody>
            </table>
        </div>
    </div>
```

一応スマホでも動く。
Xcodeで、シミュレータでは動くが実機に転送できない

#現象
実機を指定してビルドすると、こんなエラーが3つ出ます。

```
The operation couldn’t be completed. Unable to log in with account 'my acc'. An unexpected failure occurred while logging in (Underlying error code -1009).

No profiles for 'name app' were found: Xcode couldn't find a provisioning profile matching 'name app'.

Code signing is required for product type 'Application' in SDK 'iOS 10.2'
```


なぜかシミュレータでは問題なく動きます。

Xcode 8.2.1

#対策
provisioning profileに関連した問題っぽいのはわかるんですが、Accounts設定は問題なさそうに見えて頭を抱えることに。
参考リンクで似た話を見つけて、結局次のよくわからない対処でなおりました。。

1)Xcode => Preference => Account
2)自分のApple IDをいったん削除。
3)「＋」ボタンでおんなじAppleIDを追加。パスワードを打つ。
4)Xcode再起動。

これで復活しました。なんやねん。。


#参考リンク
http://stackoverflow.com/questions/41172843/simulator-can-run-project-but-device-cant-did-this
ここに、似た話がありました
activerecord-importでユニークキー制約に引っかかるようにする


[activerecord-import](https://github.com/zdennis/activerecord-import) でバルクインサートした際にデフォルトだとテーブルに設定したユニークキー制約に引っかからない事象が起きたので、その原因と解決策を書きます。

## バージョン

- activerecord-import: 0.16.2
- activerecord: 5.0.1
- MySQL: 5.7.12

## tl;dr

- `.import` メソッドを使う時に `on_duplicate_key_update: false` する

## 起きた事象

ユニークキー制約をかけたテーブルのモデル `Hoge` に対してバルクインサートの処理を書いていました。
コードだと以下のようなものです。

```.rb
hoges = params[:hoges].map do |hoge_params|
  Hoge.new(inspect_create_hoge_params(hoge_params))
end
Hoge.import(hoges)
```

制約に引っかかっているデータが送られてきた時は例外が発生することを期待していたのですが、実際やってみると最初の1件だけ保存されるという動きをしていました。

## 原因

発行されているSQLのログを見ると、

```.sql
INSERT INTO `hoges` 
(~~中略~~) 
ON DUPLICATE KEY UPDATE `hoges`.`updated_at`=VALUES(`updated_at`)
```

`ON DUPLICATE KEY UPDATE` が怪しいなと思い[リファレンス](https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html)を調べてみると、

> If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, MySQL performs an UPDATE of the old row.

ユニークキー制約にかかったレコードを保存する時に古いレコードをupdateする、というまさに今起こっていた動きが書いてありました。

## 解決策

コードを追いかけてみた結果、 `on_duplicate_key_update` をfalseにしたら `ON DUPLICATE KEY UPDATE` をしないように見えたので、

```.rb
Hoge.import(hoges, on_duplicate_key_update: false)
```

としてみたところ、期待した例外が発生するようになりました。SQLの方も

```.sql
INSERT INTO `hoges` 
(~~中略~~) 
```

と `ON DUPLICATE KEY UPDATE` が消えていることも確認できました。
[tiny fix] zsh + tmux で端末に表示されてる文字列を補完する

# 背景
tmuxのバージョンを`２．３`に上げたところ、うまく動かなくなったので少々修正しました。

# 内容
```zsh
HARDCOPYFILE=/tmp/tmux-hardcopy
touch $HARDCOPYFILE
dabbrev-complete () {
  tmux capture-pane -b 0 && tmux save-buffer -b 0 $HARDCOPYFILE && tmux delete-buffer -b 0
  local reply=($(sed '/^$/d' $HARDCOPYFILE | sed '$ d'))
  compadd -Q - "${reply[@]%[*/=@|]}"
}
zle -C dabbrev-complete menu-complete dabbrev-complete
bindkey '^O' dabbrev-complete
bindkey '^O^_' reverse-menu-complete
```
[zsh + tmux で端末に表示されてる文字列を補完する](http://qiita.com/hamaco/items/4eb19da6cf216104adf0) を元に `tmux capture-pane` 時にバッファ指定をするように修正しました。
MacでHoloLens開発をする時のメモ(完全自分用

こんにちは、最近HoloLens開発にはまっている大学生です。

HoloLensを開発するにあたって一つ残念なことがありました。

それはMacでは基本的には開発できないということです。

それは、WindowsでiPhone開発できない時と同じくらいの悲しみを産みました。

そこで、なんとかMac機だけでHoloLens開発を完結できないかと調べました。

という時にこの記事を発見

[HoloLensアプリをMac環境で開発・実機で動作確認](http://qiita.com/dengurix2@github/items/64ae718fd0df45efd838)

はい、できました。(ありがとうございます！

Windows10とParallels Desktop買ったので 5万円程度の投資...

Parallels Desktopだと、MacとWindowsで同じファイルにアクセスできるので、MacのUnityで開発して、WindowsのUnityにリアルタイムに反映させることができるんですね!

感動です。

つまった点をここにメモしておきます。

+ 最初Mac内のWindowsでBuildしようとした時、Visual Studioのインストール時の設定が足りなくてBuildできなかった。

+ 配置に失敗する
→ HoloLens内の開発用アプリを削除すると直る


基本的にチュートリアルを読みながらやってました。
参考になったチュートリアル

http://2vr.jp/2016/05/10/unity-hololens-tips/

https://developer.microsoft.com/en-us/windows/holographic/install_the_tools

https://developer.microsoft.com/en-us/windows/holographic/holograms_100

https://developer.microsoft.com/en-us/windows/holographic/holograms_101
cakephp3 modified のみ変更 touch

cakephp3 で modifedのみ変更する場合。

```php
$this->addBehavior('Timestamp', [
'events' => [
'Model.beforeSave' => [
'created' => 'new',
'modified' => 'always'
]
]
]);

```


```php
// use Cake\ORM\TableRegistry;
        $this->Users = TableRegistry::get('Users');

        $valid = $this->Users->get(1859);//ユーザーID
        $this->Users->touch($valid,'Model.beforeSave');
        $this->Users->save($valid);
```


これで modified のみ変更することができます。
jQueryとアロー関数の微妙な関係

昨日の[JSLounge #0 jQueryだけで頑張らないWeb開発ハンズオン](https://jslounge.connpass.com/event/49443/)で@potato4dに教えてもらったアロー関数の話。

# jQueryからvue.jsへ

ハンズオンのテーマは、jQueryを使って書かれたサイトをvue.jsに置き換えようというものでした。

```
$("button[type='submit']").html("<i class='glyphicon glyphicon-repeat'></i>");
$.ajax({
  url: "https://example.com/events"
}).done(function(data){
  $("button[type='submit']").html("送信する");
})
```

ボタンをローディング表示にしてAPIを呼び出し、終了後にボタンを元に戻す、というコードです。

ハンズオンでできる範囲ということで、API呼び出しそのものは$.ajaxのままでやってみましょう(つまり、ボタンの書換部分をvue.jsのv-ifで書くところをやってみよう)という感じでした。

```
<button v-if="!loading">送信する</button>
<button v-else><i class='glyphicon glyphicon-repeat'></i></button>
```

``` v-if='loading' ```をつけたボタンと ``` v-else ```をつけたボタンを用意すると、JSコードでvue.loadingを変更するのに応じてボタンの表示が切り替わります。

```
this.loading = true;
$.ajax({
  url: "https://example.com/events"
}).done(function(data){
  this.loading = false;
})
```

このコードで実際動かしてみると、ボタンを押してローディングにはなるのですけど、その後ボタンがもとに戻らなくなってしまいました。

# thisとアロー関数

```
}).done(function(data){
  this.loading = false;
})
```
問題はこの部分です。

jQuery単体でもたまに問題になるのですが、ajax関数のコールバック内のthisは、外部でのthisと異なるものを指します。```$(this)``` って書いたら動かなくなるアレです。
このため、``` this.loading ```はvue.jsオブジェクトではない別のオブジェクトのloadingプロパティ(たぶん誰も参照していない)を書き換えるだけの空回り状態になってしまって、ボタンがもとに戻らなくなってしまっています。

@potato4dは「あとで説明するので、いったんこう書き換えてください」という豪快な説明で:grinning: こう書き換えました。

```
}).done((data) => {
  this.loading = false;
})
```

説明してもらうのを待てずにググったところによると、JavaScript ES2015で導入されたアロー関数というものです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/arrow_functions

従来の``` function(data){ ```で書くと、その中のthisは文脈によって変化します。
一方アロー関数を使った場合、関数の中であっても、thisは関数の外と同じものを指します。つまりこの場合だと引き続きvue.jsオブジェクトにアクセスすることができるので、``` this.loading = false; ```はvue.jsのコードとして動作します。

# アロー関数とIEの微妙な関係

アロー関数は新しいJavaScriptの書き方なので、環境によって動かないことがあります。具体的には、IE11、iOS９、Android4あたりでは動きません。
http://caniuse.com/#feat=arrow-functions

vue.jsを勉強しに来た参加者がIE11なんて使わないことを見越してアロー関数書いた @potato4d はハンズオン上手だと思うのですけど、実際運用する上でAndroid4をバッサリ切るのは無理なので、その辺のところを質疑応答のときに聞いてみました。

まず、IE11を含む古いブラウザでも動かす方法として、[Babel](https://babeljs.io/)をつかって新しい書き方を古いOSでも動くコードにコンパイルしてしまう方法があります。ある程度の規模になるとこのやり方が必須だし、個人的にはこっちを使いたいのですが、「``` npm ```を入れて``` webpack ```から``` gulp ```をつかって``` Babel ```を呼び出してね」というと、環境設定だけでハンズオンが終わってしまうし、jQueryから乗り換えようという人には厳しい予感がします。

で、お手軽な解決法としては、従来のjQueryでも使われていたselfを使うテクニックが使えます。

```
var self = this;
self.loading = true;
$.ajax({
  url: "https://example.com/events"
}).done(function(data){
  self.loading = false;
})
```

selfにthisを退避した上で使うことで、doneの中でも外と同じオブジェクトにアクセスすることができます。

vue.jsを使うに当たってはwebpackを始めとした近代JavaScript環境の勉強が必須だと思っていたのですけど、なるほどコンパクトにまとめる方法もあるものだなあと思いました。
pythonでデバッグに役立つ情報を色々表示してみる

## 現在のクラス名を表示してみる

```python
class HogeClass:

  def hoge(self):
    print(self.__class__.__name__)

if __name__ == '__main__':
  HogeClass().hoge()
```

## 現在の関数名を表示してみる

```python
from inspect import currentframe
def hoge():
  print(currentframe().f_code.co_name)

if __name__ == '__main__':
    hoge()
```
機械学習論文読みメモ_38


[Principal Geodesic Analysis for Probability Measures under the Optimal Transport Metric](https://papers.nips.cc/paper/5680-principal-geodesic-analysis-for-probability-measures-under-the-optimal-transport-metric.pdf), NIPS2015
optimal transform distanaceとして知られるWasserstein distanceはある距離空間上で定義された確率測度を比較する上で有用である。
Wasserstein distanceが付与された確率測度空間をWasserstein spaceと呼ぶ。
本論ではこの空間上においてPCAを行うWasserstein principal geodesic analysis を考え、特に従来手法より一般的でスケーラブルな手法を提案する。
通常のPCAはユークリッド空間やヒルベルト空間上で行われるが、これはリーマン多様体上にも拡張する事が可能である。
この場合、ヒルベルト空間に対して定義出来る無限次元リーマン多様体を考えると、例えば一般化されたセントロイドであるFrechet mean周りでtangent spaceへの写像を行い、その上でPCAを行う手法がある。
しかしWasserstein spaceでは、多様体からtangent spaceへのexponential mapが定義出来ない問題があった。
従来研究では限定された条件においてそれに対処する手法が提案されてきた。
本論ではより一般的でスケーラブルな手法を提案する。
この手法では、Wassetstein distanceと多様体上の測地線計算の双方において近似計算を導入し、様々な測度に対して適用可能なアルゴリズムを提案する。
さらにvelosidy fieldを２つ定義し、その最適化問題として主成分を求める問題とする。
この最適化問題は非凸かつnon-smoothなので、そのsmoothな上界を用いて最適化する。

[Copeland Dueling Bandits](http://www.cs.ox.ac.uk/people/shimon.whiteson/pubs/zoghinips15.pdf), NIPS2015
dueling bandit問題を扱う。
この問題では、通常のbanditとは違い、一度に２つの対象を選択し、どちらがより好ましいかが、確率的に選択され帰ってくる場合である。
この設定において従来研究では、Condorcet winner、ある対象が存在しそれはその他の全て対象より確率0.5より高い確率でより好ましいとなる、が存在する事を仮定し分析されてきた。
しかし現実においてはCondorcet winnerが存在しない場合は多い。
本論ではCondorcet winnerが必ずしも存在しない場合を考え、代わりにCopeland winner、ある対象に対して好ましいとされる確率が0.5より大きいその他の対象が最大となる、を扱う。
この場合、Copeland winnerは複数いる場合があり、それらを元にregretも計算される事となる。

[A hybrid sampler for Poisson-Kingman mixture models](https://pdfs.semanticscholar.org/3a53/1dc5acbcac2d399d1e19fe3f27afb009697e.pdf), NIPS2015
事前分布がPoisson-Kingman分布になるようなBayesian nonparametric mixture modelに関するMCMCサンプリング手法を提案する。
提案手法では、モデルの無限次元因子の陽な表現法を低いメモリ、記憶領域にて実現する。
従来研究では、無限次元事前分布を有限次元分布に切り取る事で置き換えるconditional sampler、周辺化確率表現を通して無限次元表現を回避するmarginal samplerの2通りによりサンプリングが実現されていた。
しかしながらどちらの手法を無限次元を陽に考えないため、その性能に制限があった。
本論では広い範囲のbayesian nonparametric mixture modelをカバー出来るPoission-Kingman分布を利用したサンプリング手法を提案する。
この分布はnormalizedされたcomplete random measure(CRM)の一般化された分布であり、例えばPoisson processはCRMの一種である。
Poission-Kingman分布の良い特性としては、ほとんど確実に離散的であるという事である。
これは、この分布によりrandom partionを導入した時、互いに排他的な区分領域間においては互いに独立である事が言える事である。
これにより同じ領域に属するサンプルが得られた時に、それらのサンプルがある確率で同一のものとみなすモデルを導入可能になる。
またこのrandom partitionはまたexchangeabilityを持つため計算時に有用である。
この分布によるサンプリングはstick breaking processとの関連がある。
この分布は無限次元因子を陽に表す事になるが、実際の計算においては、各有限なpartition(cluster)に関する計算のみを行えば良い事になる。
golangのloggerを作ってみた

# go-easylog

https://github.com/go-easylog/el

golangでlogを吐くにあたって便利そうなパッケージは世の中たくさんあるのですが、個人的に多機能なものより、さくっと使っておきたいときに使える小回りのきくものが欲しいのですが、見つけられませんでした。

* とりあえず、すぐ使えて、すぐ出力できる。
* そのために初期設定をほとんど必要としない。
* ログレベルが設定できる
* ロガーインスタンスの取り回しを気にしないで良い
* しっかりスレッドセーフ
* **運用レベルになってもローテーション回すくらいはできる**

el自体が出せる情報は時間とエラーレベルのみですが、`"github.com/pkg/errors"`の出力に対応しており、el.SetDebug()を呼び出しておけば、error型に対してラップされた情報を出すことができます。
# Install
```bash
$ go get github.com/go-easylog/el
```

# Example
```go

package main

import "github.com/go-easylog/el"

func main() {

    // Default output level is "WARN"
    el.Warn("Output warning")
    el.Trace("This comment is don't output to log")

    // Set level for log
    el.SetLogLevel(el.TRACE)

    el.Info("This will be outputed")

    if err := el.SetRotateLog("./%Y/%M/%D.log"); err != nil {
        panic(err)
    }
    // %Y <- year  (YYYY)
    // %M <- month (MM)
    // %D <- day   (DD)
    //
    // "./prefix-%Y-%M.log"  <---  It is possible to specify like this
    //                             This pattern in one month's rotation


    el.Trace("this comment outputing to file")


    // no rotate pattern
    if err := el.SetRotateLog("./no-rotate.log"); err != nil {
        panic(err)
    }

    el.Error("this file is no rotate")
    el.Fatal("error exit") // <- Forced kill here

    el.Trace("this text is no outputed") // <- This is not output
}
```
```:ターミナル出力
$ go run main.go
2017-02-04 04:08:03 [WARN] Output warning
2017-02-04 04:08:03 [INFO] This will be outputed
2017-02-04 04:08:03 [FATAL] error exit
exit status 255
```
```:2017/02/04.log
2017-02-04 04:08:03 [TRACE] this comment outputing to file
```
```:no-rotate.log
2017-02-04 04:08:03 [ERROR] this file is no rotate
```

## Example 2
( github.com/pkg/errors 対応 )

```go:main.go
package main

import (
    "fmt"

    "github.com/go-easylog/el"
    "github.com/pkg/errors"
)

func ErrorFunc() error {
    return fmt.Errorf("base error")
}

func main() {

    // set debug mode
    el.SetDebug()
    if err := ErrorFunc(); err != nil {
        el.Error(errors.Wrap(err, "Error by ErrorFunc() <-- (1)"))
    }

    // if when release mode
    // not outputs the error details 
    el.SetRelease()
    if err := ErrorFunc(); err != nil {
        el.Error(errors.Wrap(err, "Error by ErrorFunc() <-- (2)"))
    }
}
```


```:ターミナル出力
$ go run main.go
2017-02-04 04:34:49 [ERROR] base error
Error by ErrorFunc() <-- (1)
main.main
        /Users/.../exsample_el/main.go:18
runtime.main
        /usr/local/Cellar/go/1.7.4_2/libexec/src/runtime/proc.go:183
runtime.goexit
        /usr/local/Cellar/go/1.7.4_2/libexec/src/runtime/asm_amd64.s:2086
2017-02-04 04:34:49 [ERROR] Error by ErrorFunc() <-- (2): base error
```
#　今後の予定
とはいえファイル名くらいは出せるようにしたい。  
フォーマットも設定変えられるようになると好みも反映しやすくて使い易いのかなと思ってたりするので、今後検討してみます。
Asterisk13 + CentOS6.7でSIPサーバ構築

IP電話作りたかったので、SIPサーバ構築してみた。
参考になったありがたい記事の備忘録。

http://qiita.com/kitsuki00/items/27f0aeede8d96980ecd5#asterisk%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

http://blogs.digium.com/2015/02/24/install-asterisk-13-pjsip-centos-6/

Asterisk13 + CentOS6.7の環境だとPJSIP2.4以上の場合makeコマンドでエラーになった。
エラーに関しては詳しい内容もなく、検索しても出てきませんでした。

だけど2.3に落としたら意味わからんけどできました！！
Webの直感的なUIとは

なんとなく今まで言語化出来ていなかった部分をメモ

良くWebのUIの話で`直感的だ`とか`直感的でない`とか言う話がありますが、そもそも直感的ってなにか。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/7980/9ec3865e-80d4-c25d-df4a-ce1e601ce997.png)

これもまだふわっとしていてわかりづらい。一個自分の中でまとまったのが

__直感 → `勘`や`経験`に基づいて、感じること__

その人の`経験`があるからこそ、推測や思考なしで`直感`で分かるんだと思います。

さらに進めて、じゃあ`直感的であるUI`というのはなにか？

__そのUIが表現したい、解決したい世界に即した現実的な表現方法__

とまとめました。最も重要なのが、`現実的な`という部分です。

ふわっとした例え話ですが、小さな川を渡らなくてはならない時に、「さぁどうする？」と聞かれたら`泳ぐ`とか`船を漕ぐ`が直感ですぐ浮かぶと思います。ジャンプして超えろ、と言われてもとても現実的ではないです。ですが、これが空を自由に飛べる魔法の世界だったとて「さぁどうする？」と聞かれたら`空を飛んで超える`ということになると思います。つまり、その世界での現実的な解です。逆に言うと、その世界に即した現実的な形にしないと、とても滑稽なものになるんじゃないのかな、と思います。`直感から外れたUIを提供する`というのは今の話で言うと、空を飛ぶことが出来るのに執拗に「泳げ！泳げ！泳げ！」と言われている気分になるというか。なんか滑稽で気分が悪くなります。

で、Webで言う直感というと何かというと、コンピューターが無い時代は殆どのものを紙に記入してそれをファイリングして、情報の記録と共有を図っていたと思います。それが最近では、コンピューターに情報を入れると、とたんにインターネットを通じて全世界に共有できる・半永久・半無限に記録もできる。それはとても便利だ、と電子化が進んでいるわけです。なので、極端な事を言うとWebで解決したい課題はほとんどのものが今まで現実の世界で紙で解決してきたものです。なので、その紙だった時の表現とあまりにも乖離したUIを見ると「直感的じゃないなぁ」と感じるんじゃないかな、と思います。（これがデジタルネイティブの時代が進んでいくとどうなるのかわかりませんが。スマホ、はデジタルネイティブにとって直感に近いものかもですね）

一方で、じゃあ今まで紙でなかったものをWebで表現しないといけないときもあると思うのですが、そういう時に大切になってくるのが、良く言われる`統一性`なんじゃないかな、と思います。同じ目的を達成する際には同じUIをひたすら統一して提供することで、徐々に徐々にその新しいUIがユーザーの`経験`として蓄積され、段々とそれが直感的になっていくんじゃないのかな、と思います。

もう少し業務に近い話をすると、Webで何かの情報を編集するためのUIの表現として

「ダイアログで編集する」 or 
「ダイアログを開かなくても直接値を書き換えることが出来る」

みたいなUIを見ると思います。「直接値を書き換える」というのは現実の世界で言うと消しゴムで値を消して、鉛筆で書き込むことで、「ダイアログで編集する」のは、役所で申請用紙をもらって、申請を行うのに近いと思います。今までUIを考える時に「編集」というアクションに対して「UI」を一つ（例えばダイアログ）に統一する、ということをやっていたんですが、それは違くて、編集したいモノや課題に対して適切な、直感的なUIを提供することが最も必要と思います。

## まとめ

ということで、`直感的なUIを作る`には「解決したい課題や、過去それを解決してきた手法をしっかりと調べて考えて、ユーザーの`経験`を大切に（＝ユーザーフレンドリー）して、ユーザーの目的が果たされることを助ける見た目の表現を作る」ことと思いました。
iPhoneとRN42でBluetooth

# はじめに
この記事は、

* [mbed LPC1768](https://developer.mbed.org/platforms/mbed-LPC1768/)
* [RN42VX](http://www.microchip.com/wwwproducts/en/RN42XV) 
* iPhone

を使って、RN42とiPhoneでBluetooth通信した時の備忘録です

# 構成

PC - LPC1768 - RN42 - iPhone

（RN42評価キットならLPC1768を介さずにPCと繋がる）

### PC - LPC1768

* USBでつなぐ
* Windows PC の場合はCOM port として認識するために[ドライバ](https://developer.mbed.org/handbook/Windows-serial-configuration)が必要
* PCからLPC1768にコマンドを送るためのターミナルソフト（Mac : [CoolTerm](http://freeware.the-meiers.org/)/Win : [Tera Term](https://ja.osdn.net/projects/ttssh2/) など）を用意する
* 下記コードを[mbed developer site](https://developer.mbed.org/)でコンパイルしてLPC1768にダウンロードする
* このコードにより、LPC1768は、PCとRN42間のデータの送受信を仲介するようになります（ついでに送受信のたびにLEDがチカチカする）

（参照元：https://developer.mbed.org/users/simon/notebook/rn-42-hid/）

```main.c
#include "mbed.h"
 
#define BAUDRATE 115200
 
Serial RN42(p9,p10);
Serial PC(USBTX, USBRX);

DigitalOut RN42_led(LED1);
DigitalOut pc_led(LED2);

char buf;
 
int main(void)
{
    RN42.baud(BAUDRATE);
    PC.baud(BAUDRATE);

    while (1) {
        if(PC.readable()) {
            buf = PC.getc();
            RN42.putc(buf);
            PC.putc(buf);
            pc_led = !pc_led;
        }
        if(RN42.readable()) {
            PC.putc(RN42.getc());
            RN42_led = !RN42_led;
        }
    }
}
```

### LPC1768 - RN42

* http://lumenbolk.com/?p=1335 にわかりやすい図がありました
* http://samirlovgren.se/?page_id=1299 を参考にしてRN42を設定する（下記コマンドをターミナルソフトから入力する）

```
$$$       # コマンドモード移行 (RN42のチカチカがはやくなる)
SF,1\r    # 工場出荷状態に戻す
R,1       # 設定を反映させるためREBOOT

$$$       # コマンドモード移行 (RN42のチカチカがはやくなる)
S~,6\r    # プロファイル設定（6はHID（キーボードなど））
SN,name\r # デバイス名設定(nameは好きな名前)
SC,0024\r 
SD,0704\r
ST,253\r
SO,%\r
T,1\r
SM,0\r    # slave mode
SP,1234   # pin code設定（1234は好きな数字で可）
SA,4\r    # pin code認証に設定
D\r       # setting確認
O\r       # other setting確認
R,1       # 設定を反映させるためREBOOT
```

### RN42 - iPhone

* Bluetoothで通信する
* iPhoneのBluetoothをONし、RN42と接続する（設定したPinCodeを入力（未設定なら初期値の1234））
* iPhoneでメモ帳などを開き、PCのターミナルで文字を打つとiPhoneに入力できる！！！
Juman(Juman++) & KNPの動作を高速化するパッケージを作った話

# この記事で紹介すること

- KNPのサポートパッケージ作った話
- 若干だけ(1.6倍~2倍)処理速度が向上する[^1]
    - Juman++ & KNPの組み合わせでは10倍近く、速度向上

# KNPとは・・？

「日本語構文解析器」です。
こんなことができます。

- 格解析
- 構文解析
- 固有表現抽出　

[参考までに以前の記事を](http://qiita.com/Kensuke-Mitsuzawa/items/ca6967f0ce07a978f358)


## えっ、RNNでいいんじゃね？

DNN大流行期の今に「まだパージングやってんの？」と思われるかもしれません。
実際、工夫されたRNNを利用すると、[格タイプを当てるタスクで最高精度が出る](http://www.slideshare.net/hirokiouchi5/ss-70436298)ことがすでに示されています。実際、ソースコードも公開されてるので、もうこっちで良いんじゃないか・・・という気もします。

とはいえ、[解析対象の格はまだKNPが方が多い](http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/corpus/KyotoCorpus4.0/doc/rel_guideline.pdf)ですし、
KNPは格解析だけでなく、形態素情報から、構文情報もまとめて表示してくれるので、ツールとしては使い勝手が良いのです。

# KNPの少し困るとこ

解析速度があまり早くないです。
~~「MecabやCabochaの解析速度が早すぎなだけだ」という意見もあったりしますが~~

入力データが少しだけの時はあまり気にならないのですが、データ量が増えてくると、少しでも工夫したいものです。

とはいえ、中身は触りたくないところです。 

じゃあ、__「分散化しちゃえばいいじゃん」__という、安直なアイディアを形にしたのが、本記事で紹介するパッケージです。


# KNPの呼び出し処理を分散化してくれるパッケージを作ったった

## インストール

Pypiに登録したので、 `pip` でインストールできます。

```pip install knp-utils```

## 特徴

- シングルスレッドよりも早くなる (当たり前)
- 並列処理の割にはメモリ消費が少ない。マシンに優しい。
- KNP解析結果を得るための簡単なインターフェースを用意した
- コマンドラインインターフェース/Webアプリケーションをもってるので、Python関係ない人も使うことができる
- Python2.x/3.xの両方で動く
- pyknpを使いたい人も[こうすれば](https://github.com/Kensuke-Mitsuzawa/knp-utils-py/search?utf8=%E2%9C%93&q=pyknp_parsed_result+%3D+knp_obj.result%28input_str%3Dknp_parsed_obj.parsed_result%29)、うまくいく。

## 速度比較 (Juman & KNP)

早くなりました。入力文書数が増えるほど、差は大きくなる傾向があります。
下記の数値は40文書のときの比較です。

ちなみに`pexpect`, `everytime` とはマルチスレッド内部でJuman & KNPプロセスを扱うモード名です。
`pexpect`はJuman & KNPプロセスを起動しっぱなしにしておきます。
`everytime`は入力テキストの度にJuman & KNPを起動します。

```
pexpect mode, finished with :44.13979196548462[sec]
everytime mode, finished with :38.31942701339722[sec]
pyknp, finished with :64.74086809158325[sec]
```

## 速度比較 (Juman++ & KNP)

Juman++ & KNPの組み合わせ時の時間比較です。
Juman++(1.02)は「動作が遅いだの、なんだの」言われることを耳にします。
これはプロセス起動時のモデルファイル読み込みに時間がかかるからです。

なので、プロセスを起動しっぱなしにしておけば、早くなるわけです。単純な話ですね。

```
pexpect mode, finished with :48.096940994262695[sec]
everytime mode, finished with :64.07872700691223[sec]
pyknp, finished with : 602.032340992232452[sec]
```


## 動作内容

以下の処理を繰り返しているだけです。

- 入力文書をsqlite3 DBに格納
- マルチスレッドでJuman & KNP呼び出しを分散処理する [^2]
- 解析結果をsqlite3 DBに保存

# 最後に

手早く、お手軽に、楽しい構文解析ライフを！


[^1]: 40文書の時の差分。入力文書数が多いほど、速度は大きくなります。
[^2]: multiprocessの方が早いのですが、エラーが出てしまい、うまくいきませんでした(´・ω・`)
複数ボタンのあるFormで押されたボタンを判断する


## 判断方法
- ボタンにname属性を利用して、モデルバインディングで取得する。
- JavaScriptでResponsデータを操作する。
- セレクター属性を作成し、必要なアクションにそのセレクター属性を設定する。

２番目のJavaScriptによる方法については、個人的には利用しないので説明しません。

## ボタンにname属性を利用する（nameがボタン毎に異なる場合）

```csharp:ビューのコード
@using(Html.BeginForm())
{
    @Html.AntiForgeryToken();

    // テキストボックス等の入力項目の設定

    <input type="submit" name="Search" value="検索">
    <input type="submit" name="Clear" value="クリア">
}
```

```csharp:コントローラーのコード
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string search, string clear)
{
    if (search != null)
    {
        // 検索ボタンが押された場合の処理
    } 

    if (clear != null)
    {
        // クリアボタンが押された場合の処理
    } 
}
```
- ActionResult Indexのパラメーター（search、clear）には、ボタンのvalue属性の値を受け取れます。
（searchボタンを押した場合は、パラメーターsearchに”検索”が入り、clearはブランクです。
　clearボタンを押した場合は、パラメーターclearに”クリア”が入り、searchはブランクです。）
- ・name属性とパラメーターで大文字、小文字の違いがあっても正常にモデルバインディングされます。

## ボタンにname属性を利用する（nameが全てのボタンで同じ場合）

```csharp:ビューのコード
@using(Html.BeginForm())
{
    @Html.AntiForgeryToken();

    // テキストボックス等の入力項目の設定

    <input type="submit" name="cmd" value="検索">
    <input type="submit" name="cmd" value="クリア">
}
```

```csharp:コントローラーのコード
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string cmd)
{
    if (cmd == "検索")
    {
        // 検索ボタンが押された場合の処理
    } 

    if (cmd == "クリア")
    {
        // クリアボタンが押された場合の処理
    } 
```
この方法ではValue属性が同一のボタンが複数ある場合は正しく認識できません。
（検索ボタンが２個ある場合など）

## セレクター属性を作成する

この例では、ExtensionsフォルダにButtonAttributeクラスファイルを作成します。
（実際はどのフォルダでも問題ありません）

```csharp:セレクター属性のコード
using System.Reflection;
using System.Web.Mvc;

namespace Project.Extensions
{
    public class ButtonAttribute : ActionMethodSelectorAttribute
    {
        // アクションメソッド付加時に設定したボタン名を保存
        public string ButtonName { get; set; }

        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            // 設定したボタン名と同名のデータが存在するかチェック（Requestで返ってきているか）
            return controllerContext.Controller.ValueProvider.GetValue(ButtonName) != null;
        }
    }
}
```

```csharp:ビューのコード
@using(Html.BeginForm())
{
    @Html.AntiForgeryToken();

    // テキストボックス等の入力項目の設定

    <input type="submit" name="Search" value="検索">
    <input type="submit" name="Clear" value="クリア">
}
```

```csharp:コントローラーのコード
using Project.Extensions;

[HttpPost]
[Button(ButtonName = "Search")]
[ValidateAntiForgeryToken]
public ActionResult Index()
{
    // 検索ボタンが押された場合の処理
}
```
- アクションメソッドに`[Button(ButtonName = "XXXXX")]`を付加する。
- ”XXXXX"には、このアクションメソッドを実行させたいボタンのname属性値を設定する。
- ボタンのname属性値と[Button(ButtonName = "XXXXX")]で大文字、小文字の違いがあっても
  正常に機能します。

## どれを使えばいいのか
セレクター属性を作成して押されたボタンを判断するのがMVC的な方法なのかと思います。
middleman-akcms フレームワーク構想

## middleman ベースで作りたいと思ってること

- middleman-blog だとソースファイル名に日付をつけることが前提になってるのがイヤ（source template かえて frontmatterに date: つければいいんだけど）
  - hack してみたけど、あんま美しくならない
- game/kancolle/event/2015-summer.html.md をつくると、自動的に game/index.html, game/kancolle/index.html, game/kancolle/event/index.html にサマリー作ってほしい
  - https://github.com/yterajima/middleman-tansu が近い？
- デザインは http://grabacr.net/ さんとこがいい感じ
- archives は月別があればいい
- 連載記事サポート機能
  - software/middleman/01-ready.html.md, .../02-start.html.md  とかすると title に自動的に 第n回とか入ってほしい
- pagination は欲しい
- tag はあんま使わない

ってんで
http://atarukodaka.github.io/software/middleman/middleman-akcms.html
のように動くのを akcms と銘打って https://github.com/atarukodaka/middleman-akcms/
としてみたけど、いろいろごちゃごちゃしてきてどうしようかと。

## 問題、提案など
- resource にインスタンスをつけたいんだけど、Middleman::Sitemap::Resource 直にモンキーパッチあてるのは避けたいし、
  - manipulate\_resource\_list() で each resource に extend してもいいんだけど、pagination するときに ProxyResource を new すると extend されてないんでモニョ. clone してもパラメータ上書きできないし
  - link template は apply_uri_template するよいか proxy resource へのハッシュを持っておいて link_to() するほうが楽だと思うんがねえ
- 自動サマリー、タグ、アーカイブ、ペジネーションなどをまとめるとごちゃごちゃするので別にするか
  - タグ、アーカイブは、v4 だと collection 機能でサクッとできるっぽいし
DockerでJupyterLabを構築する

![image](https://qiita-image-store.s3.amazonaws.com/0/120222/3be6004d-a136-710a-2061-7573c95b2b10.png)

## 動機
Pythonでデータ分析をする環境が欲しいだけなのに、なんちゃらenvとかやってるうちに気力が萎えてしまう

2018年03月追記
Colaboratory という素晴らしいサービスが出ております。ちょっと触るくらいなら断然こちらが簡単です！
https://colab.research.google.com/

## 前提
既に`docker`と`docker-compose`が使えるようになっているとします。

## 手順

```text:Dockerfile
FROM jupyter/datascience-notebook
MAINTAINER Kenta Mukai

RUN pip install jupyterlab
RUN jupyter serverextension enable --py jupyterlab
```

追加でインストールしたいpythonのライブラリがあれば、
> RUN pip install jupyterlab

の下に書き加えてください。

notebookを置くためのdirectoryを作っておきます。

```shell-session
$ mkdir work
```

オプションが多いのでdocker-composeを書きます。

```text:docker-compose.yml
version: "2"
services:
  jupyterlab:
    build:
      context: .
    user: root
    ports:
      - "80:8888"
    volumes:
      - "./work:/home/jovyan/work" # ← notebookをホストと共有したいためディレクトリをマウント
    environment:
      NB_UID: 500 # ← 作業するユーザーのUID 私の環境では500だったので500を指定
      GRANT_SUDO: "yes"
    command: start.sh jupyter lab
```

コンテナを実行します

```shell-session
# docker-compose build
# docker-compose up
```

```
jupyterlab_1  |     Copy/paste this URL into your browser when you connect for the first time,
jupyterlab_1  |     to login with a token:
jupyterlab_1  |         http://localhost:8888/?token=8669f6fc0b665b67a5e08017c6728976cb41558a46ce561a
```

コンソールにこのような出力が出るので、tokenをコピーしておきます。
ブラウザで80 portを開くと...

![image](https://qiita-image-store.s3.amazonaws.com/0/120222/cba03321-59ad-9017-4cbd-56172fe29e2d.png)

開きました。
先ほどのtokenでログインできます。

### パスワードの設定
パスワードを設定するにはJupyterLab上で下記を実行して

```
from IPython.lib import passwd
passwd()
```

`SHA1`の文字列が得られるので

```
sha1:c54efc741400:0e148aaf9a0d376f86742e68f89b7a95b395c35c
```

この文字列を起動時に渡すようにしてやります。
こうなります。

```text:docker-compose.yml
version: "2"
services:
  jupyterlab:
    build:
      context: .
    user: root
    ports:
      - "80:8888"
    volumes:
      - "./work:/home/jovyan/work"
    environment:
      NB_UID: 500
      GRANT_SUDO: "yes"
    command: start.sh jupyter lab --NotebookApp.password='sha1:c54efc741400:0e148aaf9a0d376f86742e68f89b7a95b395c35c'
```

```shell-session
# docker-compose up -d
```

これで設定したパスワードでログインできるようになりました:+1:

![image](https://qiita-image-store.s3.amazonaws.com/0/120222/b4063737-ab6e-3d8f-99c4-df9c171218e4.png)


## 使ってみる
DockerイメージのFROMである`jupyter/datascience-notebook`には、 `NumPy`や`Pandas`などデータ分析に関するパッケージが一通り含まれているので、すぐに使い始めることができます。どんなものが同梱されているか詳しくは最後のリンクを参照ください。

![image](https://qiita-image-store.s3.amazonaws.com/0/120222/d02163dd-1edc-d671-483c-5b028db612d8.png)

workディレクトリを作っておいたので、ここに既存のnotebookやCSVのデータを置くと、JupyterLabのhomeに出てきて便利です。

## リンク

Jupyter Notebook Data Science Stack
https://github.com/jupyter/docker-stacks/tree/master/datascience-notebook

JupyterLab
https://github.com/jupyterlab/jupyterlab
Canon RAW(CR2)を TinyDNGLoader で読む

漢だったら Canon RAW(CR2) の RAW センサー値データを読みたいですね!

やりましょう!

できました.

https://github.com/syoyo/tinydngloader

## CR2 とは

CR2 は Canon のカメラの RAW 画像のフォーマットです.
実際の中身は TIFF + 拡張タグ + lossless JPEG 圧縮(sRAW とかでない, 通常の(?) RAW の場合)なので, DNG loader(TIFF loader)をちょっと拡張してあげれば読むことができます.

lossless JPEG は, DNG(TIFF)の tiled format ではなく, CR2 独自の slice(画像が短冊状に格納されている)ので注意です.

フォーマットの詳細は以下あたりが参考になります.

http://lclevy.free.fr/cr2/

## おまけ

最近 Magic Lantern でサポートされた, カメラ内 lossless DNG 保存も, 同じ lossless JPEG を使っているので TinyDNGLoader で読めるよ!
(非圧縮 RAW な DNG は以前から Magic Lantern でサポートがありましたが, 今回の lossless DNG は, カメラ内子プロセッサ? の lossless JPEG 圧縮 API を叩くことで実現しています) 

https://petapixel.com/2016/12/30/magic-lantern-breakthrough-lets-shoot-lossless-14-bit-dngs-camera/

lossless JPEG で保存することで, いずれ RAW Video でもより解像度高く保存できるかもしれませんね!(RAW Video はカメラの CF/SD カードの書き込みスピードがネック)

## TODO

* MakersNote(xml)をパースし, RAW の現像に必要な情報を得る.
* sRAW とかも読めるようにする.

## まとめ

* 優秀な若人が, TinyDNGLoader を用い, CR2 から RAW センサー値取得を日々切磋琢磨し極めることで, 一億総 RAW センサー画像処理活躍社会を確立したい.
docker build時のapt-getが遅い

何度もdocker buildしながら試したり、
デバッグしたりするときにapt-getが遅くてつらい。
最近dockerを触りはじめてそんなことを思ったので、
対策を考えてみました。

##archive.ubuntu.comは遠い
みんな日本からやってますよね？
archive.ubuntu.comがデフォルトのサーバだけど、
日本からだとちょっとタイムラグがあります。
軽いパッケージだけならいいけど、重いものをインストールしたい時とか、
apt-get updateにも時間がかかる時にとりあえず、応急処置をしてみる。

##日本の好きなミラーサーバのsouces.listをコピーしてみる

```
COPY souces.list /etc/apt/sources.list
```

これで好きなミラーサーバが使えます

##ついでにapt-cache-ngとかつかってたら

```
COPY 02proxy /etc/apt/apt.conf.d/02proxy
```

とかプロキシ指定してみる

##でも、最後には消しておきましょう
ちゃんとビルドして動作確認できたら、
汎用性が落ちるのでデフォルトに戻します。
これで多少は効率化できるはず。
カンマ区切りの文字列を分割してデータ型を変換する


文字列から配列またはListコレクションにデータを取得します。
その時にString型からint型にデータ型を変更します。

```csharp:取り出し元の変数
string str = "1,2,3,4,5";
```

```csharp:配列を取得する例（Select使用）
int[] result  = str
.Split(',')
.Select(a => int.Parse(a))
.ToArray();
```
- List形式のデータを取得

```csharp:List型を取得する例（ConvertAll使用）
List<int> result = str
.Split(',')
.ToList()
.ConvertAll(a => int.Parse(a));
```
または

```csharp:List型を取得する例（Select使用）
List<int> result = str
.Split(',')
.Select(a => int.Parse(a))
.ToList();
```