OmniAICreator/Qiita-1.07M huggingface dataset:
raspberry pi同士でシリアルコンソール


#はじめに

pi A+が2つある。
macからSSHで2つとも操作したいが、USB-LAN変換ケーブル(PLANEX USB-LAN100R)が1つしかない。
`{mac} --[LAN]--> {pi 1号} --[serial]--> {pi 2号}`で接続できれば解決するかも、と思い試してみた。

#pi 1号の設定

raspberry piのシリアルポート(GPIO 8,10)は、デフォルトではシリアルコンソール接続の待ち受けに占有されている。
serial接続の開始側となる1号では、これを無効化する必要がある。

```:/boot/cmdline.txt(修正前)
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
```

```:/boot/cmdline.txt(修正後)
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
```

`console=serial0,115200`を削除するのだが、環境によっては`console=ttyAMA0,115200`だったり、`console=ttyS0,115200`となっている場合があるので、その場合はそれらを削除する。
また、`kgdboc=ttyAMA0,115200`というのがあればそれも併せて削除する。

サービスの無効化と再起動

```
$ sudo systemctl stop serial-getty@ttyAMA0.service
$ sudo systemctl disable serial-getty@ttyAMA0.service
$ sudo reboot
```


[参考](http://hack-le.com/44765804-2/#GPIOUART)
[参考](https://learn.adafruit.com/adafruit-ultimate-gps-on-the-raspberry-pi/using-uart-instead-of-usb)

#GPIOの結線

GNDのpinを接続する。
rpiのシリアルポート(GPIO 8,10)をクロス接続する。
※1号の8番pinと2号の10番pin、1号の10番pinと2号の8番pinを結線する。


#シリアル通信

1号側で以下のコマンドを実行すると、2号側に接続できる。

`$ sudo screen /dev/ttyAMA0 115200`
raspiでramdisk


#はじめに

SDカードの延命の為、logをramdisk(tmpfs)に移したり色々した時のメモ

swap無効化

```
$ sudo swapoff --all
$ sudo apt-get remove dphys-swapfile
```


tmpfsにするには、下記の様に追記していく。

```:/etc/fstab
tmpfs           /var/log        tmpfs   defaults,size=16m,noatime,mode=0755 0 0
tmpfs           /lib/ufw        tmpfs   defaults,size=1m,noatime,mode=0755 0 0
```



#自作の初期化script

`/var/log`とだけ設定すると、nginxが`/var/log/nginx`ディレクトリが無いとエラーになって
サービスが上がらない。
設定ファイル`nginx.conf`で場所を変更しても、起動直後〜設定を読みに行く間のlogは、
コンパイル時に指定された場所を見に行く為、エラーを回避できない。
(自前でコンパイルすれば場所を変えられるがpiでは辛い、クロスコンパイルもめんどい)
ということで、`/var/log`の下にディレクトリを掘るscriptを自作して、systemdで動かしてみる。

##systemdの現状を確認

各サービスが、現在どういった順序で起動してるか確認してみる。
[参考](http://www.clear-code.com/blog/2015/12/28.html)

```
$ systemd-analyze plot > /tmp/sys.svg
```

このファイルをブラウザで見てみる。


##scriptの作成

```/etc/systemd/system/var-log-init.service
[Unit]
Description=initialize '/var/log' directory
DefaultDependencies=no
Requires=var-log.mount
After=var-log.mount

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/root/tool/var-log-init/var-log-init

[Install]
WantedBy=sysinit.target
```

```bash:/root/tool/var-log-init/var-log-init
#!/bin/bash

if [ ! -e /var/log/nginx ]; then
  mkdir /var/log/nginx
fi
chown www-data:adm /var/log/nginx
```

[参考](http://qiita.com/irotoris/items/5187e0c741eca4d0c563)
[参考](http://enakai00.hatenablog.com/entry/20130917/1379374797)
[参考](http://enakai00.hatenablog.com/entry/20130917/1379374797)

#ufwの設定

自宅と実家のIPを固定してないので、UFWで許可するIPを動的に変えられる様にCRONで定期的に設定を更新している。

これもSDカードにダメージを与えるので、設定ファイルの更新先`/lib/ufw`をtmpfsに置くことにする。
で、固定で保持しておきたい設定(ローカルエリアからのSSH許可等)は`/lib/ufw.default.tgz`に固めておいて、boot時に`/lib/ufw`に展開するようにしてみる。

```/etc/systemd/system/pre-ufw.service
[Unit]
Description=LSB: start firewall
DefaultDependencies=no
Requires=lib-ufw.mount
After=lib-ufw.mount

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/root/tool/systemd/pre-ufw

[Install]
WantedBy=sysinit.target
```

```:/root/tool/systemd/pre-ufw
#!/bin/bash

/bin/tar xfz /lib/ufw.default.tgz -C /lib/ufw/
```

```/etc/systemd/system/post-ufw.service
[Unit]
Description=LSB: start firewall
DefaultDependencies=no
Requires=ufw.service
After=ufw.service

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/root/tool/systemd/post-ufw

[Install]
WantedBy=sysinit.target
```

```:/root/tool/systemd/post-ufw
/usr/sbin/ufw allow proto tcp from xxx.xxx.xxx.xxx/32 to any port 443
```
PHPでnewからのメソッドチェーンをできるようにする

PHPではnew に続けてメソッドを実行できない。かなしみ。

```php
class Say {
	private $name = 'hoge';
	public function hello () {
		echo "hello {$this->name}";
	}
}
$say = new Say()->hello();
// Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR)
```

```php
//めんどい
$say = new Say();
$say->hello();
```

**自分自身のインスタンスを返す静的メソッド**を用意しておくとそれに続けてチェーンできる。

```php
class Say2 {
	private $name = 'hoge';
	public static function forge() {
		return new static;
	}
	public function hello () {
		echo "hello {$this->name}";
	}
}
Say2::forge()->hello();
```
ちなみに`new クラス名`をカッコで囲ってもチェーンできる。

```php
(new Say())->hello();
// hello hoge
```
nginxでリバースプロキシ(SSLアクセラレータ)の設定


実家にサーバ(HP ProLiant MicroServer)を設置している。
IPMIに対応していて、ブラウザからも電源管理ができるのだが、この管理コンソールを直接インターネットに公開するのはチョット怖い。
ということで、前段にリバースプロキシをかまして、証明書でクライアント認証をかけてみようと思う。
24時間起動させてても電気代が気にならないraspberry piで構築してみる。

#インストール

`apt-get install nginx`では一部のモジュールが有効になっていないので、extrasを入れる

```
$ sudo apt-get install nginx-extras
```

#IP固定化

以下を追記

```:/etc/dhcpcd.conf
interface eth0
static ip_address=10.0.1.40/24
static routers=10.0.1.1
static domain_name_servers=10.0.1.1
```

#nginxの設定

##サーバ固有の情報をレスポンスに含めない設定

```:/etc/nginx/nginx.conf
server_tokens off;
```

##リバースプロキシの設定

```:/etc/nginx/sites-available/default
server {
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
        more_set_headers "Server: Apache";
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        ssl on;
        ssl_certificate サーバ証明書のパス;
        ssl_certificate_key サーバの秘密鍵のパス;

        ssl_verify_client on;
        ssl_client_certificate ルート証明書のパス;

        server_name _;
        proxy_set_header Host $http_host;


        location / {
                proxy_intercept_errors on;
                proxy_pass http://backend-url;
                proxy_redirect http:// https://;
        }

        error_page 400 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 495 496 497 500 501 502 503 504 505 = /404.html;

        location /404.html {
                return 404 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL $request_uri was not found on this server.</p>\n<hr>\n<address>Apache/2.2.31 Server at $host Port $server_port</address>\n</body></html>";
        }
}
```

ここでも、nginxを使っていることを隠すために、httpエラー(400番代と500番代)のページを独自の物に変更している。
で、[ここ](http://qiita.com/ryounagaoka/items/fd641e39a196b47db875)で面白いことをやってたのでマネしている。
(エラー画面をapache風にする)

ちょっとハマった点は、クライアント認証がエラーになった時に、レスポンス400となって、nginxの固有のエラーページが返されるが、`error_page 400`を設定しても`location /404.html`で設定している内容が反映されない。
[ここ](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client)によると、nginxは認証関連のエラーを内部的に`495 496 497`の3つのコードで扱っている為、それらのコード値で設定しないといけない。
[ここ](http://stackoverflow.com/questions/33560256/custom-nginx-error-page-for-the-ssl-certificate-error)を参考に3つのコードを独自エラー画面に飛ばしてみる。

401はクライアント認証時に一発目で返されるので除外している。

[参考](http://blog.akagi.jp/archives/3883.html)
virshからのvCenter Server経由(Esxi)の接続

MLでPacemakerでvSphere環境で利用するSTONITHプラグイン(external/libvirt)の接続設定について質問されたので、整理しておきます。
PacemakerのCRMファイルの設定中には、ユーザ名、パスワードなどは設定しない為、virshコマンド(external/libvirtで利用)での接続もユーザ名、パスワードは入力せずに接続出来るようにする必要があります。

また、vCenter Serverに収容(データセンタ内に管理）されているESXiサーバに関しては、vCenterにvirsh接続することで操作が可能となります。

以下にvCenter Serverへのユーザ名、パスワード入力無での接続について説明します。

# 前提とする環境
 - 接続先となるのはvSphere5.x
   - vCenter Server 1台
   - Esxi 複数台(今回は、vSphere HA構成内に収容されているesx1と、データセンターにのみ収容されているesx4としてみます）
 - 接続元となるLinux
   - RHEL7.2 (virshのバージョンは1.2.8でした)

```
[root@rh72-01 ~]# virsh -v
1.2.8

[root@rh72-01 ~]# virsh -V
libvirt の virsh コマンドラインツール 1.2.8
http://libvirt.org/ にあるウェブサイトを参照してください。

以下のサポート付きでコンパイルされました:
ハイパーバイザー: QEMU/KVM LXC ESX Test
ネットワーク: Remote Network Bridging Interface netcf Nwfilter VirtualPort
ストレージ: Dir Disk Filesystem SCSI Multipath iSCSI LVM Gluster
その他: Daemon Nodedev SELinux Secrets Debug DTrace Readline Modular
★サポートされているハイパーバイザーにESXが含まれない場合は、接続出来ません。

```

# 準備
## ユーザ名、パスワード入力を省略する為に認証ファイルを用意します。
エディタで/etc/libvirt/auth.confを作成します。
以下の例では、192.xx.xx.xxのvCenterサーバを経由して各Esxiホストにvirsh接続する為の設定です。

### authセクション
auth-esx-の後ろにvishのコマンドラインで接続するホスト名もしくは、IPアドレスでセクションを記載します。
また、credentialsには、このセクションが利用するcredentialsセクション名を記載します。

### credentialsセクション
credentials-の後ろに、先にauthセクションで指定したcredentials値を指定して、セクションを記載します。
接続ユーザ、パスワードを記載します。
当然ですが、接続ユーザ、パスワードはvSphere Clientなどで実際にvCenterサーバに接続可能なユーザである必要があります。

```
[auth-esx-192.xx.xx.xx]
credentials=test

[credentials-test]
username=USER1
password=XXXXXX
```

# 接続の確認
vCenter Serverに接続する場合には、接続文字列としてvpxを指定します。
また、実際に接続するゲストを起動していいるESXiホストの指定は接続文字列の中にデータセンター名、クラスタ名を含めて指定します。

以下は、vCenterサーバ配下のdata-center(データセンター)配下に構成されたdata-cluster(クラスタ)のesxi1にvirsh接続する例となります。
auth.confを設定しているので、接続時にユーザ名、パスワードは不要です。

```
[root@rh72-01 ~]# virsh -c vpx://192.xx.xx.xx/data-center/data-cluster/esxi1?no_verify=1 list
 Id    名前                         状態
----------------------------------------------------
 561   rh7x-01                        実行中
```

以下は、

以下は、vCenterサーバ配下のdata-center(データセンター)配下のesxi4にvirsh接続する例となります。

````
[root@rh72-01 ~]# virsh -c vpx://192.xx.xx.xx/data-center/esxi4?no_verify=1 list --all
 Id    名前                         状態
----------------------------------------------------
 -     rh6x-01                        シャットオフ
 -     rh6x-02                        シャットオフ
````

どちらの接続もvpx指定でvCenterサーバを経由して可能です。
あくまで、auth.conf設定ファイルでの接続は、vSphere5.x環境でしか確認していません。6.xへの接続は未確認です。
また、6.xへの接続については、libvirtのバージョンが影響しますので、注意してください。
 - http://qiita.com/HideoYamauchi/items/85a2fe7f30401f5ced00

# その他
詳細は、本家のlibvirtのドキュメントが参考になるかと思います。
 - http://libvirt.org/auth.html
 - http://libvirt.org/drvesx.html

以上です。
node-gitをTypeScript2.0で利用するときにDefinitelyTypedのディレクトリが変わっている

[node-git](https://github.com/christkv/node-git)というNode.js用のGitのWrapperライブラリがある．これをTypeScriptで使いたい場合にDefinitelyTypedにある型定義ファイルを使おうと思うと2.0以降の場合注意が必要．

# tl;dr

node-gitからgitにディレクトリが変わっています．型定義ファイルを使いたいときは

```
npm install --save-dev @types/git
```

をすれば大丈夫です．

# 理由など

[このcommit](https://github.com/DefinitelyTyped/DefinitelyTyped/commit/4f7524fc65c0d1389af81a83a95dfe1ea59ad5e9)が理由のようだ．

TypeScript 2.0から型定義ファイルを `@types/~`でnpmで管理できるようになった．これは[この記事](http://qiita.com/laco0416/items/ed1aadf335f12cd3618d)が詳しいんだけど，それに伴ってファイルとかフォルダとかの名前を変更したらしい．

というのも，node-git はnpmには[git](https://www.npmjs.com/package/git)という名前で登録されており，それに合わせる形でディレクトリ名が `node-git` から `git`に移ったらしい．



何か間違いとか勘違いがあれば教えていただけると助かります．
TreasureDataで多重実行を排除するdomain keyがサポートされました

# これまでの問題

`td query`コマンドではPOSTリクエストを発行して、その返り値にJOB IDが返却されます。
しかし、稀にジョブは発行したけれども、返り値がネットワークの問題などによって取得できないエラーが発生することがありました。
POSTリクエストの場合にはリトライすると多重にジョブが登録されてしまう可能性があり、簡単にリトライすることができません。
そうすると、JOB IDがわからないので、自分が実行したジョブが本当に発行されたかどうかを調べることが難しいという問題がありました。
特にINSERT INTOやクエリ結果書き出しなどを実行していると、多重実行されてしまうと困ってしまうケースもありました。

それを解決するために、`--domain-key`がサポートされました。
https://github.com/treasure-data/td/pull/157

# domain keyとは

ジョブにユニーク名をつけることができるオプションになります。
これを使うことで、このdomain keyが登録されていて、かつジョブが発行されていれば、再度このdomain keyを元に処理を実行しても、既にジョブが登録されているから、受付拒否するよ。ということができるようになっており、多重実行を防ぐことができます。

# 例:

まずはジョブを発行します。

```
$ td query -d sample_datasets --domain-key batch1-20160926 -T presto "select * from www_access"
Job 92034375 is queued.
Use 'td job:show 92034375' to show the status.
```

正常にジョブIDを取得できてますが、仮にこれが失敗してjob idがわからなかったときは、再度このkeyを元に発行します。

```
$ td query -d sample_datasets --domain-key batch1-20160926 -T presto "select * from www_access"
Error: Query failed: ["Domain key has already been taken"]: conflicts_with job:92034375
```

すると、上記のエラーが発生し、これによってjob idが取得できます。
つまり従来は、

query -> job id取得 -> job status -> SUCCESSまでリトライ -> done

という処理しかできず、job id取得に問題があるとこまってしまったのですが、

query (+ domain key) -> job id取得できるまでquery -> job status -> SUCCESSまでリトライ -> done

という流れに変えることができるようになり、よりロバストなバッチ処理を実現できるようになっています。

# 補足

DigdagのTDオペレータでは、内部的にこれを利用するようになっており、リトライなどがロバストに行えるようになっています。
Google Compute Engine上でSlackのBotkitを動かすぞい！

Google Compute Engine(GCE)でSlackのBotkitを動かすぞい！という話。

以降 Google Compute EngineはGCEと書きます！

Slackのbotkitの詳細については割愛しますが、全く動かしたことないです！って人は一度以下とか読んで簡単なものでも動かしておくといいかもです。

[BotkitでSlackのBotをサクッと作る方法 - http://toach.click/slack-botkit/](http://toach.click/slack-botkit/)


## Google Compute EngineのVM インスタンスを作成する

今回はLinux VMインスタンスを作成します。

公式のドキュメントにそってやれば簡単にインスタンスは作れます。ちなみに、私は操作に慣れているUbuntuを使ってます。

[Quickstart Using a Linux VM - https://cloud.google.com/compute/docs/quickstart-linux](https://cloud.google.com/compute/docs/quickstart-linux)

インスタンス作るまでの手順は割愛しますが、公式のドキュメントより細かく手順が欲しい！！って方は以下のQiitaとかがオススメです。

[【2015年版】AWS ユーザが Google Cloud Platform に15分で入門する！](http://qiita.com/FumihikoSHIROYAMA/items/205fa3aebd20b3a1bace#compute-engine%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)

マシンタイプは「f1-micro（vCPU x 1、メモリ 0.6 GB）」とかで一番安いのでいいでしょう。


## VM インスタンスにSSHで入ってnodeをインストールする

gcloudとか使ってターミナルから操作もできますが、そこまで長い作業にならないのでWebのSSHで作業します。

VMインスタンスの一覧画面で、作業したいインスタンスのSSHから以下のように「ブラウザ ウィンドウで開く」を選択すれば、WebのSSHが開きます。

<img width="550" alt="スクリーンショット 2016-09-25 20.40.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/43637/7dd39b6b-2aae-f847-a923-85d40cd69369.png">


んで、開いたらVM インスタンスにnodeをインストールします。

nodeのサイトに各メジャーOSでnodeをインストールする方法が書いてありますので、作成したVMインスタンスのOSに合わせてコマンドを見つける。

[Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/)

私が普段VMインスタンスで使うOSはUbuntuなので以下のコマンドを実行すればnodeがインストールできます。npmもね。

```bash
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
```

インストールが終わったら一応nodeとnpmのバージョンを確認してインストールされていることとか確認しておくといいですね。

## VMインスタンス上で動かすbotkitのサンプルをcloneする

今回使ったのはSlackのBotkitでbotにメンション付きで発言すると、内容をオウム返しするbotさんを動かします！

[slack-botkit-sample - https://github.com/operando/slack-botkit-sample](https://github.com/operando/slack-botkit-sample)

上記のRepositoryをVMインスタンス上で以下のようにcloneします。ついでにnpm installもして実行に必要なモジュールもインストールしておく。

```bash
git clone https://github.com/operando/slack-botkit-sample.git
cd slack-botkit-sample
npm install
```

別途自身で作成したbotがあればそちらを使うでもいいですねー。

ちなみに、Ubuntuは元からgitが入っているので追加で入れる必要はないですが、立ち上げるOSによっては別途追加が必要かもです。


## VMインスタンス上でbotkitを動かすぞい！！

VMインスタンス上で動かすbotが用意できたら、あとは実行するだけです。

私が作ったbotなら以下のように実行します。

```bash
// your_api_tokenのところに自身のSlackのAPI tokenを入れる
token=your_api_token node parrot-bot.js
```

起動が確認できたらbotが動いてるSlackに移動して動作確認してみます。


## 動いた！！

やたー！！動いたー！！

![gce-slack-bot.gif](https://qiita-image-store.s3.amazonaws.com/0/43637/b97b8d97-de9a-7bac-f168-3aa7aeed8e67.gif)


## 後処理

動いた！！と満足してもうVMインスタンス不要だったら停止するなり削除するなりしておくといいかと。

## まとめ

GCEはインスタンスの作成も操作も簡単なのでいいですねー
Docker for Mac OSX × Jekyllでエンコーディングエラー

Docker for Mac OSXを使ってJekyllをいじっているのですが。ファイルを編集すると次のようなエラーが…

```
server    |       Regenerating: 1 file(s) changed at 2016-09-26 14:48:17 E, [2016-09-26T14:48:21.007586 #6] ERROR -- : run() in thread failed: invalid byte sequence in US-ASCII:\n /usr/local/lib/ruby/2.3.0/pathname.rb:41:in `=~'
server    | /usr/local/lib/ruby/2.3.0/pathname.rb:41:in `chop_basename'
server    | /usr/local/lib/ruby/2.3.0/pathname.rb:358:in `plus'
server    | /usr/local/lib/ruby/2.3.0/pathname.rb:350:in `+'
server    | /usr/local/bundle/gems/listen-3.0.8/lib/listen/adapter/linux.rb:47:in `_process_event'
server    | /usr/local/bundle/gems/listen-3.0.8/lib/listen/adapter/base.rb:42:in `block (2 levels) in configure'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/notifier.rb:205:in `block in watch'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/watcher.rb:41:in `callback!'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/event.rb:128:in `callback!'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/notifier.rb:238:in `block in process'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/notifier.rb:238:in `each'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/notifier.rb:238:in `process'
server    | /usr/local/bundle/gems/rb-inotify-0.9.7/lib/rb-inotify/notifier.rb:221:in `run'
server    | /usr/local/bundle/gems/listen-3.0.8/lib/listen/adapter/linux.rb:39:in `_run'
```

生成されるファイル名が日本語だとエラーになります。

色々調べた結果、RubyがUS-ASCIIになっているのが原因でした（via [dockerでpuppet実行エラー (invalid byte sequence in US-ASCII) - Qiita](http://qiita.com/kijibato/items/5e6543fd6e681f916bb0)）。

docker-compose.yaml に下記を追加して解決。

```
environment:
  RUBYOPT: "-EUTF-8"
```
Pacemakerリモートのバージョンの組合せに注意

Pacemakerの[remote機能](http://qiita.com/HideoYamauchi/items/80e399ed5a2293a1e012)(pacemaker remote)を利用する場合には、Pacemakerのバージョンの組合せに注意が必要です。

最初のremote機能のリリース(Pacemaker1.1.14)のremote機能と、最新のPacemaker1.1.15リリース以降のremote機能と互換性がありません。(通信の処理が改善された模様。)

よって、Pacemakerのホスト側(Pacemakerを起動しているノード）と、remote側(pacemaker_remoteを起動しているノード）のPacemakerのバージョンが異なる場合には機能することが出来なくなります。

バージョンアップなどでPacemaker1.1.14のremote機能を利用している環境をPacemaker1.1.15以降に入れ替える場合などで、バージョンアップ漏れがあると機能が停止します。

以上です。
iOS10 で CoreData の SQLDebugログ が出力されない

CoreDataはiOS10でログ出力先がNSLogからos_log/stderrに変わったらしい。その影響で
`-com.apple.CoreData.SQLDebug 1`を指定していてもconsoleにSQLiteのログが出力されない。

その場合は起動時引数に`-com.apple.CoreData.Logging.stderr 1`を追加してやればOK。

![スクリーンショット 2016-09-26 15.34.50.png](https://qiita-image-store.s3.amazonaws.com/0/8399/0e182eed-f8ad-7568-fb7a-2fcf3103aa5c.png)

参考
https://forums.developer.apple.com/thread/63315

↑のスレ見て、`-com.apple.CoreData.Logging.stderr 1`に書き換えればいいのね、と早とちりしてしまった。正しくは書き換えるのではなく、両方指定する必要がある。
Golang / Google Places API Web Serviceの利用

### はじめに

[Google Places API Web Service](https://developers.google.com/places/web-service/) ををGolangから利用するためのライブラリである[Go Client for Google Maps Services](https://github.com/googlemaps/google-maps-services-go) を利用してNearbySearchを実施した（長い）ので備忘録がてら以下に記載します。

ちなみに、Google Places API Web ServiceからのレスポンスはJSON形式であり、上記のライブラリを利用する方法も含めて

1. "encoding/json"パッケージを利用してJSONレスポンスをパースする
    1. あらかじめ構造体を定義しておく
    2. とりあえずinterface{}で突っ込んで後処理する
     - 参考：[golangでのjsonのデコード](http://qiita.com/oahiroaki/items/ff21d9adfb843161d1d8)
2. JSON形式が簡単に扱える"github.com/bitly/go-simplejson"パッケージを利用してJSONレスポンスをパースする
    - 参考：[Goで簡単にJSON形式を扱うパッケージ： go-simplejson](http://qiita.com/TalesofFox/items/5c147a19a9ae5c41f41a)
3. 公式の "googlemaps.github.io/maps"を利用

をすべて試しましたが当然ながら3.の公式を利用したものが圧倒的にラクでした。というか、最初からちゃんと検索すればよかった。

### リソース

そもそものAPI仕様と公式ライブラリについての情報
- [Places API Web Service/Place Search仕様](https://developers.google.com/places/web-service/search)
- [googlemaps.github.io/mapsのReference Documentation](https://godoc.org/googlemaps.github.io/maps)

### 実行環境

Mac OS X: 10.11.4, Go: 1.7

### 事前準備

"googlemaps.github.io/maps"

prettyはレスポンス結果表示用、contextは実行時引数に必要になります。

```
$ go get googlemaps.github.io/maps
$ go get github.com/kr/pretty
$ go get golang.org/x/net/context
```

### コード

サンプルコードはDirectionなのでこれを修正したものを作成。

```
package main

import (
	"log"

	"github.com/kr/pretty"
	"golang.org/x/net/context"
	"googlemaps.github.io/maps"
)

func main() {
	c, err := maps.NewClient(maps.WithAPIKey("<自分のAPIキー>"))
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}
	r := &maps.NearbySearchRequest{
		Location: &maps.LatLng{Lat: <緯度>, Lng: <経度>},
		Radius:   <検索する半経>,
	}
	resp, err := c.NearbySearch(context.Background(), r)
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}

	pretty.Println(resp)
}
```

### 実行結果

```
$ go run main.go
maps.PlacesSearchResponse{
    Results: {
        {
            FormattedAddress: "",
            Geometry:         maps.AddressGeometry{
                Location:     maps.LatLng{Lat:35.7090259, Lng:139.7319925},
                LocationType: "",
                Viewport:     maps.LatLngBounds{
                    NorthEast: maps.LatLng{Lat:35.8175167, Lng:139.9198565},
                    SouthWest: maps.LatLng{Lat:35.5208632, Lng:139.5629047},
...
```
mecabをpython2.7,ruby2.3,php7で使ってみた

* ubuntu 16.04.1

## 参考

* [PythonからMeCab（とCaboCha）を使うまで - Qiita](http://qiita.com/yoshikyoto/items/1a6de08a639f053b2d0a)
* [スクリプト言語のバインディング](https://taku910.github.io/mecab/bindings.html)

## インストール

```
sudo apt install -y \
  mecab mecab-ipadic-utf8
```


## 実行

```bash:mecabプロンプトにて文字入力しEnter押下
$ mecab
おなかすいた #Enter押下
```

```bash:結果
おなか	名詞,一般,*,*,*,*,おなか,オナカ,オナカ
すい	動詞,自立,*,*,五段・カ行イ音便,連用タ接続,すく,スイ,スイ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS
```

## python2.7で実行

```
sudo apt install -y python-mecab
```

```py:a.py
# coding: utf-8
import MeCab
mt = MeCab.Tagger("-Ochasen")
print mt.parse("おなかすいた")
```

`python a.py`

```bash:結果
おなか	オナカ	おなか	名詞-一般		
すい	スイ	すく	動詞-自立	五段・カ行イ音便	連用タ接続
た	タ	た	助動詞	特殊・タ	基本形
EOS
```

## ruby2.3で実行

```
sudo apt install -y ruby-mecab
```

```rb:a.rb
require 'MeCab'
m = MeCab::Tagger.new ("-Ochasen")
print m.parse ("おなかすいた")
```

`ruby a.rb`

```bash:結果
おなか	オナカ	おなか	名詞-一般		
すい	スイ	すく	動詞-自立	五段・カ行イ音便	連用タ接続
た	タ	た	助動詞	特殊・タ	基本形
EOS
```

## php7で実行

* [PHPからMeCabを利用してよみがなを取得する - Qiita](http://qiita.com/sogawa@github/items/8b82a7836f9278a05631)

```
sudo apt install -y \
  php7.0-cli php7.0-dev libmecab-dev
```

```
git clone https://github.com/rsky/php-mecab.git
cd php-mecab
cd mecab
phpize
./configure --with-php-config=/usr/bin/php-config --with-mecab=/usr/bin/mecab-config
make
sudo make install
```

* `/usr/lib/php/20151012/mecab.so`が入る。

```bash:extension登録
sudo sh -c "echo 'extension=mecab.so' > /etc/php/7.0/mods-available/mecab.ini"
sudo ln -s /etc/php/7.0/mods-available/mecab.ini /etc/php/7.0/cli/conf.d/20-mecab.ini
```

```bash:確認
$ php -i | grep -i mecab
/etc/php/7.0/cli/conf.d/20-mecab.ini,
mecab
MeCab Support => enabled
MeCab Library => 0.996 => 0.996
mecab.default_dicdir => no value => no value
mecab.default_rcfile => no value => no value
mecab.default_userdic => no value => no value
```

* [PHP7.0+mecabでハマった事 - Qiita](http://qiita.com/murota/items/3c76cc3ca0fd819dbac7)

```diff:php7では書き方が違う
- $mecab = new MeCab_Tagger();
+ $mecab = new \MeCab\Tagger();
```

### ようやく実行

```php:a.php 
<?php
$str = "おなかすいた";
$mecab = new \MeCab\Tagger(array('-O' => 'chasen'));
echo $mecab->parse($str) . PHP_EOL;
```

`php a.php`

```bash:結果
おなか	オナカ	おなか	名詞-一般		
すい	スイ	すく	動詞-自立	五段・カ行イ音便	連用タ接続
た	タ	た	助動詞	特殊・タ	基本形
EOS
```
githubのOrganizationアカウントにあるリポジトリをmirrorバックアップ

準備

1. githubのOrganizationアカウントの管理権限があるユーザでログインします。
2. Edit profile -> Developer settings -> personal access tokenをクリック
3. Generate New Tokenボタンをクリック
4. ![スクリーンショット 2016-09-26 15.22.08.png](https://qiita-image-store.s3.amazonaws.com/0/57579/ff5f3ed0-1396-587b-7c1b-acc346e80cb5.png)
5. tokenを生成し、控えておく
6. 下のスクリプトに生成したTokenやログインIDを設定。
7. スクリプトをバックアップ先のサーバの、バックアップリポジトリ保管ディレクトリへ保存
8. cronなどお好きなツールで定期実行

```
#!/bin/sh

#####
#
# このシェルはjqコマンド使っています。
# yum -y install jq
# にてインストールをしてください。
#
# 動作概要
# 実行ディレクトリの直下にgithub organizationユーザのリポジトリのバックアップをとります。
# バックアップ方法は git clone --mirrorとしています。
# 直下にディレクトリが存在する場合は git fetch --allにて同期処理を行うようにしています。
#
# 使用方法
# バックアップ先のマシンのリポジトリバックアップディレクトリの直下にこのシェルを置いてください。
# 作成後に実行権与えていただければ実行可能になります。
# chmod 755 "このシェル".sh
#
# 変数のxxxxxxのところはそれぞれ適切なログインアカウントやtokenに書き換えてください
#####

BACKUP_REPOSDIR=`echo $(cd $(dirname $0) && pwd)`
LOGIN_NAME='xxxxxxxxxxxxxx'
GITHUB_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxx'
API_ROOT='api.github.com/orgs/xxxxx'
ORG_GITROOT_PATH='git@github.com:xxxxxxx'

# get repository list
curl https://${LOGIN_NAME}:${GITHUB_TOKEN}@${API_ROOT}/repos?per_page=1000 |
jq -r '.[].ssh_url' |
while read -r repo; do
  dir=`echo $repo | sed -e "s/${ORG_GITROOT_PATH}\///"`
  if [ -e $dir ]; then
    echo "${repo}"
    cd $dir
    git fetch --all
    cd ${BACKUP_REPOSDIR}
  else
    git clone --mirror "${repo}"
  fi
done
```
slim使用時に発生するkaminariのエラー

##問題
kaminariで以下のようなエラーが発生した。

```
NoMethodError in Contents#index

Showing /Users/.../vendor/bundle/ruby/2.3.0/bundler/gems/kaminari-be3a2c9a2182/app/views/kaminari/_paginator.html.erb where line #9 raised:

undefined method `safe_append=' for "":ActiveSupport::SafeBuffer
```

```ruby
# index.html.slim
= paginate @hoges
```

##解決方法

以下のコマンドを打つ。

```shell-session
rails generate kaminari:views default -e slim
```

##参考サイト
https://github.com/amatsuda/kaminari/issues/11
Kubernetesで複数コンテナを1Podとして動かす

#概要
1Pod内で複数のコンテナを動かしてみます。
Kubernetesの構築[(記事はこちら)](http://qiita.com/mmitti/items/6c1bedbcffdda6a63473)とDNSサーバーの構築[(記事はこちら)](http://qiita.com/mmitti/items/186280552f63931d9420)が完了していることが前提となります。
また、[前回の記事](http://qiita.com/mmitti/private/53554f9b41ae1a4950db)で作成したサンプルを一部使いまわしています。

#環境
[DNSサーバーの構築](http://qiita.com/mmitti/items/186280552f63931d9420)完了時と同じ環境です。
前回の記事で追加したnfsサーバーは今回は不要です。

||masterサーバー|nodeサーバー|
|:----|:----|:----|
|ホスト名|master|node1|
|IPアドレス|192.168.137.20|192.168.137.21|
|動作しているサービス|kube-apiserver<BR>kube-controller-manager<BR>kube-scheduler<BR>kube-dns|kubelet<BR>kube-proxy|

#構成
今回は以下2つのコンテナを1Podとして配置します。

- test-db  
  前回の記事で作成したサンプルを流用  
  DBサーバ(実際はjsonファイルを読みだすだけ)    
  DockerHub上にmmitti/test-dbとしてイメージを公開しています  
  8000番ポートで稼働しています
- test-db-viewer  
  前回の記事で作成したtest-db-clientを変更したもの  
  test-dbが読み込んでいるjsonファイルと同じものを読み込みHTMLを生成します  
  データの追加は自ホスト8000番ポート(test-db)宛にデータをポストします  
  5000番ポートで稼働しています

![図面1.png](https://qiita-image-store.s3.amazonaws.com/0/140084/8aabb7f8-e597-f3ba-2296-b13a1fafd381.png)

また、2つのコンテナはemptyDirをマウントしてjsonファイルを共有しています。

#サンプルコード
サンプルのyamlファイル及びtest-db-viewerコンテナのコードはGithub上で公開しています。必要であれば御覧ください。
https://github.com/mmitti/kube-multi-container-sample

[test-db-viewer.yaml](https://github.com/mmitti/kube-multi-container-sample/blob/master/test-db-viewer.yaml)

```
kind: ReplicationController
apiVersion: v1
metadata:
  name: test-db-viewer
  labels:
    app: test-db-viewer
spec:
  replicas: 2
  selector:
    app: test-db-viewer
  template:
    metadata:
      name: test-db-viewer
      labels:
        app: test-db-viewer
    spec:
      containers:
      - name: test-db-viewer
        image: mmitti/test-db-viewer
        ports:
        - containerPort: 5000
        volumeMounts:
        - name: data
          mountPath: /db
          readOnly: true
      - name: test-db
        image: mmitti/test-db
        ports:
        - containerPort: 8000
        volumeMounts:
        - name: data
          mountPath: /db
      volumes:
      - name: data
        emptyDir: {}
---
kind: Service
apiVersion: v1
metadata:
  name: test-db-viewer
  labels:
    app: test-db-viewer
spec:
  ports:
  - name: viewer
    protocol: TCP
    port: 5000
  - name: db
    protocol: TCP
    port: 8000
  selector:
    app: test-db-viewer

```

普通のReplicationControllerとほぼ同様でcontainersに複数のコンテナを書くだけです。
今回はストレージとしてemptyDirを用いたのでその定義も含んでいます。

#####注意
containersのportsにhostPortを含めるとノードのポートとバインドされ1ノードに1Podしか動かなくなるので注意

#動作確認
ReplicationControllerとサービス作成後以下のコマンドで動作を確認します。

```
kubectl get po  -l app=test-db-viewer
NAME                   READY     STATUS    RESTARTS   AGE
test-db-viewer-0ckpz   2/2       Running   0          9m
test-db-viewer-zov19   2/2       Running   0          9m
```

pod起動後
http://192.168.137.20:8080/api/v1/proxy/namespaces/default/services/test-db-viewer:5000/
にアクセスして見ます。

テキストボックスに適当な文字列を書き込みADDボタンを押してみてください。
INIT_HOST, DB_HOST, WRITE_HOSTが同じであれば成功です。

※2pod起動しているのでアクセスするたび、ポストするたびに接続先のホストが変わる可能性があります。わかりにくい場合はreplicasを1にしてテストしてみてください。

#参考
test-dbコンテナの詳細は前回提示したGithubで公開しています。必要であれば御覧ください。
https://github.com/mmitti/kube-petset-sample
React 事件系统



#合成事件

React 中所有的事件都会被转换为一个` SyntheticEvent`, 一个跨浏览器的对于浏览器事件的封装. 他们和浏览器的事件具有同样的接口.包括` stopPropagation` 和` preventDefault` 方法. 除了那些在所有浏览器实现里都一样的事件.

如果你要使用某些浏览器原生的事件是,通过` nativeEvent` 就可以获取.每一个` SyntheticEvent` 都有下列的属性:

```
boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
DOMEventTarget target
number timeStamp
string type
```

#事件池

这个` SyntheticEvent` 是放在事件池里,也就是说它是被重复使用的.当一个回调结束之后它所有的属性都会置空.这是为了性能考虑, 同样你不能够通过异步的方式来访问这个事件.

```
function onClick(event) {
  console.log(event); // => nullified object.
  console.log(event.type); // => "click"
  var eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.log(eventType); // => "click"
  }, 0);

  // Won't work. this.state.clickEvent will only contain null values.
  this.setState({clickEvent: event});

  // You can still export event properties.
  this.setState({eventType: event.type});
}
```


#支持的事件


- 剪贴
- 排版
- 键盘
- 焦点
- 表单
- 鼠标
- 选中
- 点击
- UI 事件
- 媒体
- 动画
- 图像
- 滚珠
- 变化
Dagger2導入


## 環境
AndoirdStudio2.2
Gradle2.14.1

## Gradle

rootのbuild.gradleに1行追加

```build.gradle

dependencies {
    classpath 'com.android.tools.build:gradle:2.2.0'
    // APT Plugin
    classpath 'com.uphyca.gradle:gradle-android-apt-plugin:0.9.4'
}

```

appのbuild.gradleに3行追加

```app/build.gradle

apply plugin: 'com.android.application'

// APT Plugin 'com.android.application'以降に追加しなければいけないので注意
apply plugin: 'android-apt'

dependencies {

    // Dagger2
    compile 'com.google.dagger:dagger:2.2'
    apt 'com.google.dagger:dagger-compiler:2.2'
}

```
## Module

Module用のクラスを作成

```java:HelloModule.java

@Module
public class HelloModule {
    @Provides
    Hello provideHelloImpl() {
        return new HelloImpl();
    }
}

```


## Component

Componet用インターフェースを作成

```java:ActivityComponent.java
	
@Component(modules = HelloModule.class)
public interface ActivityComponent  {
    void inject(MainActivity activity);
}

```

## インターフェースを作成

sayメソッドだけのインターフェースを作成

```java:Hello.java
	
public interface Hello {
    void say();
}

```


## インターフェースを実装したクラス

helloと出力するだけのメソッド

```java:HelloImpl.java
	
public class HelloImpl implements Hello {
    @Override
    public void say() {
        Log.d("TAG", "hello");
    }
}

```

## MainActivity

1度実行して、DaggerActivityComponentが生成されてから、
実際にInjectして以下のように使ってみる

```java:MainActivity.java
	
public class MainActivity extends AppCompatActivity {

   	@Inject
   	Hello mHello;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerActivityComponent.create().inject(this);
        
        // helloと出力
        mHello.say();
    }
}

```
以上で終わりですが、実際に通信して使うとこまでを追記しておきます。
Dagger2 + Retrofit2 + RxAndroidで通信してみる
http://qiita.com/MuuKojima/items/8088b43876dc8d3d1745
React 组件 API


#React.component

一个 react 的组件是 React 的 render() 方法执行的时候生成的一个组件实例. 这个组件可以重用在多个 render 方法中. 而且通过组件发任何方法中访问到这个组件的实例对象通过 this 关键字. 唯一能够获取 React 组件实例的句柄的方法就是通过` ReactDOM.render()`方法来设置或者返回它. 而在其他的组件内容,通过` refs` 也是可以达到同样目的的.

##setState

```
void setState(
  function|object nextState,
  [function callback]
)

```

这个方法就是能够将当前最新的状态 merge 到当前状态上. 这个方法完成了当事件处理或者服务器回调状态更新之后 UI 的同步. 第一个函数可以是一个对象(包含零个或者多个键用来更新)或者是一个函数(状态和属性)然后返回一个对象包含了多个更新的键.

```
setState({myKey: 'my new value'})
```

同样它也可以是传入一个函数,签名是` function(state, props)`,通过这个方式可以很容易实现一个原子性的更新,基于之前的状态和属性合集. 比如想要递增一个状态里的值:

```
setState(function(previousState, currentProps){
  return {myInteger: previousState.myInteger + 1};

});
```

第二参数就是一个回调函数,在` setState` 完成之后触发的.

**注意**

**永远**不要直接去修改` this.state`, 而是通过` setState`来完成的.可以直接把它` this.state`看成是不可变的.

而` setState` 也不是直接立即修改` this.state`, 而是创建一种过渡症状,所以即使调用 setState 也还是可以从 this.state 里拿到之前的值. 不保证这个操作是同步进行, 有可能在为了取到性能的情况下 batch 处理.

通常` setState` 都是会触发 UI 的 re-render.除非在` shouldComponentUpdate()` 函数里添加了条件式更新 UI 的逻辑在,这里就可以 diff 当前的状态和之前的状态,如果发生变化再去 re-redner.

##replaceState

```
void replaceState(
  object nextState,
  [function callback]
)

```

和` setState` 类型,但是在 merge 的时候会移除那些在` nextState` 里不存在状态.

##forceUpdate

```
void forceUpdate(
  [function callback]
)
```

默认状态下,当发生了状态属性的变化都会自动触发 UI 的 re-render, 但是有些隐藏的状态变化的时候可以显式调用这个方法来 re-renderUI.


##isMounted

```
boolean isMounted()
```


这个方法会返回` true` 如果该组件已经渲染到了 DOM 里.` false` 则反之. 你可以通过这个方法验证 setState 或者 forceUpdate异步执行是否完成.
他の人が立てたEC2を頂戴する。

# はじめに
EC2のキーペアって後から変更できないじゃないですかー。
dev環境でテストとかしていて、環境構築した人が不在とかだと
sshしてごにょごにょできないじゃないですかー。
そんな時どうしてますか?
環境立て直しますか?

# そうだ！EC2を乗っ取っちゃおう。
環境構築って、[CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html)とか[Terraform](https://www.terraform.io/)とか使われることが多いのかなと思います。
で、EC2立てる時って、`AutoScale`とか考えて`起動設定`と`Auto Scalingグループ`とかも立てると思います。
今回の乗っ取りはここを使います。
※AWSコンソールからぽちぽちします。

## すること
1. 対象EC2の起動設定をコピーして`キーペア`を変更する
2. 対象の`Auto Scalingグループ`の`起動設定`をコピーした物に置き換える
3. 対象のEC2を削除しちゃう
たったこれだけです。

## 詳細にスクショ付きで説明
### 1. 対象EC2の起動設定をコピーを押下する
<img width="1280" alt="autoconfig.png" src="https://qiita-image-store.s3.amazonaws.com/0/88884/ffaa554d-3f77-7013-4ad2-45a679292325.png">


### 2. UserDataや、インスタンスタイプの変更がない場合、飛ばされた画面の作成を押下する
<img width="1280" alt="autoconfig2.png" src="https://qiita-image-store.s3.amazonaws.com/0/88884/00c73db8-f95a-b018-3325-c5fcee357ac5.png">

<br>
### 3. キーペアを自分のものに変更して、起動設定の作成を押下する
<img width="1280" alt="autoconfig3.png" src="https://qiita-image-store.s3.amazonaws.com/0/88884/344c3157-55de-1b0f-7b25-c373fbc99ba1.png">

<br>
### 4. Auto Scalingグループの編集を押下する
<img width="1280" alt="autogroup.png" src="https://qiita-image-store.s3.amazonaws.com/0/88884/99f6c65a-f4e6-a3d9-ec0b-01f9dea901b6.png">

### 5. Auto Scalingグループの起動設定を置き換える
あれ、画像が貼れない...
容量オーバーみたいなポップアップが出ました...

### 6. 既存のEC2インスタンスを削除する
と、新規で自分のキーペアでインスタンスが立ち上がります。

### EC2頂戴できました！

# さいごに
用事が終われば、戻しておきましょう。
`CloudFormation`や`Terraform`で構成管理していると、一括削除できなくなるので。
ruby on railsでpuma.rbが見つからない時

#はじめに
[RoRのチュートリアル](https://www.railstutorial.org/book/static_pages)でherokuのローカルウェブが起動出来ずに困ったのでメモ。

```
$ heroku local web
[WARN] No ENV file found
1:19:26 PM web.1 |  bundler: failed to load command: puma 
1:19:26 PM web.1 |  Errno::ENOENT: No such file or directory @ rb_sysopen - config/puma.rb
```
#heroku

herokuのページに[サンプル](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#config)があった。

```ruby
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end
```

これをconfig/puma.rbとして保存すれば起動出来ます。
Rails備忘録：開発環境

# 開発環境について

Rails開発環境構築手順については記述しません。

OS windows7 Pro 32bit
Ruby 1.9.3
RubyGem 1.8.24
Rails 4.0.0
DB postgreSQL

社会人１年目のプログラマー
色々教えてもらいたいのでQiita参加!!

エディタ等
・NetBeans IDE 8.1 Rails仕様
・Notepad++ Rubyプラグイン導入済
・Sublime Text3　<=今一番メインで使ってます。

私はIDEで一括と言うよりコンソールを見ながらエディタで書き書きする派かな。
仕事では、Railsの一部分一部分の修正の依頼ばかりで、全体を把握してないので
全体的に学べていけたらと思いますので宜しくお願いします。

開発環境で何か質問があればどうぞ～。

使用可能言語
C言語
Rails全般
(ruby,html,jquery等)
CentOS6 にて gulp 実行環境を構築

# はじめに
普段gulpを利用して、scss や ES6 を変換しているのですが、万が一に備えて環境の再構築を出来るようにメモ書きをまとめました。
個人用のメモの側面が強いので、特に新規性のある記事ではないです。
構築環境は CentOS6.5、node-js v5.7.0です。

# nodebrew を利用して node-js のインストール
+  nodebrewをインストール

```sh:nodebrewをインストール
wget git.io/nodebrew
perl nodebrew setup
```
+ bashrcを編集して起動時に読み込むようにする

```shell:bashrcを編集
vi ~/.bashrc
export PATH=$HOME/.nodebrew/current/bin:$PATH
```
+ nodebrebrewを利用して、node-js をインストール

```sh:node-jsインストール(この場合はv5.7.0)
nodebrew remote-ls
nodebrew install v5.7.0
nodebrew use v5.7.0
```
+ 必要に応じて、g++4.8 以降をインストール
    + node-js のインストールが失敗する場合、g++ が古いor入っていないことが原因の可能性が高いので、インストールします。
    + epel の g++ は古いので、レポジトリからインストールする場合には Software Collections の Developer Toolset を利用することになります。
今回は g++4.8 で十分なので、Devtoolset-2 を利用します（Devtoolset-3 でも多分手順は同じです。）

```sh:Devtoolset-2をインストール
cd  /etc/yum.repos.d/
wget http://people.centos.org/tru/devtools-2/devtools-2.repo
yum install devtoolset-2-gcc devtoolset-2-binutils
yum install devtoolset-2-gcc-c++ devtoolset-2-gcc-gfortran
```

```sh:Devtoolset-2を有効化してnode-jsをインストール
scl enable devtoolset-2 bash
nodebrew install v5.7.0
nodebrew use v5.7.0
```

# gulp環境を構築

+ gulpはグローバルから利用できたほうが便利なのでインストール

```sh:gulpをグローバルにインストール
npm install -g gulp
```
+ その他のパッケージは --save-devをつけてインストールしていればプロジェクトのpackage.jsonに書き込まれ、npm installをした時に自動的にインストールされます。

```sh:プロジェクトをインストール
git clone ssh://git@gitlab.example.com:/project1.git
cd project1
npm install
```

# 参考文献
+ [CentOSにnodebrewをインストールする](http://qiita.com/kentana20/items/05f1a4af9812398863fa)
+ [CentOSに新しいバージョンのGCC/G++(4.8/4.9)をインストールする](http://www.task-notes.com/entry/20151114/1447492231)
Unity Version Selector (for Mac) で複数バージョンのUnityを扱う

# 免責
OS Xのユーザーのみ対象。
http://qiita.com/kyubuns/items/3feb67d4344bc645d0cc
のコードを参考にさせていただきました。

# Unity Version Selectorを作るに至る所以
Unityはバージョン互換がない。一度完成させたプロジェクトでもUnityのバージョンを替えると、そのままでは正常に動かなくなったり、コンパイルできなくなったり、挙動が変わったりする。uGuiまわりのレイアウト崩れも激しく起こるが、ARなどに関するプロジェクトは挙動が怪しくなりがちだ。

Unityのマイナーアップデートですら侮れない。
別バージョンで焼いたアセットバンドルとアプリ本体の相性も悪いので焼き直してアップロードし直しだ。

これを新しいバージョンに乗り換える度に各プロジェクトメンテナンスすると、プロジェクトの数に比例して時間的コストがかかる。
全部で一ヶ月くらいかかることもあった。この事態は一社長として見過ごせない。

そこで俺は革新的でないUnityのアップデートを無理して追いかけても革新的な物を産むことに繋がらないと思い、今更ながらただの時間の無駄と気が付いたので、複数のバージョンを取っておき使い分けることにした。しかしどのプロジェクトがどのUnityバージョンで作ったのかをいちいち意識して起動するのが面倒なのでバージョンセレクターを作った。

# Unity Version Selectorを使うための準備
複数のUnityを保持するため、/Application/以下にあるUnityを~/Developer/Unity_Versions/以下に5.4.0f1のようなディレクトリ名にして置いておく。
この要領で使う分だけバージョンを置いておく。このディレクトリに退避させたあとならUnity公式のインストーラーを動かしても/Application以下にUnityがなければ上書きされないのでインストーラーでインストール後、Unityを移動していけば良い。

# Unity Version Selectorの仕様
このアプリをOS Xにいれた状態でUnityプロジェクトのルートディレクトリに.unityprojという拡張子をつけるだけで、あとはそれをダブルクリックなりで開くとそのプロジェクトが最後に開かれたunityに最も近いバージョンで開く。（ただしパスにスペースを含むと正常に動作しない。）
アプリはunityproj拡張子に関連付けられているのでファイルオープナーとして使う用に作ってあるが、アイコン自体を叩くと最もバージョンが新しいUnityを選んで起動するので新しいプロジェクトを立ち上げる時などに便利だ。
つまりDockからUnityアイコンをとっぱらってこのUnity Version Selectorを置いておけば良い。

# ダウンロードはgithubから

https://github.com/GeneralD/Unity-Version-Selector
Ubuntuをアップグレードした後にBundleで「bad interpreter」と出た

`bundle exec ruby hello.rb`が通らなくなった。

```
ruby -v       
ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]
```

rubyはOK

```
bundle -v
zsh: /usr/local/bin/bundle: bad interpreter: /usr/bin/ruby2.1: そのようなファイルやディレクトリはありません
```

bundlerがダメだった。入っているrubyが2.3.1で、見に行ってる場所が違うという事は分かったので…

再インストールした :innocent: 

```
which bundle
/usr/local/bin/bundle
```

`sudo rm /usr/local/bin/bundle`

```
which bundle
bundle not found
```

```
sudo gem install bundler
```

```
bundle -v                  
Bundler version 1.13.1
```

実行出来た。`bad interpreter`が出たら再インストールすればどうにかなるかもしれない。
ls -Rでフルパスを取得

あってもおかしくないのに、見当たらなかったので。
私の探し方がまずかったのかな…？
念のため、備忘録おいときます。

# find -ls -maxdepth (n)
一番手っ取り早いのはこれ。
とはいえ、ls -Rの出力形式のようにしたい場合はfindは邪魔になります。
力技でいい感じにするというのも手ではありますが、今回はlsにこだわります。

# キーポイント
ターミナルでpwdを打つ機会は多いと思いますが、`$PWD`で自分の場所がフルパスで取れます。
`$(PWD)`でも`PWD`でも同じです。

これを使って、今いる場所(./)をフルパスに置き換える、というのが目的です。
仕組み自体はそんな難しくないです。

``` sh:fullls.sh
#!/bin/sh
nowDir=$PWD

cd $(dirname "lsで取りたいディレクトリ")
ls -R $PWD

cd ${nowDir}
```

これだけです。とても簡単！
nowDirしているのは、lsした後で今いる場所に戻ってくることがあるかも知れないので、念のため入れてます。

気をつけてほしいのが、nowDirでsh実行をする想定でteeとかしたい場合は以下のようにします。

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

# shファイルのフルパスをthisに持っておく
cd $(dirname ${0})
this=$(PWD)

...
ls -R $PWD | tee ${this}/tee.txt
```

これでどこに移動しても一意の場所を設定できます。
結構落とし穴なので、出力先の設定も絶対パスにするようにしましょう。
逆に、相対パスで都合がいい場合はこの限りではありませんが、運用に気をつけてください。
Watson APIを使ってAndroidアプリを作ってみた

ちょっと前にIBMのCMでよく流れていたwatsonを使ってみたいと思い。ちょっと調べてみた。

[IBM Blumix](https://console.ng.bluemix.net/)にWatson APIがありAPI経由でいろいろ使えるみたいです。ちなみにBluemixは30日間は無料です。

API仕様を見てみる（だいたい英語）と利用方法はこんな感じのようです。
１．Bluemixにログインする。
２．カタログからwatsonサービスからAPIを選ぶ。
３．必要内容を記述してサービスを作成する。
４．作成されたアプリを選択。サービス資格情報を選択しusername,passwordを取得する。

```

{
  "credentials": {
    "url": "https://gateway.watsonplatform.net/dialog/api",
    "password": "XXXXXXXXXXXXX",
    "username": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  }
}

```

５．使い方はこのような感じ。

[java SDK](https://github.com/watson-developer-cloud/java-sdk)

```

	    DialogService service = new DialogService();
	    service.setUsernameAndPassword("username","password");


```


作ったアプリがこちら（Dialogのサンプルを日本語化している）
![androidwatson.gif](https://qiita-image-store.s3.amazonaws.com/0/58286/fd2b7f13-e95a-4bba-b2c4-44ee86719519.gif)


使ったAPIは３つ。音声認識とDialog（※現在は新しく[Conversation](https://www.ibm.com/watson/developercloud/conversation.html)というのが出ています。）
![image](https://qiita-image-store.s3.amazonaws.com/0/58286/dfe45b15-ac2b-6ca6-a583-9a196f1b2212.png)
Windowsでcronみたいな事をやらせる


掲題の要望自体はタスクスケジューラを使えばできます。
ここではwindowsバッチで書いてますが、exeに引数渡していい感じに使えるならそうしましょう。

# やりかた

windowsスタートメニュー
→全てのプログラム
　→アクセサリ
 　　→システムツール
   　　→タスクスケジューラ
     
タスクスケジューラライブラリ上で右クリックし、基本タスクを作成します。

1.名前。なんでもいいです
2.トリガー。見たままです。ここではテストをするので、リアルタイムに近い場所を設定しておきましょう。
3.操作。プログラムの開始→それぞれ設定します。デスクトップにショートカット張ってプロパティ設定して動いたらそれを入れてください。
4.実際に動くことを確認してください。
5.動くことを確認できたらトリガーを指定時間にします。

# 使用例

たとえば、お子さまにパソコンを使わせたいけど、時間を過ぎたら強制的に落として寝かせる、という運用を考えた場合、以下の運用をするといいです。

まずはお子さまがパソコンを使うためには、親がログインしてあげるという運用対処を行います。（ここでは説明を省略します）
次に強制的にマシンを落とすものを作りましょう。

``` bat:shutdown.bat
shutdown -s -t 0
```

これは、実行すると即時シャットダウンをします。
動かすときは他のプログラムが起動していないことを確認してください。

念のため、テスト用のファイルを置いておきます。

``` bat:test.bat
echo "実行完了"
pause
```

タスクスケジューラからtest.batのフルパスを設定して、実行完了が表示されれば成功です。
shutdown.batにパスを変えて、そちらも動くことを確認してみましょう。
（実行したらパソコンが落ちますので、他のアプリケーションは終了させておきます）

# 応用編

というか本編。
同じようにファイルを定期的にバックアップする仕組みを作っておきます。
gitとかsvnが出てる中でこんなアホな事をするのはどうなんだ？と思うんですが、サードパーティーを入れられない環境もあります。
前時代的ではありますが、いつか困るだろうなので備忘録として残してます。

``` bat:backup.bat
rem batで実行。powershellなり他のが使えるならその方がいい。
rem 宗教戦争になるが、よく分からない場合はperlオススメ

@echo off
if "%~1" == "download" goto download
if "%~1" == "upload" goto upload
exit

rem dateで取得する時にファイル名に使えないアレコレをYYYYmmddにする
set day=%date:~0,4%%date:~5,2%%date:~8,2%

set backupfromF="バックアップ元フォルダ"
set backuptoF="バックアップ先フォルダ"

rem バックアップ先を日付管理などで保存。いい感じに改変推奨
:download
mkdir %backuptoF%\%day%
xcopy /e %backupfromF% %backuptoF%\%day%
exit

rem バックアップ元に復元する。こっちは特に意識していない
:upload
xcopy /e %backuptoF%\%day% %backupfromF%
exit
```

# 注意、というか忠告
タスクスケジューラやcronでrmコマンドを実施するのは心底おススメしません。
renameとかmvで保持しておいて、本当に削除して大丈夫なのか、確認しましょう。

# 大事なことなのでもう一度
batでやるならshell系使える環境を作って、そっちでやった方がいいと、個人的には思います。
Windowsならpowershellとか、そういうのを使うと文字列処理などでぐぬぬする事が比較的少ないと思います。

# [2017/11/30] 別解　Windows Subsystem for Linux
この記事を見ている人はLinuxに慣れてる人だと思うので、こういうのはアリだと思います。
クライアントがWindows10 Pro版だよ～って人はこっちが断然オススメ！

https://qiita.com/nomurasan/items/95837a309f4bc8a0dbae

# [2021/12/07] 別解 Windows Subsystem for Linux
WSLにcron入れる必要なくね？という当たり前の事に当時気付きませんでした。
「これ(batからshellファイルを実行させる)をするんだ！」という目線で考えると視野が狭まって良くないですね。。

https://qiita.com/nomurasan/items/68a5ee741eb04ab50714

# 読了後いいね！をお願いします。
どれだけの方に読んでもらっているか知りたいので、お手数をおかけしますがご協力いただけると嬉しいです。
Quantum Chemistry - Correspondence Principle

関連 http://qiita.com/7of9/items/d3a1799928734375f34f

CG分野で使われるSpherical Harmonics。自分の数値シミュレーション計算に用いたいと思い調べると、量子化学の講義にたどり着く。

短く分かりやすそうな159本のビデオを少しずつ消化中。

Quantum Chemistry - Correspondence Principle
https://www.youtube.com/watch?v=1Pd9iyD26i8&list=PLm8ZSArAXicL3jKr_0nHHs5TwfhdkMFhh&index=41

- 量子力学の一般原理の最後の一つ
- Correspondence Principle
   - 量子力学と古典力学は「ある条件下では」同じである
- 黄色
   - High Energy
   - Large Mass
   - Large Length
   - の場合は量子力学は古典力学と同じである
   - マクロな視点からは同じ
- オレンジの式
   - 異なるエネルギーレベルの式
   - P.I.B
      - Particle In a box モデル
   - H.O
      - Harmonic Oscillatorモデル
      - 分子の振動のモデル
   - R.R 
      - Rigid Rotor
          - 剛体回転?
      - 分子の回転など
      - 量子数Jによる
   - これらのエネルギーが黄色の条件でどうなるか見る
- 水色の式
   - lengthが無限大の時Enは0
      - P.I.Bモデルの式 (分母にエルより)
   - massが無限大の時Enは0
      - P.I.Bモデル、H.Oモデル, R.Rモデルの式 (分母にmより)
   - nが無限大の時En / E_(n-1)は0
- 右上の緑
   - 以下の条件を考える
   - massが1kg
   - lengthは1m
   - kは1N/m (N: ニュートン)
- ピンクの式
   - Enの値はP.I.B, H.O, R.Rすべてにおいて小さい
   - http://ejje.weblio.jp/content/inconsequential
       - 取るに足らない 
       - (補足) negligibleとも言える? 
   - マクロな視点で見た時
デザイナーが1からウェブサービスを作る | dockerの設定編2

#今回の目標
前回はDockerのインストールと、VirtualBoxとの連携を行いました。
今回はdockerでNinixを起動するところまでやってみたいと思います。

#Dockerを立ち上げる
前回のステップと繰り返しになりますが、DockerとVirtualBoxをもう一度連携します。

`docker-machine ls`
machineのステータスを確認。Stoppedしているので、起動します。

`docker-machine start dev`
起動完了。次に、machineでdockerコマンドが使えるように再度環境設定します。
この作業はbash_profileで自動化できるようですが、慣れるためにしばらくは手動で進めます。

`eval $(docker-machine env dev)`
machineの環境変数を、仮想環境に割り当て。

`docker images`
前回のhello-worldイメージがあるかを確認。あれば仮想環境に接続できている。

`docker rmi -f (image_name)`
前回使ったhello-worldは使わないので、削除します。上手くいかない場合は-fをつけると強制的に削除する。

`docker ps -a`
同様にコンテナも削除。まずは名前を確認。

`docker rm (container_name)`
コンテナを削除。

#Nignxイメージを取得、コンテナを作成、ブラウザに表示する。
`docker pull nginx`
nginxのイメージを取得

`docker create -p (macからmachineへのポート):(machineからコンテナへのポート) --name (container_name)  (image_name)`
例：`docker create -p 80:80 --name snake nginx`
今回はrun(コンテナ作成+起動)ではなく、少し細分化して実行してみます。

- `docker create`： コンテナを作成。
- `-p (host_port):(container_port)`：ポートを指定。
- `-P`：ランダムにポートを指定。
- `--name (container_name)`：コンテナの名前を指定。

`docker start (container_name)`
コンテナを起動。これで、runコマンドと同様の結果になる。ただしバックグラウンドで起動する`-d`コマンドがついていないので、どこかでバックグラウンド起動する指定が必要になると思う。

`docker-machine ip (machine_name)`
machineのipを表示
*PORTSの0.0.0.0:(port)->80/tcp*

`docker ps`
起動したコンテナ、ポートの確認。
ブラウザで、IPとポートを入れてNngixが起動したかどうかを確認。

ブラウザで`(ip):(container_port)`
Welcome to nginx!が表示されたらOK。起動を確認。ただいろいろなサイトを見ると`-d`を付けてバックグラウンド実行している。フォアグラウンド実行とバックグラウンド実行の違いがわからない。

#今回覚えたコマンド
`docker create -p (host_port):(container_port) --name (container_name) (image_name)`
コンテナを作成する

- `-p (host_port):(container_port)`
ポートを指定する。
- `-P`
ランダムにポートを指定する。
- `--name (container_name)`
コンテナに名前を付ける。指定しない場合は、ランダムな名前が付与される。

`docker start (container_name)`
コンテナを起動する

`docker stop (container_name)`
コンテナを停止する

`docker run -P -d (image_name)`
コンテナを作成し、起動する。

- `-d`
バックグラウンドで起動する。


#不明点
- バックグラウンドとフォアグラウンドの違いがわからない。参考サイトでは、大体run -dになっていてるが、なぜnginxはバックグラウンドで開く必要があるのか？
- create -> startの方法で`-d`を付けられない。何かしらバックグラウンド実行する方法があると思うのだが。。。
- createやrunでオプションを指定できるが、これの変更方法がわからない。変更したい場合は、一旦破棄して作り直す必要があるのか？

##一覧
[<< 前回](http://qiita.com/gamips/items/0136336b89cf7fcc2bf5)
Quantum Chemistry - Schrodinger's Cat

関連 http://qiita.com/7of9/items/d3a1799928734375f34f

CG分野で使われるSpherical Harmonics。自分の数値シミュレーション計算に用いたいと思い調べると、量子化学の講義にたどり着く。

短く分かりやすそうな159本のビデオを少しずつ消化中。

Quantum Chemistry - Schrodinger's Cat
https://www.youtube.com/watch?v=xoKDuc5uE5s&list=PLm8ZSArAXicL3jKr_0nHHs5TwfhdkMFhh&index=40

- シュレディンガーの猫
- 1935年 Schrodingerが発表
- 紫の記載
  - 2つの状態を持つQuantum particle
  - 50% でdecayする
  - 50% でdecayしない
  - 右の図
      - Qというところにparticleがある
      - particleがdecayするとその右上のPoisonというところに毒を出す
      - Poison記載のところは封がされている
      - 猫がいる
      - particleがdecayしてPoison記載のところから毒が漏れ猫が死ぬ
      - 何故猫を殺すかは聞かないでください
- 左のピンクの式
   - `|y>`ではparticleはdecayしない
      - 猫は生存している
   - `|n>`ではparticleはdecayする
      - 猫は死ぬ
- 黄色
   - quantum particleの式
   - 1/2の確率で`|y>`が
   - 1/2の確率で`|n>`が有効である
- 左下の図
   - 箱を開けると
       - 50%の確率で猫が生きていて (50%...の文字)
       - 50%の確率で猫が死んでいる (50%...の文字)
   - 再度見ると (Look Again)
       - 50%の確率で猫が生きた後は100%の確率で猫が生きている
       - 50%の確率で猫が死んだあとは100%の確率で猫が死んでいる
       - コペンハーゲン解釈 [前回](http://qiita.com/7of9/items/68abfbaa2774a0c950c8)
- 水色
   - 測定をするまでは猫は生きてもいるし、死んでもいる
Rails5でサーバー起動したらsymbol lookup errorが出た

### 実行環境
- ruby 2.3.1
- Rails 5.0.0.1
- gem 2.5.1
- PostgreSQL 9.4.5

（なお、DBはHerokuの練習のためにPostgreSQLを使っているが
MySQL等で試しても、今回のエラーが出た。）

```$ rails new hoge -d postgresql``` でRailsプロジェクトを作成し、
いざ起動！

```
$ rails s
=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
/usr/local/bin/ruby: symbol lookup error: /home/vagrant/sample/vendor/bundle/gems/debug_inspector-0.0.2/lib/debug_inspector.so: undefined symbol: rb_data_typed_object_alloc
```
サーバーが立ち上がらない・・・

どうやら、debug_inspectorというgemがおかしいようなので
再インストールしてみる。

```
$ sudo gem uninstall debug_inspector
$ sudo gem install debug_inspector
```

・・・解決！


[追記]
その後・・・

サーバーが途中で止まってしまった
```puma 3.6.0 (tcp://192.168.33.10:3000) [hoge]: symbol lookup error: /home/vagrant/sample/vendor/bundle/gems/therubyracer-0.12.2/lib/v8/init.so: undefined symbol: rb_data_object_alloc```

therubyracerのgemがおかしいようなので、
先程と同様に、therubyracerを再インストール！