OmniAICreator/Qiita-1.07M huggingface dataset:
Excelファイル内の全シートをCSV保存するPerlスクリプト

指定されたExcelファイル（.xls、.xlst）、または指定されたディレクトリ内のExcelファイルを、1シート1ファイルでCSV保存するスクリプトです。ExcelのインストールされたWindows環境でのみ動作します。

# usage

    perl excel2csv.pl [Excelファイル名] [...]

または

    perl excel2csv.pl [ディレクトリ名] [...]

# 実行結果

ファイル名の拡張子より前の部分をディレクトリ名としてディレクトリが作成され、各シートが`シート名.csv`のファイル名で保存されます。

    .\test.xls
      ↓
    .\test.xls
    .\test\Sheet1.csv
    .\test\Sheet2.csv
    .\test\Sheet3.csv

# スクリプト

[gist](https://gist.github.com/mtsukamoto/bf8006c38fef83240ca2)からも取得できます。

    #!perl
    # Written by Makio Tsukaoto (tsukamoto at gmail.com)
     
    use strict;
    use warnings;
    use File::Spec;
    use Win32::OLE;
    use Win32::OLE::Const 'Microsoft Excel';
    our $VERSION = "0.01";
     
    $| = 1;
     
    &usage unless (@ARGV);
     
    my @files = @ARGV;
    @files = grep { -f $_ } map { (-d $_) ? glob("$_/*") : ($_) } @files;
    @files = grep { /\.xlsm?$/i } @files;
    @files = map { File::Spec->rel2abs($_) } @files;
     
    &usage("Error: no xls/xlsm files found at " . join(', ', map {"'$_'"} @ARGV)) unless (@files);
    printf("%d books found.\n", scalar(@files));
     
    printf qq(launching "Excel.Application"\r);
    my $excel_launched = 0;
    my $excel = Win32::OLE->GetActiveObject('Excel.Application');
    unless ($excel) {
        $excel = Win32::OLE->new('Excel.Application', 'Quit');
        $excel_launched = 1;
    }
    print qq(launching "Excel.Application" ... done.\n);
     
    foreach my $file (@files) {
        my $rel = File::Spec->abs2rel($file);
        print qq(opening "$rel"\r);
        my $book = $excel->Workbooks->Open($file); 
        $excel->{DisplayAlerts} = 'False';
        print qq(opening "$rel ... done"\n);
     
        my $dir = $file;
        $dir =~ s/\.[^\.\\\/]+$//;
        mkdir($dir) unless (-d $dir);
        my $count = $book->Worksheets->{Count};
        foreach my $i (1..$count) {
            my $sheet = $book->Worksheets($i);
            my $csv   = sprintf("%s/%s.csv", $dir, $sheet->{Name});
            my $rel   = File::Spec->abs2rel($csv);
            print qq( -> saving "$rel"\r);
            $sheet->SaveAs($csv, xlCSV);
            print qq( -> saving "$rel" ... done.\n);
        }
     
        print qq( -> close "$rel"\r);
        $book->Close;
        print qq( -> close "$rel" ... done.\n);
    }
     
    if ($excel_launched) {
        printf qq(quiting "Excel.Application"\r);
        $excel->Quit();
        printf qq(quiting "Excel.Application" ... done.\n);
    }
     
    exit(0);
     
    sub usage {
        my @messages = @_;
        foreach my $message (@messages) {
            $message =~ s/\s*$/\n/s;
            print $message if ($message =~ /\S/);
        }
        print "usage: excel2csv.pl [FILE or DIRECTORY] [FILE2 or DIRECTORY2] [...]\n";
        exit(1);
    }
knife-ec2を使ってインスタンスを作成しようとしてハマった問題の共有 (2015-6-30)

2015-6-30時点におけるknife-ec2(master)には多少問題があります。

knife-ec2はfogの`~> 1.25.0`に依存してます。
fogは`v1.25`からモジュールが細分化されてfog-coreとfog-ほげほげという各サブモジュールに分かれました。
最近のfogでawsを触る時にはfog-awsというgemが利用されます。
しかし、fogの`v1.25`時点ではfog-awsはまだ分割されておらず依存関係に含まれていません。
fogの`v1.27`時点ではfog-awsへの依存関係が定義されています。

一方でfog(fog-coreではない)の`v1.25`はfog-coreのバージョン指定が緩いため、fog-coreの最新版が入ります。
fog-coreの最新版は2015-6-30時点において`v1.31`です。

結果、knife-ec2はfogの`~> 1.25.x`に依存しているのですが、fog-coreは最新版が入りかつ、fog-awsが入らないという状態になり、非常に歪なバージョン同士で運用が行われることになります。
これでも大体は上手く動くのですが、EIPを指定して起動しようとするとIPが見つからなくてこけたり、warningが大量に出たりします。
fog-awsは普通にインストールできるので、Gemfileにfog-awsを追記して手動で突っ込めば、概ね問題なく動くようです。

gemとしてリリースされてるknife-ec2は更に古いfog-1.23に依存しているので、こっちでやれば上手く動くかもしれませんが、こっちはこっちでwarningが一杯出ます。(ruby-2.2だからかな)

というわけでbundlerでmasterのknife-ec2を入れてる人は注意した方が良さそうです。
chefのorgスペースの中にあるというのにバージョン指定が適当で困る。
AFNetwokingで複数ファイルアップロードでハマった時の対処法


## 問題
AFNetworkingを使用して、画像を8ファイルアップロードする処理を実行したところ、なぜか7ファイル目から下記のエラーが発生してアップロードに失敗する。

```
"リクエスト・ボディ・ストリームがなくなりました"
```

## 対処法
GitHubのIssueに対応方法がアップされていました。 
https://github.com/AFNetworking/AFNetworking/issues/1713  
どうやら、AFURLConnectionOperationのカテゴリを作成して、下記のメソッドを追加すればOK。

```objectivec:AFURLConnectionOperation+AFURLConnectionOperationFix
@interface AFURLConnectionOperation (AFURLConnectionOperationFix)
@end

@implementation AFURLConnectionOperation (AFURLConnectionOperationFix)

- (NSInputStream *)connection:(NSURLConnection __unused *)connection needNewBodyStream:(NSURLRequest *)request {
    if ([request.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) {
        return [request.HTTPBodyStream copy];
    }
    return nil;
}

@end
```

見て分かる通り、HTTPBodyStreamをcopyしているのがわかります。 
これで無事アップロードされることが確認できました。
多数のホストの root 権限を安全に共有する

# root 権限共有の悩み

チームメンバーに対する root 権限の付与は、今のところ、不本意ながらパスワード共有式となっています。

個人情報流出事件等のあおりを受け、定期的に共有パスワードを変更するポリシーで運用されてはいます。しかし、管理しているホストが多いのでメンテナンスコストもばかにならないし、作業効率も利便性も良くない。なにより、メンバーの入れ替わりはパスワード変更時期とは無関係に発生するので、安全面でも問題があります。

なんかいい方法はないものだろうかと探してみると、「これは！」と思うものを見つけました。

[Sharing Admin Privileges for Many Hosts Securely](http://www.linuxjournal.com/content/sharing-admin-privileges-many-hosts-securely?page=0,0)

詳しくは原文に当たってもらうとして、ここではかいつまんで仕組みと注意点をまとめます。

# 実現できること

主に管理者サイドからの視点として、

- チームメンバーの増減が発生しても、多数のホストのアカウント修正は不要
- 各ホストの鍵の更新・削除は不要
- 個々のメンバーの鍵のメンテナンスは不要（各自が責任を持つ）
- 特別な権限管理ツールの導入は不要
- パスワードやパスフレーズの共有は不要（原則として）

といったところが実現できます。特に重要なのは、最後のところです。では、どうやって実現しているのか？

# 基本的な仕組み

全メンバーのアカウントを集中管理するホストが一つ必要です。ここでは仮に darter とします。darter には univ アカウントを用意し、このアカウントの公開鍵を、管理対象となるホスト群の ~root/.ssh/authorized_keys にあらかじめ追加しておきます。

チームメンバーは darter にログインしたあと、`sudo su - univ` して、管理すべき他のホストに ssh します。univ に su できるかどうかは、/etc/sudoers で制御します。

# どこが安全なの？

univ アカウントの秘密鍵はパスフレーズで暗号化しておきます。このパスフレーズは、長くて簡単には推測できない強固なものであり、チームメンバーの中でもコアな管理者である Joe が最初に設定しておく必要があります。

しかし、このままではチームメンバーが ssh するたびにパスフレーズを求められてしまいます。

そこで、ssh-agent が登場します。

まず、以下のように `sudo su - univ` した時に ssh-agent のインスタンスをチェックし、動いていれば再利用、動いていなければ自動起動するようしておきます。

```bash:~univ/.bash_profile
/usr/bin/pgrep -u univ 'ssh-agent' >/dev/null

RESULT=$?

if [[ $RESULT -eq 0 ]]  # ssh-agent is running
then
    if [[ -f /tmp/.env_ssh.univ ]]   # bring env in to session
    then
        source /tmp/.env_ssh.univ
    else    # error condition
        echo 'WARNING:  univ ssh agent running, no environment file found'
        echo '          ssh-agent being killed and restarted ... '
        /usr/bin/pkill -u univ 'ssh-agent' >/dev/null
        RESULT=1     # due to kill, execute startup code below
    fi

if [[ $RESULT -ne 0 ]] # ssh-agent not running, start it from scratch
then
    echo "WARNING:  ssh-agent being started now; ask Joe to cache key"
    /usr/bin/ssh-agent > /tmp/.env_ssh.univ
    /bin/chmod 600 /tmp/.env_ssh.univ
    source /tmp/.env_ssh.univ
fi
```

darter が起動すると Joe はおもむろにログインし、周りに誰もいないことを確認した上で以下のコマンドを打ち込みます。

```
$ sudo su - univ
$ ssh-add ~/.ssh/univ_key
Enter passphrase for /home/univ/.ssh/univ_key:
```

これでパスフレーズがキャッシュされました。

Joe は「準備完了」とつぶやき、これ以降ログインするチームメンバーは、管理対象のホストに軽々と ssh することができるようになるわけです。

# 良いところ

繰り返しになりますが、以下のようなメリットは評価できます。

- 全メンバーでパスワードを共有しなくて良い
- メンバー離脱できちんと権限を剥奪できる
- おおげさなツールが不要（sudo と ssh だけ）
- メンテナンス対象のホストは一つだけ（管理対象ホストが増えると、authorized_keys の更新は必要）
- ユーザー追加で権限のグルーピングが容易（univ は全ホスト管理可能、rstr はホスト限定などいくらでも）
- たとえ univ の秘密鍵が盗まれたとしても、パスフレーズを盗まれなければ安全

# 注意点

一方で、多くの人が気づいているであろう注意点も挙げておきます。

- darter は SPOF になる
- darter の root を乗っ取られると壊滅状態
- darter の再起動がプレッシャーになる
- Joe の不在（休暇・転職・入院・急死等）に備え、パスフレーズの共有は不可避（限定的にせよ）
- パスフレーズを知るメンバーの離脱タイミングでパスフレーズの変更が必要

元記事のコメント欄では、チームメンバーが管理対象ホストの authorized_keys を書き換え可能だからこれではダメだ、と書いた人がいましたが、そもそも~~の発端は root 権限を安全に共有しようという話~~ darter を必ず経由する必要があるという前提なので、ピントがずれてる気がします。

というわけで、以下のような課題が浮かび上がります。

- darter の可用性・耐障害性・冗長性確保
- Joe をはじめとするコア管理メンバー間のパスフレーズ共有手段
- 悪意を持ったメンバーの検出（いやな仕事だ。。。）

なかなか、一筋縄ではいかないですね。
gitwatch > commit message > fix / fixing 

https://github.com/Itseez/opencv/commits/master?author=StevenPuttemans

同じ人のコミットメッセージで以下のような違う書き方をしているのを見た

> fixing SVM negative value rounding …
> fix formula getGaussianKernel in docs

gitのコミットメッセージでは「命令形」で書くという考えがあるが、この人の場合、それで書いていたと思いきや、fixingがある。

fixingで作業中という意味を持たせたいのだろうか?

adding/added/add などのコミットメッセージもある。
shell スクリプト二重起動防止


特に説明する部分でもないですが、cron等の繰り返し設定で２重に起動しないようにするbashです。該当シェルスクリプトの先頭に追加しておくと便利

```bash
# 二重起動防止
_process=`basename $0`

_pcnt=`pgrep -fo ${_process} | wc -l`

if [ ${_pcnt} -gt 1 ]; then
  echo "This script has been running now. proc : ${_pcnt}"
  exit 1
fi
```
お名前.comでドメインを取得してConoHaで公開するまで

#はじめに

先日初めて[ブログ](http://www.se2programmer.com/)をインターネット上に公開しました。

その際、URLにドメインからWebページを見れるようにするのに苦労したので、詰まった点を中心に書いていきます。

#お名前.comでドメインを取得

[お名前.com](http://www.onamae.com/)
で好きなドメインを取ってください。
画面に従えばできるはず

#ConoHaでサーバを借りる

[ConoHaのサイト](https://www.conoha.jp/)から好きなサーバををレンタルして、WordPress付のLinuxをインストールしください。
そして、httpの通信を許可しておいてください
ここまでは問題ないと思います。
グローバルIPを利用してサーバに接続できることは確認しておいてください。

#ConoHaコントロールパネルの設定

1．サーバ⇒ネームタグをクリックし、
ネットワーク情報でIPアドレスを確認しておきます。

2．DNSにお名前.comで取得したドメインを追加し、先ほどのIPアドレスをタイプAで設定します。
![1-4.png](https://qiita-image-store.s3.amazonaws.com/0/71215/b4897777-301c-dd2f-3899-f076fa135d7d.png)


NSの値は後で使うので控えておくとよいでしょう。

ここまでの設定では不十分で、ドメインでサーバに接続しようと試みても、以下のようにお名前.comのページに繋がってしまいます。

![1-3.png](https://qiita-image-store.s3.amazonaws.com/0/71215/9944f3a3-3a43-4d34-bc1b-9c79c036a8f9.png)


#ドメインNaviの設定
上記までの設定ではまだドメインは利用できません。
[ドメインNavi](https://www.onamae.com/navi/domain.html)での設定が必要です。

ネームサーバーの設定⇒ネームサーバーの変更から他のネームサーバーを利用を選択します。
ネームサーバーに先ほどConoHaのコントロールパネルで確認したNSの値を入力してください。
![1-5.png](https://qiita-image-store.s3.amazonaws.com/0/71215/03199584-896a-8991-7ccb-a2ef1a183f6a.png)

変更を確定させれば、全ての設定は完了です。

１～３日でドメインが利用できるようになるそうです。
(私の場合は3時間ほどでした。)

ブラウザに、http://se2programmer.com
のようにドメインを入力して、Webサーバーに接続できれば成功です。

#結論

DNSの設定はお名前.comのドメインNaviとConoHaコントロールパネルの両方で必要。
皆さんも気を付けてください。
Jenkins でシェルスクリプトの実行ユーザを指定

Jenkins でシェルスクリプトを実行する際のユーザは jenkins アカウントですが、
他のユーザで実行したい場合も多々あると思います。
(この場合、jenkins のサーバとシェルスクリプトは同じホストですよね)

ググったら visudo コマンドを使って sudo コマンドを使うというものが多かったのですが、私的には以下の方法を思いついたので紹介まで。

その方法は...

**[ssh プラグイン](https://wiki.jenkins-ci.org/display/JENKINS/SSH+plugin)を使って(リモートホストとして)シェル実行**

です。

スミマセン、、、ただそれだけです。

ssh プラグインではユーザ名の指定はもちろんの事、パスワード or キーファイルも選べるので問題なく使えると思います。
![alt](https://wiki.jenkins-ci.org/download/attachments/42470275/ssh-global-cfg.png?version=1&modificationDate=1267072997000)

これだと jenkins の世界だけで済んでいるのでメンテも楽だと思います。

***

参考:

Jenkinsでsudoが必要な場合
http://qiita.com/ykirishima/items/2f32dae7fa28a2b45801

Jenkinsでシェルスクリプトを他のユーザとして実行
http://qiita.com/tmtysk/items/37c8c58cd59f834b1939
PHPで深さ優先探索を用いて迷路問題を解く

#PHPで深さ優先探索を用いて迷路問題を解く

##問題
S地点からG地点にたどり着くかどうか検証せよ
但し、0は進め、Xは進めないとする。
たどりついた場合はtrueを失敗した場合はfalseを返せ
迷路はCSVファイルから読み取る

##コード
```csv:maze.csv
0,0,S,0,X,0
0,G,X,0,0,0
X,0,0,X,0,0
X,X,0,0,0,X
```

```php:Maze.php
/*
迷路クラス
 深さ探索法で迷路を解く
 */

Class Maze{
    public $maze;    //迷路の配列
    public $reached; //探索した地点を記録する配列
    public $isGoal;  //ゴールできたらtrue
    const MAX_W = 6; //x軸方向の幅
    const MAX_H = 4; //y軸方向の幅

    public function __construct($filePath) {
        $this->maze    = self::createMazeFromCSV($filePath);
        $this->reached = array();
        $this->isGoal  = false;
    }

    //迷路のcsvファイルを読み取って、迷路の配列を作成する
    public function createMazeFromCSV($filePath) {
        $maze = array();

        $data  = file_get_contents($filePath);
        $lines = explode("\r\n", $data);
        foreach ($lines as $line) {
            $maze[] = explode(",",$line);
        }
        return $maze;
    }

    public function search($row, $col) {
        //Goalしていたらスキップする。
        if ($this->isGoal) {
            return true;
        }
        //迷路の外側か壁の場合は何もしない
        if ($row < 0 || self::MAX_H <= $row || $col < 0 || self::MAX_W <= $col || $this->maze[$row][$col] == 'X') {
            return false;
        }
        //既に到達している場合は何もしない
        if (isset($this->reached[$row][$col]) && $this->reached[$row][$col] == true) {
            return false ;
        }

        //今いる地点にチェックしたことを記録する
        $this->reached[$row][$col] = true;

        if ($this->maze[$row][$col] == 'G') {
            //exit('ゴール');
            $this->isGoal = true;
            //echo'<pre>';
            //var_dump($this->reached);
            //echo '</pre>';
            return true;
        }

        self::search($row, $col + 1); //右に進む
        //var_dump('実行した？');
        self::search($row, $col - 1); //左に進む
        //var_dump('実行した？');
         self::search($row + 1, $col); //上に進む
        //var_dump('実行した？');
        self::search($row - 1, $col); //下に進む

        //最終結果
        if ($this->isGoal) {
            return true;
        } else {
            return false;
        }
    }
}
```

```php:mazeTest.php
/* 
深さ優先探索で迷路を解く
問題はS地点からG地点にたどり着くかどうか検証せよ
但し、0は進め、Xは進めないとする。
たどりついた場合はtrueを失敗した場合はfalseを返せ
 */

require_once './part/Maze.php';

$maze = new Maze('../file/maze.csv');
//S地点を引数にセットする
var_dump($maze->search(0, 2));


```

##参考サイト (チョー分かりやすい)
http://www.slideshare.net/chokudai/dfs-49066641

##参考書籍
最強最速アルゴリズマー養成講座 プログラミングコンテストTopCoder攻略ガイド
Goのfor rangeで思った値が取れなかった話


GoでArrayやSliceの各要素に対して、何かしようとするときに`for range`を使いますよね

例えばこんな感じ

```go
words := []string{"hoge", "fuga", "foo", "bar"}

for word := range words {
	// do something
}
```

でも、これだと`word`には、`hoge`やら`fuga`が入らず数値が入ってくる。

```go
for word := range words {
	fmt.Println(word)
}
```

```bash
> go run main.go
0
1
2
3
```

なぜかと言うと、これ`word`にはインデックス値が入ってきているから。
要素の値を取りたければ、rangeの左辺に変数を２つ置けばOK

```go
for _, word := range words {
	fmt.Println(word)
}
```
```bash
> go run main.go                                                                                                                  
hoge
fuga
foo
bar
```

冷静に考えれば当たり前のことなんですが、左辺に変数が１つだけでもコンパイル時にエラーにならないから、気付きづらい。他の言語で言うところのforeach感覚で書いてると良くやってしまう。

で、なぜこうなるかというと、`range`が返す2番目の値はオプショナルだから。

さらに言うと、1番目と2番目それぞれに入ってくる値がそれぞれ何なのかは、`range`の対象が何か？で変わってくるので要注意です。

詳しくはgithubのwiki、[Range#Reference](https://github.com/golang/go/wiki/Range#reference)を見ると良いと思います。

オプショナルだからとか言わず、いっそコンパイルで警告してくれたらなーとか、個人的には思ったりしたんですが、慣れの問題なんでしょうね。気をつけよう。
48時間でSchemeを書こう/構文解析2

# 参考URL
[48時間でSchemeを書こう/構文解析](https://ja.wikibooks.org/wiki/48%E6%99%82%E9%96%93%E3%81%A7Scheme%E3%82%92%E6%9B%B8%E3%81%93%E3%81%86/%E6%A7%8B%E6%96%87%E8%A7%A3%E6%9E%90)

#ソース
https://github.com/0zawa/scheme_in_48_hours/blob/master/parsing.hs

# spaceの除去
入力文字列に含まれた余計なスペースを除去するための関数を作ります。

```hs
spaces :: Parser ()
spaces = skipMany1 space
```

型をみるとParser ()になっているので、
この関数はパース結果は返しません。

space関数は入力文字列の先頭がスペースなら
それをパースする関数です。

```hs
> parse space "space_test" " 1"
Right ' '

> parse space "space_test" "1"
Left "space_test" (line 1, column 1):
unexpected "1"
expecting space
```

skipMany1は引数に渡すパーサ関数がパースに成功する限り
パースを継続し、パース結果は破棄する関数です。

なので

```hs
skipMany1 space
```

と組み合わせると
入力文字列の先頭にある１個以上のスペースを
全て取り除くパース関数になります。

更にこれとsymbolを組み合わせてparse関数に渡すと、

```hs
> parse (spaces >> symbol) "test" "    #"
Right '#'
```

入力文字列の最初の連続した空白を全て取り除き、
その次の文字をsymbolで指定した文字列でパースすることになります。

ただしspacesは１文字以上のスペースを取り除くパース関数なので、
空白が含まれない場合はエラーになります。

```hs
> parse (spaces >> symbol) "test" "#"
Left "test" (line 1, column 1):
unexpected "#"
expecting space
```


[48時間でSchemeを書こう/構文解析3](http://qiita.com/0zawa/items/f3d799a5a5fc6b5cc6f9)へ
headerでリダイレクトしない時に、真っ先に疑うべきところ

#headerでハマった
headerで指定したページになぜかリダイレクトしない。
ページは真っ白だし、エラーも吐かない。

`exit();`を入れるとか、
`header`の前に`print`とかで出力しないとか、
お約束は守ったよ…？

そんな時は、以下のようになってないか、まず確認するべき。

#気をつけよう

**OK** :  `header('location: hoge.php');`
**NG** :  `header('location : hoge.php');`

違いがお分かりいただけただろうか。
`location`　と　`:`の間には、スペースを入れてはいけないということらしい。
`location:`と書きましょう。


小ネタでした。
CodeIgniter + PHPExcel 備忘録

CodeIgniter + PHPExcel 備忘録

PHPExcelとPHPExcel.php は /application/libraries/配下に配置。

```
/application/libraries/PHPExcel
/application/libraries/PHPExcel.php
```

あとはこんな感じで利用できる。

```php
require_once 'application/libraries/PHPExcel.php';
require_once 'application/libraries/PHPExcel/IOFactory.php';

$objPHPExcel = new PHPExcel();
$objPHPExcel = PHPExcel_IOFactory::load($file);

$data = array();
$cells = $objPHPExcel->getActiveSheet()->getCellCollection();
foreach ($cells as $cell) {
    $col = $objPHPExcel->getActiveSheet()->getCell($cell)->getColumn();
    $row = $objPHPExcel->getActiveSheet()->getCell($cell)->getRow();
    $val = $objPHPExcel->getActiveSheet()->getCell($cell)->getValue();
    $data[$row][$col] = $val;
}
```
javascriptでviewのデータを使いたい時のやり方 

サイト上のナビゲーションのA/Bテストを実施し、その効果としてどのくらいクリックされるのに差が出るのかというのをやりたかったときに調べたのでメモとして残します。

####view内
クリックした時にデータを渡したかったのでviewでは以下のように記述しました。
対象となる箇所にクラスをもたせます。"js-名"というように宣言することでjs内でクラス指定のもと使用することができます。一応インクルードするところも含めておきました、要らないとは思いますが。。。レファレンスも一応載せておきます。http://railsdoc.com/references/javascript_include_tag

```
<%= javascript_include_tag('hoge') %>
・
・
・
<div class="js-link" data-url-name="hoge">
  <%= link_to 'HOGE', hoge_path %>
</div>
<div class="js-link" data-url-name="hogehoge">
  <%= link_to 'HOGEHOGE', hoge_hoge_path %>
</div>
```

####javascript内
A/Bテストを行いたかったので「指定先のurlにデータurlをpostする」という余計なものまでくっついていますがそこは大目にみてください。
さきほどview内で"js-"とクラスで指定したものをここで使用します。そのクラスの中のdataで指定した文字列を呼び出しています。

```
$(function() {
  $(".js-link").on("click",function(){
      var urlName = $(this).data("url-name");
      $.post("送信先url", { 
　　　　　　'url': '/mobile/'+ urlName
　　　 });
  });
});
```

ここで2つのリンク先をひとつのクリック処理にまとめています。クリックした時にそのクリックしたデータを取得したいので"this"を使用しました。こいつの存在を知らなかった笑。こちらがまとまっていると思います。
http://qiita.com/vvakame/items/74005adacc0e8e2a3cab

まあこんなものを使用しながら対応しました。

ちなみにview内で

```
<div class="js-link" data-url-name="hoge" data-user-id="<%= @login_user.id %>">
  <%= link_to 'HOGE', hoge_path %>
</div>
```
のようにrubyを持たせることもできるみたいです。あともう一点、書き方ですがjavascript内でのデータの受け方で

```
var urlName = this.dataset.urlName;
```
っていう書き方もできるっぽいです。これらに関しては未だ調べ中です。。。
【AngularJS】テンプレート（.html）を1ファイルにまとめたい！ - gulp ver.

元記事: [【AngularJS】テンプレート（.html）を1ファイルにまとめたい！][qiita-grunt-angular-template]

# gulp-angular-templatecache

~~grunt~~ gulpでJSやCSSをビルドするとき，

- ひとつにまとめて（`concat`, `browserify`）
- ちっちゃくして（`uglify`，`cssmin`, `htmlmin`）

少しでもページの読み込みを軽くしようとします，が…．
AngularJSで`Directive`や`ng-include`する用のテンプレートファイル（.htmlファイル）はどうしたらいいの？( ﾟдﾟ)

- 「jsファイルにHTMLをつらつら書いていくのはﾁｮｯﾄ…」
- 「かと言ってバラバラのままだとリクエストが増えて重くなる…」

そんな時に便利なのが[**gulp-angular-templatecache**][gulp-angular-templatecache]です．

```text
.
├── app
│   └── assets
│       ├── javascripts
│       └── templates
│           ├── hoge.html
│           └── fuga.html
```

みたいな大量のテンプレートファイルを

```javascript
angular.module('myApp').run(["$templateCache", function($templateCache) {
  $templateCache.put("hoge.html",
    // hoge.htmlのなかみ
  );
  ...
  $templateCache.put("piyo.html",
    // piyo.htmlのなかみ
  );
}]);
```

のようにイイカンジのJSにまとめてくれます（これをふつうに読みこめばOK）

## つかいかた

### ふつうのつかいかた

```javascript:gruntfile.babel.js
import templateCache from "gulp-angular-templatecache";
 
gulp.task("build:templates", () => {
  return gulp.src('app/templates/**/*.html')
    .pipe(templateCache({module: "myApp"}))
    .pipe(gulp.dest("dist"));
});
```

基本は上のような感じ．注意点は「`templateCache`のmoduleオプションは自分のangularアプリのモジュール名にする」ことです．
`app/javascripts/constants.js`に定義しておいてimportしてくると綺麗ですね．

```javascript
export const appName = "myApp";
```


```javascript
import {appName} from "./app/javascripts/constants";
```

---

### minifyしたい！
何もせずともminify済みのが出てきます．

---

### ファイルパスと`templateUrl`を別にしたい！
たとえば，`app/assets/templates`以下のHTMLファイルを`templates/**.html`というURLで扱いたい場合，下記のいずれかのオプションを追加すればOK.

* `prefix: "templates"`
* `base: "app/assets"`

---

ほかにもいろんなオプションがあるみたいですが，僕が使うのはコレぐらいです．

サクサク動くアプリを~~Grunt~~ Gulpでイイ感じに自動化しながらつくろう！
これでみんなもモテモテだ！！！！！ *[要出典]*

## 参考

* [**gulp-angular-templatecache**][gulp-angular-templatecache]
* [【AngularJS】テンプレート（.html）を1ファイルにまとめたい！][qiita-grunt-angular-template]

[gulp-angular-templatecache]: https://www.npmjs.com/package/gulp-angular-templatecache
[qiita-grunt-angular-template]: http://qiita.com/izumin5210/items/6489476c650c022e402a
[Phoenix]Ectoを使って再マイグレーションする

#目的
Ectoで再マイグレーションを実施する。

#実行環境
OS： Windows8.1
Erlang： Eshell V6.4, OTP-Version 17.5
Elixir： v1.0.4
Phoenix Framework： v0.13.1
PostgreSQL： postgres (PostgreSQL) 9.4.4

#始める前に
私が行ったプロジェクト作成を書いておきます。

```cmd
>cd プロジェクト作成ディレクトリ
>mix phoenix.new ecto_models_sample
>cd ecto_models_sample
>mix phoenix.server
>ctrl+c
>mix phoenix.gen.html User users name:string email:string
ルーティングの追加
>mix ecto.create
>mix ecto.migrate
```

準備良し。
以降、この記事でのプロジェクトと言えば、
`ecto_models_sample`を指し示す。

マイグレーションして生成したテーブルにカラムの追加/削除を行います。
今回は、usersテーブルに対してageの項目を追加/削除してみる。

現在のDBの状態。
![re_migration001.png](https://qiita-image-store.s3.amazonaws.com/0/80934/1dad15c3-2e45-c92a-f531-c5fdc5341b9c.png)

#目次
1. カラム追加
2. カラム削除
3. まとめ

##1. カラム追加
ectoのコマンドを使ってマイグレーションファイルを生成します。
名称は、`処理_カラム名_to_テーブル名`とすると分かりやすいのではないでしょうか。

```cmd
>mix ecto.gen.migration add_age_to_users
* creating priv/repo/migrations
* creating priv/repo/migrations/20150630005902_add_age_to_users.exs
```

priv/repo/migrations/20150630005902_add_age_to_users.exsを
以下のように編集しました。

```ex
defmodule EctoModelsSample.Repo.Migrations.AddAgeToUsers do
  use Ecto.Migration

  def change do
    alter table(:users) do
      add :age, :integer
    end
  end
end
```

マイグレーションしてカラムを追加します。

```cmd
>mix ecto.migrate
[info] == Running EctoModelsSample.Repo.Migrations.AddAgeToUsers.change/0 forward
[info] alter table users
[info] == Migrated in 0.0s
```

DBのusersテーブルを確認してみて下さい。
![re_migration002.png](https://qiita-image-store.s3.amazonaws.com/0/80934/51ad8050-c49a-4e4c-21c2-46a81e072783.png)

##2. カラム削除
カラムを削除します。

```cmd
>mix ecto.gen.migration remove_age_to_users
* creating priv/repo/migrations
* creating priv/repo/migrations/20150630014132_remove_age_to_users.exs
```

作成されたファイルを以下のように編集します。

```elixir
defmodule EctoModelsSample.Repo.Migrations.RemoveAgeToUsers do
  use Ecto.Migration

  def change do
    alter table(:users) do
      remove :age
    end
  end
end
```

マイグレーションします。

```cmd
>mix ecto.migrate
[info] == Running EctoModelsSample.Repo.Migrations.RemoveAgeToUsers.change/0 forward
[info] alter table users
[info] == Migrated in 0.0s
```

これで削除完了です。
![re_migration001.png](https://qiita-image-store.s3.amazonaws.com/0/80934/ab210bd9-54e7-2344-a356-51ae00487b11.png)


##3. まとめ
難しくないですね。
他の処理もEctoのドキュメントを参照すれば大体問題ないと思います。

毎回こうすんなり終わると楽でいいのだが・・・

#参考文献
[Phoenix Framework - Guide Mix Tasks](http://www.phoenixframework.org/v0.13.1/docs/mix-tasks)
[hexdocs - Ecto.Migration](http://hexdocs.pm/ecto/)
.gitconfigのhttp設定のsslCAInfoはちゃんとサイト指定する

Goのクロスコンパイル環境を作っている時に、Gitで特定のリポジトリがclone出来なかった。

```bash
$ git clone https://go.googlesource.com/tools.git

fatal: unable to access 'https://go.googlesource.com/tools.git/': SSL: certificate verification failed (result: 5)
```

良くないけど、SSLの検証をオフって実行してもダメ。

```bash
$ GIT_SSL_NO_VERIFY=1 git clone https://go.googlesource.com/tools.git

fatal: unable to access 'https://go.googlesource.com/tools.git/': SSL: CA certificate set, but certificate verification is disabled
```

.gitconfigを確認すると、社内GitLab用にpemが指定されていた。

```:.gitconfig
[http]
	sslCAInfo=/path/to/gitlab.pem
```

公式サイトを見ると、サイトごとの指定が出来るらしい。指定しないと全てのサイトに効いてしまうことが想像されたので、明示的に指定した。

```:.gitconfig
[http "https://gitlab.intra.foo.bar"]
	sslCAInfo=/path/to/gitlab.pem
```

その結果、問題なくclone出来るようになった。

### 参考

http://git-scm.com/docs/git-config
Railsアンチパターン<テスト編>③rake taskや④gemのテスト

ソリューション:rakeタスクをアプリケーションコードにできないか考える
=
RakeTaskのテストはアプリーションコードをテストするようにはいかない。rubyコード内でシェルを叩いて実行することはできるが、

 - forkするプロセスのテストはむずいし、時間がかかる
 - 関連するfileのテスト中の扱いとかめんどくさい
 - 同じプロセスでないのでmockすらもできない
 - DBのコネクションも貼り直しなのでtransactionとか意味なくなる

という問題がある。一応、[やり方はある程度確立](https://robots.thoughtbot.com/test-rake-tasks-like-a-boss)されているみたいだけど。

解決法は今貼ったリンクの最初にも書いてるけど、クラス(メソッド)に切り出してアプリケーションコードにしてしまうこと。
これで、テストに特別なことが必要なくなる。

さて次はgemのテスト。
gemには特にテストを書くべきだ。それは動作説明書にもなるし、ちゃんとテストされてないgemはあんまり誰も使おうと思ってくれない。
しかしながらgemとRailsの結合度によってテスト難度は変わってくる。

ソリューション1: rails関係ないテストを書く
=
railsの機能を使用していないgemならこれでよい。Railsプロジェクトで使用されてるからと言ってRailsをテストで読み込む必要があるかは別の話なのでよく考えてみよう。

ソリューション2: railsの一部を読み込む
=
railsは幾つかのgemの集まりなので、あなたのgemがどの部分に依存しているかよく考えよう。active_recordしか使っていないのなら何もrails全部を読み込む必要はない。active_recordだけをrequireすればよい。

ソリューション3: テスト用の小さいrailsアプリケーションを丸ごと入れてしまう
=
これの実現方法が本意は詳しく解説されてるんだけど、現在はpluginを作成するコマンド(`@bin/rails plugin new`)を叩くと内部にdummy railsプロジェクトが作成されるので、これで良いと思う。

##結論:rakeタスクはなるべくアプリケーションコードに含めよう。rails plugingemのテストはデフォルトで作成されるdummy railsプロジェクトで行おう。
ATOM 1.0導入時のMenuの日本語化について

メニューの日本語化についてですが、ここ最近Localizationが使えなくなっており、代わりにjapanese-menuをプラグインとして使ってもらえればOKです。Atom1.0でもキチンと動くことを確認しました。

現場からは以上です。
シェルで動画や音楽ファイルのメタ情報を読み取る

#概要
iTunesやWindows Media Playerは気軽に曲のメタ情報を確認できるが、
GUIツールなのでコマンドラインでは見れない。
そんなときに、このツールが役に立つ

「mp4v2」は、M4AなどのMP4コンテナを解析し、
メタ情報を表示したりファイルとして抽出したりできる。
**※なので解析できるのはMP4系だけである**（それが少し残念）

##インストール方法

```bash:bash
$ wget https://mp4v2.googlecode.com/files/mp4v2-2.0.0.tar.bz2
$ bunzip2 mp4v2-2.0.0.tar.bz2
$ tar xvf mp4v2-2.0.0.tar
$ cd mp4v2-2.0.0
$ ./configure
$ make
$ sudo make install
```


##使用例
以下のコマンドで曲の情報が閲覧できる

```bash:bash
$ mp4info filename.m4a
```

曲名とファイル名が必ずしも一致しない場合などには便利

##補足
「mp4art」を使うと、M4A/M4Pファイルに収録されている画像ファイルを取り出せる。
「mp4tags」では、各種IDタグを登録することができる。
「mp4extract」を使えば、DRMのないM4Aファイルから楽曲データ(RAW AAC)を抽出できる。
docker buildのオプションまとめ

#docker build時のオプションまとめ

##対象のDockerバージョン

```lang:bash
[root@master cent_mount]# docker version
Client version: 1.6.2.el7
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): c3ca5bb/1.6.2
OS/Arch (client): linux/amd64
Server version: 1.6.2.el7
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): c3ca5bb/1.6.2
OS/Arch (server): linux/amd64
```

詳細は　man docker build　より

##-f, --file=PATH/Dockerfile
```lang:bash
Path to the Dockerfile to use. If the path is a relative path then it must be relative to the current directory. The file  must  be  within  the build context. The default is Dockerfile.
```

Dockerfileの格納パス。相対パス指定をした場合は、カレントディレクトリからの相対となる。ファイルはビルドコンテキストに内包される。

##--force-rm=true|false

```lang:vim
Always remove intermediate containers, even after unsuccessful builds. The default is false.
```

デフォルトはfalse。trueにするとビルド失敗後に、作成された中間コンテナを削除する。


##--no-cache=true|false
```lang:vim
Do not use cache when building the image. The default is false.
```

デフォルトはfalse。trueにするとbuild時にcacheを使用しない。
※docker build は通常imageを作成した時に、コマンドの結果をcacheに格納し、次回以降おなじbuildの同じコマンドが実行された場合には、cacheのデータを使用する。

※注意：yum updateなどのコマンドは、取得したタイミングのupdate内容がcacheに残っているため、cacheを利用すると最新ではない可能性がある


##--help
```lang:vim
Print usage statement
```

ヘルプ

##--pull=true|false
```lang:vim
Always attempt to pull a newer version of the image. The default is false.
```

デフォルトはfalse。trueにすると、dockerfile内のFROM句で指定したベースイメージの最新を毎回取得する。（base/latestを取得する）

##-q, --quiet=true|false
```lang:vim
Suppress the verbose output generated by the containers. The default is false.
```

デフォルトはfalse。trueにすると、コンテナで生成される冗長な出力を抑止する

##--rm=true|false
```lang:vim
Remove intermediate containers after a successful build. The default is true.
```

デフォルトはtrue。ビルド成功後中間コンテナを削除する

##-t, --tag=""
```lang:vim
Repository name (and optionally a tag) to be applied to the resulting image in case of success
```

ビルド成功後、作成されたメッセージにリポジトリ名（とオプションタグ）を付与する

##--cgroup-parent=""
```lang:vim
Path to cgroups under which the cgroup for the container will be created. If the path is not absolute, the path is considered to be relative to the cgroups path of the init process. Cgroups will be created if they do not already exist.
```

コンテナのcgroupsへのパスを指定します。指定されたパスが絶対パスでない場合は、initプロセスの cgroupsのパスからの相対パスと見なされます。cgroupsが存在しない場合は、作成されます。
また1歩僕がマウス離れになったキーボードショートカット2選

<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">トラックパッドから乗り換えテスト <a href="http://t.co/OgHhreWmRI">pic.twitter.com/OgHhreWmRI</a></p>&mdash; くろねこ (@laprasDrum) <a href="https://twitter.com/laprasDrum/status/596890184374951937">May 9, 2015</a></blockquote> 

確かに便利です。まだ完全には離れられそうにはありません。
しかし最近見つけたショートカットによってトラックボールをコロコロする時間が減ってしまったので共有します。

# ⌘ + Shift + ?
![HelpMenu](https://qiita-image-store.s3.amazonaws.com/0/7950/efe85f1d-23ad-348e-cd00-c720ada8c39d.png "Help Menu")

ヘルプメニューの検索ボックスにフォーカスします。
アプリによってはキーボードショートカットが割り当てられていない機能があるので、ここで検索するかメニューバーを移動しながら選択して実行しています。
加えて、ショートカットを忘れたときの確認にも利用しています。

# Control + Shift + 電源ボタン
ディスプレイをスリープさせます。離席が多い時に多用しています。
このショートカットを知るまでは Alfred から`sleep`を叩いたり、 Mission Control のホットコーナーに割り当ててマウスカーソルを動かしてました。
![HotCorner](https://qiita-image-store.s3.amazonaws.com/0/7950/4f51f721-b21b-c3f8-5516-1d75b093c191.png "Hot Corner")

ちなみに HHKB から電源ボタンのイベントを起こすには Fn + Esc でいけるそうです。(これも知らなかった)

[Happy Hacking Keyboard Professional / Professional2 / Type-S サポートFAQ](https://www.pfu.fujitsu.com/hhkeyboard/hhkb_support/faq_pro.html)

> Q2
> キーボードから電源のON、OFFはできますか？

> A2
> POWERキー(【Fn】+【Esc】)により、電源OFFが可能です。電源投入は本体の電源スイッチでお願いします。

# 便利ショートカット探し足りない
[公式ページ](https://support.apple.com/ja-jp/HT201236)を見ても載っていないものもあるので色々探してみます。
複数まとめてD&Dされたファイルやディレクトリをそれぞれ別の7zに圧縮するbatファイル

過去のプロジェクトのディレクトリとその中身のファイル群、もう使わないかもしれないけど残しておきたいってこと、ありますよね。
そういう場合って正直もう二度と使わないことのほうが大半だとは思うんですけど、それでも残しておきたい。
そんな時に使うbatファイルです。

動作するためにはこのバッチファイルと同じ場所に7zipのexeが必要です。
私はx64用コマンドライン版7zip 15.05 betaにて使用しています。

バグが出るほど難しいことはしていないので大丈夫だとは思いますが、このスクリプトを用いたことによるいかなるデータの損失も僕は補償しかねますので予めご了承ください。

```bat:archive.bat
@echo off

cd /d %~dp0

for %%f in (%*) do (
  7za.exe a -t7z -mx=9 %%f.7z %%f
  cls
  rmdir /s /q %%f
)
```

以下を参考にさせていただきました、ありがとうございます。

7zip Command Line Syntax
http://sevenzip.osdn.jp/chm/cmdline/syntax.htm

【Windows】バッチファイルのコマンドライン引数
http://qiita.com/bokkuri_orz/items/9c9c93fae56cc8653988

[Windows][バッチファイル]カレントディレクトリをバッチファイルのディレクトリにする
http://d.hatena.ne.jp/nakamura001/20090203/1233652705
Linuxにおける色々なユーザー管理コマンド

#概要
Linuxにおいて、よく使うであろうユーザー管理のコマンドをまとめてみました


##コマンド

```bash:bash
#通常のユーザー新規追加コマンド
$ useradd hogeuser
$ passwd hogeuser

#ログイン出来ないユーザーを新規に作成する
$ useradd -s /sbin/nologin hogeuser

#通常に作成した後、ログインできなくしてしまう
$ usermod -s /sbin/nologin hogeuser

#ログイン出来ないユーザーをログインできるようにする
$ usermod -s /bin/bash hogeuser

#ユーザーをグループに追加する
$ gpasswd -a hogeuser hogegroup

#ユーザーをグループから削除する
$ gpasswd -d hogeuser hogegroup
```

##それらの情報を確認する
```bash:bash
# ユーザーログインシェルの確認（ユーザーがログインできるかどうか）
$ cat /etc/passwd | grep hogeuser

# ユーザーがどのグループに所属しているか
$ id hogeuser
```
手軽にOAuth認証するリバースプロキシツールを作ってみた

## はじめに

作らなくても同じ機能のツールがあるので、利用される方はそちらと比較されるのが良いです。
Rubyistなので、Rubyで作ってみたかったというお話。

* [bitly/oauth2_proxy · GitHub](https://github.com/bitly/oauth2_proxy)
    * もとはgoogle_auth_proxy
* [typester/gate · GitHub](https://github.com/typester/gate)

## できること

* 認証機能のないアプリケーションでOAuth認証
* バックエンドに対してBasic認証できる点で[oauth2_proxy](https://github.com/bitly/google_auth_proxy)や[gate](https://github.com/typester/gate)と機能差異あり

## ツールの詳細

Sinatra + OmniAuth + RackReverseProxy のシンプルなアプリケーションです。

| | 説明 |
|:-----------|:------------|
| ツール名 | OMonban |
| ツール概要 | 手軽にOAuth認証するリバースプロキシツール |
| デモサイト | https://omonban.herokuapp.com/ |
| ソースコード | [arukoh/omonban · GitHub](https://github.com/arukoh/omonban) |
| アーキテクチャ、コンセプト | [oauth2_proxy](https://github.com/bitly/google_auth_proxy)や[gate](https://github.com/typester/gate)と同じなため詳細は割愛 |
| サポートしているOAuthプロバイダ | （現時点で） GitHub, Google, Facebook, Twitter |
Linuxショートカットキー

**移動系**
``Ctrl+b``：左方向へ移動
``Ctrl+f``：右方向へ移動
``Ctrl+p``：一つ前の履歴を見る
``Ctrl+n``：一つ後の履歴を見る
``Ctrl+a``：行頭に移動
``Ctrl+e``：行末に移動

**文字列削除**
``Ctrl+d``：カーソルの文字を削除
``Ctrl+h``：カーソルの一文字前を削除
``Ctrl+u``：行頭まで削除する
``Ctrl+k``：行末まで削除
``Ctrl+w``：ワード単位で行頭方向の文字列を削除
``Ctrl+c``：コマンド強制終了
``Ctrl+r``：コマンド履歴の検索 [Enter] コマンドを実行, [Esc]戻る
``Ctrl+l``：ターミナルのリセット

あと、macのアラートウィンドウで"保存しない"を選択したい場合は``command+d``
キャンセルする場合は``esc``を実行すればよし。
ちゃんとEager Loadingをした結果、逆に遅くなった件


背景
---

N+1を起こしている箇所があったので必要なデータをEager Loadingしてデプロイをした
その結果、逆にレスポンスが劣化した…

tl;dr
---

1:N のような関連の場合、eager_load(LEFT OUTER JOIN)した上で1の側にLIMITをかけると非常に遅いクエリが出来るケースがある

関連するモデル
---

Message/Attachmentの2つ
Messageは複数のAttachmentを持つ


```rb
class Message
  has_many :attachments
  scope :latest, -> { order(id: :desc) }
end  

class Attachment
  belongs_to :message
end
```

遅かったコード
---

```rb
Message.eager_load(:attachments).limit(5).latest
```

発行されていたSQL
---

SQLは2つ発行されいてた

### 対象となるMessage#idの抽出

```sql
SELECT
  DISTINCT `messages`.`id`
FROM `messages`
  LEFT OUTER JOIN `attachments`
    ON `attachments`.`message_id` = `messages`.`id`
ORDER BY
  `messages`.`id` DESC
LIMIT 5
```

### 実際に使うデータの読み出し

```sql
SELECT
  `messages`.*,
  `attachments`.*
FROM
  `messages`
  LEFT OUTER JOIN `attachments`
    ON `attachments`.`message_id` = `messages`.`id`
WHERE
  `message`.`id` IN(1, 2  3, 100, 100000)
ORDER BY `messages`.`id` DESC
```    

何が遅かったのか?
---

対象となるMessage#idの抽出の中にある**DISTINCT message.id** の部分

Message/AttachmentをJOINしているのでその結果は以下の表のような感じになる
このままではMessageに対してにLIMITはかけられない←Message#idの重複がある(1,2,2,5,5,5...)
そこで DISTINCT Message#id をして重複を除いた上でLIMITをかけることになる

| Message | Attachement |
| ------: | ----------: |
| 1       | 1           |
| 2       | 5           |
| 2       | 7           |
| 5       | 10          |
| 5       | 11          |
| 5       | 18          |
| 6       | 22          |
| 6       | 23          |


手元のデータ量では全く問題ないクエリだったのだが、本番ではJOINをした結果10万件ぐらいのデータに対して
DISTNCTをかけることになり、これが非常に遅かった

解決策
---

eager_loadではなくpreloadを使う

```rb
Message
  .preload(:attachments)
  .limit(5)
  .latest
```

発行されたクエリ
---

```sql
SELECT
  `messages`.*
FROM
  `messages`
ORDER BY `messages`.`id` DESC
LIMIT 5
```

```sql
SELECT
  `attachments`.*
FROM
  `attachments`
WHERE
 `attachments`.`message_id` IN (1, 2  3, 100, 100000)
```

そもそも
---

本番のデータ規模で確認したほうがいいと思うので、以下のような事例を参考にしてもいいと思います

* [開発環境のデータをできるだけ本番に近づける - クックパッド開発者ブログ](http://techlife.cookpad.com/entry/2014/10/03/110806)
* [Rails - production db の内容を staging db に import する雑なスクリプト - Qiita](http://qiita.com/sonots/items/0251f7596dae84b11495)
Weblogicの公式dockerイメージの使用方法

#WebLogic 12.1.3のofficialDockerImageを導入してみる

公式で12.1.3のサポートというか、検証済みらしい。（docker/OracleWebLogic）

##最初に

日本語サイト：
http://orablogs-jp.blogspot.jp/2015/03/oracle-weblogic-server-now-running-on.html

作成方法pdf（英語）：
http://www.oracle.com/technetwork/middleware/weblogic/overview/weblogic-server-docker-containers-2491959.pdf

GitHub：
https://github.com/oracle/docker/tree/master/OracleWebLogic


### 公式で検証済みの組み合わせ

|Oracle WebLogic Server|JDK Version|Host OS|Kernel|Docker Version|
|:------------|:-------------|:-------------|:-------------|:--------------|
|12.1.3| 7/8| Oracle Lunux 6 UL 5+| Unbreakable Enterprise Kernel Release 3 (3.8.13)+| 1.3.3+|
|12.1.3| 7/8| Oracle Linux 7 UL 0+| Unbreakable Enterprise Kernel Release 3 (3.8.13)+ or Red Hat  Compatible Kernel (3.10)+| 1.3.3+|
|12.1.3| 7/8| Red Hat EnterpriseLinux 7+| Red Hat  Enterprise Linux Kernel (3.10)+| 1.3.3+|

##導入方法


#### 社内プロキシなどで制限がある場合
git/wgetはproxy通過できるように、パラメータ設定しておきましょう
http://gintec.hatenablog.com/entry/2015/04/27/180142

### build前準備

```lang:bash
[root@master]# cd /root/weblogic
[root@master]# git clone https://github.com/oracle/docker.git

[root@master]# cd /root/weblogic/docker/OracleWebLogic/dockerfiles/12.1.3

```
※取得先
http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
http://www.oracle.com/technetwork/middleware/weblogic/downloads/index.html
ファイルを取得し/root/weblogic/docker/OracleWebLogic/dockerfiles/12.1.3に格納
（xxx.download となっているファイルを取得する）


### build実行

```lang:bash
[root@master]# cd ..
[root@master]# ./buildDockerImage.sh -g
※-g :generic
　-d :developer
※build時にdownloadしたファイルのチェックサムを確認していますので、エラーが出力された場合にはファイルがあっているか確認しましょう

[root@master]# cd /root/weblogic/docker/OracleWebLogic/samples/12c-domain
[root@master]# vi Dockerfile
FROM oracle/weblogic:12.1.3-dev
FROM oracle/weblogic:12.1.3 に変更
※./buildDockerImage.sh -g　で -dを指定した場合は変更不要

[root@master]# docker build -t samplewls:12.1.3 .
```


### コンテナ起動

```lang:bash
[root@master]# sudo docker run -d -p 8001:8001 --name=wlsadmin samplewls:12.1.3 startWebLogic.sh
[root@master]# sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' wlsadmin
xx.xx.xx.xx

http://xx.xx.xx.xx:8001/console
Admin Username: weblogic
Admin Password: welcome1

```

### ノードの追加

ノードマネージャ―の作成:

```lang:bash
 $ sudo docker run -d --link wlsadmin:wlsadmin samplewls:12.1.3 startNodeManager.sh
Start NodeManager and Create a Machine Automatically:
```

ノードマネージャ―とマシンの作成:

```lang:bash
 $ sudo docker run -d --link wlsadmin:wlsadmin samplewls:12.1.3 createMachine.sh
Start NodeManager, Create a Machine, and Create a ManagedServer Automatically
```

ノードマネージャ―とマシンとマネージドサーバーの作成:

```lang:bash
$ sudo docker run -d --link wlsadmin:wlsadmin samplewls:12.1.3 createServer.sh
```


※その他のオプションについては、公式のreadmeをご覧ください。
https://github.com/oracle/docker/tree/master/OracleWebLogic
もってけエンジニア！エラートラッキングツール【Sentry】のplaybookを書いたよ

<img src="http://nikuniku.me/wp-content/uploads/sentry.png" alt="sentry" title="sentry.png" border="0" width="372" height="282" />
Ansibleのplaybookをちょくちょく書いてます。

業務で<strong>【Sentry】</strong>というエラートラッキングツールを使っているのですが、それを構築するplaybookを書いてみました。

といってもすごく簡単な事しかしてません。

<a href="https://github.com/maaaato/Ansible-Sentry" target="_blank">https://github.com/maaaato/Ansible-Sentry</a>

ポイントとして、postfixをAnsibleで入れるときにdebconfを使いました。

<h2>参考サイト</h2>
<a href="http://sentry.readthedocs.org/en/latest/index.html" target="_blank">sentry</a>
<a href="https://gist.github.com/voluntas/6937403" target="_blank">Sentry + Django コトハジメ</a>


<h2>まとめ</h2>
OSSと商用版があるのですが、OSS版ですと7.5.4でユーザ作成時にプロジェクトを作るにチェックを入れて、登録ボタンを押すと、エラーとなってしまいます^^;

さらに、チェック入れずに登録しても、作成したユーザでログインするとリダイレクトループが発生してしまいます...
スーパーユーザでプロジェクトを作り、そのプロジェクトに招待するという形であればリダイレクトループやエラーにはなりませんでした。

だれがこの現象知ってますか？
AndroidStudio アンインストール

Android Studioが何もかもうまく行かない場合完全削除する方法

``` shell
rm -rf /Applications/Android\ Studio.app
rm -rf ~/Library/Preferences/AndroidStudioPreview
rm -rf ~/Library/Preferences/com.google.android.studio.plist
rm -rf ~/Library/Application\ Support/AndroidStudioPreview
rm -rf ~/Library/Caches/AndroidStudioPreview
```
AndEngineでTexturePackerを使う

AndEngineでTexturePackerを扱うメモ


#TexturePacker側
1.メニューの[File]-[New Project]を選択
2.下記画面でAndEngineを選択
![image](https://qiita-image-store.s3.amazonaws.com/0/75209/1f8dd7e4-9cac-e134-2e02-18b9b1fd975d.png)

3.Max Size W とHをそれぞれ1024にしておく。（AndEngineで扱える最大テクスチャサイズが、多くの端末において1024x1024であるため。)
![image](https://qiita-image-store.s3.amazonaws.com/0/75209/2d55468b-2a59-c11b-1d65-5d1f563c4406.png)

3.リーソースにしたい画像を突っ込む
ドラッグして入れていく。フォルダをドラッグするとフォルダにある画像を全部読み込んでくれる

![image](https://qiita-image-store.s3.amazonaws.com/0/75209/cf2cec73-5b2e-4565-c35c-d2067cfdfd58.png)

4.[Publish sprite sheet] をクリックして、保存する。ここではプロジェクト内のassetsフォルダにgfxという名前のフォルダを作ってそこに保存する。

1.hoge.png
2.hoge.xml
3.hoge.java

この3つのファイルが保存される。
hoge.javaファイルでは、それぞれの画像名にIDを割り当てています。
中身はこんな感じです。

````hoge.java
package Texture;

public interface hoge
{
	public static final int ICONSHOCK_REAL_VISTA_MOBILE_ANDROID_PLATFORM_ICO_ID = 0;
	public static final int ANDROID_ID = 1;
	public static final int ANDROID_ICO_BY_GIOVANEFUORI_D6M8COY_ID = 2;
}

````
#AndEngineで読み込む

以下にコードを示します。

インポート部分

````java
import org.andengine.util.texturepack.TexturePack;
import org.andengine.util.texturepack.TexturePackLoader;
import org.andengine.util.texturepack.TexturePackTextureRegionLibrary;
import org.andengine.util.texturepack.exception.TexturePackParseException;
````

読み込み部分

````java
    TexturePackTextureRegionLibrary tpl = null;
    TexturePack tp = null;
 
    try {
      tp = new TexturePackLoader(getAssets(), 
          getTextureManager()).loadFromAsset("gfx/hoge.xml", "gfx");
      tp.loadTexture();
      tpl = tp.getTexturePackTextureRegionLibrary();
    } catch (final TexturePackParseException e) {
      Logger.d(e.getMessage());
    }
 
    //それぞれのテクスチャの読み込み
    ITextureRegion texture = tpl.get(hoge.ANDROID_ID);

````

以上。
世界の中心で、アクションを叫ぶ

# Target Actionとは
OSX/iOSの開発では必須のなのでみなさんご存知ですよね。ね？

[iOS Developer Library Target-Action](https://developer.apple.com/library/ios/documentation/General/Conceptual/Devpedia-CocoaApp/TargetAction.html#//apple_ref/doc/uid/TP40009071-CH3)

# nilターゲット
ターゲットとしてnilを与えると、アクションはレスポンダーチェーン経由で処理されるようになります。これを利用するとviewからview controllerに簡単にアクションを送信することができます。

もちろん、プログラムから直接nilターゲットにアクションを送ることもできます。

```objc:ObjectiveC
    [UIApplication.sharedApplication sendAction:@selector(action:)
                                             to:nil
                                           from:self
                                       forEvent:nil];
```

```swift:swift
        UIApplication.sharedApplication().sendAction("action:", to: nil, from: self, forEvent: nil)
```

# アクションを叫ぶ！
UITableViewCell等にボタンを配置した場合でも、nilターゲットを使うと簡単にview controllerまでイベントを送ることができます。あとは、senderからindexPathを取得すれば綺麗に処理が書けると思います。

senderがUITableViewCellのsubviewなので、そのindexPathは簡単に取得できます。UICollectionViewCellでも同じテクニックが使用できます。下記の例はUITableViewのカテゴリとして実装しているので、selfはTableViewと思って読んでください。

```objc:objectivec
- (UITableViewCell *)ppTableViewCellForView:(UIView *)view {
    if (view == nil) {
        return nil;
    }
    if ([view isKindOfClass:[UITableViewCell class]]) {
        return (UITableViewCell *) view;
    }
    return [self ppTableViewCellForView:view.superview];
}

- (NSIndexPath *)ppIndexPathForView:(UIView *)view {
    return [self indexPathForCell:[self ppTableViewCellForView:view]];
}
```

```swift:swift
import UIKit

extension UITableView{
    func btk_tableViewCellForView(view:UIView?)
        -> UITableViewCell?
    {
        if(view == nil){
            return nil
        }
        if let cell = view as? UITableViewCell{
            return cell
        }
        return btk_tableViewCellForView(view!.superview)
    }
    
    func btk_indexPathForView(view:UIView?)
        -> NSIndexPath?
    {
        if let cell = btk_tableViewCellForView(view){
            return indexPathForCell(cell)
        }
        return nil
    }
}
```

誰かに届け、このアクション！
クエリーで or と in の処理時間差を確認する

InfiniDB を使ってみる。
select で or を含む検索をしたときの処理時間パフォーマンスを確認する。


##InfiniDB バージョン

    $ idbmysql
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 9
    Server version: 5.1.73 InfiniDB 4.6 Beta

##テーブル定義

    mysql> show create table t1;
    +-------+-------------------------------------------------------------+
    | Table | Create Table                                                |
    +-------+-------------------------------------------------------------+
    | t1    | CREATE TABLE `t1` (
      `key1` char(50) DEFAULT NULL,
      `key2` char(50) DEFAULT NULL,
      `key3` char(50) DEFAULT NULL,
      `key4` char(50) DEFAULT NULL,
      `data1` char(50) DEFAULT NULL,
      `data2` int(11) DEFAULT NULL,
      `data3` int(11) DEFAULT NULL
    ) ENGINE=InfiniDB DEFAULT CHARSET=latin1 |


##データ件数

    mysql> select count(*) from t1;
    +----------+
    | count(*) |
    +----------+
    |  5754240 |
    +----------+

    ※登録データのカーディナリティ
        key1 = 1
        key2 = 1
        key3 = 2
        key4 = 1000
        data1 = 10
        data2 = 2880
        data3 = 1 


##クエリー

　key1, 2, 3 は固定
　key4 を or で検索
　key4, data1, data2 で sort (ASC)

    (or クエリー)
    select
        key4,data1,data2,data3
    from
        t1
    where
        data2 >= n1 and data2 < n2
    and
        key1='aaa'
    and
        key2='bbb'
    and
        key3='ccc'
    and
        (
            key4='ddd'
            or key4='eee'
            ・・・
        )
    order by
        key4,data1,data2
    ;

    (in クエリー)
    select
        key4,data1,data2,data3
    from
        t1
    where
        data2 >= n1 and data2 < n2
    and
        key1='aaa'
    and
        key2='bbb'
    and
        key3='ccc'
    and
        key4 in (
            'ddd'
           ,'eee'
            ・・・
        )
    order by
        key4,data1,data2
    ;


##結果

**処理時間(秒)**

| key4 数 (データ取得数) | 10 (14400)    | 20 (28800)    | 30 (43200)    |
|:----------------------|:-------------:|:-------------:|:-------------:|
| or 指定               | 0.971         | 1.767         | 2.561         |
| in 指定               | 0.190         | 0.218         | 0.273         |
| 試しに union で       | 1.322         | 2.655          | 3.989         |


**断然、in 指定が有利！！

**or 指定って、union 並み ？


##反省

すっかり油断して、or を使ってた。
どうりで検索スピードが上がらなかったわけです。


##リンク

[クエリーで or と in の処理時間差を確認する(その2)](http://qiita.com/nishimry/items/8b2508f4b45d21c59ff9)
[クエリーで or と in の処理時間差を確認する (その3)](http://qiita.com/nishimry/items/2e120c7c71f2bcce9e15)
Gitを深く理解するための資料

- Pro Git
https://progit-ja.github.io/
- LearningGitBranching(original)
http://pcottle.github.io/learnGitBranching/
- LearningGitBranching(japanese)
http://k.swd.cc/learnGitBranching-ja/
- tryGit
http://try.github.io/
- Git ユーザマニュアル (バージョン 1.5.3 以降用)
https://img.atwikiimg.com/www8.atwiki.jp/git_jp/pub/Documentation.ja/user-manual.html#id2546751
- Git の仕組み (1)
http://koseki.hatenablog.com/entry/2014/04/22/inside-git-1
Pro Gitの最終章、Gitの内側、の解説。
電子回路 > 最小定理 > a + b = sqrt( (a - b)^2 + 4ab )

引用: 基礎から学ぶ電気回路計算 by 永田博義さん

```math
a + b = \sqrt{ (a - b)^2 + 4ab }
```

上記の式から分かるのは、a==bの時、a+bの値が最大になるということ (a>0, b>0の時)。

> p47.
> ところで、R=100[Ω]は電源側の内部抵抗r=100[Ω]の値と一致しています。...実は、電源側の内部抵抗r[Ω]と同じ値の負荷抵抗R[Ω]を接続したとき、負荷の消費電力P[W]は最大になるということを、次のように最小定理を適用して確かめることができます。
...

<hr>
(追記 2015/07/03)
重要な条件が抜けていた。

> 2つの正数の積(a x b)が一定のとき、
作業マシンとしてのGCEプリエンプティブインスタンスとAWSスポットインスタンスの比較

ベンチマークや重いソフトウェアのビルドなど、ノートPCには適していない作業をするマシンとして、いままで AWS のスポットインスタンスを使っていました。
しかし5月に GCE のプリエンプティブインスタンスが出て、試してみたところ予想以上に快適でした。
こういったスポットでの作業環境としてのプリエンプティブインスタンスのメリットを紹介していきます。

## 起動が早い

スポットインスタンスは、入札してから実際にマシンが起動するまでのタイムラグが5分程度ありました。

プリエンプティブインスタンスは、通常の Compute Engine のインスタンスのオプションという扱いなので、入札という手順が存在せず、1分程度で起動できます。

## 設定が簡単

AWS だと新しいインスタンスを使おうとすると VPC の設定が必要だったり、セキュリティグループの設定をしないと起動した２台のマシン間での通信すらできなかったりしました。

GCE の場合、デフォルトのネットワークがマシン間の通信をフルオープン、外からのアクセスはSSHとRDPだけという設定になっているので、ネットワークを使うプログラムをベンチマークするために2台のマシンを起動するのが簡単です。

一方で、AWSの「プレースメント・グループ」相当の機能がないので、2台のマシンを起動した時のネットワーク上の距離がプレースメント・グループを使った場合に較べて安定しない可能性はあります。 (プレースメント・グループを使ってても保証されるわけではないので必要ですが) ベンチマークするときはまず ping や iperf の結果を記録しておきましょう。

## 停止・再開ができる

スポットインスタンスは AMI からしか起動できない、停止がなく終了しかないという欠点がありました。ちゃんと EBS をマウントしたりしたら永続化できるのでしょうが、ズボラなので、作業が一区切りするたびにAMIを作るという使い方をしていました。
この方法では、最後にAMIを作ってからの作業は終了時に消えてしまいます。最近スポット価格が不安定なので、こまめにAMIを作る必要がありました。

一方、プリエンプティブインスタンスは、突然停止される可能性がある、24時間以上連続稼働できないという以外は通常の GCE インスタンスと同じく停止・再開が可能です。
（まだ強制停止を食らったことが無いのですが、）失う作業内容は実行中のプログラムなどメモリ上のものだけになると思います。

また、再開は10秒前後で可能なので、AMIからスポットインスタンス立て直すよりもずっと早くて、その分気軽に停止することができます。

## 課金が分単位

AWS だと課金が時間単位なので、最初にやりたかったことが早めに終わった時にもったいなくて別のことを始めたり、そしたら今度は1時間をちょっとだけ超えてしまって悔しい思いをしたりすることがありました。

それに比べると、（最低10分から）分単位の課金の GCE なら、起動時間だけでなくお金の面でも気軽に停止できます。

## リージョンを超えるのが簡単

コンソールでインスタンスの一覧を見るときに、複数のリージョンのインスタンスがすべて見られます。
asia で作ったスナップショットから us-central にマシンを建てる時も、特にリージョン間の移動を考える必要がありません。

「別のリージョンでマシンが起動しっぱなしだった」なんてこともないですし、 us-central で複数台立ち上げてベンチマークするためのイメージを asia で作るみたいなことも簡単なはずです。

## 一般的なディストリでネットワーク性能を引き出せる

AWS でネットワーク性能を出すには、できるだけ最新のカーネルを使い、拡張ネットワーキングを使う必要がありました。また、 c3.8xlarge や c4.8xlarge でも NICあたりキューが2つしか無いので、 RPS などの設定も必要でした。 ([参考](http://www.slideshare.net/understeer/jaws-ec2tips-jawsmeguro-jawsug))

そのため、ベンチマークするために一番性能を出しやすい Amazon Linux を利用していたのですが、 bash-completion の導入方法が分からなかったりと作業環境としては不満がありましたし、 RPS の設定等は毎回する必要がありました。

一方 GCE で Debian wheezy with backported kernel を使えば、一般的なディストリビューションである Debian で最新に近いカーネルを利用することができます。 NIC は virtio なのですが、コア数分のキューがあり、デフォルトでちゃんとマルチコアを使えるような状態で起動してくれていました。

Debian 以外のディストリビューションを利用した場合はカーネルは最新版ではないかもしれませんが、 virtio なので ixgbevf のドライバを用意して拡張ネットワーキングを有効にするよりは簡単に性能を出せると思います。
技術英語 > take it apart / put it together


take it apart: 分解する
put it together: 組み立てる

以前youtubeでこういうフレーズを聞いたのを思い出した。時計を分解して組み立てる話だったようだが、どのyoutubeかは失念した。

<hr>
take it apartに関連して以下のような物を分解していく過程を紹介しているサイトを見つけた。

https://www.takeitapart.com

<hr>
put togetherについては以下の使い方がある。
http://www.healthyfoundations.com/airbed7.html

> Assembled vs. Put it Together Air Beds
> Air beds come in two variations - those that are delivered fully assembled vs. those that come in a few boxes that you <font color=red>put together</font> yourself. 

<hr>
別のput togetherの使用例もある。

https://github.com/Teknoman117/cuda
> Just some examples of using CUDA I have put together

こちらは「組み立てる」でなく「集めて置いている」意味になる。