OmniAICreator/Qiita-1.07M huggingface dataset:
Xcode7でプロジェクト名を変更する


Xcode7でプロジェクト名を変更する方法  
---
Xcode7でプロジェクト名を変更しようとした際に、手順を間違えると
プロジェクトが動かなくなることがあったので、備忘録として書き記します。  

適当な名前のプロジェクトを作成しデスクトップに保存します。
ここではプロジェクト名をsample1として作成し、sample2へ変更します。 

1.プロジェクト名を変更
　・確認のダイアログが表示されるので、Renameを実行

<img width="252" alt="スクリーンショット 2016-08-06 16.39.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/134872/97eaa277-d9fd-a6d3-e0ed-c048d13f3bc5.png">  
  
2.Bundle Identifier を変更(ドメインの後のsample1をsample2へ変更)<img width="598" alt="bundle identifier.png" src="https://qiita-image-store.s3.amazonaws.com/0/134872/2d289501-a01b-e552-4408-d5edba49134a.png">  

3.Scheme名を変更  

<img width="279" alt="スクリーンショット 2016-08-07 20.23.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/134872/d4aa7ea7-8b4a-742a-0c47-ac31d1a3b1b1.png">  
　・sample1を押下し、Manage　Schemes...を選択  
![スクリーンショット 2016-08-07 20.30.47.png](https://qiita-image-store.s3.amazonaws.com/0/134872/cba10b9c-0902-eb80-bc07-952ef976b2b8.png)  
  
　・Scheme名を変更し(sample2へ変更)Close  
  
4.一度Xcodeを終了し、Finderでプロジェクトディレクトリー名とプロジェクトディレクトリー直下にあるクラスファイルなどが入っているディレクトリー名(以後クラスファイルディレクトリー（仮称）)も変更 
(2つともsample1をsample2へ変更)　　
　　
5.Xcodeを開きPackagingのInfo.plist Fileのパスを変更(sample1/Info.plistからsample2/Info.plist)  
![スクリーンショット 2016-08-07 20.56.08（2）.png](https://qiita-image-store.s3.amazonaws.com/0/134872/18ba1d30-2bb9-714c-1faf-823b899af2b2.png)

6.手順4で変更したクラスファイルディレクトリー名をXcode上でも変更し
(sample2へ変更)
ユーティリティー・エリアにあるディレクトリーアイコンを押下し、パスを変更 
(/Desktop/sample2/sample1を/Desktop/sample2/sample2へ変更)  
![加工済み.png](https://qiita-image-store.s3.amazonaws.com/0/134872/124f864a-59dc-0943-bb8a-8300ea3c49c3.png)  
  

以上の手順後、ビルドすると上手く動きました。  
なお、プロジェクト作成時に作成されるAppDelegate.hファイルなどのヘッダー部にコメントで記載されている、プロジェクト名はそのままなので、動きには関係ありませんが、手動で変更しました。
Xcode plugin not present in DVTPlugInCompatibilityUUIDs

Xcode バージョンアップで発生する例のやつ。
git init で発生する。
このままでも git 側は使えないということはない。

```
$ git init
2016-08-07 22:04:34.767 xcodebuild[7996:395674] [MT] PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/XVim.xcplugin' not present in DVTPlugInCompatibilityUUIDs
```

対象の UUID が見つからないよと言われているので追加してあげる。

| UUID                                 |
|--------------------------------------|
| ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C |

Add 

```
$ find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist | xargs -IFILE defaults write FILE DVTPlugInCompatibilityUUIDs -array-add ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C
```

Check

```
$ find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist | xargs -IFILE defaults read FILE DVTPlugInCompatibilityUUIDs | grep -i ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C
    "ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C"
```

Refer to http://qiita.com/furu8ma/items/b720272d9bad8560b613
Teraterm マクロでコマンドの結果をファイルに保存する

# 背景など
ネットワークストレージのディスク容量を毎月取る必要に迫られたものの、windows のバッチファイルで telnet など使えないため手作業でログ取りをしています。
teraterm マクロをタスクスケジューラに仕込めば簡単になると聞いて、teraterm マクロについて調べてみました。

# teraterm マクロの実行方法
実行ファイル `ttpmacro.exe` の引数に、マクロを記述したファイルを与えることで実行できます。
具体的には以下のような設定になります（タスクにそのまま登録しても良いですが）。

```bat:get_disk.bat
"C:\Program Files\teraterm-4.78\ttpmacro.exe" /V "C:\scripts\teraterm\get_disk.ttl"
```

マクロを記述したファイルの拡張子は `ttl` が使われることが多いようです。

注意するべき点として、普段使用している `ttermpro.exe` との混同があります。マクロの実行には `ttermpro.exe` ではなく `ttpmacro.exe` を使います。

# マクロ

`inputstr` と `result` はシステム変数であり、`strscan` や `recvln` を実行すると値が書き換えられます。

`df -k` を送信すると、結果が複数行で返ってくるのでプロンプト `$` が見つかるまで `recvln` を繰り返しています。
送信したコマンドの結果に `$` が含まれる場合、この方法では全ての結果を取得できません。

```
; 変数の定義
timeout=2 ; 2 秒でタイムアウト
servername='hoge'
ipaddr='192.168.XXX.ZZZ'
port='23'
username='user'
password='pass'
filename='Disk_'
logdir='C:\Temp'


; 変数の加工・構築
strconcat filename servername
strconcat ipaddr ':'
strconcat ipaddr port
strconcat ipaddr ' /nossh /T=1'


; 接続開始 ログイン
connect ipaddr
wait ':'
sendln username
wait ':'
sendln password


; コマンド結果の記録開始
changedir logdir
fileopen handle filename 0; 上書きモード

setsync 1 ; 同期モードの開始
wait '$' ; プロンプトが返ってくるのを待つ

sendln 'df -k';
recvln; エコーバックの読み捨て

result=1
recvln
strscan inputstr '$'
while result=0
    filewriteln handle inputstr
    recvln
    strscan inputstr '$'
endwhile

setsync 0

sendln 'exit'
```

# 所感
泥臭い感じですね。`bat`ファイルと良い勝負してると思います。
`system.net.sockets.tcpclient` などで `telnet` を使ってみると `wait` とか案外面倒だと分かりました。
RapidSSLで購入したSSL証明書をCloudFrontに登録するメモ

# ドメイン取得
Route 53とかで取得
# 秘密鍵、CSR作成
```
# openssl genrsa 2048 > server.key
# openssl rsa -in server.key -out server.key
# openssl req -new -key server.key > server.csr
```

# 証明書購入
https://www.ssl-store.jp
で購入。購入すると、メールでSSL証明書と中間CA証明書が添付されてくる
（以下では、SSL証明書=server.crt、中間証明書=chain.crtとする）

# 証明書アップロード
IAM操作権限のあるアカウントでAWS CLIすること

```
# aws iam upload-server-certificate --path /cloudfront/ --server-certificate-name test --certificate-body file://server.crt --private-key file://server.key --certificate-chain file://chain.crt
```
[Linux]環境変数の読み込み順番

Linuxの環境変数の読み込み順番について調査してみました。

Linux上コマンドが使える理由は何だ？
それは、様々なディレクトリにコマンドが保存されているからです。

#Linuxコマンドが使える理由

/bin　基本コマンド
/sbin　管理者用コマンド
/usr/bin　アプリケーションで利用する基本コマンド
/usr/sbin　アプリケーションで利用する管理者用コマンド
/usr/local/bin　追加したソフトやパッケージ用のコマンド

確認してみました。
/bin
![image](https://qiita-image-store.s3.amazonaws.com/0/115472/d70669df-4756-3972-70d2-1f67f1e3f898.png)

/usr/bin
![image](https://qiita-image-store.s3.amazonaws.com/0/115472/8ad25bdc-f7a4-edac-2f33-425d9d7b9e80.png)

/usr/local/bin
![image](https://qiita-image-store.s3.amazonaws.com/0/115472/7d4575a5-a696-a083-8ce3-c819f2aa704d.png)

/sbin
/usr/sbin　
はroot権限がないので、、確認できなかったです。
すみません。。
でも、とりあえずコマンドがディレクトリに保存されているのは
確認できました。

それなら、/bin/???? , /usr/bin/??? , /usr/local/bin/???
のようにパスを指定する必要は？
ないですね。
普段パスを指定しなくコマンドが使えた理由は
ログインの時にコマンドへのパスが記録された設定を読み込んでいるからです。

#環境変数の読み込み順番
今からはこの設定ファイルを読み込む順番についてみてみましょう
1. /etc/profile
2. ~/.bash_profile　
&nbsp;&nbsp;上のファイルがなければ
&nbsp;&nbsp;  2-1. ~/.bash_login
&nbsp;&nbsp;  2-2. ~/.profile
3. ~/.bashrc
4. /etc/bashrc
5. bash実行

設定ファイルを読む順番は上のようになっています。
上から説明すると
1. /etc/profile
このファイルはログイン時に読み込む全てのユーザ共通の設定が書いています。


2. ~/.bash_profile　
その後ユーザの[home]ディレクトリにある「.bash_profile　」を
読み込みます。
&nbsp;&nbsp;上のファイルがなければ下の順に読み込めます。
&nbsp;&nbsp;  2-1. ~/.bash_login
&nbsp;&nbsp;  2-2. ~/.profile
ログインの時一回だけ読み込みます。

3. ~/.bashrc
このファイルはbashが読みこまれる度に更新されます。
設定を変更する時は[bash]とコマンドを打って設定ファイルへの更新が反映されます。

4. /etc/bashrc
このファイルはシステム全体の関数とエイリアスに関する設定が記録されています。ここでデフォルトのプロンプトを決める「PS1」の設定などをしています。

「PS1」は何？
プロンプトの設定はシェル変数（環境変数）によって定義されます。（上の話と一緒）
bashの場合PS1という名前のシェル変数です。なぜPS１なのかは、
マニュアルによると”The primary prompt string”
つまりプライマリプロンプト文からです。
"The secondary prompt string"という２番目のプロンプトを指すPS2もあります。

5. bash実行

#参考ページ
http://oxynotes.com/?p=5418
githubを二段階認証に変更後に起こるエラーの対処方法

## はじめに
Githubの設定を二段階認証に変更をした。
二段階認証に変更するとgitの通信プロトコルがhttpsからgitに変わる仕様になっている。
そこで今まで使っていたリポジトリがhttps経由ではpush出来なくなるので、自分の遭遇した2つのエラー内容と解決方法をメモしておきます。

#### まず確認すること

まずssh keyが登録されているか `ssh -T git@github.com`のコマンドで確認。
正しく登録されていることが確認できた前提。

## 1.git pushに失敗する

gitpushをした際に変更前に聞かれなかったusernameとpasswordを求められ、正しいものを答えても認証に失敗する

    Username for 'https://github.com': hoge-user
    Password for 'https://hoge-user@github.com':
    remote: Invalid username or password.
    fatal: Authentication failed for 'https://github.com/hoge-user/repository-name.git/'

### 解決方法
該当するリポジトリまで移動し、Vimで`vi .git/config`を開きます。

    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = https://github.com:hoge/repository.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master

以上のようになっているかと思います。
[remote "origin"]内の`url = https://github.com:hoge/repository.git`を`url = git@github.com:hoge/repository.git`に変更します。
これでusernameとpasswordは聞かれずにpushすることができます。

## 2. git pushに失敗したもう一つのエラー

`fatal: Unable to look up git@github.com:hoge (port 9418) (nodename nor servname provided, or not known) `というエラーに遭遇した。

sshキーは正しく登録されているし、ドキュメントルートで`less gitconfig`を見てみてもおかしな記述がない。
何かと思い色々調べていて再度該当リポジトリで`vi git/config`を見てみると、

    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = git://git@github.com:hoge/repository.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master

という風に表示され、一見変な記述がないように見え、見逃していたのですが、`url = git://git@github.com:hoge/repository.git`という記述になっていました。
この箇所を`url = git@github.com:hoge/repository.git`に修正することでpushがうまくいきました。

### 修正後
```
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = git@github.com:hoge/repository.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
```
Vue.jsでMDL(material design lite)を使う時の注意

軽くハマってしまったので備忘録。

- vue-material-componentsの記載を追加。(2016.08.27)
- mdl-textfieldのfocusに関する記載を追加。(2016.09.18)

# Vue.js用のマテリアルデザインコンポーネント
https://github.com/vuejs/awesome-vue#component-collections
Vue.jsで使えるUIコンポーネントはこちらに一覧があるので、ここから好きなのを選ぶ。

## ■ vue-mdl

http://posva.net/vue-mdl/#!/installation
vue-mdl というのがあるのでこれを使う。

```
npm install --save-dev vue-mdl
```

基本的にインストールガイドに書いてある通りだけど ルートのjsファイル等に

```js:main.js
// es2015の場合
import VueMdl from 'vue-mdl'
Vue.use(VueMdl)
```

このように記述すればOK。ただしMDL本体は含まれていないので、index.html あたりにMDL本体をインクルードする。
http://www.getmdl.io/started/index.html

```html:index.html
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.indigo-pink.min.css">
<script src="https://code.getmdl.io/1.1.3/material.min.js"></script>
```

### 注意事項

**1. ReferenceErrorが出る場合**
MDLの GETTING STARTED の通りに記述すると

```
Uncaught ReferenceError: componentHandler is not defined
```

のエラーが出てしまうので、scriptタグの中にある `defer` は削除する。
本件はこちらのissueに記載があった。
https://github.com/posva/vue-mdl/issues/20

**2. mdl-textfieldコンポーネントのfocus関連イベント**
http://posva.net/vue-mdl/#!/textfields
使用頻度が高いテキストボックスのコンポーネント。
~~これを使用する場合、`v-on:focus/v-on:blur` だと、フォーカスイベントが拾えない。レンダリングされたHTMLを見れば分かるが、`v-on:focusin` `v-on:focusout` にする必要がある。~~
↑Chromeでは問題なかったが、Firefoxでは `focusin/focusout` イベントが拾えなかった。mdl-textfieldコンポーネントの中身を確認したら、名前付きslotが設定されていたので、input要素を自分で書けば良さそう。

```js:sample.vue
<mdl-textfield floating-label="ほげほげ">
  <input class="mdl-textfield__input" type="text"
         slot="input"
         :value="hoge"
         @focus="onFocus"
         @blur="offFocus">
</mdl-textfield>
```

## ■ vue-material-components
vue-mdl以外にもmaterial design用のライブラリがあった。こちらは MaterializeCSSベースになっている。
http://appcomponents.org/material-components/#!/

### 注意事項
ただし、これをそのまま使うと hot reload した時に、以下のようなHMRの警告が表示されてしまう。（Webpack利用の場合）

> WARNING in ./~/vue/dist/vue.common.js
There is another module with an equal name when case is ignored.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Rename module if multiple modules are expected or use equal casing if one module is expected.
> 
> WARNING in ./~/Vue/dist/vue.common.js
There is another module with an equal name when case is ignored.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Rename module if multiple modules are expected or use equal casing if one module is expected.

原因はライブラリに含まれる、webpack.config.js のvueの指定が正しく記述されていないせい。

```js:webpack.config.js
    externals: {
        'vue': 'Vue', // <= 本来はすべて小文字で'vue'と書かなければいけない
        'vue-router': 'VueRouter'
    }
```

自分のプロジェクトの webpack.config あたりに、以下を追記すると一応解決する。

```js:webpack.base.conf.js
  resolve: {
    alias: {
      'Vue': path.join(__dirname, 'node_modules/vue') // vueのパスは自分の環境に置き換えてください
    },
  }
```

本件はこちらのIssueに記載があった。
https://github.com/appcomponents/material-components/issues/32
PHP でマルチキャストパケットを送信したり受信したり

PHP 5.4 以上が必要。

## 送信側

```php
<?php
$group = '239.255.1.1';
$port = 1234;
$iface = 'enp0s8';

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, IPPROTO_IP, IP_MULTICAST_IF, $iface);
socket_set_option($socket, IPPROTO_IP, IP_MULTICAST_LOOP, 0);

$data = implode(' ', array_slice($argv, 1));
socket_sendto($socket, $data, strlen($data), 0, $group, $port);
socket_close($socket);
```

## 受信側

```php
<?php
$group = '239.255.1.1';
$port = 1234;
$iface = 'enp0s8';

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', $port);
socket_set_option($socket, IPPROTO_IP, MCAST_JOIN_GROUP, [
    'group' => $group,
    'interface' => $iface,
]);

for (;;) {
    socket_recvfrom($socket, $buf, 1024, 0, $remoteAddr, $remotePort);
    echo "[$remoteAddr:$remotePort] $buf\n";
}
```

## 補足

- 送信側は `IP_MULTICAST_IF` でインタフェースを指定して送信時にマルチキャストアドレス＆ポートを指定する
- 受信側は `MCAST_JOIN_GROUP` でインタフェースとマルチキャストアドレスを指定してマルチキャストグループに参加
- `IP_MULTICAST_IF` を指定しない場合はルーティング結果の I/F から送信される
- `MCAST_JOIN_GROUP` で I/F に `0` を指定するとルーティング結果の I/F が選択される
- つまりデフォルトゲートウェイ側の I/F を使うなら `IP_MULTICAST_IF` は未指定で `MCAST_JOIN_GROUP` の I/F も `0` で良い
    - あるいは次のようなルーティングが設定されているか
    - `ip route add 239.255.1.1/32 dev enp0s8`
- `IP_MULTICAST_LOOP` に `0` を指定すると同じホストでは受信されなくなる
    - 送信側と受信側を同じホストで実行しても受信しないという意味
    - デフォルトの `1` なら同じホストでも受信される
MacにAnacondaでPython環境構築


[Anaconda](https://www.continuum.io/downloads)を使いたいので、以下の記事を参照
[HomebrewのインストールからpyenvでPythonのAnaconda環境構築までメモ](http://qiita.com/oct_itmt/items/2d066801a7464a676994)

グラフィカルインストーラーを使うと「コンピュータに損害を与える可能性があります」みたいな警告が出てくるので、pyenvを使う！


しかしpyenvが通らなかったので、こちらの記事を参考
[pyenvはインストール済みだが、pyenvコマンドが効かない](http://pyoonn.hatenablog.com/entry/2014/09/24/152610)

それでもうまくいかなかったので一旦アンインストール
`brew uninstall pyenv`


pythonが`.pyenv`を通っているか確認
`which python`

パスが通っていなかったので`.zshrc`に以下を追加

```zsh
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc
```

> 参考
[pyenvを使ってMacにPythonの環境を構築する](http://qiita.com/1000ch/items/93841f76ea52551b6a97)


## ipython notebook

Anacondaにデフォルトで入っている機能

[はじめるiPython notebook](http://qiita.com/icoxfog417/items/175f69d06f4e590face9)

- 実行コマンド

`ctrl + enter` : 実行
`shift + enter` : 実行＋次の入力（だいたいこれを使う）

- 補完機能

例えば、`import random`したあとに
`random.`のところでtabを押すと補完してくれる
Bash on Ubuntu on Windows を 触ってみての… 20160807版


正直「beta」を書いてあるし、これからのフィードバックと改良次第、なのですが、個人的には

* 「git環境を整えたPowershell」や「git for windowsについてくるgit bash」より使えない

と言わざるおえないです。なので

Windowsにbashキタ！Macざまぁｗｗｗ

と草生やしていらっしゃる方は、返り討ちに合いますのでご注意を。

* 追記
    * どうやらgithubにISSUE専用のリポジトリがたっている模様ですので、この辺の問題はいずれ解決されるのかもしれません…
    * GitHub - Microsoft/BashOnWindows: Issues found within and using Bash on Ubuntu on Windows https://github.com/Microsoft/BashOnWindows


* vscodeのTerminalと連携できるよ！というお話も見かけたが、自分は指定されたPathにBash.exeが置かれなかったです。
    * 少なくともこの人が言っている場所にbash.exeがなく、「？:\windows\system32\bash.exe」にあるように見えるんですよね…
    * https://blogs.msdn.microsoft.com/ayatokura/2016/08/06/vsc_windows_bash/

* bashのTerminalは日本語表示がおかしい状態です。
* 動きや表示されているウィンドウの状況を見るとcmd.exeの枠組みを利用しているような気はします。→コピペが面倒です。

* bashの起動は今のところは「直接スタートメニューから起動」ではなく、「Powershellやvscode 内のTerminalからbashを起動」のほうがよさそうです。そうすると、日本語表示おかしい問題はPowershellの枠組みがフォローしてくれるようなので、ましになります。

* あと悲しみを覚えたのが、「ubuntu bashの中からpingが打てない (名前解決できずに逝く)」という所です。自前で名前解決の手段を整えればいいんでしょうけど、ちょっと辛いっすね…
* これに関連してか、sshdがまともに起動しません。起動するとssh_keyがねぇぞ、と怒られる模様。


* windows\sysnative から見えない、という時点で自分の環境がおかしい可能性はあるのですが、まぁ、アレという事で。
Fedora24 Serverのroot partitionを拡張する

# Fedora24 Serverをインストールしたら
何故か論理ボリュームが最大まで割り当てられていなかった。そういう設定になったのかな？

## 論理ボリュームの確認の仕方
`# lvdisplay`
コマンドで現在の割り当て状況を確認
`# pvscan`
で使えるLVMの容量を確認

# 論理ボリューム（lv）の拡張
面倒なので/に前振り。
`# lvextend -l +100%FREE /dev/fedora/root`
これでlvmが管理している残りのボリュームが全部/dev/fedora/rootに割り当てられる。
`# xfs_growfs /dev/mapper/fedora-root`
これをやらないとファイルシステムが新たに拡張したボリュームを認識しない。
ext3, ext4なファイルシステムの場合はresize2fsコマンドで同様
Railsのデバイス判定にbrowser

ブラウザ判定（IEやFirefox、Chromeとか）やデバイスの判定（PCかスマホか）したい時には大体UserAgentつかうでしょうが、最近は複雑化しているから対応が簡単でないですね。
RailsはこれをやるためにbrowserというGemがあります。超便利。
https://github.com/fnando/browser

しかし、ここのReadme通りにインストールすると依存関係の問題か0.9.1（2016年8月現在）しか入らないです。
ということで自分なりの使い方ですが、Gemfileに

``` :Gemfile
# browser detection
gem 'browser', '~> 2.2.0'
```

と書きます。

あとはいつもの`bundle install`。

Viewの箇所には
`if browser.device.mobile?`

とヘルパーbrowserを入れるのでOKです。他にも`browser.ie?(6)` とか`browser.platform.android?(4.2) `とか`browser.device.xbox?`なんて出来る。

便利ですな。
[Play 2.5] サブプロジェクトの作成

参照：
https://www.playframework.com/documentation/2.5.x/SBTSubProjects

## サブプロジェクト用ディレクトリの準備

ディレクトリ構造は、
https://www.playframework.com/documentation/2.5.x/SBTSubProjects
に記載されている通り、下記のようになる。

```
build.sbt
app
  └ controllers
  └ models
  └ views
conf
  └ application.conf
  └ routes
modules
  └ core
    └ build.sbt
    └ conf
      └ core.routes
    └ app
      └ controllers
      └ models
      └ views
project
  └ build.properties
  └ plugins.sbt
```

自分のプロジェクトの場合はまずcoreというサブプロジェクトを作りたかったので、名前がcoreになっているが、自分の作りたいサブプロジェクト名を使う。

## サブプロジェクトにbuild.sbtを追加する
coreディレクトリ下にbuild.sbtを下記のように作成。

```scala
name := """core"""

version := "1.0-SNAPSHOT"

scalaVersion := "2.11.7"
```

## プロジェクト全体のbuild.sbtの編集
プロジェクト全体のbuild.sbtに下記を追加する。

```scala
lazy val core = (project in file("modules/core"))
	.enablePlugins(PlayScala)
	.enablePlugins(SbtWeb)

lazy val root = (project in file("."))
	.enablePlugins(PlayScala)
	.enablePlugins(SbtWeb)
	.dependsOn(core) // メインプロジェクトのクラスパスにサブプロジェクトを追加する。
	.aggregate(core) // コンパイルやテストなどを、ベースプロジェクトで実行する時に、サブプロジェクトも実行する。
```

## ベースプロジェクトのroutesにサブプロジェクトのroutesをインポートする。
ベースプロジェクトのroutesファイルに下記のようにサブプロジェクトのroutesをインポートする。

```scala
-> / core.Routes
```

これで、サブプロジェクトのcore.routesが使えるようになる。
Linux vimまとめ

## コマンドモードと入力モード

* コマンドモード→入力モード
  * i: カーソルの直前に挿入（insert）
  * I: カーソル行の最初に挿入
  * a: カーソルの直後に挿入（add）
  * A: カーソル行の最後に挿入
  * o: カーソルの下の行に挿入
  * O: カーソルの上の行に挿入
  * 入力モード→コマンドモード: ESC

## 選択
* V: 行単位の選択をするビジュアルモードに入る
* Ctrl-v: 矩形選択をするビジュアルモードに入る

## 移動
参考:[入門】Vimで高速で移動~プラグインなしでの移動まとめ~](http://qiita.com/takeharu/items/9d1c3577f8868f7b07b5)
（ちょうど右手のホームポジション）

* h: 左
* j: 下
* k: 上
* l: 右
（ページ移動）

* Ctrl-b: PgUp（back）
* Ctrl-f: PgDn（forward）
* Ctrl-u: back 半画面
* Ctrl-d: forward 半画面
* { : back 段落毎に上へ
* } : forward 段落毎に下へ
* ^: 行頭（正規表現）
* $: 行末（正規表現）
（単語移動）

* w: 単語の先頭に進む
* b: 単語の先頭に戻る
* e: 単語の末尾に進む
* ge: 単語の末尾に戻る

（行指定）

* Ctrl-g: 現在の行表示
* gg: ファイルの先頭に移動
* G: 最終行
* 数字G: 指定行に移動

## コピー、カット、ペースト
* x: 文字削除（数指定）
* dw: 単語削除（数指定）
* dy: 単語コピー（数）
* dd: 行削除（数指定）
* yy: 行コピー（数指定）
* p: カーソルの下に貼り付け
* P: カーソル行に貼り付け）
* s: カーソル位置の文字を修正、上書き（数指定）
* J: カーソル行と次行を連結する

### ペーストするときに自動的にインデントせずにペーストするには
:set paste


## undo,redo
* u: 直前の作業の取り消し
* .: 直前の作業の繰り返し

## 検索、置換
* :/文字列: 文字列の検索（/.はエスケープが必要）
* n: 下方向への検索
* N: 上方向への検索
* :%s/文字列1/文字列2/g: ファイル内の文字列1を文字列2に置換（全箇所）
* :10,20s/before/after/g: 10~20行目の全ての"before"を"after"に置換
* :'<,'>s/before/after/g: ビジュアルモードで選択中の範囲の全ての"before"を"after"に置換

## 設定

* .swpファイルを生成しない。 :set noswapfile
* .swpファイルを生成する。 :set swapfile
* 行番号を表示 :set number
* 行番号を表示しない :set nonumber

## ファイル操作
* :e ../toedit.txt: 指定したパスのファイルを開く
* :e. エクスプローラーを開く
* :w!: 保存
* :q!: 終了
* :wq!: 保存して終了
* :w ファイル名: ファイル名として保存
* :w !sudo tee % 権限がない場合の保存
JSONでのコメント

JSONの書式にはコメントの定義が無いため、フレームワークの設定ファイルがJSONで与えられた場合、原本の値を変更後の値の隣に残したいのに、コメントにできずに悩ましい思いをすることがあると思います。今回はそんなときに使った自分なりに分かりやすい記法です。

#bower.jsonでの成功例

```bower.json

"scripts": {
    "postinstall": "bower install",

    "prestart": "npm install",
    "//start": "http-server -a localhost -p 8000 -c-1 ./app",
    "start": "http-server -a localhost -p 8000 -c-1 ./static",

```
**//start**で始まる行を無効にすることができました。

ちなみに、この修正の背景としては、最初にAngularJSで作成したアプリケーション(/appフォルダ)を、Spring Bootのstaticフォルダに移動したかった（＋移動した後もnpm installコマンドで動かせるようにしたかった）ので、このような変更を行った次第です。
Power Shell で再帰的なスクリプトブロックとパーサコンビネータ


[powershellでパーサコンビネータ - Qiita](http://qiita.com/jca02266/items/b7e1dc21d8d537827290)の二番煎じだが、元記事にない再帰的なパーサーを実現している。

実際のコードについてはGistに貼ってある。

* [fnparse.ps1](https://gist.github.com/yumura/94ef4d72a2af011819f838f55ae1bbe4#file-fnparse-ps1)

動作確認は下記２つを実施している。

* [fnparse.Tests.ps1
](https://gist.github.com/yumura/94ef4d72a2af011819f838f55ae1bbe4#file-fnparse-tests-ps1)
    * 基本的な動作確認
* [fnparse.Ex.Tests.ps1
](https://gist.github.com/yumura/94ef4d72a2af011819f838f55ae1bbe4#file-fnparse-ex-tests-ps1)
    * 応用として数式パーサを作って確認


元記事で実現できなかった再帰的なスクリプトブロックを定義する方法について、以下に考察を書く。


# 現在の値を捕獲する GetNewClosure

元記事では、下記のようなスクリプトブロックの`GetNewClosure`の挙動により、`lazy`パーサの実装がうまくいかないと書いてある。

> 以下のクロージャのサンプルが"BAR"ではなく"FOO"を表示してしまうことに起因している。
> 
> ```.ps1
> & {
>   $foo = "FOO"
> 
>   $bar = {
>     Write-Warning $foo
>   }.GetNewClosure()
> 
>   $foo = "BAR"
> 
>   & $bar
> }
> ```

つまり、クロージャを作成した後、外部から変数`$foo`に束縛される値を換えても、クロージャ内部の`$foo`に束縛されている値は換わらない問題がある。なぜこのようなことが起こるのか。下記リンク先を読むと見えてくる。

* [ScriptBlock.GetNewClosure Method (System.Management.Automation)]( https://msdn.microsoft.com/en-us/library/system.management.automation.scriptblock.getnewclosure(v=vs.85).aspx)

> In this case, the new script block is closed over the local variables in the scope that the closure is defined in. In other words, the current values of the local variables are captured and enclosed inside the script block that is bound to the module.

そう、そもそも`GetNewClosure`は、ローカルスコープの**現在の値**を捕獲してスクリプトブロックにねじ込むためのものだったのだ。
そのため、先の例で言えば、`GetNewClosure`が実行された時、ローカル変数`$foo`の現在の値`"FOO"`が捕獲されることになり、`GetNewClosure`が実行された後のローカル変数`$foo`の値`"BAR"`は捕獲されないのである。



# 変数の状態が追えないなら、値の状態を追えばいいじゃない

で、次のようにすると、"BAR"が出力できる。

```.ps1
& {
    $foo = @{value = "FOO"}
 
    $bar = {
        Write-Warning $foo.value
    }.GetNewClosure()

    $foo.value = "BAR"

    & $bar
}
```

つまり、クロージャを作成した後であっても、クロージャの外の変数`$foo`に束縛される値（オブジェクト）の状態を変えれば、クロージャ内部の`$foo`に束縛されている値（同一のオブジェクト）の状態も連動して変わるのである。同一オブジェクトの状態を変更しているのだから当然ではあるが。。。


# 再帰的なスクリプトブロックの作成

しからば、スクリプトブロックを包み込むオブジェクトを作成することで、下記の通り自分自身を参照するオブジェクトを返す（再帰的な）スクリプトブロックを作れる。

```.ps1
& {
    $x = @{Recursive = $null}
    $x.Recursive = {$x}.GetNewClosure()

    (& $x.Recursive) -eq $x # => True
    (& (& $x.Recursive).Recursive) -eq $x # => True
    (& (& (& $x.Recursive).Recursive).Recursive) -eq $x # => True
}
```

まあ、実際のコード([fnparse.ps1](https://gist.github.com/yumura/94ef4d72a2af011819f838f55ae1bbe4#file-fnparse-ps1))では、スクリプトブロックを包むオブジェクトを作るなら捕獲したい値（と変数名の組）を一緒に包んじゃえば良いよね、という考えて実装している。そのため、`GetNewClosure`使わないで、自前で Closure っぽいものを作っている。
proftpd

## proftpd
### インストール

```
$ sudo apt-get install proftpd
```

### 設定ファイルの編集

- ユーザhogeに /var/wwwに許可してみる
- デフォだとでGMTなのでローカルロケールにする追記


```
$ sudo nano /etc/proftpd/proftpd.conf

ServerName "hogehogeFTPserver"
ServerType standalone
ListOptions "-al"
DefaultRoot /var/www hoge

TimesGMT off ←追記してローカルタイムを使う
```
上記で ```DefaultRoot ~ !admin``` とすればadmin以外は自分のhome配下のアクセスに限定

### 再起動

```
$ sudo service proftpd restart
```
Linux基本コマンド sort diff uniq

## sort
### オプション
| オプション | 説明| 
|:-----------|:-----------|
| -n | 数字としてソートする |
| -t | 区切り文字を指定 |
| -k | 何列目 |
| -r | 逆順 |

### testファイルで確認

    ```
    kuroda male tokyo 70
    amy female tokyo 60
    yoko male tochigi 80
    hana female osaka 75
    ```

#### 1. ソート 

```bash
$ sort test 

amy female tokyo 60
hana female osaka 75
kuroda male tokyo 70
yoko male tochigi 80
```

#### 2. 逆順でソート
```bash
$ sort -r test

yoko male tochigi 80
kuroda male tokyo 70
hana female osaka 75
amy female tokyo 60
```

#### 3. 2列目でソート
```bash
$ sort -k 2 test

hana female osaka 75
amy female tokyo 60
yoko male tochigi 80
kuroda male tokyo 70
```

#### 4. 数字でソート 
```bash
$ sort -k 4 -n test

amy female tokyo 60
kuroda male tokyo 70
hana female osaka 75
yoko male tochigi 80
```

### 利用例
```
# ファイルサイズでsort
ls -la | sort -rk 5
```

## uniq
ファイル内容をユニックにする、sortと合わせて利用が多い

### オプション
| オプション | 説明| 
|:-----------|:-----------|
| -c | 重複数を集計 |
| -i | 大文字、小文字区別しない |

```bash
$ cat uniq.txt
abc
123
abc
123

$ sort uniq.txt | uniq
123
abc

$ sort uniq.txt | uniq -c
2 123
2 abc
```

## diff

    ```
    $ diff -u file1 file2 # 見やすい形式
    ```
色付きで見る

    ```
    $ brew install colordiff
    $ colordiff -u file1 file2
    ```

### 関連
[linuxのテキスト編集（vi, sed, tr, grepなど＋xargs）まとめ](http://qiita.com/gigamori/items/1a4bf45b4cd4fe1c2a00)
連想配列などのオブジェクトの値をマージするにはObject.assign()を利用する

はじめてのqiitaです。

2つの~~jsonオブジェクト~~連想配列をマージしようとすると、実は今までいい方法はあまりありませんでした。

```js

var json1 = {"dog":"poti", "cat":"tama"};
var json2 = {"fish":"sashimi", "bird":"karaage"};
// この2つから {"dog":"poti", "cat":"tama", "fish":"sashimi", "bird":"karaage"} を作成したい
```

for in構文を用いれば一応やりたいことは出来るんですが、for in構文はすでに[非推奨](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features)となっており、コード規約によってはlintで弾かれる場合があります。(弊社がそう)

```js
var json3 = {};
for(key in json1){
  json3[key] = json1[key];
}
for(key in json2){
  json3[key] = json2[key];
}
console.log(json3);
```

また、あまり見た目のいいもんでもないです。スマートに結合したい。

そんなとき、Object.assign()が使えます。

###Object.assign()

[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)を見てみましょう。

>一つ以上の ソース オブジェクトから、直接所有で (own)  列挙可能な (enumerable) すべてのプロパティの値を、ターゲット オブジェクトへコピーします。戻り値はターゲット オブジェクトです。

らしいです。使い方はこう。

```js
var json3 = Object.assign(json1, json2);
```

第一引数のオブジェクトに、第二引数以降のオブジェクトのプロパティを追加していく方法で結合しているらしいです。
この場合戻り値として帰ってくるものは、第一引数に与えられたオブジェクトの参照となります。
つまり、json1に値が追加されていく破壊的関数であります。

```js
Object.assign(json1, json2);
console.log(json1); // {"dog":"poti", "cat":"tama", "fish":"sashimi", "bird":"karaage"}
```
挙動に注意しながら、便利に使いましょう。
Raspberry Pi 3を外付けモニター・キーボードなしでセットアップする

ラズパイを買ったのはいいものの、外付けキーボードやディスプレイを持ってないし今更買いたくない。。
ということで、普段使っているMacBook Airからsshでラズパイに接続することにした。

参考資料はこちら。
[Raspberry Piをモニタ等無しでMacから使えるようにする方法 « TORQUES LABS](http://labs.torques.jp/2014/08/17/3684/)
[Raspberry Pi 3を買ってからやった事の備忘録① \- ハードウェアエンジニアの備忘録](http://tosh419.hatenablog.com/entry/2016/03/27/231111)


用意するもの
・Raspberry Pi 3
・MicroSD Card
・MicroSD Cardリーダ
・USB電源ケーブル
・ケーブル（Thunderbolt <-> 有線LAN）
・ケーブル（有線LAN）

[ホームページ](https://www.raspberrypi.org/downloads/raspbian/)からRASPBIAN JESSIE LITE（zip）をダウンロード
解凍してimgファイルにしておく

どの辺がSDカードか確認しておく
容量的にdisk2かな

```
$ diskutil list
/dev/disk0 (internal, physical):
・・・
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *16.1 GB    disk2
   1:             Windows_FAT_16 RECOVERY                1.2 GB     disk2s1
   2:                      Linux                         33.6 MB    disk2s5
```

アンマウント

```
$ diskutil unmountDisk /dev/disk2
Unmount of all volumes on disk2 was successful
```

imgが置いてあるディレクトリに移動して書き込み

```
$ sudo dd bs=1m if=2016-05-27-raspbian-jessie-lite.img of=/dev/disk2
Password:
1323+0 records in
1323+0 records out
1387266048 bytes transferred in 720.379991 secs (1925742 bytes/sec)
```

書き込みが終わったらSDカードをラズパイに挿して起動
Macとラズパイの接続は有線LAN経由で行うので、 `Mac <-> Thunderbolt <-> 有線LAN <-> ラズパイ` という感じでつなげる

次はMac側でインターネット共有設定を行う
`システム環境設定 -> 共有 -> インターネット共有` で
`共有する接続経路：Wi-Fi、相手のコンピューターでのポート：Thunderbolt Ethernet`とする
（2つめは接続方法によって異なる）
ちなみにMacBook Airだと以下の作業が必要だった。
[MacにUSBイーサネットポートを追加する方法](http://ezxnet.com/mac/entry12443/)

続いてラズパイのIPを特定する
今回は192.168.2.2かな

```
$ arp -a
? (192.168.2.2) at b8:27:eb:ab:de:b4 on bridge100 ifscope [bridge]
・・・

$ ifconfig
・・・
bridge100: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=3<RXCSUM,TXCSUM>
	ether a6:d1:8c:1e:15:64
	inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
	inet6 fe80::a4d1:8cff:fe1e:1564%bridge100 prefixlen 64 scopeid 0xa
	Configuration:
		id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
		maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
		root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
		ipfilter disabled flags 0x2
	member: en3 flags=3<LEARNING,DISCOVER>
	        ifmaxaddr 0 port 9 priority 0 path cost 0
	nd6 options=1<PERFORMNUD>
	media: autoselect
	status: active
```

ログイン
初期パスワードはraspberryらしい

```
$ ssh pi@192.168.2.2
pi@192.168.2.2's password:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
-bash: warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8)
-bash: warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8)
-bash: warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8)

// localeなおしておきましょう
$ sudo localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
```

ログインできた！
Macだけで完結できるの嬉しい！！
![img](https://pbs.twimg.com/media/CpOmYp6UIAACguP.jpg)
iOS Push通知のinvalidトークン削除の際注意すること


## はじめに 
iOSでリモートpush通知を実装する際、注意する点があります。
それはinvalidトークン(使用不可となったトークン)の削除です。
これをしないと、push通知が届かないといった事が起きます。
また、invalidトークンを偽装(テストの為)する際も注意しなければいけません。

## invalidトークンの抽出
こちらのサイトを参考にトークン一覧にpush通知を送った後、
何番目にinvalidなトークンがあったかという情報を抽出することができます。
http://knowledge.sakura.ad.jp/tech/1721/
これにより、後でまとめてinvalidトークンを削除する感じです。

## invalidトークン作成
適当なトークンを設定するとアプリ(サーバ)が落ちます。
Appleは「トークンの長さをハードコードしてはいけません。」と言っています。
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
試してみた結果文字列の長さを変更しなければ良いようです。
なので端末から送られてきた実際のトークンの文字を変更します。(これもハードコードな気がする)

- `test1invalid1token` -> アプリ落ちる
- `e215bfbffa75476a9965b7279540fae2f0c53c2174438cd3a513b87d20e5bec8` -> 実際のトークン(通知発行される)
- `e215bfbffa75476a9965b7279540fae2f0c53c2174438cd3a513b87d20e5bec7` -> invalidトークン扱い(実際のトークンの最後の文字を変更)
[boost::python] TypeError: No to_python (by-value) converter found for C++ type: boost::shared_ptr<...>

boostのバージョン上げたら

```
TypeError: No to_python (by-value) converter found for C++ type: boost::shared_ptr<...>
```

と出てビルド通らなくなったので調べると

https://github.com/boostorg/python/issues/56
https://github.com/vslashg/python/commit/f2c465ffa508459216f7093bf95ba001ad994206

boostの方では解決済みですが、追いついていないディストリビューションがあるので、自分でパッチを当てるか、バージョンを落とすか、待ちましょう。
フラッシュ記憶

flash_kioku.php

~~~~

<!DOCTYPE html>

<head>
<title>flash_kioku</title>
 <script type="text/javascript" src="hantei.js"></script>
</head>

<body>
<script type="text/javascript"><!--
var ID="100705795";
var AD=0;
var FRAME=0;
// --></script>
<script src="http://j1.ax.xrea.com/l.j?id=100705795" type="text/javascript"></script>
<noscript>
<a href="http://w1.ax.xrea.com/c.f?id=100705795" target="_blank"><img src="http://w1.ax.xrea.com/l.f?id=100705795&url=X" alt="AX" border="0"></a>
</noscript>

<script>
<!--

var img = new Array();
var img2 = new Array(4);

img[0] = new Image();
img[0].src = "http://www.onlyonehappy.top/1.JPG";
img[1] = new Image();
img[1].src = "http://www.onlyonehappy.top/2.JPG";
img[2] = new Image();
img[2].src = "http://www.onlyonehappy.top/3.JPG";
img[3] = new Image();
img[3].src = "http://www.onlyonehappy.top/null.JPG";
img[4] = new Image();
img[4].src = "http://www.onlyonehappy.top/0.JPG";

var img2 = [5,5,5,5];

var id=0;
var n=0;
var s=0;


function appear_f1(){

document.getElementById("IMG1").src = img[0].src;
s += 1;
img2[n++] = 0;

}

function appear_f2(){

document.getElementById("IMG1").src = img[1].src;
s += 2;
img2[n++] = 1;

}

function appear_f3(){

document.getElementById("IMG1").src = img[2].src;
s += 3;
img2[n++] = 2;

}

function appear_f4(){

id++;

var timer = window.setTimeout("appear_f4()", 1000);

var rand = Math.floor(Math.random()*3);

if (rand==0){
   appear_f7();}
else if(rand==1){
   appear_f8();}
else{
   appear_f9();}

if(id==3){
clearTimeout(timer);
id=0;
i=0;}

}


function appear_f6(){

document.getElementById("IMG1").src = img[3].src;

}



function appear_f7(){

timerID = window.setTimeout("appear_f1()", 800);
appear_f6();

}

function appear_f8(){

timerID = window.setTimeout("appear_f2()", 800);
appear_f6();

}

function appear_f9(){

timerID = window.setTimeout("appear_f3()", 800);
appear_f6();

}

function appear_f11(){

img2[0]=5;
img2[1]=5;
img2[2]=5;

a=5;
b=5;
c=5;
n=0;

myWin.window.close();

}




// -->
</script>

<form>

<IMG id="IMG1" name="num1" alt="" src="0.JPG">

<input type ="button" style = "position: absolute; left:50%; top: 50%"/ name = "b4" value = "start" onclick = "appear_f4()">

<INPUT id="Button2" style = "position: absolute; left:65%; top: 50%"/ onclick="appear_f10()" value="check" type="button" name="check">

<input type="button" style = "position: absolute; left:80%; top: 50%"/ onclick="appear_f11()"  value="close" name="close">

 
</form>


</body>

</html>

~~~~

今度は、フラッシュ記憶 PG です。^^
startで、表示が始まります。
checkで、判定。タブが開きます。
closeにて、判定タブを 閉じて下さい。

以下の hantei.jsファイルと、ワンセットです。

~~~~

function appear_f10(){

var a = img2[0];
var b = img2[1];
var c = img2[2];

myWin = window.open();
myWin.document.open();
myWin.document.write("<html>");
myWin.document.write("<head>");
myWin.document.write("<title>hantei</title>");
myWin.document.write("</head>");
myWin.document.write("<body>");
myWin.document.write("<img src=", img[a].src, "><br />");
myWin.document.write("<img src=", img[b].src, "><br />");
myWin.document.write("<img src=", img[c].src, "><br />");
myWin.document.write("</body>");
myWin.document.write("</html>");
myWin.document.close();

}

~~~~
Haskell で AWS を扱う amazonka ライブラリの紹介

# Haskell で AWS を扱うライブラリの紹介 (Amazonka)

Haskell で AWS を扱える実用的なライブラリとして [Amazonka](http://hackage.haskell.org/package/amazonka) を紹介します。
本記事の執筆時点で十分にメンテナンスかつ網羅的に実装されているライブラリの1つです。
今回は非常に単純な実装例として、S3バケットを表示させてみます。
本記事のソースコードは以下の github repository にアップロードされています。
https://github.com/algas/amazonka-examples

## 前提知識

本記事では以下のような読者を想定しています。
- AWS IAM を使うことができる
- AWS Client から S3 を使える環境を持っている
- Haskell Lens の基本を理解している

## セットアップ

haskell stack 環境を構築済みとします。

1. IAM の設定  
AWS IAM でユーザを作成し、S3 に対する権限を付与します。  
accessKey と secretKey は次で使うので忘れずに記録しておくこと。  
2. 環境変数の設定  
上記のユーザ作成時に取得した accessKey, secretKey を環境変数に渡します。  
`export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY`  
`export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY`
3. リポジトリの取得  
`git clone https://github.com/algas/amazonka-examples.git`
4. ビルド  
`cd amazonka-examples && stack build`
5. 動作確認  
` stack exec amazonka-examples`  
上記のコマンドを入力すると、以下のような出力が得られます。  
`[BucketName "mybucket1",BucketName "mybucket2"]`

## 依存関係

Amazonka, Amaaonka-S3 以外に [Lens](http://hackage.haskell.org/package/lens) に依存しています。
Lens ライブラリの説明はここでは省略します。

```hs:amazonka-examples.cabal
executable amazonka-examples
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , lens
                     , amazonka
                     , amazonka-s3
  default-language:    Haskell2010
```

## 実装

S3 バケットの一覧を表示するクライアントを実装します。

```hs:Main.hs
{-# LANGUAGE OverloadedStrings #-}
module Main where

import           Control.Lens
import           Network.AWS
import           Network.AWS.S3
import           System.IO

example :: IO ListBucketsResponse
example = do
    e <- newEnv Tokyo $ FromEnv "AWS_ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY" Nothing
    runResourceT . runAWS e $ send listBuckets

printBuckets :: IO ()
printBuckets = do
    ex <- example
    print $ [ x ^. bName | x <- ex ^. lbrsBuckets ]

main :: IO ()
main = printBuckets
```

`example` は `IO ListBucketsResponse` を返します。上述のとおり環境変数で AWS の認証情報を設定しています。認証情報については、環境変数以外にも `aws configure` で設定したファイルと profile から設定する方法などの複数の設定方法があります。
`send` は `listBuckets` を渡して得られた `AWSResponse` から IO へとモナド変換を行っています。
`send :: (MonadAWS m, AWSRequest a) => a -> m (Rs a)`

`printBuckets` では `ListBucketsResponse` から `bName` すなわちバケット名を取得しています。 `^.` は `lens` の関数です。

以上が S3 のバケット名一覧を取得するコードです。
Amazonka には S3 以外にも AWS サービスを扱う機能が実装されています。
Swiftのジェネリクスってなんぞや

#\<T>って書いてるアレ
アプリのソースコードやライブラリなどを眺めていると、\<T>っていう謎の記述をよく見かける。これはSwiftが汎用的な記述を可能にするための、ジェネリクスという記法らしい。

##特徴
クラスや関数などで良い感じに使うと、抽象的にコード記述することができる！！
ちなみにジェネリクスで定義された型はジェネリック型と呼ぶ。（薬?）

###書式
```swift:genericsFmt
func 関数名 <任意の型> () {
	// 何らかの処理
}
```

##使われている場所
実は、ジェネリクスは知らぬ間に結構使っているもので、Swiftにある標準ライブラリなどは頻繁に使われています。例えば、値を入れ替えるだけのswap関数などは以下のように定義されています。

```swift:genericsSwap
swap<T>(inout a: T, inout _ b: T)
```

このジェネリクスの何がいいのか？
例えば、同じような動作で以下のようなメソッドを書いたとします。

```swift:mySwap
func mySwap(inout a: Int, inout b: Int) {
	// 処理   
}
```
もし、これをIntやFloatもDoubleもなどと対応していると、その数分だけ関数を定義しなければいけません！めんどい！こういう問題を解決してくれるものがジェネリクスということらしいです。

###実際の処理
ちなみにジェネリクスは、通常の関数などで定義した型とは違って、プログラムで記述された時に与えられた具体的な値の型をTにあたはめて推論し、矛盾がなければコンパイルされるようです。

##簡単な例

全く良い例が浮かばなかったので、今回は会計する時に、支払う金額が正しく購入金額より多く支払われるかを判定したいという場合のプログラムを書いてみました。

```swift:genericsPay
func cash(pay: Int, purchase: Int) -> Bool {
    return pay == purchase ? true: false
}

cash(1000, purchase: 1000) // true
```

ここで、例えば、ありえないですが、新たにお金が１銭とか２銭出せるようになったとしましょう。この場合、いまの通貨では小数点部分として扱われます。という想定で上のメソッドで、小数点も比較したい！となったとします。

```swift:genericsPay2
func cash(pay: Int, purchase: Int) -> Bool {
    return pay == purchase ? true: false
}

cash(1000.1, purchase: 1000) // エラーで死にます
```

上記の例では当然ながら、エラーで落ちます。これは、冒頭にも説明した通りで、Intしか許容していないためです。ではどうするか？
ここでジェネリクス使えば行ける！！と感じますが、見事に死にます。

```swift:genericsPay3
func cash<T>(pay: T, purchase: T) -> Bool {
    return pay == purchase ? true : false
}

cash(1000.1, purchase: 1000) // エラーで死にます。
```

実は、なんでも許容するとは書いてますが、制限はしっかりあります。その制限の中で許容されている動きかどうかが判断されて初めて、実行されるのがジェネリクスの便利なところでもあり、少し理解がしにくいところでもあります。

```swift:genericsPay4
func calc<T: Equatable>(atai1: T, atai2: T) -> Bool {
    return atai1 == atai2 ? true : false
}

calc(1000.0, atai2: 1000)	 // true
```

\<T: Equatable>という記述が追加されただけで、急に処理が実行されました。これはプロトコルというもので、Equatableというのは、"=="について記述がされている制約です。Int, Float, DoubleはEquatableに適合した型なので、問題ないと判断され実行されます。

###急に出てきたプロトコルについて
Swiftの標準ライブラリはジェネリクスとプロトコルの組み合わせが肝になってるようなので、勉強した方が良い記法だと思います。

##まとめ
上手に使えば、汎用的なものがサッと書けるので、是非マスターしたい。
プロトコルについては、また書いてみます。
【katakata.js】入力中っぽいエフェクトをつけるnode moduleを作って公開した。

かつてからやってみたかったnode moduleの公開をついに果たせたので記念に発表してみたいと思う。

作成過程においては下記記事がとても参考になりました。
これからモジュールを開発して公開したいという方は1を、generator/iteratorの理解を深めたい方は2を読むことをおすすめします。

1.  [3分でできるnpmモジュール](http://qiita.com/fnobi/items/f6b1574fb9f4518ed520)
2.  [JavaScript の ジェネレータ を極める！](http://qiita.com/kura07/items/d1a57ea64ef5c3de8528)


..さて、今回タイプライター風のエフェクトを与えるシンプルなライブラリを書いた。

サンプルgif
![demo](https://github.com/vsanna/katakata.js/raw/master/images/sample.gif)

[サンプル on browser](https://vsanna.github.io/katakata.js/)

コードは[こちら](https://github.com/vsanna/katakata.js)

他にもgeneratorの仕組みも理解したいと思っていたところだったので、generatorを使ったモジュールが仕上がった（ので、使うにはいくつかのloader, pluginなどが必要になる。）

## できること
このライブラリでは以下のことができる。

1. タイピング中のような効果付きで一文字ずつ表示する
2. 編集中のワードには編集中っぽい効果をつけるべく、classを与えられる
    - githubにあげたstyleを使えば最初からそれっぽい感じになっている。と思う。
3. 複数行OK
4. ワードの区切りを好きな文字で指定できる
5. タイピングのスピードを好きに調整できる

## 先行事例と開発経緯
npmにて「typewrite」で検索しヒットしたものを眺めてみたが、これが一番近かった。

**yobacca/typewrite:**
A flexible typewriter simulator written in plain Javascript, well tested using Mocha, Chai, Karma and Istanbul.
https://github.com/yobacca/typewrite

一方で、こちらは日本語ならではの編集中のエフェクトがなく(欧米なので当たり前)、それをかつてブログで実装した際に個人的満足度が高かったために、今回ライブラリとして作成・切り出すことにした。

以下は個人的なメモなので、TODOまで飛ばしていただいて問題ありません

## 努力した点
見た目では日本語ならではの編集中の背景・下線と、入力中の右サイド明滅バーに大分力を割いた感がある。

コードの中身としてはgeneratorの仕組みを理解するのに若干手こずったが、ある程度なれることが出来た。

また、node moduleの適切な開発フローが完全に手探りで、知見ある方に相談してみたい。


## 終わりにかえて今後のTODO
- [x] サンプルコードとして最低限のものをまとめておきたい
- [ ] generatorの良い書き方がまだまだわかっていないので、ガシガシリファクタしたい。
- [ ] 多分依存関係のあるライブラリの提示の仕方を間違っているのでこれは早めに調査・対応したい
- [ ] jsでのテスト経験が殆どと言っていいほどないので、これを題材に色々試してみたい。
  - 今やるならどのテストフレームワークが良いのかなどコメント・アドバイスいただけるととっても嬉しいです。
- [ ] 広められるようテスト・コードの洗練を継続したい。


以上!
SSHの設定

## openssh
sshは公開鍵、秘密鍵を使い、rsa認証する。
クライアントとサーバ間で、同じ公開鍵を持ち、秘密鍵を使ってログイン認証する。

### インストール

```
$ sudo apt-get install openssh-server
```

動作確認

```
$ sudo lsof -i:22
```
### rsa鍵の生成
クライアント側で秘密鍵（id_rsa）、公開鍵（id_rsa.pub）を生成。
公開鍵をサーバに登録

```
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa):  ←空Enter（任意）
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/root/.ssh/id_rsa.
Your public key has been saved in /var/root/.ssh/id_rsa.pub.
```

### 公開鍵の設置
サーバに公開鍵を設置する
サーバに$HOME/.shhフォルダを作成し、そこに公開鍵をauthorized_keysとして置く

```
$ sudo mkdir -m 700 ~/.ssh

$ cat id_rsa.pub >> ~/.ssh/authorized_keys

$ sudo chmod 600 authorized_keys
```

### 設定ファイル編集

```
$ sudo vi /etc/ssh/sshd_config
Port 10022 ←適当に
PermitRootLogin no
PasswordAuthentication no

ユーザー許可を追記
AllowUsers hoge
```

再起動

```
@server:~$ sudo service ssh restart
```

### 鍵を更新する場合
鍵を再作成した場合はknown_hostsファイルを削除。
ログインしてみる

```
$ sudo rm ~/.ssh/known_hosts
$ ssh hogehoge.com -l hoge
Are you sure you want to continue connecting (yes/no)? : yes
```
JPAでEntityを親クラスと子クラスに分ける方法

システムによって全テーブルに共通したカラムが存在することがあると思います。
(楽観ロック用のバージョニングカラムや登録日、更新日、登録者名、更新者名など)

JPAのEntityクラスを作成するときに全Entityに同じ変数を作るのはイヤだったので、上位クラスを作ってまとめられないかな、と思って調べてみたらその方法がありました。

**上位クラスに<code>@Entity</code>ではなく<code>@MappedSuperclass</code>アノテーションをつけるだけです。**
これだけで、上位クラスを継承したEntityクラスで共通カラムを使用することができました。

```AbstractEntity.java
package jp.co.test.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * DB共通Entity
 */
@MappedSuperclass
public class AbstractEntity implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /** 登録日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "TOROKU_DATE")
    private Date torokuDate;
    
    /** 更新日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "KOSIN_DATE")
    private Date kosinDate;

    /** バージョン */
    @Version
    @Column(name = "VERSION")
    private Integer version;

    // getter,setter
```

```NameT.java
package jp.co.test.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "NAMET")
public class NameT extends AbstractEntity implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    @Id
    @Column(name = "ID")
    private Integer id;
    
    @Column(name = "NAME")
    private String name;

    // getter,setter
```

さらに、<code>@PrePersist</code>や<code>@PreUpdate</code>と併用して、登録日、更新日を自動で設定することも可能

```AbstractEntity.java
package jp.co.test.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * DB共通Entity
 */
@MappedSuperclass
public class AbstractEntity implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /** 登録日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "TOROKU_DATE")
    private Date torokuDate;
    
    /** 更新日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "KOSIN_DATE")
    private Date kosinDate;

    /** バージョン */
    @Version
    @Column(name = "VERSION")
    private Integer version;

    /**
     * 登録前処理
     */
    @PrePersist
    public void prePersist() {
        // 登録日、更新日を設定
        Date date = new Date();
        torokuDate = date;
        kosinDate = date;
    }
    
    /**
     * 更新前処理
     */
    @PreUpdate
    public void preUpdate() {
        // 更新日を設定
        kosinDate = new Date();
    }

    // getter,setter
```

insertやupdateするたびに手動で日付設定する必要もなくなるし、上位クラスで処理を一つにまとめることもできました。
※昔やってたプロジェクトでは手動で設定してたので誰もJPA知らなかったんだなって思いました。。。

![image](https://qiita-image-store.s3.amazonaws.com/0/133525/4f8ea8b3-07d6-0866-20e9-8c97cdecabb3.png)


### 参考リンク
http://etc9.hatenablog.com/entry/20090830/1251606823
sambaの設定

## samba
win用文字コードの指定と最下部に共有ポイントを追加

```
$ sudo vi /etc/samba/smb.conf
[global]
dos charset = CP932
valid users = hoge1 hoge2　アクセス許可ユーザ
valid users = +hogegroup　システムグループ指定

[public]
  # Windows側から見た時に付加されるコメント
  comment = Public space; anyone can write any files.
  # 共有するディレクトリのパス
  path = /media/hogehoge
  # guestユーザのアクセスを許可するか
  guest ok = no
  # 読み出しのみ可能か
  read only = no
  writable = yes
  # 書き込みを許可する
  writable = Yes
  # 強制的にファイルに与えるアクセス権
  create mode = 0664
  # 強制的にディレクトリに与えるアクセス権
  directory mode = 0775

```
下記のようにUNIXのシステムアカウントと同期するよう設定しておく

```
unix password sync = yes
```
Linuxユーザと同期する設定にしておく

```
$ sudo sambapasswd -a hoge
```
[Play Framework]外部ライブラリー管理

## build.sbtの設定
``` scala
libraryDependencies ++= Seq(
	"org.webjars" %% "webjars-play" % "2.5.0",
	"org.webjars" % "bootstrap" % "3.3.6",
	"org.webjars" % "knockout" % "3.4.0",
	"org.webjars.bower" % "knockout-mapping" % "2.4.1"
)
```
上のようにwebjars-playと、各必要なライブラリーを追加。
各ライブラリーの一覧は、以下を参照
http://www.webjars.org/

## ライブラリー読み込み
``` html
<link rel="stylesheet" href="@routes.Assets.versioned("lib/bootstrap/css/bootstrap.css")">
```
各ライブラリーのフォルダーは
target/web/public/main/lib
内にあるので、ここを参考にライブラリーの読み込みをする。
ぐるなびAPIの使い方


## ぐるなびAPIとは
題の通り、ぐるなびの情報を使用するためのAPIです。
使用するには登録が必要になります。

## 導入
まずは新規登録をします。

![スクリーンショット 2016-08-07 14.06.03.png](https://qiita-image-store.s3.amazonaws.com/0/120969/d9b87cc4-c38c-b963-c80c-d0847eb2e40b.png "スクリーンショット 2016-08-07 14.06.03.png")


一通り入力して認証を終えると、メールが届きますので、そちらにあるAPIキーをメモします。（コンソールのようなものはないので、メールはなくさないようにしましょう）

## ぐるなびAPIを使用してみる
APIは様々ありますが、僕が一番使用するのはレストラン検索APIなのでそちらを利用してみます。

```URL
// レストラン検索API
http://api.gnavi.co.jp/RestSearchAPI/20150630/?keyid=[メモしたkey]&format=json
```

これを打ち込むと適当なデータが出てしまうので、
ある程度範囲は絞りたいです。
そこで、Mエリア検索APIを使用します。

```URL
// Mエリア検索API
http://api.gnavi.co.jp/master/GAreaMiddleSearchAPI/20150630/?keyid=[メモしたkey]&format=json
```

僕は恵比寿のお店を知りたいので、MエリアコードAREAM2178をメモします。
そして、

```URL
http://api.gnavi.co.jp/RestSearchAPI/20150630/?keyid=[メモしたkey]&format=json&areacode_m=AREAM2178
```

とすると、恵比寿のお店が取得できます。簡単ですね。

今回はこれだけの説明でしたが、他にもAPIがあります。
詳しくは下記のリンクをご覧ください。
http://api.gnavi.co.jp/api/manual/

暇があったら、これ使ってアプリでも作ってみたいです。
pythonの外部ライブラリのインストール

```
pip -h
```
これでだいたいわかる

search で欲しいやつを探す
ない場合、できない場合↓

pythonのライブラリのWindows向けバイナリファイルをダウンロード出来るサイトです

http://www.lfd.uci.edu/~gohlke/pythonlibs/

ダウンロードした後はファイルのフォルダに移動して

```
pip install ファイル名
```

をすればインストールできます。
diff オプション

# とりあえず比較
## 指定ディレクトリ配下を比較してファイル名だけ表示
```bash
diff -qr /home/example1 /home/example2
```
## 改行空白および改行コードを無視して比較
```
diff -Bw --strip-trailing-cr example1.txt example2.txt
```
## 差分箇所だけ横に並べて表示
```
diff -y example1.txt example2.txt | grep "|\|<"
```
## 横に並べて比較 (vimdiff)
```bash
vimdiff example1.txt example2.txt
```
または

```bash
vim -d example1.txt example2.txt
```
Vim がインストールされている必要がある。

# diff オプション
## ディレクトリごと比較
```bash
diff -r /home/example1 /home/example2
```

## ファイル名だけを表示
```bash
diff -q /home/example1 /home/example2
```

## 改行を無視
```bash
diff -B example1.txt example2.txt
```

## 空白を無視
```bash
diff -w example1.txt example2.txt
```

## 改行コードを無視
```bash
diff --strip-trailing-cr example1.txt example2.txt
```

## 大文字小文字の違いを無視
```bash
diff -i example1.txt example2.txt
```

## 横に並べて比較
```bash
diff -y example1.txt example2.txt
```