OmniAICreator/Qiita-1.07M huggingface dataset:
LambdaでS3にデータを格納する

# はじめに
なんらかのクライアントからS3にデータを格納したい場合に、例えばデータのチェックをしたり、なんらかの簡単な処理を保存前にかけたいというケースってよくあると思います。
その際にクライアントから送られてくるデータをLambdaで一旦受けて、チェックなり処理を施してからS3に保存するという選択があると思います。

その中でLambdaからS3にデータを保存する場合に、躓きやすい点があります。

# 下記のコードには問題点があります(Sample1)
なおLambdaFunctionとS3は同一リージョンにあるとします。

```js:sample1.js
var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = function(event, context) {
    // クライアントからデータが渡ってきて、所望の処理を施されてから
    // inputedValueに詰められる
        
    var params = {Bucket: 'myBucket', Key: 'myKey', Body: inputedValue};
    
    s3.putObject(params, function(err, data) {
        // ログを吐き出すなどS3へのデータ格納の後処理
   });
}
```

上記のコードを実行するとS3にデータは格納されるのですが、実行結果を見てみると下記の通りエラーが発生しています。リクエストが完了する前にプロセスが終了しているというエラーメッセージです。

```json:ErrorMessageOfSample1
{
  "errorMessage": "Process exited before completing request"
}
```

LambdaFunctionではリクエストが完了したことを明示的に教えてあげる必要があります。`context`の持っているいくつかのメソッドを呼び出すことでリクエストの完了を通知することができ、上記のようなエラーが出なくなります。

# 下記コードにも問題があります(Sample2)
```js:sample2.js
var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = function(event, context) {
    // クライアントからデータが渡ってきて、所望の処理を施されてから
    // inputedValueに詰められる
        
    var params = {Bucket: 'myBucket', Key: 'myKey', Body: inputedValue};
    
    s3.putObject(params, function(err, data) {
        // ログを吐き出すなどS3へのデータ格納の後処理
   });
   context.done();// ここに追加しました
}
```

上記コードを実行するとエラーが発生しなくなりました。
`context.done()`を呼び出すことで明示的にLambdaにリクエストが完了したことを教えてあげているためです。

しかし、S3を見てみると肝心のデータが格納されていません。
これは`s3.putObject...`によるデータの格納完了を待たずに`context.done()`が呼び出されてしまっていることが原因です。
LambdaFunctionを実行するコンテナが`context.done()`が呼び出されたことによって終了されてしまうのです。

# ということで
```js:sample3.js
var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = function(event, context) {
    // クライアントからデータが渡ってきて、所望の処理を施されてから
    // inputedValueに詰められる
        
    var params = {Bucket: 'myBucket', Key: 'myKey', Body: inputedValue};
    
    s3.putObject(params, function(err, data) {
        // ログを吐き出すなどS3へのデータ格納の後処理
        context.done();// ここに移動しました
   });
}
```
ということで、`context.done()`はputObjectのコールバック内で呼び出すようにしましょう。
これでputObjectが完了してからcontex.done()が呼び出されるようになるため、前述の「S3にデータが格納される前に処理が終わってしまう」「明示的にリクエスト完了を伝えていないのでエラーが発生する」という問題が解消されました
簡単にSinatraまとめ


## とりあえず公式
[Sinatra README](http://www.sinatrarb.com/intro-ja.html "sinatra")

# この記事でまとめていること
公式見たらだいたい分かります。その中でも、よく使うものをまとめてみました。

- ルーティングに正規表現
- 名前付きパラメータから値を取得
- ブロックパラメータで名前付きパラメータにアクセス
- ビューに値を渡す
- ビューのデフォルトテンプレート
- 全ページ共通の処理
- ヘルパー
- GET/POSTで送信されたデータの受け取り
- セッションの利用
- セッションの値を使った条件式
- ビューファイルのフォルダ分け

## ルーティングに正規表現
```ruby
get %r{/hoge/([\w]+)} do
  yo
end
```

## 名前付きパラメータから値を取得
```ruby
get '/hello/:name' do
  "Hello #{params[:name]}"
end
```

## ブロックパラメータで名前付きパラメータにアクセス
```ruby
get '/hello/:name' do |n|
  #n が params[:name] を保持
  "Hello #{n}"
end
```

## ビューに値を渡す

```ruby
get '/' do
  @hoge = "hoge"
  erb :index
end
```

テンプレート側は

```erb
<%= @hoge %>
```

で値を受け取って表示できる。

## ビューのデフォルトテンプレート

テンプレートのレイアウトは
views/layout.erb
を用意すればそれがレンダリングされます。

それ以外のテンプレートを用意して利用したい場合は、第2引数にハッシュ形式のオプションを渡せばよいです。

```ruby
get '/wiki' do
  @title = "wiki"

  erb :index, :layout => :piyo #piyo.erbがレンダリングされる
end
```

ビューのデフォルトテンプレートからビューを呼び出すこともできます。

```erb
<body>
  <header>
    <%= erb :header %>
  </header>

  <%= yield %>

  <footer>
    <%= erb :footer %>
  </footer>
</body>
```

## 全ページ共通の処理
リクエスト前の処理

```ruby
before do
  @piyo = "hoge"
end

before '/hoge/*' do #ページの指定もできる
  @piyo = "hoge"
end
```

リクエスト後の処理

```ruby
after do
  logger.info "loading data"
end

after '/hoge/*' do #ページの指定もできる
  logger.info "loading data"
end
```

## ヘルパー

トップレベルのhelpersメソッドを使用して共通関数を定義できます。

```ruby
helpers do
  def bar(name)
    "#{name}bar"
  end
end
```

## GET/POSTで送信されたデータの受け取り

```ruby
post '/test' do
  params[:hoge] #GET/POSTの区別は特に必要ない
end
```

## セッションの利用

```ruby
enable :sessions

post '/' do
  session[:hoge]
end
```

Sinatraではセキュリティのため、セッションデータはセッション秘密鍵で署名されます。
セッション秘密鍵はアプリケーション立ち上げごとにランダムで生成されますが、もし固定したい場合は

```ruby
set :session_secret, 'your session secret'
```

でOK。


## セッション値を使った条件式

未定義のセッションを条件式にかけると爆発するので、未定義ならnilを代入してあげましょう。

```ruby
session[:hoge] ||= nil #未定義ならnilを代入する

if session[:hoge].nil? then
  redirect to('/')
end
```

# 豆知識
知ってると便利なもの

## ビューファイルのフォルダ分け

viewをhogeフォルダにまとめた場合です。
/view/hoge/index.erb を読み込む場合

```ruby
get '/hoge' do
  erb 'hoge/index'.to_sym
  erb :'hoge/index' #値はシンボルで渡す必要がある
end
```
「AからBまでの間に存在する全ての兄弟ノード」をXPathで表現する

# 書式

```xquery:AからBまでの間に存在する全ての兄弟ノード
A/following-sibling::*[following::B]
```

# 使用例

前提知識: [「PHPネイティブのDOMによるスクレイピング入門」](http://qiita.com/mpyw/items/c0312271819baee09132)

```php
<?php

$html = <<<'EOD'
<!DOCTYPE html>
<title>淫夢要素はありません</title>
<h1>野獣</h1>
<p>イ　ン　テ　ル　長　友</p>
<p>北　島　康　介</p>
<p>鈴　木　福</p>
<h1>遠野</h1>
<p>レ　シ　ー　ト　リ　ザ　ー　ド</p>
<p>世界のトオノ</p>
<h1>MUR</h1>
<p>ベ　ッ　キ　ー</p>
<p>ポッチャマ…</p>
<p>池沼</p>
<p>智将</p>
EOD;

$dom = new \DOMDocument;
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new \DOMXPath($dom);

$stringify = function ($node) {
    return $node->nodeValue;
};
$execute = function ($query) use ($xpath, $stringify) {
    return array_map($stringify, iterator_to_array($xpath->query($query), false));
};
$results = array_map($execute, [
    '野獣' => '//h1[.="野獣"]/following-sibling::p[following::h1[.="遠野"]]',
    '遠野' => '//h1[.="遠野"]/following-sibling::p[following::h1[.="MUR"]]',
    'MUR' => '//h1[.="MUR"]/following-sibling::p',
]);

var_dump($results);

/*
array(3) {
  ["野獣"]=>
  array(3) {
    [0]=>
    string(33) "イ　ン　テ　ル　長　友"
    [1]=>
    string(21) "北　島　康　介"
    [2]=>
    string(15) "鈴　木　福"
  }
  ["遠野"]=>
  array(2) {
    [0]=>
    string(45) "レ　シ　ー　ト　リ　ザ　ー　ド"
    [1]=>
    string(18) "世界のトオノ"
  }
  ["MUR"]=>
  array(4) {
    [0]=>
    string(21) "ベ　ッ　キ　ー"
    [1]=>
    string(18) "ポッチャマ…"
    [2]=>
    string(6) "池沼"
    [3]=>
    string(6) "智将"
  }
}
*/
```
Bayesian NMFを確率的変分ベイズ法で解く

#はじめに
非負値行列分解(Nonnegative Matrix Factorization;NMF)の確率的変分ベイズ法(stochastic variational Bayesian method)による解法です。
[こちら](http://www.columbia.edu/~jwp2128/Papers/PaisleyBleiJordan2014.pdf)の文献をまとめたものです。

#Bayesian NMF
NMFは行列を非負値の行列の積に分解する、毎度おなじみのあれです。分解後の行列の各要素に事前分布を導入したものがBayesian NMFです。

```math
X_{vd} \sim Poisson(\sum_{k=1}^{K}\beta_{vk}\theta_{kd})
\\
\beta_{vk} \sim Gamma(c_{0}/V, c_{0})
\\
\theta_{kd} \sim Gamma(a_{0}, b_{0})
```
同じベイズ的行列分解モデルのLDAとの対応を考えると、$\beta_{:k}$をtopicと見なせます(Bayesian NMFの$X$とLDAの$W$は転置の関係にあることは少し注意です)。

一方で$\sum_{v}\beta_{vk} \neq 1$となるところが異なります。

#Stochastic variational Bayesian method
変分ベイズ法に確率的最適化を適用した学習アルゴリズムです。与えられたデータの一部を使って事後分布を更新する操作を逐次的に繰り返します。
行列データは巨大になりがちなので、一回の更新に用いるデータを絞って学習をコンパクトにできるのはとてもありがたいことですね。

イメージはこんな感じです。
![スクリーンショット 2015-09-05 15.23.38.png](https://qiita-image-store.s3.amazonaws.com/0/66317/7786e0a4-6f8b-27c6-b726-c723d145db56.png)

1回のイテレーションで$\Theta$を一部更新して、これを$B$全体の更新に用いています。$\Theta$はLDAで言う文書毎のトピック分布に対応することを考えると、$\Theta$を一部更新するには対応する文書だけ投入してやれば良いという訳です。

一方で$B$の更新に$\Theta$全量を使うことができなくなってしまいますが、この問題を補うのが確率的最適化というテクニックです。
発想はシンプルで、sumを含む目的関数$f(x)=\sum_{i=1}^{n}f_i(x)$を$f(x)=nE[f_i(x)]$と見なした時に、期待値の箇所を実際のサンプル$f_{i}$で近似しようという考え方です。

#導出時のポイント
ポアソン分布の期待値計算において、1カ所解けない箇所があります。$E[\ln\sum_{k}\beta_{vk}\theta_{kd}]$です。この部分は次の様に下から支えてあげます。

```math
\ln(\sum_{k=1}^{K}\beta_{vk}\theta_{kd})\geq\sum_{k=1}^{K}p_{k}^{(vd)} \ln(\beta_{vk}\theta_{kd}) - \sum_{k=1}^{K}p_{k}^{(vd)}\ln p_{k}^{(vd)}
\\
p_{k}^{(vd)} \propto \exp{(E_{q}[\ln\beta_{vk}] + E_{q}[\ln\theta_{kd}])}
```

#実験してみた
$K$を変えながら学習結果の検証です。batchVBが普通の変分ベイズ法、stochasticVBが確率的変分ベイズ法です。個人的には、動作確認程度なら画像が使いやすいと思いました。

* batchVB($K=10$)

![bK10.png](https://qiita-image-store.s3.amazonaws.com/0/66317/debac40a-dcd0-4b53-1f26-dacd4eff150b.png)
* stochasticVB($K=10$)

![sK10.png](https://qiita-image-store.s3.amazonaws.com/0/66317/e72a7600-039d-874a-e49e-f802dca66c3d.png)
* batchVB($K=30$)

![bK30.png](https://qiita-image-store.s3.amazonaws.com/0/66317/38262687-2a74-c98a-13e9-0321a38e02b4.png)
* stochasticVB($K=30$)

![sK30.png](https://qiita-image-store.s3.amazonaws.com/0/66317/1492d257-ff7d-c026-6d85-06d8c91556a6.png)
* batchVB($K=50$)

![bK50.png](https://qiita-image-store.s3.amazonaws.com/0/66317/1fead186-e68e-e795-6924-2555cb0d99ac.png)
* stochasticVB($K=50$)

![sK50.png](https://qiita-image-store.s3.amazonaws.com/0/66317/cf18bce0-cb96-aa0f-8aea-f6602fac6be4.png)

やっぱりbatchと比べると少しぼやけてる印象がありますね。

投入した画像のサイズは512^2ですが、この程度の大きさだとstochasticVBの恩恵はあまり得られないと思います。
実験に使ったソースコードは[こちら](https://github.com/tn1031/stochasticNMF)。

#さいごに
相関があるバージョンと、大規模データセットでの実験はまた今度ということで。。。
外部キー制約かけたカラムを削除するのにハマったのでメモ。



## 前提
### Bookモデルを作成(belongs_to :author)

```
rails g model Book title:string author:references
```

### migration fileを確認

3333333_create_books.rb


```ruby

class CreateBooks < ActiveRecord::Migration
  def change
    create_table :books do |t|
      t.references :author, index: true
      t.string :title

      t.timestamps null: false
    end
    add_foreign_key :books, :authors
  end
end
```

※外部キー制約をかけると、必ずindexが付いてきます。
Bookテーブル

|  id | title  |author_id   |  
|---|---|---|---|
|  1 |hoge   |   3|   
|  2 |  fuga |   3|   
|   3|   piyo|   5|   



ここから、author_idを消します。
## 外部キー制約したカラム削除
### change columnのmigration file作成

```
rails g migration ChangeColumnToBook
```

### migation fileを確認

4444444_change_column_to_book.rb


```ruby

class CreateBooks < ActiveRecord::Migration
  def change
  end
end
```


ここから、外部キー制約を掛けられているauthor_idを消します。



### migration fileをいじる


4444444_change_column_to_book.rb


```ruby

class CreateBooks < ActiveRecord::Migration
  def change
    remove_foreign_key :books, :authors
    remove_index :books, :author_id
    remove_reference :books, :author
  end
end
```

なんで面倒くさい。。
単数形 or 複数形 モデル or カラム名に注意して下さい。


#### remove_foreign_key

3333333_create_books.rb


```ruby
add_foreign_key :books, :authors
```

に対し

4444444_change_column_to_book.rb

```ruby 
remove_foreign_key :books, :authors
```



# rake db:migrate!!!


### 解説(見なくてもいい)
#### remove_index
これが一番ややこし買ったです。
3333333_create_books.rb


```ruby
t.references :author, index: true
```

のindex: trueに対し

4444444_change_column_to_book.rb

```ruby 
remove_index :books, :author_id
```

#### remove_reference


3333333_create_books.rb


```ruby
t.reference :author
```


に対し

4444444_change_column_to_book.rb

```ruby 
remove_reference :books, :author
```


比べてみたら確かにという感じですが、3段階の処理が必要だということを忘れると大きくはまります。
unity > System.DateTime > 指定日付の日曜日(0時0分0秒)を取得 > TimeSpan / .DayOfWeek を使用 > work -= new TimeSpan ((int)work.DayOfWeek, work.Hour, work.Minute, work.Second);

```txt:動作確認
Unity 5.1.3f1 on MacOS X 10.8.5
```

ある指定日に対して週始まりの日曜日を取得したい。

http://stackoverflow.com/questions/38039/how-can-i-get-the-datetime-for-the-start-of-the-week
にある Skizz さんの方法がシンプルだと思った。

## try1

```sample.cs
using System; // for TimeSpan

	void FindSundayOfTheWeek() {
		System.DateTime work = System.DateTime.Now;
		Debug.Log (work.ToString ());
		work -= new TimeSpan ((int)work.DayOfWeek, 0, 0, 0);
		Debug.Log (work.ToString ());
	}

	void Start () {
		FindSundayOfTheWeek ();
	}
```

![Untitled_-_150912-dateTimeTest_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/a4c04028-08b9-4c72-77ec-b0c102c28bf6.jpeg)


## try2

上記の場合、hour, minute, secondには中途半端な値が入っている。
上記の実装の流用で、以下で0時0分０秒が取得できるようだ。

```sample2.cs
	void FindSundayOfTheWeek() {
		System.DateTime work = System.DateTime.Now;
		Debug.Log (work.ToString ());
		work -= new TimeSpan ((int)work.DayOfWeek, work.Hour, work.Minute, work.Second);
		Debug.Log (work.ToString ());
	}

	void Start () {
		FindSundayOfTheWeek ();
	}
```

![Untitled_-_150912-dateTimeTest_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/0eb916ee-4783-9c39-ddea-10cbe17e0810.jpeg)

こちらが本来欲しかった値だった。
現在時刻がコードに埋め込まれているので、再実行(リラン)できないじゃん

Qiita yubaさんが書いていらっしゃる

現在時刻の取得をコード中に直に書かない(http://qiita.com/yuba/items/f52f90c4bd249d24b7d6)

にすごく共感し、私も書きたくなったので。


#とあるバッチ処理での出来事(現在時刻がコードに埋め込まれているので、再実行(リラン)できないじゃん)
## 業務要件
次のようなバッチ処理の業務要件がありました。

「外部○○システムの□□データの更新日時を、**前日２０時締め**で自システムに取り込んで、**翌日のオンラインサービスで開示したい**」

というものです。

## 制約
この処理の他にもバッチ処理があり、処理時間の制約もあって、このバッチ処理は、**前日の２２時から処理を開始**しなければなりませんでした。


## 実装イメージ
INSERTとUPDATEが絡むので、実際はもう少し複雑なSQLなのですが、次のようなSQLだと思ってください。
**前日の２２時から処理を開始**してよいという制約が逆に都合が良いという判断から、単純に現在日時**「NOW()」**を取得して、**時分秒だけ２０時に置き換え**ています。

```sql:mysql前提のSQL文
SELECT
*
FROM
T_TABLE_A
WHERE
UPD_DTTM <= STR_TO_DATE(DATE_FORMAT(NOW(),'%Y/%m/%d 20:00:00'), '%Y/%m/%d %H:%i:%s')
;
```

## このバッチ処理の後続で、別のバッチ処理が深夜AM１時頃異常終了しました！！
夜間障害CALLの電話がAM１時になりました。タクシーを飛ばして出社して、障害対応開始。
漸くAM３時に、直接障害を起こしたバッチ処理の修正が終わりました。
オンラインサービスは９時からなので、まだ余裕です。再実行をするのことになりました。

今回の障害は、自システムのテーブル群が色々更新された後での障害だったので、再実行開始点は、
外部システムからの取り込み処理である、このバッチ処理からとせざるをえない状況でした。


ここで、さらに問題発生。上記のSQLの現在日時を取得している**「NOW()」**です。
業務要件では、**「前日２０時締め」の縛り**があるので、**前日２０時以下のデータを取り込まなければなりません。**
しかし、異常終了したのは翌日のAM１時です。**このまま再実行してしまうと、２０時以降のデータが取り込まれてしまいます。**

# 現在日時の取得は、SYSDATEやNOW等の現在日付をコードに直接埋め込まない。間に一枚噛ませること。
結局、現在日時の取得は、「NOW()」を止めて、Viewから取得するように変更しました。
このViewは日々使うときは「NOW()」から現在日時を取得し、障害対応等の再実行するときは、テーブルから現在日時を取得します。

もっと言うと、オンライン、バッチともにViewから現在日付を取得するように統一しておくと、「今日はｎ月ｍ日のつもり」というようなテストができるので、テストのしやすさ的にもGOODです。

顧客の受け入れテストやシステム総合テストなどでは、ある日の本番データを、１日遅れくらいの頻度でテスト機に持ってきて、テストを実施したりしますが、こんな時「今日はｎ月ｍ日のつもり」ということができれば、１日遅れであっても、あたかも当日のふりをすることができます。

```SQL:SYSDATEやNOW等の現在日付をコードに直接埋め込まない。間に一枚噛ませること。
-- 現在日時を取得するView(日々使う)
CREATE VIEW V_DATETIME (CURRENT_DTTM)
AS
SELECT
NOW() AS CURRENT_DTTM
;
-- 現在日時を取得するView(再実行用。実テーブル内の日時)
CREATE VIEW V_DATETIME (CURRENT_DTTM)
AS
SELECT
CURRENT_DTTM 
FROM
T_DATETIME
;
-- 再実行用の日付を登録するレコード
INSERT INTO T_DATETIME (ID, CURRENT_DTTM) VALUES (1, STR_TO_DATE('2015/08/30 20:00:00', '%Y/%m/%d %H:%i:%s'));

-- 現在日時をViewから取得するように変更
SELECT
*
FROM
T_TABLE_A
WHERE
UPD_DTTM <= STR_TO_DATE(DATE_FORMAT((SELECT CURRENT_DTTM FROM V_DATETIME),'%Y/%m/%d 20:00:00'), '%Y/%m/%d %H:%i:%s')
;
```
【monaca】Inappbrowserにて、複数のoptionを指定する方法

# 問題点
[Monaca](https://ja.monaca.io "Monaca")にて、アプリ開発を行っておりまして、
[Inappbrowser](http://docs.monaca.mobi/3.5/ja/reference/phonegap_34/ja/inappbrowser/ "monca")という、webブラウザビューを立ち上げるプラグインを使用して、
Safari等のアプリを使用せずに開発アプリ内でブラウザビューを起動する実装を行っておりました。

```js:InAppbrowser書式
var ref = window.open(url, target, options);
```
optionsにパラメータを指定する事で、ツールバーを非表示にしたりなどのカスタマイズを行う事が出来るのですが、複数指定すると上手く読み込んでくれません。

```js:問題コード
var ref = window.open('http://qiita.com/', '_blank', 'toolbar=yes, toolbarposition=top');
```

ツールバーは表示されるけど、ツールバーは下段に表示されたまま・・・(´・ω・`)

# 解決方法
我らが[stackoverflow](http://stackoverflow.com/questions/19181365/how-to-set-mutipule-inappbrowser-options "stackoverflow")様に投稿がありました。

以下要約です。
>**How to set mutipule inAppBrowser options**
> **Q.**
> 下のように書いたのですが、複数読み込んでくれません。！
>
> ```js
>  var ref = window.open('http://apache.org', '_blank', 'location=no&hidden=no');
> ```
>
> 助けてください。
>
> **A.**
> 下のように書いてください。
>
> ```js
>  var ref = window.open('http://apache.org', '_blank', 'location=no,hidden=no');
> ```
>  
> Phonegapのドキュメントによると
> ・オプションの文字列は、空白を含んではいけません。
> ・プロパティは カンマ[,]で句切られる必要があります。
> ・プロパティは大文字と小文字は区別しません。
> と書かれています。

以上を参考にし、書き直しました。

```js:修正後コード
window.open('http://qiita.com/', '_blank', 'toolbar=yes,toolbarposition=top');
```

結果、期待通りに、ツールバーは表示され、また、ツールバーの位置は上部になりました。
(※ そもそもtoolbarはデフォルトでyesなので、ある意味不要ですが。)

# まとめ
**Inappbrowserのオプションには**
**　・空白をいれない**
**　・各プロパティは、カンマで区切る**

# 補足
[Inappbrowser](http://docs.monaca.mobi/3.5/ja/reference/phonegap_34/ja/inappbrowser/ "monca")のMonaca公式ドキュメントにかかれてました。。

> options の文字列に、空白は挿入できません。
> 各設定 ( 名称と値の組み合わせ ) の間を、コンマで区切る必要があります。
> 各設定の名称では、大文字・小文字を区別しません。

書いてありました。。。
Monacaのドキュメント本当助かるので、しっかり読まないといけませんね。

どなたかの役に立てば幸いです。
docker-machineで立てたvmにipアドレスではなくドメインでアクセスする



いちいち192.168.・・・みたいにipアドレスを入力するのは面倒です。
hostsを書き換えて`docker`+ポート番号でアクセスできるようにします。

## 方法
ipアドレスを調べる

```bash:
$ docker-machine ip default
# 192.168.99.100
```

`/etc/hosts`に追記する。

```/etc/hosts
192.168.99.100		docker

````

これでブラウザにipアドレスで入力していたところをただ`docker`とアクセスできるようになります。
docker-compose upでnetwork timed outが出た場合の対処


docker-compose upをしたら以下の様なエラーが出ました。

```bash:
Network timed out while trying to connect to https://index.docker.io/v1/repositories/library/node/images. You may want to check your internet connection or if you are behind a proxy.
```

docker-machineを再起動で動きました。

```bash:
$ docker-machine restart default    
$ eval $(docker-machine env default) 
```


## 参考

- [Network timed out while trying to connect to https://index.docker.io - Stack Overflow](http://stackoverflow.com/questions/31990757/network-timed-out-while-trying-to-connect-to-https-index-docker-io)
Mac（Yosemite）のVirtualBoxにCentOS7（minimal ISO）をインストールしてみた


##必要なもの

VirtualBox
CentOS7 Minimal ISO

##ダウンロード先

###VirtualBox

公式サイトのDownloadから最新版をダウンロードしましょう。

[公式サイト](https://www.virtualbox.org/)

私はVirtualBox2.x系を使っていたのですが、あまりに古かったので、下記の最新版をインストールし直しました。
（インストールはポチポチするだけなので割愛）
_VirtualBox 5.0.4 for OS X hosts_
ちなみに、旧バージョンで作成していた仮想環境はそのまま引き継がれる模様。

###CentOS7 Minimal ISO

公式サイトからダウンロードしましょう。

[公式サイト](https://www.centos.org/download/)

今回はサーバ構築が目的なのでシンプル構成のMinimal ISOをダウンロードします。
ミラーサイトのリストから適当なところを選んでダウンロード。
気分的に日本の大学のミラーリングからダウンロードしてみました。
なお、普通のOSとして利用したい方はDVD ISOがいいと思います。

##VirtualBoxで仮想環境を構築

1. 新規ボタンをクリック。
2. ダイアログが開くので名前のところに「CentOS」と入力すると、タイプとバージョンのプルダウンがCentOS用に変更されますので続けるをクリック。
3. 仮想マシンに割り当てるメモリーの設定画面に遷移するので、メモリサイズを入力します。私は1024MBにしてみました。続けるをクリック。
4. ハードディスクについての設定画面に遷移します。私は「仮想ハードディスクを作成する」を選択しました。作成をクリック。
5. ハードディスクのファイルタイプの設定画面に遷移します。VirtualBoxでしか使用しないのでデフォルト設定のままで続けるをクリック。
6. 物理ハードディスクにあるストレージの設定画面に遷移します。私はMacbookAirのSSDの容量を圧迫したくないので「可変サイズ」を選択。続けるをクリック。
7. ファイルの場所とサイズの設定画面に遷移します。特に変更する必要がないのでデフォルト設定のまま作成をクリック。
8. これでVirtualBoxにCentOS用の仮想ディスクが作成されました。
9. 続いて、設定ボタンをクリックして、設定画面に遷移します。
10. ストレージを選択して、「コントローラー：IDE」の「空」を選択。右側の「光学ドライブ」のプルダウンの横のCDアイコンをクリックして、「仮想光学ディスクファイルを選択...」を選択して、ダウンロードしたCentOSのISOを選択します。OKをクリック。
11. 以上で、仮想環境の構築は終了です。

##VirtualBoxの仮想環境にCentOSをインストール

1. 起動ボタンをクリック。
2. VirtualBoxのウインドウが開き、CentOSのインストールが開始されます。
3. 黒い画面に文字がずらーっと表示されるので眺めます。
4. CentOSの環境設定画面が表示されるので、まずは言語環境を設定します。私はもちろん日本語を選択。Continueをクリック。
5. インストールの概要画面に遷移するので、必要に応じて設定を行います。インストールの開始をクリック。
6. ルートユーザーのパスワードとユーザ作成の画面に遷移するので必要に応じて設定します。
7. しばらく待っているとインストールが完了するので、再起動をクリックするとCentOSが再起動し、ログイン画面が表示されれば、インストール完了です。

##CentOSの環境設定

そのうち書きます。
unity > 値を[-1.0, 1.0]へ変換する方法2つ > 1:自作 / 2:Mathf.InverseLerp()使用

```txt:動作確認
Unity 5.1.3-f1 on MacOS X 10.8.5
```

[2.0, 4.0]の範囲の値を[-1.0, 1.0]に変換したい。

## try 1
素直に実装すると以下でできる。

```try1.cs
	float getNormalizedYValue(float val_, float min_, float max_)
	{
		// convert the value to [-1.0, 1.0] using [min,max]
		float res;
		res = (val_ - min_) * (1.0f - (-1.0f)) / (max_ - min_) + (-1.0f);
		return res;
	}
```

## try 2

UnityにはMathf関連の関数がある。その中でめぼしいのが以下。
http://docs.unity3d.com/jp/current/ScriptReference/Mathf.InverseLerp.html

使ってみた。

```try2.cs
	float getNormUsingInvLerp(float val_, float min_, float max_) 
	{
		// convert the value to [-1.0, 1.0] using [min,max]
		float res = Mathf.InverseLerp(min_, max_, val_);
		return res * 2f - 1f;
	}
```

## try1とtry2の計算比較

比較のsnippet

```check.cs
	void Test_calc() {
		float work, work2;
		float val;
		string res;

		for (int idx=0; idx<7; idx++) {
			val = Random.Range(2f, 4f);
			work = getNormalizedYValue (val, 2f, 4f);
			work2 = getNormUsingInvLerp (val, 2f, 4f);
			res = val.ToString("0.00 >> ") +  
				work.ToString ("0.00 :") + work2.ToString ("0.00");
			Debug.Log(res);
		}
	}

```

上記を実行した結果が以下。一応あっているっぽい。

![Main_unity_-_150908-udpTimeGraph_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/37e5f0ea-cc8b-158b-8510-5a272b70e5c5.jpeg)



Mathf.InverseLerp()学習済みの人には後者の方が読みやすいだろうか？

1. Mathf.InverseLerp()で[0,1]に変換
2. `* 2f - 1f`で[-1, 1]に変換
Angular 1.x でイベントハンドラを設定できる directive を作る（$parse の使い方）


`$parse` を使って `ngClick` のように `$event` などの引数付きでイベントハンドラを設定できる directive を作ります。

```html
<a ng-click="vm.doSomething($event)">Do Something</a>
```

ただ関数を実行するだけなら `scope.$eval(attrs.onSomething)` すれば OK です。`ngClick` の `$event` のように scope にはない引数を渡すにはどうすればいいでしょうか？ngClick の実装を見てみましょう。

## ngClick の実装

`ngClick` など DOM のイベントそのままの directive は `angular/angular.js` の `src/ng/directive/ngEventDirs.js` で定義されています。`ngClick` は概ね以下のような実装になっています（本当は複数のイベントに対応する directive を一気に定義するようになっていますが、簡明のため ngClick だけになるよう書き換えています）。

```js
var ngClickDirective = function($parse) {
  return {
    compile: function($element, attr) {
      var fn = $parse(attr.ngClick, null, true);
      return function(scope, element) {
        element.on('click', function(event) {
          var callback = function() {
            fn(scope, {$event:event});
          };
          scope.$apply(callback);
        });
      };
    }
  };
};
```

`$parse` なるものが使われていますね。

## $parse と locals

[$parse の公式ドキュメント](https://docs.angularjs.org/api/ng/service/$parse)を読むと、expression を関数に変換するとあります。ドキュメント中の例では object のプロパティに get/set をしています。

```js
var getter = $parse('user.name');
var setter = getter.assign;
var context = {user:{name:'angular'}};
var locals = {user:{name:'local'}};

expect(getter(context)).toEqual('angular');
setter(context, 'newValue');
expect(context.user.name).toEqual('newValue');
expect(getter(context, locals)).toEqual('local');
```

`$parse()` の結果が getter で、その `assign` プロパティが setter ですね。getter には locals というものを使うことで、scope に加えてその expression 中だで使う context を指定できます。これにより scope を汚すことなく、そのイベントハンドラだけで使える変数を用意することができます。ちなみに scope と同じプロパティがある場合は、locals が優先されるようです。

上の ngClick では `{$event:event}` という locals が使われていました。これを真似すれば、イベントハンドラに独自の引数を渡せますね。

## $parse の隠れた引数

公式ドキュメントでは `$parse` の引数は一つだけです。しかし `ngClick` を見ると、もう 2 つあることがわかります。

2 つ目の引数は `interceptorFn` とあるので、expression の評価結果をいじるための関数と思われます。

3 つ目の引数は `expensiveChecks` というものだそうで、`$parse` に渡す expression が `window` にアクセスしないかを、戻り値の関数実行時にチェックするようです。コメントには、イベントハンドラは頻繁に実行されないので expensive でも構わず実行すると書いてあります。

[Expression Sandbox](https://docs.angularjs.org/guide/security#expression-sandboxing) によれば、これはセキュリティのためではなく `window` を使った設計をできないようにするためだそうです。

scope で window を露出させることは通常ないのでチェックしていないが、このフラグを true にするとチェックする模様。

セキュリティ目的というわけでもないので気にしなくても良さそうですが、`ngClick` とかでつかってるので真似しておくといいかもしれません。

## 自作する

仕組みは分かったので、後は `ngClick` を真似するだけですね。

1. compile で expression を `$parse()` して結果の関数をとっておく（link でもいいけど）。
2. イベントハンドラを実行するときは `fn(scope, locals)` のように scope と（必要なら）locals を渡して実行する。
[Ruby] rubyのJSON.parseした結果をシンボルのキーで受け取る

通常、RubyでJSON.parseするとシンボルをキーにしていたHashが文字列のキーになってしまう。

```rb
irb(main):013:0* require 'json'
=> true

irb(main):014:0> test = {key1: 'value1', key2: 'value2'}
=> {:key1=>"value1", :key2=>"value2"}

irb(main):017:0* test_json = test.to_json
=> "{\"key1\":\"value1\",\"key2\":\"value2\"}"

# シンボルのキーが文字列になってしまう
irb(main):021:0* test_parse = JSON.parse(test_json)
=> {"key1"=>"value1", "key2"=>"value2"}
```

これをシンボルのまま使いたい場合はJSON.parseの第二引数にsymbolize_namesをtrueで指定してあげればOK

```rb
irb(main):024:0* test_parse = JSON.parse(test_json, {symbolize_names: true})
=> {:key1=>"value1", :key2=>"value2"}
```
[短文メモ][X11] コマンドラインでのSelectionやクリップボード操作

xselというコマンドを使えば、コマンドラインでX11のSelection(中クリックで貼り付けられるやつ)やクリップボードを操作できる。

```bash
$ xsel --version
xsel version 1.2.0 by Conrad Parker <conrad@vergenet.net>
```

Selectionに文字列をぶちこむには、stdinに流し込めばいい。
`$ echo foo |xsel`

既にあるSelectionに、文字列を追加することもできる。
`$ echo foo2 |xsel -a`

Selectionをstdoutに吐き出すには、パイプをつけなければいい。
`$ xsel`

Selectionではなくクリップボードを使いたいときは、-bオプションをつける。
`$ echo foo |xsel -b`
`$ echo foo2 |xsel -ab`
`$ xsel -b`

ファイルの中身をWeb上に張り付けないといけないときや、Webからコピーした内容をコマンド上で扱いたいときに便利です。
【CakePHP】カラムの存在チェック


Model::hasField('カラム名')で戻り値がtrue/false。
第二引数にtureを渡すとバーチャルフィールドもチェックしてくれる。

```php
if($this->User->hasField('name')){
  //nameカラムが存在する場合

}else{
  //nameカラムが存在しない場合

}
````

参考：[cookbook](http://book.cakephp.org/2.0/ja/models/virtual-fields.html#model-hasfield)
BOINCクライアントのインストール CentOS7にて

CentOSでboincクライアントを使用するには自分でビルドするしか方法がないようです。

#結果だけ書きます。
`cd ~`
`git clone https://github.com/BOINC/boinc boinc`

`cd ~/boinc`

`sudo yum install libcurl-devel libcurl openssl-dev gcc-c++`

`sudo yum install git make automake m4 libtool autoconf`

`./configure --disable-server --disable-manager --enable-libraries`

`make`


#boinc の起動
`cd ~/boinc/boinc/client`
たとえばWCGの場合は
./boinc --attach_project www.worldcommunitygrid.org　[あなたのキー（WCGのHPにログインして確認する）]


途中でいくつか警告が発生するが無視を決め込む。
>diagnostics.cpp:707:6: warning: unused parameter 'siginfo' [-Wunused-parameter]
> void boinc_catch_signal(int signal, struct siginfo *siginfo, void *sigcontext)...

経緯：勉強用に格安VPSを借りているが、未使用時間がもったいなく感じていたので自分が使用しないときはフルに計算資源を使い切ってやろう・・・という貧乏性からインストールに至りました。（管理者さんにはうれしくないのかも・・・。まぁいいｋ...）

参考URI
[BOINC Configuration @BarkeleyUniv](http://boinc.berkeley.edu/wiki/Client_configuration)
[BOINC Compiling Client @BarkeleyUniv](https://boinc.berkeley.edu/trac/wiki/CompileClient)
[インストールに必要なパッケージなど@BarkelryUniv](http://boinc.berkeley.edu/trac/wiki/SoftwarePrereqsUnix)
[ビルドの大まかな手順@BarkeLeyUniv](http://boinc.berkeley.edu/trac/wiki/BuildSystem#no1
CakePHP3でマイグレーションこんな感じ？

# はじめに
ちょっと色々と準備が必要そうだったので試してみた。
ScaffoldとDB作成は別の様子（ScaffoldしてもDBは作成されないと思う、合ってるのかな）なので、まずマイグレーションだけ調べてみた。

本家ドキュメントはこれ。マイグレーションはここではやってないけど。
http://book.cakephp.org/3.0/en/tutorials-and-examples/bookmarks/intro.html

マイグレーションについてはこれ。
http://book.cakephp.org/3.0/en/migrations.html

# 手順
## ファイル作成

基本的にプロジェクトのルートでコマンドを叩く想定。

```terminal
$ bin/cake bake migration create_test
```

すると、

`config/Migrations/20150912015727_create_tests.php`みたいな名前のファイルが作られる。これが雛形。

## ファイル修正

作ったファイルの内容を修正する。例えば下記のような感じ。

```php:config/Migrations/20150912015727_create_tests.php
<?php
use Migrations\AbstractMigration;

class CreateTests extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-change-method
     * @return void
     */
    public function change()
    {
        $table = $this->table('tests');

        //このあたりを記述する
        $table
          ->addColumn('name', 'string') //文字列カラム
          ->addColumn('description', 'text') //テキストカラム
          ->addTimestamps(); // created_at、updated_atを作る

        $table->create();
    }
}
``` 

## DBに反映！

```terminal
$ bin/cake migrations migrate
```

して、テーブルが無事に作成されればOK！

## その他・気づいたこと

- 基本は not null 制約がかかる様子なので、nullにしたければ明示する。
- IDはAutoIncrementで作成される
- updated_atはnullableで作成される（Railsとは違うかな？）。

外部ライブラリを取り込んだものの様子なので、細かいことはこちらを見ると良いらしい。indexやforeign_key等もあるらしいし、基本的なところはどうにかなるのではないかと。
http://docs.phinx.org/en/latest/migrations.html

下記はとても参考になった。多謝。
http://qiita.com/ukisoft/items/68c35d56a913d0afde6e
GitHubのWebhookとStatus checkでWIP PRのマージを禁止する、という案はありか？

TL;DR
----

[sanemat/do-not-merge-wip-for-github](https://github.com/sanemat/do-not-merge-wip-for-github) で良いと思いました。


GitHub protected branch
----

protected branch で Status check を有効にする事で、自動テストを通るまでは PR のマージボタンが押せなくなります。
(ベースブランチが先行してしまった場合は、ベースブランチの先行分をブランチにマージして改めてテストを通す必要があったりもします。)

- [Protected branches and required status checks](https://github.com/blog/2051-protected-branches-and-required-status-checks)

ここで、ふと思いました。
protected branch によって、サーバ(GitHub)側で `WIP` である PR のマージを禁止することもできるのではないか、と。
それに、どれだけの意味があるかは分かりませんけれども！


GitHub Statuses API
----

GitHub の Statuses API を使うと、コミットの状態を更新させる事ができます。

- [Statuses | GitHub API](https://developer.github.com/v3/repos/statuses/)

GitHub Webhooks でイベントデータを受け取り、結果を Statuses API で反映させるという流れになるのでしょう。
`WIP` の間は `pending` とでもしておき、 `WIP` でなくなったら `success` とします。


GitHub Webhooks
----

GitHub のリポジトリなどで発生する各イベントを Webhook に受け取らせることができます。
Webhook は任意の URL で設定可能で、POST で json を受け取る様な形になります。

- [Webhooks | GitHub API](https://developer.github.com/webhooks/)

PR が `WIP` であるかの判断基準は、「タイトルに `[WIP]` の様なマークが含まれている」としておきます。
PR のタイトルを確認可能な Webhook イベントは、 `pull_request` か `pull_request_review_comment` だけの様です。
`pull_request_review_comment` は diff に対するコメントが付いたときなので、今回は見送ります。

- [Event Types & Payloads | GitHub API](https://developer.github.com/v3/activity/events/types/#pullrequestevent)

`pull_request` イベントは、以下の様なアクションで細分化されます。

- “assigned”
- “unassigned”
- “labeled”
- “unlabeled”
- “opened”
- “closed”
- “reopened”
- “synchronize”

お気づきでしょうか？
はい、そうです。「PRのタイトルを変更した」時にはイベントは発生しない様なのです。


完。


もう少しだけ、続きます。


実験アプリ
----

GitHub Webhooks も GitHub API もまともに触ったことがなかったので、思いついたままに突き進むことにしました。

- [koshigoe/github-webhook-wip-checker](https://github.com/koshigoe/github-webhook-wip-checker)

タイトル変更をトリガーにできない(方法が分からない)ので、無駄に制約を増やしてしまうこのアプリ、無駄の極みです。
必要に応じて、各自で [Do Not Merge WIP for GitHub](https://chrome.google.com/webstore/detail/do-not-merge-wip-for-gith/nimelepbpejjlbmoobocpfnjhihnpked) の様なブラウザ確証を使うのが妥当なのではないでしょうか。

なお、一般に、 WIP PR のマージ防止に気をつかっているのか、どう気をつかっているのか、について知見はありません！

### WIP 判定チャンス

GitHub の `pull_request` イベントを対象に、各アクションで `WIP` かどうかの判定を行う様にしてみます。

#### closed

PR を閉じた時は無視します。

#### opened, reopened

PR を作った時、開き直した時は、 `WIP` 判定のチャンスです。
タイトルに `WIP` らしき情報が入っているか判定します。
アクションが reopened である場合、既にマージされているかもしれないので、 `merged` キーの値も確認するべきでしょう。

#### synchronize

ブランチに push したタイミングで発生する様です。
opened アクション同様にタイトル判定チャンスと考えます。

> updated due to a new push in the branch that the pull request is tracking

#### assigned, unassigned

タイトル変更は検知できませんが、タイトルから `WIP` を外すと同時にレビュアーに担当者を変更するかもしれません。いいや、そのはずだ。
PR の担当者が変わるタイミングがタイトルでの判定チャンスです。

#### labeled, unlabeled

タイトル変更を検知できないため、タイトルによる `WIP` 運用を諦めてラベルによる `WIP` 運用を行いましょう。
`WIP` ラベルが付いた時、 `WIP` ラベルが外され時が判定チャンスです。

### Status check

Webhook で受け取ったイベントデータを使って `WIP` 判定をしたら、その結果を GitHub Statuses API を使ってコミットに反映させます。
`WIP` なら `pending` とし、 `WIP` でないなら `success` とします。


まとめ
---

GitHub Webhooks の実験道具を作りました。
GitHub リポジトリの Webhooks のページからどんなイベントデータ(ペイロード)が送られているのかを見られる様になります！
Ubuntu14.04にpython用にOpenCV3.0.0をインストール

DeepLearning用に画像を加工するのにPythonでOpenCVが使いたかったので、インストールしました。以前まで2.4系を使っていたのですが、3.0.0も出てしばらく経つので、そろそろ最新版をインストールしようと試みました。

## OpenCV3.0.0のソースの取得
```
$ cd ~/work/download
$ wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/3.0.0/opencv-3.0.0.zip
$ unzip opencv-3.0.0.zip
```

## requirementのインストール
必要そうなのをかたっぱしインストール

```
$ sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff4-dev libjasper-dev libopenexr-dev cmake python-dev python-numpy python-tk libtbb-dev libeigen3-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev default-jdk ant libvtk5-qt4-dev
```

## configure
ubuntuでは、WITH_FFMPEG=OFFを忘れずに。

```
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D WITH_FFMPEG=OFF -D BUILD_opencv_python2=ON ..
```

## make用にコア数を調べておく

```
$ grep -c ^processor /proc/cpuinfo
8
```

## make&install

```
$ make -j8
$ sudo make install
```

## インストール確認

```
cd ../sample/cpp
./cpp-example-facedetect lena.jpg
```

* 怒られた

```
cannot connect to X server
```

* 環境変数DISPLAYが原因っぽい

```
$ export -p | grep DISPLAY
"なにもでない"
```

* 以下を設定

```
export DISPLAY=":0"
```

* 再び実行すると、うまくいった


## python用設定
* [こちら](http://qiita.com/mitokazzy/items/df2d8a4fd93f46210f5f)の通りに、しようとしたが  
/usr/local/lib/python2.7/dist-packages/  
にcv2.soがなぜかなかった。なので

```
$ find / -name cv2.so
```
で検索したら、ビルドフォルダにはあったので
そちらを/usr/local/lib/python2.7/site-packages/にコピー

```
$ cp ~/work/downloads/opencv-3.0.0/build/lib/cv2.so /usr/local/lib/python2.7/site-packages/
```

## python確認

```
$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.0.0'
>>> exit()
```
うまくいったみたい

## 参考
[AMIにOpenCV3.0をインストールしてみる](http://qiita.com/mitokazzy/items/df2d8a4fd93f46210f5f)

[Why cv2.so missing after opencv installed?](http://stackoverflow.com/questions/15790501/why-cv2-so-missing-after-opencv-installed)

[Thread: cannot connect to X server](http://ubuntuforums.org/showthread.php?t=2084801)
fastlane で build/version number をインクリメントする


# version/build number のインクリメント
[fastlane](https://github.com/KrauseFx/fastlane) を使ってビルド、配布をしたい場合、build number や version number をインクリメントしたいことがあったので手順をまとめました。


# 準備

プロジェクトの Build Settings の Versioning の部分を下記のように変更します。

![スクリーンショット 2015-09-12 11.38.50.png](https://qiita-image-store.s3.amazonaws.com/0/27210/a5b2c34d-c444-5ec4-01be-1778a531a716.png "スクリーンショット 2015-09-12 11.38.50.png")

Info で Bundle versions を "2.0.1" のような値に設定します("1" や "1.2" などのバージョン指定はダメ)。
Bundle version は整数値を指定します（例では "9")

![スクリーンショット 2015-09-12 10.39.10.png](https://qiita-image-store.s3.amazonaws.com/0/27210/5a72322e-e203-5b9c-ce9e-d87c28aae6c1.png "スクリーンショット 2015-09-12 10.39.10.png")

# Fastfile

インクリメントしたい部分で increment_build_number または increment_version_number を記述します。
下部の例では fastlane deploy の際にインクリメントしています。

```
  desc "Deploy a new version to the App Store"
  desc "** Full Markdown** Support: `code`"
  lane :deploy do
    # snapshot
    increment_build_number
    increment_version_number
    sigh
    deliver(skip_deploy: true, force: true)
    # frameit
  end

```

# 実行結果

build number, version number ともにインクリメントされました。

![スクリーンショット 2015-09-12 11.45.54.png](https://qiita-image-store.s3.amazonaws.com/0/27210/1a0f80f0-acc0-8799-cc38-655daac891c6.png "スクリーンショット 2015-09-12 11.45.54.png")

## 注意

CI などで fastlane を実行する場合はインクリメント後の値を保存(git add,commit,push)しておく必要があります。

下記コマンドでインクリメント後の値を git で保存できます。

```
commit_version_bump
push_to_git_remote
```

くわしくはこちら。
https://github.com/KrauseFx/fastlane/blob/ba72a484f81c09eac616ac821b0186667835843f/docs/Actions.md#using-git
Grasshopper / Pythonでライノオブジェクトをスクリプトでコントロールするための準備


#はじめに

GrasshopperでPythonが扱えるプラグインGhPythonを使うさい、例えばライノスクリプトでは使えるGetObject()のようなコマンドが使えなかったりします。ライノ上でライノスクリプトを使う場合はライノ上のオブジェクトを扱うのに対して、Grasshopper上でライノスクリプトを使う場合はGrasshopperで使っている仮想オブジェクトを扱っているためです。ではどうするのか。

#Documentの位置を指定する

ライノ上のオブジェクトを扱えるようにするために、pythonスクリプトの以下のような記述をします。

```python:sample.py
import scriptcontex as sc

sc.doc = Rhino.RhinoDoc.ActiveDoc

```

こうすることで、このスクリプト内でライノスクリプトを使った場合は、グラスホッパーの仮想オブジェクトではなく、ライノ空間に置かれているオブジェクトを扱えるようになります。

元に戻す場合は、

```python:sample.py
import scriptcontext as sc

sc.doc = ghdoc
```

#どんなシチュエーションのときにどちらのDocumentを選ぶか

```
sc.doc = Rhino.RhinoDoc.ActiveDoc
```

は、以下のようなシチュエーションの時に使います。

* ライノ上に置かれているオブジェクトを選択したいとき
* ライノ上にオブジェクトをベイクしたいとき
* ライノ上のオブジェクトのコントロールポイントなどを操作したいとき。

また、

```
sc.doc = ghdoc
```

は以下のようなシチュエーションの時に使います。

* Grasshopper空間内でライノスクリプトを使ってモデリングをしたいとき
* 他のGrasshopperのコンポーネントやRhinoCommonと組み合わせたいとき

#もっと詳しくは

ここを見るともっと詳しく正しい情報が得られます。
GrasshopperでPythonスクリプトを使いたい人は、必見です。

[TIPS | SCRIPT CONTEXT IN GH PYTHON](http://cu.t-ads.org/?p=345)
OSX Yosemite に MySQL5.5 をインストールする方法


デフォルトだと MySQL 5.6 が入るので、古い MySQL を入れる手順

```
brew uninstall mysql
brew tap homebrew/versions
brew install mysql55
ln -sfv /usr/local/opt/mysql55/homebrew.mxcl.mysql55.plist ~/Library/LaunchAgents
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql55.plist
export PATH=$PATH:/usr/local/opt/mysql55/bin
mysql.server start
```

```
cp /usr/local/opt/mysql55/mysql-test/include/default_my.cnf /etc/my.cnf
```

~~~my.cnf
!include default_mysqld.cnf
!include default_client.cnf

[mysqld.1]
# Run the master.sh script before starting this process
#!run-master-sh

log-bin=                 master-bin

# Run tests with the performance schema instrumentation
loose-enable-performance-schema

[mysqlbinlog]
disable-force-if-open

[ENV]
MASTER_MYPORT=           @mysqld.1.port
MASTER_MYSOCK=           @mysqld.1.socket

[mysqld]
bind-address = 192.168.21.199
#datadir=/var/lib/mysql
#socket=/var/lib/mysql/mysql.sock
skip-name-resolve
default-storage-engine = InnoDB
character-set-server = utf8
skip-character-set-client-handshake

# log
log-error=/var/log/mysql/error.log
log-warnings=1
#general_log     = 1
#general_log_file = /var/log/mysql/mysql.log
#slow_query_log  = 1
#slow_query_log_file = /var/log/mysql/slow.log
long-query-time=10
log-queries-not-using-indexes

# max connections
max_connections = 256
thread_cache_size = 8

# global buffer
key_buffer_size = 512M
max_allowed_packet = 16M
table_open_cache = 512
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
query_cache_type = 1
query_cache_size = 32M
query_cache_limit = 4M

# InnoDB
innodb_buffer_pool_size = 512M
innodb_additional_mem_pool_size = 20M
innodb_log_buffer_size = 32M
innodb_file_per_table
innodb_log_file_size = 128M
innodb_flush_log_at_trx_commit = 0

# replicate
#log-bin=mysql-bin
#expire_logs_days = 3
#server-id = 1

[mysqld_safe]
pid-file=/var/run/mysqld/mysqld.pid
character-set-server = utf8

[mysqldump]
quick
max_allowed_packet = 16M
default-character-set = utf8

[mysql]
default-character-set = utf8

[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M
~~~
論理演算子(&&, ||)の短絡評価

Qiitaの新着エントリを眺めてると、論理演算子の特殊性について、これまでに2度ほど「初めて知った」と言ってる人を見かけたので、試しにまとめてみる。
知ってる人には当たり前だけど、だからこそ知らない人もいるのではないだろうか。

#短絡評価
trueまたはfalseを返す論理演算子(&&, ||)は、最後まで評価しなくても、途中で返すべき値が分かる場合がある。

これを眺めてほしい。
true && true → true
true && false → false
false && true → false
false && false → false

こういう挙動になっていることに気づく。

* &&の左側がtrueの場合、&&の右側がtrueだとtrueを返し、falseだとfalseを返す
* &&の左側がfalseの場合、&&の右側が何であってもfalseを返す

同様に||の場合は、

* ||の左側がtrueの場合、||の右側が何であってもtrueを返す
* ||の左側がfalseの場合、||の右側がtrueだとtrueを返し、falseだとfalseを返す

つまり、&&の左側がfalseの場合や、||の左側がtrueの場合は、右側の値を見る(評価する)必要はない。言語として、この場合は右側の値を評価しない、という仕様にすれば、多少は無駄が省けるかもしれない。そのような仕様を「短絡評価」と呼ぶ。

##C/C++における、評価順序
実は、C/C++では、式中の値の評価順序は処理系に依存する。もちろん演算結果は演算子の優先度通りとなるが、内部的にどういう順序で評価が行われるかは未規定である。
だが、&&と||については、左側から評価すると規定されている。

#短絡評価と副作用
プログラミングにおける副作用とは、値を返す以外の挙動のことを指す。例えば、値の代入や、文字列のコンソールやファイルへの出力などがある。
&&や||が返す値がtrueかfalseかは、短絡評価が行われても変わらないが、短絡された部分に副作用が含まれている場合は短絡評価の有無によって挙動が変わりうる。

```C
#include <stdio.h>
int main(void){
  1 && puts("1");  //  1と表示される。
  0 && puts("0");  //  何も表示されない。(puts("0")の呼び出しが短絡されたため)
}
```
この挙動は、エラーチェックなどに使える。

```C:例
a || error();  // if(!a){ error(); } のような挙動
a || (a = 1);  // if(!a){ a = 1; } のような挙動(代入が式である言語で有効)
a && doSomething();  // if(a){ doSomething(); } のような挙動
```

##ゼロ除算チェックや配列の境界チェックと、短絡評価

短絡評価について特に意識したことがなかった人も、こういうコードを書いたことがある人は多いのでは？

```C:
if(b>0 && a/b > c){ doSomething(); }
if(i < size && array[i] == a){ doSomething(); }
```
もし短絡評価がなければ、こんなコードは書いてはいけないはずだ。&&の左側がfalseのとき、&&の右側は評価せずに飛ばしてくれる短絡評価のおかげで、このコードは許されている。

ちなみに、短絡評価を使い倒すなら

```c
b>0 && a/b > c && doSomething();
i < size && array[i] == a && doSomething();
```
となる。

#最後に評価した値を返す、過激な言語たち
bool型への暗黙の型変換が行われる言語では、&&や||の左側、右側にくる値はtrueかfalseとは限らない(1や2や3かもしれないし、"aaa"かもしれない)し、また、それらが返す値もtrueやfalseである必要はない。
Cでは、&&や||は、1か0しか返さないが、Perl, Ruby, Python, JavaScriptなどでは、最後に評価した値(つまり、短絡が行われたら演算子の左側の値を、行われなかったら右側の値)を返す。

失敗する可能性のある処理、指定されていない可能性のある引数の評価を行い、
失敗あるいは指定がない場合にデフォルト値を入れる、などの処理が簡単に書ける。

```c
foo = trySomething() || default_value
```

##三項演算子もどき

Cなどには `condition ? true_value : false_value` として、conditionが真のときはtrue_valueを、偽のときはfalse_valueを返す三項演算子がある。これと似たものを短絡評価によって作ることができる。

`condition && true_value || false_value`
ただし、true_valueが、bool値として評価するとfalseとなる場合は、これではできない。

配列が簡単に作れて、また、空でない配列がtrueとなる言語では、こういう風にできる。
`(condition && [true_value] || [false_value])[0]`
読みづらいので正直おすすめしないが。

#その他こまごま
##Visual Basicの場合
VB6, VBAは短絡評価をしないので、コードを書く際は注意すること。
VB.NETでは、And, Orは短絡評価しないが、短絡評価する論理演算子AndAlso, OrElseが付け加えられている。

##演算子のオーバーロード
C++では、演算子をオーバーロードできるが。そうした場合、もはやただの関数である。短絡評価も左からの実行もまったく保証されなくなってしまうので注意すること。
デモ: http://codepad.org/WX8myJuK
他にも演算子のオーバーロードが可能な言語があるかもしれないが、その場合も同様に注意すること。
MacでEvernoteの選択されたノートをKindleにメール送信 (JXA)

Evernoteの選択中のノートをHTMLにエクスポートして、メールでKindleに送信するスクリプト

```js:evernote_to_kindle.js
// 自分のKindleのメールアドレス (必ず変更すること)
KINDLE_MAIL_ADDRESS = "your_kindle_address@きんどる.com"

// Kindleへの送信を許可しているメールアドレス
KINDLE_PERMITTED_ADDRESS = "your_name <your_address@gmail.com>"

TEMP_DIR = "evernote_to_kindle"
ZIP_NAME = "evernote_to_kindle.zip"

app = Application.currentApplication()
app.includeStandardAdditions = true

// Evernoteの参照と、選択中のノートを取得
Evernote = Application("Evernote")
selected_notes = Evernote.selection()

// 一時フォルダを作成
se = Application("System Events")
temp_folder = Path(se.temporaryItemsFolder.posixPath() + "/" + TEMP_DIR)

// ノートをHTMLとしてエクスポートし、HTMLをZIPに固める
Evernote.export(selected_notes, {to:temp_folder, format:"HTML"})
app.doShellScript("cd " + temp_folder + ";zip " + ZIP_NAME + " *.html")

// メール作成
Mail = Application("Mail")
m = Mail.OutgoingMessage({sender: KINDLE_PERMITED_ADDRESS, subject:"変換"}).make()
m.toRecipients.push(Mail.Recipient({address: KINDLE_MAIL_ADDRESS }))

// ZIPを添付して送信
m.attachments.push(Mail.Attachment({fileName: temp_folder + "/" + ZIP_NAME}))
Mail.send(m)

// 一時フォルダを削除
se.delete(se.diskItems[temp_folder.toString()])
```

`KINDLE_MAIL_ADDRESS`のみ、書き換えが必須です。
Kindleのメールアドレスに必ず書き換えてください。

`KINDLE_PERMITTED_ADDRESS`はKindleへの送信を許可しているメールアドレスです。
Macの送信メールアドレスが一つしかなく、かつKindleへの送信を許可されているアドレスであればいじる必要はありません。

Macのどのメールアドレスで送信するかを設定するのですが、存在しなければ無視されます。
また、登録されてる名前・メールアドレス・括弧が一字一句同じでないと送信アドレスを変更できません。(Mailの仕様です。)
ターミナルで以下を実行すると名前とメールアドレスの一覧が表示されるので、コピペしてください。

```
osascript -l JavaScript -e 'Application("Mail").accounts().forEach(function(account){console.log(account.fullName() + " <" + account.emailAddresses()[0] +">")})'
```

複数のノートが選択されているとEvernoteがindex.htmlを作り~~やがり~~ますので適当に削除してください。

# 参考
[Send email with attachment using Javascript for Automation](http://stackoverflow.com/questions/27746418/send-email-with-attachment-using-javascript-for-automation)
windowsのテキストファイルをLinuxで解析してメールを送ると添付ファイルになる問題対応

windowsのテキストファイルをLinuxで解析してメールを送ると添付ファイルになる問題が発生した。

```bash:メール送信
tail -n 30 /mnt/windows/app.log | mail my@server.com
```

## 現象

Gmailで受信した場合

![nn.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0eaa0009-e5ff-5e59-9571-3ec04aef42c5.png)

muttで受信した場合

> [-- application/octet-stream 形式は未サポート (このパートを表示するには 'v' を使用) --]


## 対策

改行コード`^M`が含まれるのが原因だった。

```bash:置換
tail -n 30 /mnt/windows/app.log | sed 's/\r//' | mail my@server.com
```

これでbodyにログが表示されるようになった。
mrubyがバンドルされたh2oで画像を表示する

# mrubyのAPIがRackベースに変更



にてAPIがRackに変更された。

# 任意のコンテンツタイプの指定が可能になっている

当初は、レスポンスを返す際の実装が

```
h2o_send_error
```

を使って行われており。コンテンツタイプがtext/html固定だった。

これが、Rack APIベースになって実装が変更され、任意のコンテンツタイプの
指定が可能になっている。

# 画像を表示する

```hello.rb
Proc.new do |env|
  c=""
  File.open("test.jpg") {|f| c = f.read}

  [200, {"content-type" => "image/jpeg"}, [c]]
end
```

ちなみにカレントディレクトリはh2oを実行したディレクトリになる。

test.jpgをそこに置く。
patch - 普通の diff ファイルの使い方。


[ここ](http://qiita.com/bunzaemon/items/206cffdf1c6105990714)の "app.psgi#1" から、[ここ](http://qiita.com/bunzaemon/items/83dd11cbe48ca0fe9867)の "diff#2" を使って、 "app.psgi#3" を作るのに。


##### 準備

"app.psgi#1" がクリップボードにある状態で、保存

```
$ pbpaste > app.psgi
```


## patch

### patch を当てる。

"app.psgi" があるディレクトリで "diff#2" を適当（app.psgi.dif）に保存して

```
$ patch app.psgi < app.psgi.dif
patching file app.psgi
Hunk #1 succeeded at 17 (offset -1 lines).
Hunk #2 succeeded at 36 (offset -1 lines).
```

Hunk... のコメントは、この場合は、行は違うけどパッチは上手く当ったよ。ってコメント[^1]。

[^1]: このコメントを出させるために、数値を改変してる。

"app.psgi#3" を app.psgi.new って名前で保存して

```
$ diff app.psgi app.psgi.new
```

で、再現出来てるのが確認出来る。

### reverse patch を当てる。

で、"app.psgi#3" を "app.psgi#1" に戻すには。
"diff#2" を再度適用する。

```
$ patch app.psgi < app.psgi.dif
patching file app.psgi
Reversed (or previously applied) patch detected!  Assume -R? [n] 
```

すると逆じゃねーの？ と聞いてくるので `y` と答える。

もしくは最初から `-R` オプション付きでコマンドを実行する。

```
$ patch -R app.psgi < app.psgi.dif
```


ので、 Web に数多ある diff 結果は普通に野良 patch として使えるんですよ、、、と。
技術英語 > My car gets 20 kilometers to the liter. / 145 yen to the dollar

引用: 冠詞マスター教本 by 石井隆之さん

> They are paid by the day.

などのように[定冠詞 + 単位名詞]の用法の説明で以下の説明があった。

> 計量単位につく前置詞がtoの場合もある
> My car gets 20 kilometers to the liter.
> (私の車は1リットルあたり20キロメートル走る)

<hr>
これも似たようなものだろうか。

http://ejje.weblio.jp/content/yen-dollar+exchange+rate

> The rate of exchange is 145 yen to the dollar.
Amon2::Lite おさらい 2. 簡単な Web Appli


[1.](http://qiita.com/bunzaemon/items/206cffdf1c6105990714)の続き

bio の題材で、塩基配列を reverse-complement をするだけの Web Appli を作成。

## 編集

前回の状態の app.psgi を元にして。

```
$ cp app.psgi app.psgi.bak
# editing...
$ diff app.psgi.bak app.psgi
```

```diff#2
18,19c18,26
<     my $c = shift;
<     return $c->render('index.tx');
---
> my $c = shift;
>      my $data ;
>      my $seq = $c->req->param('seq') || '';
>      {
>          last if $seq =~ /[^ACGTN\r\n]/i ;
>          $seq =~ s/[\r\n]//g ;
>          ( $data = reverse $seq ) =~ tr/ACGTacgt/TGCAtgca/ ;
>      }
>      return $c->render('index.tx', { data => $data });
30,32c37,39
<     <header><h1>Example</h1></header>
<         This is a Example
<     <footer>Powered by <a href="http://amon.64p.org/">Amon2::Lite</a></footer>
---
>      <form method="get" action="/">
>      <textarea name="seq" rows="4"><: $data || 'input sequence' :></textarea><br>
>      <input type="submit" value="submit" /></br>

```

この状態に。


### `index.tx`

```
---
>     <form method="get" action="/">
>     <textarea name="seq" rows="4"><: $data || 'input sequence' :></textarea><br>
>     <input type="submit" value="submit" /></br>
```

- `<body>` の中身を、がさっと、テキストエリアの記載に差し替え。
	- `form` は、`action` を `/` にしといて、煩雑にならないコードに。例なので。
- テキストエリアには、デフォルト値 'input sequence' と、結果の戻り値が収められる、 $data をセット。
	- `<:    :>` が `Kolon` の記載方法。この場合は変数の展開。
		- `||` は perl と同じく `or`

### perl コード部分

このケースだと get で十分なので、 `get '/' ` のまま。

```
---
>     my $data ;
>     my $seq = $c->req->param('seq') || '';
>     {
>         last if $seq =~ /[^ACGTN\r\n]/i ;
>         $seq =~ s/[\r\n]//g ;
>         ( $data = reverse $seq ) =~ tr/ACGTacgt/TGCAtgca/ ;
>     }
>     return $c->render('index.tx', { data => $data });
```

- `$c->req->param('seq')` で戻り値を `$seq` にセット。
	- 戻り値が塩基配列でなければ、`$data` には何もセットされない。
	- 塩基配列だったら、 reverseq-complement して、`$data` にセット。
- テンプレート側の変数 `data` に perl 側の `$data` をセットするために、リファレンスを渡す。




## app.psgi
今回の app.psgi の全コード。
非常に単純

```app.psgi#3
use strict;
use warnings;
use Amon2::Lite;

sub load_config {
    +{
        'Text::Xslate' => +{
            syntax => 'Kolon',
            suffix => '.tx',
            module => undef,
            cache  => 0,
        },
    }
}

get '/' => sub {
my $c = shift;
     my $data ;
     my $seq = $c->req->param('seq') || '';
     {
         last if $seq =~ /[^ACGTN\r\n]/i ;
         $seq =~ s/[\r\n]//g ;
         ( $data = reverse $seq ) =~ tr/ACGTacgt/TGCAtgca/ ;
     }
     return $c->render('index.tx', { data => $data });
};

__PACKAGE__->to_app(handle_static => 1);

__DATA__

@@ index.tx
<!doctype html>
<html>
<body>
     <form method="get" action="/">
     <textarea name="seq" rows="4"><: $data || 'input sequence' :></textarea><br>
     <input type="submit" value="submit" /></br>
</body>
</html>

```


ブラウザをリロード[^1]すると、塩基配列を受け取るフォームが表われる。後は、塩基を投げるだけ。



[^1]: `plackup -r` してる前提。
Amon2::Lite おさらい 1. Plack, Amon2 のインストールと起動の確認


なんか、久々に `Amon2::Lite` 使ったので、おさらい。
「イントラで、コマンドラインを使えない人に対して、 `bl2seq` サービスを提供する。」ってのを題材に、ざっと書く。

- port 5000 を使うので、そこを塞いでる人は開ける。

##### 一応クリーン環境作成。

`plenv` 環境下。

```
$ export PERL5OPT=        # 自己都合
$ plenv install 5.18.4
$ plenv shell 5.18.4
$ plenv install-cpanm
```
- 以下、環境によっては、 `sudo` が必要

## インストール

### `Plack`

前から一発だったっけか？

```
$ cpanm Task::Plack
```

- 別環境の 5.22.0 では、 Corona が入らなかった。

### `Amon2`

```
$ cpanm Amon2 Amon2::Lite
```

`Amon2::Basic` とかでは `carton` 使うのがスタンダードっぽいけど、今回はいらない。

以上でインストール終了。

## 起動確認

### ガワ作成

```
$ amon2-setup.pl --flavor=Lite Example
```

ガワの中身

```
$ cd Example
$ tree          # 本物の tree コマンドじゃないよ。
/PATH/TO/Example/
+--.git/
   (omitted)
+--.gitignore
+--app.psgi
+--Makefile.PL
+--t/
   +--01_root.t
   +--Util.pm
+--xt/
   +--03_pod.t
```

- [tree もどき](http://qiita.com/bunzaemon/items/ab8eedae6a1e380c9859#tree-%E3%82%82%E3%81%A9%E3%81%8D)

### 起動

```
$ plackup -r
```

http://0:5000/

にアクセスして動いてるの確認[^1]。
[^1]: chrome だとダメ。素直に IP か `localhost:5000`

### `Kolon` の有効化と整理

`Lite` では、テンプレートが `Kolon` じゃない。
`Kolon` を使うように、`app.psgi` を編集。

```app.psgi#1
use strict;
use warnings;
use Amon2::Lite;

sub load_config {
    +{
        'Text::Xslate' => +{
            syntax => 'Kolon',
            suffix => '.tx',
            module => undef,
            cache  => 0,
        },
    }
}

get '/' => sub {
    my $c = shift;
    return $c->render('index.tx');
};

__PACKAGE__->to_app(handle_static => 1);

__DATA__

@@ index.tx
<!doctype html>
<html>
<body>
    <header><h1>Example</h1></header>
        This is a Example
    <footer>Powered by <a href="http://amon.64p.org/">Amon2::Lite</a></footer>
</body>
</html>

```

* 元の app.psgi から今回使わない部分を、がっさり削除。
*  `load_config` のデータベースの設定部分を削除して、 `Kolon` を指定するコードに差し替え。
* 拡張子を `.tx` にしたので、その他の `.tt` を全て `.tx` に変更
* `cache` は 0 にしとかないと、テンプレートを弄るときにキャッシュを読んでしまって混乱するので、 **必ず** 0 に[^2]。
	* 運用では、 2 にするらしい。

差し替え後に、ブラウザをリロードして動いてるのを確認。
削ったコードは、必要になったら、復活させて行けばいい。

[^2]: 改変した foo.tx をカスケードして、キャッシュされた bar.tx で読み込んだりして、混乱するのを避ける為。