OmniAICreator/Qiita-1.07M huggingface dataset:
Rails の ActiveRecord で膨大なレコード数を高速かつ省メモリで処理する

Rails の task で超巨大なテーブルに対して集計を行いたくて、
いろいろ調べてみたところ、以下の 2 つの方法をみつけました。

- pluck
- find_each

pluck は任意のカラムのデータを配列で取得するメソッドです。
find メソッドのようにインスタンスを取得することはできませんが、
その代わりにインスタンス生成にかかるオーバーヘッドがかからないため非常に高速です。
メモリ消費の点でも、インスタンスを生成しない分有利ですが、
取得するレコード数に比例してメモリ使用量は大きくなるため、
巨大なテーブルに対して使用するのは危険が伴います。

find_each は少しずつデータをメモリに展開して処理を行うメソッドです。
一度にメモリに展開するレコード数を制限できるため、
使用メモリ量をコントロールすることができます。
ただし、インスタンス生成のオーバーヘッドがかかるため、
データ量が膨大だと pluck に比べて速度が出ません。

そこで、これらの考えを組み合わせることで
高速かつ省メモリで大量レコードを処理するメソッドを書いてみました。
それが以下の pluck_each です。

```ruby
# coding: utf-8
module ActiveRecord
  module Calculations

    def pluck_each(columns = [], batch_size = 100000)
      # primary key の位置特定 (なければ columns の最後に追加)
      pk_idx = columns.map(&:to_s).index(self.primary_key) || columns.count
      columns << self.primary_key if pk_idx == columns.count

      relation = self.reorder(self.primary_key).limit(batch_size)
      part = relation
      last_pk_val = nil
      loop do
        part = relation.where('? > ?', self.primary_key, last_pk_val) unless last_pk_val.nil?

        # 全レコードを yield したら終了
        c = part.count
        break if c == 0

        # LIMIT を残り件数よりも多く設定すると遅くなる問題への対処
        part = part.limit([batch_size, c].min)

        # 部分的に pluck を実行
        part.pluck(*columns).each do |ary|
          yield ary
          last_pk_val = ary[pk_idx]
        end
      end
    end

  end
end
```

# 使い方
  Rails で使用する場合は `lib/core_ext/active_record/calculations.rb` に上記のコードを記述し、
  `config/initializers/extensions_loader.rb` 等に以下のようなコードを書いておけば読み込めます。

```ruby
  Dir.glob("#{Rails.root}/lib/core_ext/**/*.rb").each {|ext| require ext }
```

  pluck_each を使用する際は、取得したいカラム名 (シンボル) の配列を渡します。第 2 引数にはメモリに展開するレコード数も渡せます (デフォルトは 10 万)。

  以下のような感じです。おそらく pluck と find_each を使用したことがあれば、(汎用性には乏しいですが) それなりに違和感なく使えると思います。

```ruby
  # 1000 レコードずつメモリに展開
  User.where(last_login: s..e).pluck_each([:id, :username, :email, :last_login], 1000) do |ary|
    # レコード 1 件毎の処理内容
    # (ary = [1, 'user1', 'user1@mail.com', '2015-04-01 13:00:00'], ...)
  end
```

# 注意点
  - Primary Key が複合キーのテーブルには使用できません
  - 第 1 引数に Primary Key が入っていない場合、ブロックパラメータの配列の最後に Primary Key の値が追加されます

# 最後に
  MySQL だけなのかはよくわからないのですが、LIMIT を残り件数よりも多く設定するとかなり遅くなるため、
  pluck_each にはその対策として毎ループで count も取得してます。
  無駄な気もしますが、これしか思いつかなかったので、もっと良い方法があれば教えてください。
  (それ以前に、LIMIT が残り件数よりも多いときになぜ遅くなるかもよくわかってないので、そっちも教えて欲しいです。)

  ちなみに、find_each にはこの対策がされていなくて、最終ループだけ遅くなってしまうという問題があり、
  それを pluck_each と似たような方法で対策すると find_each も速くなったりします。
Centos6.6にGUI環境をインストールして、VNCサーバーを建てる方法

# GUI環境をインストールして、VNCサーバーを建てる方法

- 通常、サーバーにはCentos6をMinimum installすると思いますが、何らかの理由でVNCしたくなった場合にどうぞ。

##1.1 GUI環境とVNCサーバーを導入します。
~~~sh
su
yum -y update
yum -y groupinstall "X Window System" "Desktop" "General Purpose Desktop" "Japanese Support"
yum -y remove tigervnc-server
yum -y install tigervnc-server
vncserver -geometry 800x600
~~~

==VNC接続の際のパスワードを入力します。==

##1.2 一旦、VNCサーバーを停止し、GNOME環境で起動する設定に変更します。

~~~sh
vncserver -kill :1
echo 'exec gnome-session' >> /root/.vnc/xstartup
vncserver -geometry 1680x1050
chkconfig vncserver on
chkconfig vncserver --list
~~~

##2 VNCクライアントをダウンロードし、1で用意したVNCサーバーに接続します。

###2.0 Windows/Linuxから接続する場合は、VNCクライアントのダウンロードが必要です。下記URLからお好みのVNCクライアントをダウンロードしてインストールしてください。その後の手順は、Macと同じです。

[VNCクライアント比較](http://gihyo.jp/lifestyle/serial/01/ganshiki-soushi/0060)

###2.1 Mac OS Xの場合は、OSに標準でVNCクライアント機能がついているので、それを利用します。

- 1. Finderメニュー->Go->Connect to Server...を選択します。

![VNC Server Fig 1.png](https://qiita-image-store.s3.amazonaws.com/0/9023/12c7d265-5cdf-e22e-4425-71f43c53462a.png)


- 2. サーバーのIPアドレス:VNC接続のポート番号を入力して、Connectを押下します。

==ポート番号は、5900に、ディスプレイ番号を足したものになります。通常は5901でOK。==

![VNC Server Fig 2.png](https://qiita-image-store.s3.amazonaws.com/0/9023/49b79c5d-d15c-fb5e-27bb-8a415567b1f4.png)

- 3. 接続完了

![VNC Server Fig 3.png](https://qiita-image-store.s3.amazonaws.com/0/9023/46d3f9df-36bb-9420-c60d-e3336c375ccf.png)


おまけ

- Firefoxのインストール

~~~sh
yum -y install firefox 
~~~

- 日本語入力環境の追加

~~~sh
yum -y install anthy ibus ibus-anthy
ibus-setup
echo 'export XMODIFIERS="@im=ibus"' >> ~/.bashrc
echo 'export GTK_IM_MODULE="ibus"' >> ~/.bashrc
echo 'export QT_IM_MODULE="xim"' >> ~/.bashrc
~~~
VMWaretoolsのインストール

#VMWaretoolsのインストール

---
##1-A ESXi上のVM(Centos6.6)の場合
###1.1 vSphere Clientで、[インベントリ]->[仮想マシン]->[ゲスト]->[VMware Toolsのインストール]をクリックし、VMがVMwareToolsをマウント可能状態にします。

###1.2 VM上で、下記コマンドでVMWare Toolsをインストールします。
~~~sh
yum -y install perl
mount /dev/cdrom /media/
mkdir /tmp/VMwareTools/
cp /media/*.tar.gz /tmp/VMwareTools/
cd /tmp/VMwareTools/
tar zxvf /tmp/VMwareTools/*.tar.gz
cd vmware-tools-distrib
./vmware-install.pl
reboot
~~~
--- 

##1-B MacOSX上にあるVM(Centos6.6)の場合
###1.1 /Applicationsフォルダを開き、VMWare Fusionを右クリック、Show Package Contentsを選択します。

###1.2 /Applications/VMware Fusion.app/Contents/Library/isoimages/linux.isoをデスクトップにコピーします。


###1.3 VMWare FusionのメニューからVirtual Machine->CD/DVD->Choose Disk Imageで、先ほどのlinux.isoを選択します。(CD/DVDが有効になっていない場合は、有効にして、VMを再起動します。)

###1.4 次のコマンドを実行します。

~~~sh
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
cd /tmp
ls /mnt/cdrom
tar zxpf /mnt/cdrom/VMwareTools-9.9.0-2304977.tar.gz 
umount /dev/cdrom 
cd vmware-tools-distrib
./vmware-install.pl
~~~
初回起動時にGCMメッセージを受信する現象


> GCM Helper LibraryはC2DM終了に伴い使えなくなる疑いがあります。
> [アナウンス](https://plus.google.com/+AndroidDevelopers/posts/9ui5Ywfgqeh)
> コメントでは中の人がGCM Helper LibraryはGCMを使っているよ(=C2DMではない)とありますがアナウンスと矛盾しているので早めの移行をオススメします。

[古いGCMのライブラリ(GCM Helper Library)](https://developer.android.com/intl/ja/google/gcm/helper.html)を使用していると初回起動時にGCMにregisterする際に下のようなデータのメッセージを受信するようになってた。

```
extras=Bundle[{CMD=RST_FULL, from=google.com/iid}]
```

上のメッセージをググったらStackOverflowがひっかかった。
[Weird push message received on app start](http://stackoverflow.com/questions/30479424/weird-push-message-received-on-app-start)

> This is intended for the new GCM APIs, and it will cause your InstanceIdListenerService implementation's onTokenRefresh() method to be called, where your app should obtain all its tokens again.
>
> Unfortunately, if you are writing your own BroadcastReceiver, these messages will be unexpected and may cause your app to crash. The right thing to do is to filter on the "from" field, and if you see one of these messages, to register again with GCM as your tokens may be invalid.


Google Play Services SDKを使う分には全く問題ないす。
supervisordを使う

# supervisordを使う

##1 ダウンドーロドおよびインストール
###1.1 EPELパッケージを使ってインストールします。

~~~sh
yum -y --enablerepo=epel install supervisor
~~~

##2 /etc/supervisord.confを編集します。
###2.1 WebUI用のIPアドレスとユーザー名,パスワードを設定します。

~~~sh
vi /etc/supervisord.conf
~~~

~~~
[supervisord]
http_port=/var/tmp/supervisor.sock ; (default is to run a UNIX domain socket server)
http_port=131.113.xxx.xxx:9001     ; (alternately, ip_address:port specifies AF_INET)

http_username=soushi             ; (default is no username (open system))
http_password=password           ; (default is no password (open system))
~~~

###2.2 プロセスの設定ファイル/etc/supervisord.d/*.iniを読み込むようにします。

~~~sh
vi /etc/supervisord.conf
~~~

~~~
[include]
files = /etc/supervisord.d/*.ini
~~~

##3 起動します。

~~~sh
service supervisord start
chkconfig supervisord on
~~~

##4 プロセスの登録
- supervisordによってデーモン化したいプロセスを登録します。
- <プロセス名>.iniというテキストファイルを作成し、その中に起動コマンドなどを書いてから、/etc/supervisord.d/に保存しておくと、supervisordが自動でプロセスを起動してくれます。
- 今回は、練習として、zookeeperを登録します。

~~~sh
vi /etc/supervisord.d/zookeeper.ini
~~~

~~~
[program:Zookeeper]
command=/usr/local/zookeeper/bin/zkServer.sh start
~~~

##6 dockerコンテナで使うためのスクリプト

~~~
RUN mkdir -p /usr/local/download/
WORKDIR /usr/local/download/
RUN curl -O wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN rpm -Uvh epel-release-6-8.noarch.rpm
RUN yum -y install supervisor
ADD supervisord.conf /etc/supervisord.conf

VOLUME ["/etc/supervisord.d"]
~~~
windowsで、Ansible on cygwin with zshを手軽に動かす。

# はじめに
サーバー側は実験もあり。動きさえすれば、多人数で共有可能。クライアント環境はなるべく即戦力ありきで。個別のクライアント環境がバラバラで、汎用化しにくい。ということで、以下、作業を初めてから無駄な苦労なく１時間以内に、windows上で、Ansibleとzshが動くcygwinを用意できるであろう手順を記す。目標は、あえていえば、mac並みのクライアント環境をwindows上にも整えること。

## 検証環境はwindows10 pro(64bit版)
理由は、[人柱中](http://qiita.com/kmry2045/items/545cb4399617eac538a7)なもので。windows7以上の環境では、基本的に動作すると思う。
##エディタ周りとかについては省略。
特記事項あれば、追記したい。

#目的　複数のサーバーの設定をAnsibleでいじりたい。
- Ansibleは、Linux上のPythonで動作。ローカルでAnsibleを動作させるのが簡易(委細は、)
- Windows上では、boot2dockerなどVMを活用したLinux環境が盛んだが、動作しない場合の検証がめんどうになりがち(boot2docker/Docker/Virtualbox..のどれが悪さをしている・・？)

#シンプルな解@2015年夏
- Ansible入りcygwin.zip [32bit版]　 を[ここ](http://www.lnc.jp/2015/03/23/2317.html)からダウンロードさせてもらう。
- 解凍する(解凍先はc:\cygwinを推奨)とansibleが即動作してくれる[やることはダウンロード+解凍のみ]=> 以下、これを"本ツール"と呼ぶ
- ご好意による作なので、今後のバージョンアップ時はまた、考える[せっかくなので、cygwinの最低限の知識を得ておけば、今後にも対応しやすくなるはず]

#Windows(10)と親和的な環境つくり
cygwin-ansible.batにPathを通しておく(例えば、管理者モードのコマンドラインで以下を実行):
> setx /M PATH "%PATH%;c:\cygwin"

以降はコマンドラインで以下を実行し起動:
> cygwin-ansible

# cygwinのバッケージ管理ツールapt-cygを動作するようにする。
本ツールを解凍した当初は、apt-cygが正常動作しない。近時のapt-cygをめぐる状況と対応方法については、[Cygwinでapt-cygを使う](http://keisanbutsuriya.hateblo.jp/entry/2015/01/23/172537)にまとめてくれている。
すなわち、cygwin-ansible.batを管理者権限で立ち上げ、リンク先通り、apt-cygの現開発者のサイトからwgetして、一連の手順を踏むだけでapt-cygは*(当座は)*動作する。
> wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg
> chmod 755 apt-cyg
> apt-cyg -m ftp://ftp.iij.ad.jp/pub/cygwin/ update

#./apt-cygでzsh等をインストールする
カレントディレクトリでとりあえず動作させると、zshがインストールされる。
> ./apt-cyg install zsh

もともと入っているapt-cygとの関わりをどうするかは、apt-cygをどのくらい使うのかも見据えつつ、対策。apt-cyg install curlでcurlが入らなかったりとかあったので、apt-cygには過度の期待を抱かないのが良いのでは、と思う。

#[付記]　python2.7系のエコシステムも活用可能
ansibleは、python上のツールなので、当然本ツールでは、pythonのエコシステム(pip等)が動作する。
これを機会にpydata等のツールを試すのはありかもしれない。

##例えば，以下は本cygwinで動作
> pip install bottle

インストール後は、[ここ](http://symfoware.blog68.fc2.com/blog-entry-1068.html)に従い、bottle　webフレームワークがwindowsローカルで立ち上がった。少なくともwindowsユーザーがpythonの何かを試す際には役立ちそう。
SSHエージェント転送

#SSHエージェント転送

##エージェント転送を使う
###1 ローカルマシン上に~/.ssh/configを作成して、下記のように踏み台サーバのアドレスを設定します。

~~~
ForwardAgent yes
#Agent to access the servers in LAN
Host agent
    HostName 131.113.102.199
    Port 60022
    User soushi
    IdentityFile ~/.ssh/id_rsa
~~~

###2 次に、LAN内にあるサーバーのアドレスを下記のように設定します。


|**項目**|**設定値**|**説明**|
|---|---|---|
|Host| agent-master1 | ホストにアクセスするための名前です。この例では、`ssh agent-master1`のように接続できるようになります。|
|HostName|192.168.56.201|ホストのIPアドレスです。|
|User|root|ホストにアクセスする際に利用するユーザー名です。(rootでのSSHログインが許可されていない場合は、変更してください。)|
|Port|60022|ホスト上のsshdがリスニングしているポート番号を指定します。(SSHはデフォルトで22番ポートを利用しますが、安全のため60022番ポートに変更してあるため、このように記述しています。)|
|ProxyCommand|踏み台サーバーで実行するコマンドです。|

~~~
Host agent-master1
    HostName     192.168.56.201
    User         root
    Port         60022
    ProxyCommand ssh -W %h:%p agent
~~~

##SSHで接続した際に、keep-aliveを行いたい。(放置すると勝手に切断されるのを防ぎたい)
###1 ローカルマシン上の~/.ssh/configを編集して、下記のように設定します。

|**項目**|**設定値**|**説明**|
|---|---|---|
| ServerAliveInterval |300|keep-aliveを実行する間隔(sec)です。|
| TCPKeepAlive |yes|TCPでのkeep-aliveを有効にします。|

~~~
ServerAliveInterval 300
TCPKeepAlive yes
~~~
Ruby Sinatraのインストール

#Ruby Sinatraのインストール

- 簡易WebサーバーであるSinatraを導入します。

##1 Rubygemsをインストールします。

###1.1 こちらのマニュアルに従って、rubygemsをインストールしておきます。

[Ruby+gems+Railsインストールガイド](http://qiita.com/soushiy/items/72060222d557eb0e55ca)

##2 Sinatraをインストールします。

~~~sh
gem update --system
gem install rdoc
gem install sinatra
gem install sinatra-contrib
~~~

###2.1 bundlerを使っている場合はこちら

/root/Gemfile

~~~
source "https://rubygems.org"
gem 'sinatra'
gem 'sinatra-contrib'
~~~

を書き加えた後、`Gemfile`のあるディレクトリで、(通常、ホームフォルダ)

~~~sh
cd
bundle install --path vendor/bundle
~~~

を実行。

##3 helloworldスクリプトを書きます。
※保存先はどこでも良い

myapp.rb

~~~
require 'sinatra'
require 'sinatra/reloader'
get '/' do
    "Hello world " 
end
~~~

###3.1 bundlerを使っている場合

~~~
Bundler.require
get '/' do
    "Hello world " 
end
~~~

##4 Webサーバーを起動します。
※http://IPアドレス:12345/にアクセスすると、"Hello world"と表示されます。
※ver.1.4.0から==development環境だと、localhostからのアクセスしか受け付けないのがデフォルト==となったため、`-o 0.0.0.0`オプションをつけること。(0.0.0.0は全てのアドレスを指す)

~~~sh
bundle exec ruby myapp.rb -o 0.0.0.0 -p 12345
~~~
AWS S3からGoogleCloudStorageへ直接転送はオススメしない

## やりたいこと
AWS S3に格納されているファイルをGoogleCloudStorageにコピーしたい。
どうするのが速いか。

## どっちがいいか
AWS S3 に格納されているファイルを、GoogleCloudStorage にコマンドラインで転送する。
どっちもファイル数に応じた並列処理はせず、フォルダごと処理。
1. 直接転送
`gsutil -q cp -r s3://bucket/target_folder gs://bucket/`
2. 間接転送（ローカル経由）
`s3cmd --no-progress -f -r get s3://bucket/target_folder .
gsutil -q cp -r target_folder gs://bucket/`

## 比較パターン
###カジュアルな用途
- 1ファイルサイズ：1MB
- ファイル数：10
- 合計：10MB

###ビジネスカジュアルな用途
- 1ファイルサイズ：10MB
- ファイル数：10
- 合計：100MB

###でっかいの１つ
- 1ファイルサイズ：1GB
- ファイル数：1
- 合計：1GB

###ちっちゃいのたくさん
- 1ファイルサイズ：1KB
- ファイル数：10,000
- 合計：10MB

## 結果（平均）
回線状況やストレージの機嫌もあるので時間自体は参考程度。

|パターン|1.直接転送|2.間接転送|
|:-:|--:|--:|
|カジュアル(1MB*10)|20秒|20秒|
|ビジネスカジュアル(10MB*10)|52秒|25秒|
|でっかいの１つ(1GB*1)|5分50秒|1分25秒|
|ちっちゃいのたくさん(1KB*10,000)|1時間30分00秒|33分00秒|

## サマリ
- s3://からgs://への直接転送は合計数MB程度、数十ファイルのみにしておこう。
- いずれにせよファイル数多いとキツイ。tarできるやつはしておくこと。
nginxを導入する

#nginxを導入する
**rootで実行**

|**起動コマンド**|**説明**|
|---|---|
| dockerイメージから起動する場合 | docker run -d -p 80:80 --name nginx1 soushi/nginx:1.0 |
| Centos:6イメージから新規に作成する場合 | docker run -i -t -d -p 80:80 -v /etc/localtime:/etc/localtime:ro --name nginx1 centos:6 /bin/bash |

- dockerイメージが無い場合、Dockerfileから作成できます。

~~~
docker build [ -t ｛イメージ名｝ [ :｛タグ名｝ ] ] <Dockerfileのあるディレクトリ>
~~~

- Dockerfileからdockerイメージを作成するコマンド例

~~~sh
docker build -t soushi/nginx:1.0 <Dockerfileのあるディレクトリ>
~~~
- dockerイメージを作成するためのDockerfileの場所

[~/Dropbox/docker/nginx1.0/Dockerfile](/Users/soushi/Dropbox/docker/nginx1.0/Dockerfile)

##1.1 nginxのリポジトリを登録します。
[公式サイト](http://nginx.org/en/linux_packages.html#stable)から、使用するOSのバージョンを探し、リポジトリを追加します。
※今回はCentos6.6用

~~~sh
rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
~~~

/etc/yum.repos.d/nginx.repoが作成されます。

~~~
# nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
~~~

##1.2 nginxをインストールします。

~~~sh
yum -y install nginx
~~~

##1.3 nginxを起動します。

~~~sh
/etc/init.d/nginx start
~~~

※この時点でアクセス可能になるが、設定が必要と言われる。

![Nginx Fig 1.png](https://qiita-image-store.s3.amazonaws.com/0/9023/d5f3f7cc-4b1a-4e21-d52c-c9819c91b2c8.png)

##1.4 nginxの設定を行う。
- 設定ファイルの場所は/etc/nginx/nginx.conf
- [こちらを参考](http://nginx.org/en/docs/beginners_guide.html)に設定を行う。
- ドキュメントルートを/var/wwwに設定する。

~~~sh
mkdir /var/www
sed -i -e "/^http/a \ \ \ \ server \{\n\tlocation \/ \{\n\t\troot \/var\/www\;\n\t\}\n\n\ \ \ \ \}" /etc/nginx/nginx.conf
service nginx restart
~~~

##2 ホストのIPアドレスにアクセスして、起動していることを確認します。

![Nginx Fig 2.png](https://qiita-image-store.s3.amazonaws.com/0/9023/946319bf-bb60-9404-e2ea-f4bd25a98a7f.png)

---

#全コマンド
~~~sh
rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
yum -y install nginx
mkdir /var/www
echo "Hello world. Nginx is working. The document root directory is /var/www." >> /var/www/index.html
RUN sed -i -e "/^http/a \ \ \ \ server \{\n\tlocation \/ \{\n\t\troot \/var\/www\;\n\t\}\n\n\ \ \ \ \}" /etc/nginx/nginx.conf
service nginx start
~~~
Mavenの使い方

#Mavenの使い方

##1 Mavenのダウンロードとインストール

- ここでは、Maven-3.3.1をセットアップします。

~~~
sudo mkdir /usr/local/download
sudo cd /usr/local/download
sudo curl http://ftp.tsukuba.wide.ad.jp/software/apache/maven/maven-3/3.3.1/binaries/apache-maven-3.3.1-bin.tar.gz -o apache-maven-3.3.1-bin.tar.gz
sudo tar xvzf apache-maven-3.3.1-bin.tar.gz
sudo mv apache-maven-3.3.1 /usr/local/
sudo ln -s /usr/local/apache-maven-3.3.1/ /usr/local/maven
echo 'export PATH=$PATH:/usr/local/maven/bin' >> ~/.bashrc
export PATH=$PATH:/usr/local/maven/bin
mvn -version
~~~

##2 mvnコマンドの使い方

- mvnコマンドは、pom.xmlファイルを読み込み、その内容によって必要なライブラリを自動ダウンロードしたりしてくれます。
- 基本的には、`mvn clean` `mvn compile` `mvn package`の3種類を覚えておけば大丈夫です。
- `mvn`コマンドを実行する場所は、プロジェクトフォルダのルート（例えば、/Users/soushi/NetbeansProjects/AdContex/）です。

- treeコマンドの結果

~~~sh
$ tree /Users/soushi/NetbeansProjects/AdContex/
~~~

~~~
/Users/soushi/NetbeansProjects/AdContex/
├── lib
│   └── gson-2.3.1.jar
├── nb-configuration.xml
├── nbactions.xml
├── pom.xml
└── src
    └── main
        ├── java
        │   └── jp
        │       └── soushi
        │           └── adcontex
        │               ├── AdContexTopology.java
        │               ├── AuctionBolt.java
        │               ├── FilteringBolt.java
        │               ├── PricingBolt.java
        │               ├── PrintResultBolt.java
        │               └── SensorSpout.java
        └── resources

8 directories, 10 files
~~~

###ソースコードのコンパイル
- プロジェクトルートフォルダにcdしてから、`mvn compile`コマンドを実行します。

~~~sh
cd /Users/soushi/NetbeansProjects/AdContex/
mvn compile
~~~

- 再度、treeコマンドでフォルダを見てみると、targetディレクトリが追加されています！(この中にコンパイルされたコードが入る)

~~~sh
tree /Users/soushi/NetbeansProjects/AdContex/
~~~

~~~
/Users/soushi/NetbeansProjects/AdContex/
├── lib
│   └── gson-2.3.1.jar
├── nb-configuration.xml
├── nbactions.xml
├── pom.xml
├── src
│   └── main
│       ├── java
│       │   └── jp
│       │       └── soushi
│       │           └── adcontex
│       │               ├── AdContexTopology.java
│       │               ├── AuctionBolt.java
│       │               ├── FilteringBolt.java
│       │               ├── PricingBolt.java
│       │               ├── PrintResultBolt.java
│       │               └── SensorSpout.java
│       └── resources
└── target
    ├── classes
    │   └── jp
    │       └── soushi
    │           └── adcontex
    │               ├── AdContexTopology.class
    │               ├── AuctionBolt.class
    │               ├── FilteringBolt.class
    │               ├── PricingBolt.class
    │               ├── PrintResultBolt.class
    │               └── SensorSpout.class
    ├── generated-sources
    │   └── annotations
    └── maven-status
        └── maven-compiler-plugin
            └── compile
                └── default-compile
                    ├── createdFiles.lst
                    └── inputFiles.lst
~~~

###jarファイルを作成する。

- プロジェクトルートフォルダにcdして、`mvn package`を実行するだけです！

~~~sh
mvn package
~~~

###プロジェクトのクリーン

- targetフォルダを削除してくれます。

~~~sh
mvn clean
~~~
Phoenix Framework環境構築


Macの環境構築方法メモ

Phoenixについては、こちらの記事がオススメ
[Phoenix Framework Guide Overview(翻訳)](http://qiita.com/rtbt525/items/afbf666e0c026c5658f4)


### Elixerのインストール
Elixirのインストールはhomebrewを利用します。


```bash
brew update
brew install elixir
```

これでelixir, openssl, unixodbc, libpng, libtiff, wxmac, erlangがまとめてインストールできるようです。

以上でElixirの環境構築は完了です。


### Phoenixインストール

```bash
mix local.hex

```


```bash
mix archive.install https://github.com/phoenixframework/phoenix/releases/download/v0.13.1/phoenix_new-0.13.1.ez
```

これでインストール完了です。

### プロジェクト作成

```bash
mix phoenix.new sample
```

sampleというプロジェクトを作成できます。プロジェクト名は小文字でなければエラーが出るようです。

プロジェクトディレクトリに移動して

```bash
mix phoenix.server
```

を実行してもエラーがでます。インストールしたPhoenixのバージョンが古いようです。
こちらの記事から修正してください。最新ファイルをDLしてインストールするだけです。
[Phoenix.new で作ったプロジェクトが動かない](http://qiita.com/Kazunori_Sada/items/6d650e33d054a47a9d93)


インストールが完了したら、再度プロジェクトを作成します。前のプロジェクトは削除します。

```bash
mix phoenix.new sample
```

ターミナル上にコマンドが表示されるので、作成されたプロジェクトディレクトリに移動して以下のコマンドを実行します。

```bash
$ mix ecto.create
$ mix phoenix.server
```

おそらくnpm installしろとエラーでるのでインストールします。

```bash
$ npm install
```

これでサーバーを起動できます。

```bash
mix phoenix.server
````

以上です。
HubotのHTTPクライアントでBasic認証

以下のようにするとHubot同梱のHTTPクライアントでBasic認証を行える。

```coffeescript:scripts/foo.coffee
module.exports = (robot) ->
  robot.http(uri)
    .auth("user", "password")
    .get() (err, res, body) ->
      console.log body
```
Box-Muller法による正規分布列生成

Qiitaにおける数式の表示、画像の表示の練習も兼ねて。

間違っていたら教えて下さい(下記に示すBox-Muller法は乱数を2つ求める方法なのですが、その内の一方しか使っていないので、大丈夫なのか…という…)。

また、下記内容は、私自身のブログに書いた内容のコピーです。http://mude.hateblo.jp/?page=1410412272

# 一様分布から正規分布へ

大抵のプログラミング言語には、擬似乱数を生成するための関数が用意されています。そして、よくあるパターンとしては、その擬似乱数は0.0以上1.0以下の適当な値を返します。ヒストグラムを描くと分かりますが、大抵の場合はどの区間も同じ程度抽出されます(一様分布)。

さて、世の中には正規分布という分布が有ります。正規分布についての説明は端折りますが、正規分布に従う適当な値を出してくれるような便利な関数が常に用意されているとは限りません。一様分布から標準正規分布に変換する方法として、Box-Muller法というのが知られています。それを実際に実装してみましょう。

# Box-Muller法

Wikipediaの[Box-Muller法](https://ja.wikipedia.org/wiki/%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%EF%BC%9D%E3%83%9F%E3%83%A5%E3%83%A9%E3%83%BC%E6%B3%95)を見れば分かりますが、方法としては$(0,1)$の一様分布から2つの確率変数(すなわち、乱数)を用意して、示されている式に従ってZ1もしくはZ2を求めれば良さそうです。

例えばZ1であれば、$Z_1=\sqrt{−2 \log X} \cos 2 \pi Y$と書かれているので、これを素直にJavaのプログラムで表現して、

```java
z1 = Math.sqrt(-2.0 * Math.log(x)) * Math.cos(2.0 * Math.pi * y);
```

とすれば良いですね。ということで、実際のJavaのコードは次の通りです。

# ソースコード

```java:BoxMuller.java
import java.util.Random;

public class BoxMuller {
 private Random random;
 private double mu;
 private double sigma;
 private boolean useCosine;
 
 /**
  * Constructor
  * @param mu
  * @param sigma
  * @param useCosine
  */
 public BoxMuller(double mu, double sigma, boolean useCosine){
  random = new Random(System.currentTimeMillis());
 
  this.mu = mu;
  this.sigma = sigma;
  this.useCosine = useCosine;
 }

 /**
  * get next value
  * @return
  */
 public double next(){
  double x = random.nextDouble();
  double y = random.nextDouble();
  double result = 0.0;
 
  if(useCosine){
   result = Math.sqrt(-2.0 * Math.log(x)) * Math.cos(2.0 * Math.PI * y);
  } else {
   result = Math.sqrt(-2.0 * Math.log(x)) * Math.sin(2.0 * Math.PI * y);
  }
  return result * sigma + mu;
 }
}
```

呼び出すプログラムもついでに。

```java:BoxMullerTest.java
public class BoxMullerTest {
 public static void main(String[] args) {
  BoxMuller boxMuller = new BoxMuller(0,1,true);
  for(int i=0;i<10000;++i){
   System.out.println(boxMuller.next());
  }
 }
}
```

# 実行結果

```mu=0, sigma=1```として、10000回繰り返して値を取り出しました。これは、平均が0、標準偏差が1の正規分布、すなわち標準正規分布を求めることを意味します。

プロットしたグラフが次のとおりです。なんだか良さそうに見えますね。

![boxmuller_test.png](https://qiita-image-store.s3.amazonaws.com/0/54488/6c2ead2e-fa06-18a8-bfd4-f35282896f1a.png)

正規分布は$\pm 1\sigma$の区間に、計算上約68.27%の値が含まれ、$\pm 2\sigma$の区間に、計算上約95.45%の値が$\pm 3\sigma$の区間に、計算上約99.73%の値が含まれます。今回求めた値のうち、その値が$(-1, 1)$に含まれる個数は6678、$(-2, 2)$に含まれる個数は9583、$(-3, 3)$に含まれる個数は9979、それぞれありました。なかなかいい数値のような気がします。

# その他

とはいえ、正規分布の乱数列を生成するライブラリを使うのが良いと思います。

数式を書くにも、画像を挿入するのも、とても簡単なことが分かりました。技術的な話については、個人的なブログではなく、Qiitaに貼り付けて行こうと思います。
PerlでLWPを使って仮想ブラウザを作る

perlとLWPがインストールされている状態にて。

    perl -MLWP -le "print(LWP->VERSION)"

→ 6.13 (例)

.pl のソースを下記のように実装する。

    use LWP 6.13;
    my $browser = LWP::UserAgent->new;
    my $url = "http://www.yahoo.co.jp";
    my $response = $browser->get( $url );
    print $response->decoded_content;

.pl を実行すると、Yahoo!のソースコードが標準出力される。
プログラミングスタイルのチェーンとパイプラインの違い

Scala勉強中です。

Javaのようなオブジェクト指向言語ではよくメソッドチェーンを使いますが、関数型言語を勉強していると出てくるパイプラインとの違いは何ぞや？と思ったため、その違いについて調べてみました。

# チェーン
チェーン内のそれぞれのメソッドが同じ自身のオブジェクトの参照を返すことで、メソッドを連結していきます。

```java:java

public class Person {
    private String firstName = "";
    private String lastName = "";

    public Person setFirstName(final String firstName) {
        this.firstName = firstName;
        return this;
    }
    public Person setLastName(final String lastName) {
        this.lastName = lastName;
        return this;
    }
    public String toString() {
        return firstName + " " + lastName;
    }
    public static void main(final String[] args) {
        Person person = new Person();
        System.out.println(person.setFirstName("山田").setLastName("太郎"));
    }
}
```

出力結果は下記です。

```
山田 太郎
```

チェーンを使うととても流暢な感じでプログラミングできます。

これをデータ指向っぽい使い方に適用してみます。3, 1, 2というリストの末尾に0を足してソートしてみます。(今度はScalaで)

```scala:scala
import java.util.ArrayList
import java.util.Collections

class ChainSample {
  val list = new ArrayList[Integer]()
  list.add(3)
  list.add(1)
  list.add(2)

  def add(num: Int): ChainSample = {
    list.add(num)
    this
  }

  def sort(): ChainSample = {
    Collections.sort(list)
    this
  }
}
object ChainSample {
  def main(args: Array[String]) {
    val chain = new ChainSample()
    println(chain.add(0).sort().list)
  }
}
```
※わざとScalaのListは使っていません。

結果は下記になります。

```
[0, 1, 2, 3]
```

チェーンでも全く問題がないように思えますが、この場合、メソッド呼び出しのたびに参照オブジェクト自身の内容が変化しています。

関数型プログラミングでは関数に渡されたオリジナルのデータは実行後も変更されず、オリジナルのまま残るべきです。

# パイプライン

ということで、パイプラインとチェーンの違いが見えてきました。  
パイプラインとはおそらく、

* パイプラインは入力値を壊さず、新しいデータを作って進む
* 入力値にはオブジェクトへの参照ではなくて値(コレクション等も含む)を扱う

上記を踏まえて作成したパイプラインが下記になります。  
※これもわざとScalaのListは使っていません。

```scala
import java.util.ArrayList
import java.util.Collections

object PipelineSample {

  // 第一引数を順番を元に第二引数以降の関数リストを再帰的に実行していく
  def pipeline(seed: ArrayList[Integer], functions:Any*): ArrayList[Integer] = { 
    val func =  functions(0).asInstanceOf[(ArrayList[Integer])=>ArrayList[Integer]]
    val result:ArrayList[Integer] = func(seed)
    functions.length match {
      case i:Int if i >= 2 => pipeline(result, functions.takeRight(functions.length - 1): _*)
      case _ => result
    }
  }

  def add(num: Int, list: ArrayList[Integer]): ArrayList[Integer] = {
    list.add(num)
    new ArrayList(list) // 新しいListを返す
  }

  def sort(list: ArrayList[Integer]): ArrayList[Integer] = {
    Collections.sort(list)
    new ArrayList(list) // 新しいListを返す
  }

  def main(args: Array[String]):Unit = {
    val list = new ArrayList[Integer]
    list.add(3)
    list.add(1)
    list.add(2)

    val curriedAdd = (add _).curried
    println(pipeline(
            list,           // 入力データ
            curriedAdd(0),  // 関数その1
            sort _))        // 関数その2
  }
}
```

実行結果は

```
[0, 1, 2, 3]
```

どうやらパイプラインのコードを作ることができた(?)模様です。

ちなみに、、、いろいろやりましたが、ScalaのListにはパイプライン用のメソッドがちゃんと用意されているので、下記だけで上記のパイプライン処理ができます(^_^;)

```scala
(List(3,1,2) :+ 0).sorted
```
CentOS 6でOracle JDK 7を導入する方法

#CentOS 6でOracle JDK 7を導入する方法
動作環境

|**compornent**|**version**|
|---|---|
| Centos | 6.6 |

##1 下記スクリプトを実行。
- すでに導入済みのJDK,JREを削除後、Oracle JDK 7を導入します。

~~~sh
yum list installed | grep "java-" | awk '{print $1}' | xargs yum -y remove {}
cd /usr/local/download
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm"
yum -y localinstall --nogpgcheck jdk-7u79-linux-x64.rpm
~~~
【C#】WebAPIで新着チェックをしてサーバ上の画像を自動印刷する

##概要
自作のWebアプリケーションに来た写真データをブラウザで自動印刷できないので
監視ソフトをWindowsで作ってデータの自動印刷が行えるようにしました。

いろいろ調べながら二日くらいかかりましたね・・・
リクエストの送信方法とJsonのパース部分で結構時間がとられました。
ソースをアップするので、同じようなことがしたい方の参考になれば。
[GitHub/WindowsAutoPrint](https://github.com/tdaiku/WindowsAutoPrint)
GitHubのReadmeにも書いてますが
・WebClient によるGetリクエスト送信
・DynamicJsonによるパース
・設定オブジェクトのシリアライズ・デシリアライズ
・WEBサーバに配置された画像を読み込み印刷する

ってのが今回作った部分です。

##ついでにGitHubに
GitHubに公開したことがなかったので、テストとしてアップロードしてみました。
アカウントは作ってたんですけどね！実に作ってから２年くらい？
業務以外でプログラム触る時間がないので、仕事時間で作ったものは公開できないですからね・・・・
もっと勉強しないと。

###アップロード
このサイトを見ながらアップロードしました。（2015/08/12時点）
2014年版Githubの使い方！Windowsで初心者でも簡単アップロード
http://kawaidesu.hatenablog.com/entry/2014/06/28/092347
 
publishがSyncボタンに代わってるところぐらいですかね、ちょっとん？ってなったのは。
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/7fdd409d-4af1-0f73-81cd-6c5858013f83.png)


###README.md
GitHubのサイトで編集するとレスポンスがひどいので、Qiitaで書いてからコピペしました。
改行も指定しないといけないみたいで半角スペース×２が必要みたいです。


##IDEの使い勝手
ここ一か月でXcode、AndroidStudio、今回のVisualStudio、Colud9（クラウドIDE）を使って開発してるので、IDEの使い勝手所感です。
個人的な感想です。全IDEすげーなーと思いながら使ってますよ！

####・Xcode
iPhoneアプリの開発で使ってます。
Swiftで作ってますが、言語としてはすごく使いやすいですね。オプショナルもなんか自分の書いたソースがバグってそうな不安が残りますが、使い勝手がいいです。
ほかの言語みたいにnullを参照型で許容しないのは、バグを生みにくくなるだろうし、正しい在り方なのかなって気がします。

IDEはいい感じです。
リファクタリングが使えないのが面倒ですが、コーディングは快適ですね。
画面をStoryBoardで作るのがなかなか難しい。
重かったりクラッシュしたりしますが、許容範囲の頻度なのでいいかな。

####・AndroidStudio
そもそもAndroidのプロジェクト構成事態がファイルがたくさん必要で面倒。
画面を作って、画面を立て固定にするためにその都度マニュフェストファイルを開いて、リソースフォルダの画面レイアウトをいじって、ソースコードをいじって、いろいろ忙しいです。
別ファイルにリソースを定義するとまたファイルも増えるし。

ログの表示もおかしくなったり、遅延が発生したり、端末のいらない情報でログがスクロールしたりと微妙。
画面デザインは使いづらいので、複雑な画面ならXMLを直接いじったほうが早いですね。
XMLをいじればすぐ画面が変更できるのは、Xcodeと比べていいです。
時々StoryBoardの中身を直接いじりたいって思います。

動作はXcodeよりは早いと思います。僕は別にXcodeでも問題ないと感じるので、全然問題ないです。
真面目に使って一か月ぐらいですが、クラッシュしたことはないかな、たしか。

####・VisualStudio
もともとこればっかりだったんですが、久々に触ると使いづらかったですねー。
そもそもOSのショートカットを間違えまくってイライラしました。これはどうにもならないです。
デバッグはダントツでやりやすいと思います。
インターフェースは一番しっくりくるんですよね。一番長く使ってるから当たり前だろうけど。
イベントの作り方とかすごく簡単ですよ。
エラーの内容も分かりやすいものが多いと思います。

動作はAndroidStudioと同じくらいかちょっと遅いくらいかなと思います。

####・Cloud9
Railsプロジェクト用
[【Ruby On Rails】クラウドIDEのCloud9が素晴らしい](http://qiita.com/tdaiku/items/8c611c78e748546dc393)
ブラウザだけどレスポンスも問題ないし、ファイルのアップロードも簡単です。
ちょっと履歴を見たいときもさかのぼって見れます。
インターフェースもすごい好きです。

デメリットとしてはプロジェクト全体のダウンロードが遅いですね。
あとは無課金なのでメモリが足りなくてよくWebサーバが落ちます。
一回だけつながらなくなったこともあり、やはりつながらないと危機感を覚えますね！
AWS CloudFrontで極力キャッシュさせたくない時の話

## 目的
CloudFrontで出来るだけキャッシュさせないようにする！

CDNなのにキャッシュしないの？！とかいうツッコミは無しです。
要件によっては、CDNなのにキャッシュしない。なんてことはあるんです。

CloudFront挟むけど、一部のファイルは高頻度に更新されるからキャッシュさせたくない。とか、
s3ホスティング機能だけじゃhttps使えないから、CloudFrontをクラウド(s3)のフロントに配置してSSL通信させるとか。

## 本題の設定内容
CloudFrontの一般的な設定方法とかは他サイトに沢山あるので割愛して、**「極力キャッシュさせない(1秒キャッシュ)」**設定方法だけ記載します。
~~（某所より0秒キャッシュは推奨されないとの事で、1秒キャッシュにしています。）~~

追記: 2017.1.12
0秒の場合はそのままオリジンにアクセスすることになるため、大量アクセスからのオリジン保護の意図も含めて１秒の設定になります。
そのままオリジンに流したい場合は0秒、大量の同時アクセスに対するオリジンの保護も考えるなら1秒の設定値が良いです。

1. CloudFront作成中の画面で、[Object Caching]の[Customize]をONにします。
2. [Minimum TTL]、[Maximum TTL]、[Default TTL]を1に設定します。

![AWS_CloudFront_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/75573/848e71a2-ac17-d3b6-d04b-2c15b6ed5ff2.png)

## 注意点
さて、これで終わりでも良いんですが、このままだと200/300番台以外のステータスコードは1秒以上キャッシュされます。（300秒）
なので、[Create Distribution]でCloudFrontを作成した後に、以下の通りに設定変更します。

1. 対象の CloudFront(Distribution)をチェックし、[Distribution]をクリック
￼![AWS_CloudFront_Management_Console 2.png](https://qiita-image-store.s3.amazonaws.com/0/75573/6ec1f0ef-7da6-2cd6-8762-905a8d35ed1a.png)

2. [Error Pages]を選択し、[Create Custom Error Response]をクリック
![AWS_CloudFront_Management_Console 3.png](https://qiita-image-store.s3.amazonaws.com/0/75573/e959d342-1d6e-d0a2-1757-7d08ae9d5557.png)
￼
3. 後はこの表示されているエラーコードに対して、[Error Caching Minimum TTL]を1に設定する **←これが重要**
　　※ Customize Error Responseは必要に応じて指定ください。
![AWS_CloudFront_Management_Console 4.png](https://qiita-image-store.s3.amazonaws.com/0/75573/c1c6b79f-3819-46be-b39e-299a927c92ca.png)

Enjoy! AWS Life!
定時に自動で自撮りをGyazoにアップロードする方法

定時になったら自動で自撮り画像を[Gyazo](https://gyazo.com)にアップロードする方法です
ちなみに、OSX専用です

# everyday_selfieを使う
ということで自撮りしてGyazoにアップロードするシェルスクリプトを書いたのでこれを使います
https://github.com/henteko/everyday_selfie

## 使い方
自撮りにはimagesnapを使うのでそのインストールと、everyday_selfieのgit cloneします

```shell-session
$ git clone git@github.com:henteko/everyday_selfie.git
$ cd everyday_selfie/
$ brew install imagesnap
```

次に、everyday_selfie/upload_selfie内に書いてあるYOUR_ACCESS_TOKENを自分のものに置き変えます
このアクセストークンは、[GyazoのAPIページ](https://gyazo.com/api)で自分のアプリを作ると取得できます
![Screen_Shot_2015-08-12_at_19_17_55.png](https://qiita-image-store.s3.amazonaws.com/0/6717/723e0c64-9564-b767-19f0-1a47670b1569.png)

```shell-session
$ vim upload_selfie # Edit the YOUR_ACCESS_TOKEN(Gyazo)
```

最後に定期的に実行する用の設定です
定期実行にはOSXの[launchd](https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html)を使います
その為の設定がeveryday_selfie/everyday_selfie.plistに書いてあるので、これを編集します
編集箇所は、/path/to/everyday_selfieとなっているところを自分のlocalのeveryday_selfieまでのpathにしてください
あとは適当にStartCalendarIntervalの時間などを弄ってみてください
編集し終わったら~/Library/LaunchAgents/以下にplistを配置してlaunchctlでloadしてあげれば設定終了です

```shell-session
$ vim everyday_selfie.plist # Edit the /path/to/everyday_selfie
$ cp everyday_selfie.plist ~/Library/LaunchAgents/everyday_selfie.plist
$ launchctl load ~/Library/LaunchAgents/everyday_selfie.plist
```

## あとは定時を待つだけ
定時をワクワクしながら待ちましょう
良い自撮りが撮れるといいですね

# さいごに
2014年の5月から2015年の2月末まで平日の仕事がある日のみ、始業の午前10時と終業の午後19時に自動で自撮りをしてgithubにpushするという活動をしていましたが、これが意外と面白かったです
自撮りを定期的に撮って残していくと、ライフログ的な役割を持って、その日の体調がわかったり、太ってるなーとか思えたり、他人と共有すると面白かったりするのでオススメです

素晴らしい自撮りライフを送りましょう
Terraform + AnsibleでEC2の構成管理


## Overview

TerraformのprovisionerにはAnsibleがないが [terraform-inventory](https://github.com/adammck/terraform-inventory) が .tfstateファイルからdynamic inventoryを生成しAnsibleでのterraformリソースの構成管理を可能にしてくれるようなので試してみた。

## Requirements

- [Terraform](https://www.terraform.io/) (Tested on 0.6.1)
- [terraform-inventory](https://github.com/adammck/terraform-inventory) (Tested on 0.5)

## Installation

### golangのインストール

#### CentOS

```
yum install golang --enablerepo=epel
```

#### Debian系

```
apt-get install golang
```

### terraform-inventoryをインストール

```
$ export GOPATH=/usr/local/go
$ go get github.com/adammck/terraform-inventory
$ export PATH=$PATH:/usr/local/go/bin
$ which terraform-inventory
```

なおterraform-inventoryがサポートしているTerraformリソースとしては、2015/08/12現在 **AWS**, **DigitalOcean**, **CloudStack** のみなのに注意。

### .tfstateファイル

デフォルトはカレントディレクトリの`terraform.tfstate`を参照する。
別のパスを指定したい場合は`TF_STATE`環境変数で指定する。

### ansible実行

```
vim test.yml
```

```test.yml
- hosts: all
  remote_user: ec2-user
  tasks:
    - name: Hello
      command: echo Hello!
```

```
$ export PATH=$PATH:/usr/local/go/bin
$ ansible-playbook -i $(which terraform-inventory) test.yml

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [52.69.47.41]

TASK: [Hello] ***************************************************************** 
changed: [52.69.47.41]

PLAY RECAP ******************************************************************** 
52.69.47.41 
```

実行出来た。
なお生成されるinventoryは.tfファイルのリソースブロックの`NAME`に当たる部分がホスト名になる。
例えば

```
resource "aws_instance" "web" {
    ami = "ami-123456"
    instance_type = "m1.small"
}
```

というリソース定義なら`web`がホスト名になるのでplaybookでは

```
- hosts: web
  remote_user: ec2-user
  tasks:
    - name: Hello
      command: echo Hello!
```

と書ける。

### terraformとの連携

`provisioner`ブロックの発火タイミングではまだ.tfstateファイルが生成されていないのでterraform実行後にansibleを発火する必要がある。

```example
terraform apply
cat terraform.tfstate
ansible -i $(which terraform-inventory) all -m ping
```

## Conclusion

TerraformとAnsibleでAWSリソースの構成管理をした。
Terraformが公式にサポートしているprovisionerとしてはChefがあるが既にAnsibleを使ってる場合はこの方法でもいいかなと思った。
postgresでcsv出力

postgresからcsv出力するメモ
COPYでのファイル名指定は、DBサーバから見たパスになるため注意

## COPY TO

https://www.postgresql.jp/document/9.3/html/sql-copy.html

```bash
# csv形式での出力
# 区切り文字、QUOTE文字、NULL文字列、復帰、改行文字を含む値の場合はダブルクォーテーションつく
$ psql TESTDB -c "COPY (select * from foo) TO '/tmp/foo.csv' (FORMAT csv)"

# 全項目(null値以外) ダブルクォーテーションつく
$ psql TESTDB -c "COPY (select * from foo) TO '/tmp/foo.csv' (FORMAT csv, FORCE_QUOTE *)"
```

## psqlコマンド

https://www.postgresql.jp/document/9.3/html/app-psql.html
ダブルクォーテーションつけたい場合はselect文で自前で付与しないとダメ？？

```bash
# ダブルクォーテーションつかない
$ psql TESTDB -c "select * from foo" -A -F, > /tmp/foo.csv
```
- -A = 位置揃えなし
- -F, = カンマ区切り
iOS7のUIScrollViewでAspect Ratioを指定すると発生するバグと対処法


iOS7.1のUIScrollView上に設置したUIViewにAspect Ratioを指定し、そのViewをtapしたりすると下記のようなエラーが発生しました。 
ちなみにiOS8では問題は起こりませんでした。

```エラー
 Statistics:
	28 rows. Variable counts:
		  1 ->   4
		  2 ->  16
		  3 ->   2
		  4 ->   2
		  5 ->   2
		  6 ->   2
}: internal error.  Cannot find an outgoing row head for incoming head HogeUIView:0x120398740.Height{id: 424}, which should never happen.'
```

どうも調べてみるとiOS7でUIScrollView上でaspect ratioを指定すると発生するバグだということがわかりました。

## 解決方法
### 16:9の比率を若干ずらして対応する
かなり力技ですが、下記のようにconstraintの数値を手動で書き換えます。なぜ比率を少し書き換えると上手く動くのか。。 
16:9 → 15999:9000
![スクリーンショット 2015-08-12 19.08.37.png](https://qiita-image-store.s3.amazonaws.com/0/10532/8b383979-1068-48ba-d4ae-e2d9bbd6fa1a.png "スクリーンショット 2015-08-12 19.08.37.png")

### aspect ratioとheightを両方指定する
heightのconstraintが被ってしまうので警告が出ますが、一応動くようです。

## 参考
http://stackoverflow.com/questions/28111635/ios-aspect-ratio-constraint-breaks-on-ios7-works-on-ios8
Arduinoをいじりはじめてみたよ-その3

#1. はじめに
## あいさつ
ひょんなことからArduinoを使って遊ぶことになったので
その備忘録としてまとめていこうかと。
の第三回です。
[第一回](http://qiita.com/kojisato118/items/df1fb5437c90e2ca5abd)
[第二回](http://qiita.com/kojisato118/items/5e5e23d68a0807a26117)

## 今回の内容
今回は、第二回の延長でGPSデータが有効な状態のときに、必要な情報だけ抜き出すということをやります。

## 参考ページ
前回とだいたいいっしょです。

* [データシート](http://akizukidenshi.com/download/ds/canmore/GMS7-CR6_v1.0_ak.pdf)
* [参考ページ1](http://www.geocities.jp/zattouka/GarageHouse/micon/GPS/GPS2.htm)
* [参考ページ2](http://www.ct-robo.sakura.ne.jp/489)
* [参考ページ3](http://baticadila.dip.jp/arduino_105.html)

#2. GPSから取得するデータについて
## データフォーマット
下記の例のような感じでデータが並ぶ。
先頭の文字列がIDとなってそれによってデータの形式が変わる。
\$GPGGA, \$GPGSA, \$GPGSV, \$SPRMCなど。
詳細はデータシートや参考ページをみてください。

(例)
\$GPGGA,\<1>,\<2>,\<3>,\<4>,\<5>,\<6>,\<7>,\<8>,\<9>,M,\<10>,M,\<11>,\<12>,*\<13><CR><LF> 

## データの有効性
$GPRMCの二番目の領域のデータが、Aならば有効なデータである。

## 位置情報
$GPGGAから取得する。

#3. スケッチ(プログラム)
参考ページ3を元に作成。
[github](https://github.com/kojisato118/arduino_gps_logger)にあげました。

## 説明
- sGps.read()
	- ソフトウェアシリアルポートから1文字読み取ります。
	- http://www.musashinodenpa.com/arduino/ref/index.php?f=1&pos=190
- getLine(char* buf)
	- 自作の関数
	- bufにgpsからの情報1行分を格納する。
	- sGps.read()で一文字位ずつぶち込む。
- analyzeData(char* buf)
	- 自作の関数
	- gpsデータ1行分のbufデータを分析する
	- まず、データの有効性の確認をし、無効だったら何もしない。
	- 有効の場合、$GPGGAだった場合、時間・緯度・南北・経度・東西の情報を抜き出し、シリアルモニタに出力
	
## 動作
下記みたいな出力がされます。
VやAは有効無効の確認用のログ出力

```
V
V
A
Time = 084623.005 : Latitude = N - 1234.1234 : Longitude = E - 12345.1234
A
Time = 084624.006 : Latitude = N - 1234.1234 : Longitude = E - 12345.1234

```
smartMockを入れ子にしたときジェネリック型が使えない

ScalaのTestクラスで以下のようなものを書くと

```scala
import org.specs2.mock.Mockito
import play.api.test.PlaySpecification

case class A1(id: B)
case class A2[T](id: T)
case class B(id: Int)
class HogeSpec extends PlaySpecification with Mockito {
  override def is =s2"""
      これはパスする $tes1
      これはパスする $tes2
      これはパスする $tes1s
      これはパスしない $tes2s
    """
  def tes1 = {
    val a = mock[A1]
    val b = mock[B]
    a.id returns b
    a.id must_== b
  }
  def tes2 = {
    val a = mock[A2[B]]
    val b = mock[B]
    a.id returns b
    a.id must_== b
  }
  def tes1s = {
    val a = smartMock[A1]
    val b = smartMock[B]
    a.id returns b
    a.id must_== b
  }
  def tes2s = {
    val a = smartMock[A2[B]]
    val b = smartMock[B]
    a.id returns b
    a.id must_== b
  }
}
```

`tes2s`の3行目でMockitoが `ClassCastException` を返し、`a.id` と `b` の型が異なるというエラーを吐く

http://stackoverflow.com/questions/10324063/mockito-classcastexception
http://mockito.googlecode.com/svn/tags/1.8.3/javadoc/org/mockito/Mockito.html#RETURNS_DEEP_STUBS
> Good quote I've seen one day on the web: every time a mock returns a mock a fairy dies. 

エラーで検索したら、「モックがモックを返すたび妖精が死ぬ」という謎の格言が出てきた



## 追記
どうやら`smartMock` でなく `mock` を用いた場合はエラーにならない。
jQuery CoffeeScript 画像の遅延読み込み lazy-load

#まえがき
サイトのページ速度改善のために、サイト内の画像をlazy-loadを使用して遅延読み込みします。
簡単に遅延読み込みを設定出来るので便利です。

#使い方
##準備
以下よりダウンロード。
[jQery Lazy Load](http://plugins.jquery.com/lazyload/)

##コード(jQuery)
###ポイント
* lazy-loadはjQueryに依存するので、jQueryの読み込みが必要。
* 遅延読み込みするためにクラス等をつける（ここでは.lazy)
* 画像にsrcを指定しない。(指定すると画像は表示されても遅延読み込みになっていない)
* 画像のwidthとheightを設定する必要があるようです。

```html:lazy.index
<script src="jquery.js"></script>
<script src="jquery.lazyload.js"></script>

<img class="lazy" data-original="img/example.jpg" width="640" height="480">

<script>
$(function() {
    $("img.lazy").lazyload();
});

//オプションを付けたいときは以下のような感じで
$(function() {
    $("img.lazy").lazyload(
      threshold: 200,  //200pxのところまで近づいたら読み込む
      effect: "fadeIn",  //画像をfadeInさせる
      effect_speed: 3000,  //画像の表示を3秒間かける
    );
});

</script>
```

##コード(slim + CoffeeScript)
###ポイント
* 別途、jQueryとlazy-loadの読み込みが必要。
* data-originの設定をする。srcの設定をしない。
* jQueryのときと若干違うので注意。
* widthとheightを別途追加して下さい。

```slim:lazy.slim
= image_tag "", :class => 'lazy', 'data-original' => "img/example.jpg")
```

```coffeescript:lazy.js.coffee
$ ->
  $("img.lazy").lazyload()

  #オプションを付けたいときは以下のような感じで
  $("img").lazyload
    threshold: 200
    effect: "fadeIn"
    effect_speed: 3000
```

#参考
[Lazy Load(画像の遅延読み込み)を実装する方法](http://syncer.jp/how-to-setting-lazy-load-images)
[Lazy Load Plugin for jQuery Plugin 見えるようになってから画像を読み込む](http://blog.matome-ranking.com/2012/09/lazy-load-plugin-for-jquery-plugin.html#.VcsHIjDtmkr)
[Lazy Load Plugin for jQuery](http://www.appelsiini.net/projects/lazyload)
Vue.jsにはAngularのng-changeに相当するディレクティブがないので自分でv-changeを用意してみる


## コード

```coffeescript:v-change.coffee
# CoffeeScriptで御免

Vue.directive 'change',
    acceptStatement: true
    priority: 1024
    update: (fn)->
        model = @el.getAttribute Vue.config.prefix + 'model'
        @handler = ((v)->
            cache = @vm.$value
            if model
                @vm.$value = v
            else
                @vm.$value = @el.value
            fn @vm.$value
            @vm.$value = cache
        ).bind this

        if model
            @vm.$watch model, @handler
        else
            @el.addEventListener 'input', @handler

    unbind: ->
        @el.removeEventListener 'input', @handler
```
ちゃんと使うならタグの制限や`type`属性のチェックが入るけど、最低限の骨組みはこんな感じ。

## 使い方

```coffee:vm.coffee
new Vue
    template: ...
    methods:
        func: (v)->
            console.log v
```

なVMで

```html
<input type="text" v-model="hoge" v-change="func(hoge)">
```

とか

```html
<input type="text" v-change="func($value)">
```

とか。`$value`が`v-on`の`$event`みたいに使える。

## 解説

### v-modelとの併用
`v-model`が与えられている場合は`$watch`を使うようにしている。`input`イベントはモデルの値が更新される前に発生するので、`v-model`がある場合でも`input`イベントからコールバックを実行してしまうと前回の値が使われてしまうからである。またコールバックに渡す値は`number`属性を一緒に使うときなど、`@el.value`が必ずしも`v-model`でバインドされた値と一致しない場合があるので、`v-model`がある場合は`$watch`で呼び出された引数から引っ張っている。


### priorityについて
`priority`はディレクティブ評価の優先度を設定する。高い方が先に評価される。v-modelの`priority`は`800`で、デフォルトは`0`である。ドキュメントのどこにも書いてないけど、`priority`は
v-modelは[ここ](https://github.com/yyx990803/vue/blob/dev/src/directives/model/index.js#L12)とデフォルトは[ここ](https://github.com/yyx990803/vue/blob/6cd3a16f159b873e96d2b0dcb87e62c9240e197f/src/compiler/compile.js#L622)で確認できる。

Vue.jsのディレクティブではAngularとちがって評価後は要素から属性が取り除かれてしまうため、`v-model`を読み取ろうと思ったら`priority > 800`にする必要がある。

### $eventみたいなローカルスコープっぽいやつ（$value）の作り方
行儀悪いように見えるけど、単純に`v-on`のソースでやってることの流用である。`$event`は特殊なことをしてると思っていたのだが、このやり方で実現してるのを確認したときは少々面食らった。ただ、もともと内側からは`$`で始まるモデルが作れないの対し外部からは普通に書き込みできるので、一瞬だけ埋め込んで外すというやり方は全てが同期的に行われる限り合理的ではある。


## 動機など

基本的にVue.jsではインタラクティブな要素に直接ハンドラを与えて変更を拾うようなディレクティブは存在しないので、`vm.$watch`やComputed propertyのsetterを用いるしかない。

変更の通知のためだけにモデルを用意して`vm.$watch`をVMの実装から呼ぶなんて到底まとな人間の所業ではないし、Computed propertyにしても`v-model`で使うにはgetterが必要で、状態の保存のためは結局モデルを用意しないといけないし、しかもそのモデルの名前はComputed propertyとは別にしないといけないので、命名で気を揉んで辛いってのが何よりの動機。

あとは「`methods`に直接変更のハンドラを書ける必要がある」という意識もある。  

Vue.jsの開発周りの議論などを詳しく追っかけてないんで、なんで実装されてないのかわからないが、何か深いわけがあって`v-change`をビルトインで持っていないのであれば理由を知りたいところである。
DateTime::createFromFormatが年月日を省略すると実行年月日になる問題

#年月日を省略すると実行年月日になる

```php
$time = '08:02:42.34';
$date = DateTime::createFromFormat('H:i:s.u', $time);
echo $date->format('Y-m-d H:i:s.u');
```

とすると生まれるのは`2015-08-11 08:02:42.340000`で
実際の感覚的には`1970-01-01 08:02:42.340000`になって欲しい

#解決
以下のようにすると簡単解決

```php
$time = '08:02:42.34';
$date = DateTime::createFromFormat('!H:i:s.u', $time);
echo $date->format('Y-m-d H:i:s.u');
```

##ちゃんとマニュアルを読め

http://php.net/manual/ja/datetime.createfromformat.php
>format に文字 ! が含まれない場合は、作成した時刻値のうち format で指定されていない部分を 現在のシステム時刻で初期化します。
>format に文字 ! が含まれる場合は、作成した時刻値のうち format で指定されていない部分と ! の左側の部分を Unix エポックの対応する箇所の値で初期化します。
webpackを使ってコマンドラインツールを作る

markdownから1ファイルなhtmlを生成する[md-standalone](https://github.com/ukyo/md-standalone)というツールを作ってみました。これは内部でwebpackを使っていて、その中でも汎用的に使えそうなtipsをここで紹介します。

## 読み込んで欲しいモジュールをaliasでどうにかする

md-standaloneではレンダラを自作のものに置き換えられます(以下参照)。こいつはテキトーなところに置ける仕様になっています。(デフォルトは[md-standalone/defaultRenderer.js at master · ukyo/md-standalone](https://github.com/ukyo/md-standalone/blob/master/lib/defaultRenderer.js))

```js
var html = require('mdHelper').getHtml();
var options = require('options');
var tocHelper = require('tocHelper');

module.exports = function() {
	document.body.innerHTML = '<div id="md">' +html + '</div>';
	document.title = '（＾ω＾ ≡ ＾ω＾）おっおっおっ';
};
```

ただテキトーなところに置きながらも、オプション(↑だと`mdHelper`, `options`, `tocHelper`)等々を読みこんでもらいたいときもあります。そういうときは[alias](http://webpack.github.io/docs/configuration.html#resolve-alias)を使うことができます。`webpackConfig.resolve.alias`で対象のパスを絶対パスとかにすれば`require('options')`とかで読み込むことができます。

```js
var webpackConfig = {
  ...
  resolve: {
    alias: {
      options: path.resolve(__dirname, './options.js')
      ...
    }
  }
};
```

## 入力ファイルのパス解決もaliasでどうにかする

このツールだと、markdown、スタイル(css, scss, less)、自作レンダラ(js)にあたります。これもaliasを使います。以下例ならjsから`require('mdPath')`で読み込めます。

```js
var webpackConfig = {
  ...
  resolve: {
    alias: {
      mdPath: path.resolve(process.cwd(), mdPath) // mdPathは 'path/to/foo.md' とか
      ...
    }
  }
};
```

## 自作ローダー

npmから持ってきた`hoge-loader`でかゆいところに手が届かないような場合、自作ローダーを作ります。

### 基本

`require('./foo!./bar!./baz!mdPath')`みたいなかんじでrequireしたとき、mdPathのファイルを読み込んでbazしてbarしてfooした結果が最終的に受け取れます。例えば`require('./foo?a=aaa&b=bbb!mdPath')`のように読み込むローダーは以下のように作れます

```js
var loaderUtils = require("loader-utils"); // npm installしてね
module.exports = function(content) {
  var query = loaderUtils.parseQuery(this.query);
  ...
  return result;
}
```

基本的には文字列を返す必要がありますが、以下のようにすればオブジェクトを返すこともできます。

```js
module.exports = function() {
  ...
  return 'module.exports = ' JSON.stringify(obj); 
};
```

### webpackConfigからオプションをぶっこ抜く

webpackConfigにオプションを生やしておいて

```js
var webpackConfig = {
  ...
  fooOptions: {...}
};
```

ローダーからぶっこ抜き

```js
module.exports = function() {
  return 'module.exports = ' + JSON.stringify(this.options.fooOptions);
};
```

最終的にこうします(`require('options')`はつまりこういうこと)。

```js
module.exports = require('./optionsLoader!./hogehoge'); // hogehogeは存在すればなんでも良い
```

なんというか、ローダーは工夫次第でもっと色々できそうですね。

## まとめ

ツール内部でwebpackをつかうときのtipsを紹介しました。1つのファイルにまとめる系のツールを作りたい場合はwebpackベースで作るのもありだと思います。
Dockerのプライベートregistry:v2用にnginxを設定する

nginxをリバースproxyにして、dockerのプライベートレジストリ(v2系)をSSL+Basic認証で運用しようとしていたのですが、微妙なバグのような挙動があってなかなか難儀しました。
今だけの過渡的な問題かもしれないですが、回避策を見つけたのでメモしておきます。

https://github.com/docker/distribution/blob/0d52ec61ad02fcff08dd44c6f6bf9ff26a06c5fd/contrib/registry-with-auth/nginx/nginx.conf
特定のカラムの初めの頭文字でグループ化する方法


## はじめに

ブランド情報を管理するBrandモデル＆実際のデーターが以下のような状況の時にアルファベットごとにグループ化する方法がすぐにわからなかったのでメモっておきます

### app/models/brand.rb

```rb
# == Schema Information
#
# Table name: brands
#
#  id              :integer          not null, primary key
#  name            :string(255)
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#
class Brand < ActiveRecord::Base
end
```



```json
{ "name": "titivate"},
{ "name": "MERCURYDUO"},
{ "name": "GYDA"},
{ "name": "jouetie"},
{ "name": "PAMEO POSE"},
{ "name": "MURUA"},
{ "name": "dazzlin"},
{ "name": "merry jenny"},
{ "name": "Re:EDIT"},
{ "name": "Agneau7"},
{ "name": "ANAP"},
{ "name": "Apuweiser-riche"},
{ "name": "AULA AILA"},
{ "name": "BACKS"},
{ "name": "Boisson Chocolat"},
{ "name": "BONICA DOT"},
{ "name": "bpb"},
{ "name": "BUBBLES"},
{ "name": "Candy Stripper"},
{ "name": "X-girl"},
{ "name": "UNRELISH"},
{ "name": "deicy"},
{ "name": "chuu"}
```

## 最初に考えた書き方

こんなのを思いつきました。

mapが2回出てくる時点でちょっと気持ち悪いし、これだと後でメンテナンスするのはちょっとツライなぁと思ってました

```rb
@brands = Brand.all
brands_group_by_alphabet = ("A".."Z").map do |alp|
  {
    alphabet: alp ,
    brands: @brands.select{|brand| brand.name[0] == alp}.map{|brand| brand}}
end
```

## もっとスッキリ書ける

[ActiveRecordでgroup Byしてカウントをして、カウント数でorderする](http://morizyun.github.io/blog/count-order-active-record-rails/)を読んで、group Byできることを知りました。

この記事で突破口が開けた感じがしたものの、アルファベットごとにどのようにグループ化すればいいのかすぐにわからなかったのですが[Rubyリファレンス](http://ref.xaio.jp/ruby/classes/enumerable/group_by)見て以下のようにすることで意図したことができました。

```rb
Brand.all.group_by {|brand| brand.name.chr.upcase }.sort

=> [["A",
  [#<Brand:0x007fc42fed8398
    id: 11,
    name: "Agneau7",
   #<Brand:0x007fc42fed8230
    id: 12,
    name: "ANAP",
   #<Brand:0x007fc42fed80c8
    id: 13,
    name: "Apuweiser-riche",]],
 ["U",
  [#<Brand:0x007fc430abb3b8
    id: 22,
    name: "UNRELISH"]],
 ["X",
  [#<Brand:0x007fc430abb520
    id: 21,
    name: "X-girl",
    >]]]
```

少し補足すると

- [chrで文字列の最初の1文字を新しい文字列で返し](http://ref.xaio.jp/ruby/classes/string/chr)てあげる
- ブランドは大文字と小文字が混在してるのでひとまず大文字で統一

することでアルファベットごとにグループ出来ます。