OmniAICreator/Qiita-1.07M huggingface dataset:
折って切る 〜 横へな 2014.1.10 問題

1 時間半くらいでした。敗北。

```rb
def solve(input)
  fold, punch_pos = input.split(?-)
  punch_pos = punch_pos.upcase.split("")
  h_count = accum_h_count(input)
  v_count = accum_v_count(input)

  punch(h_count, v_count, last_pos(fold), punch_pos)
end

def accum_v_count(fold)
  fold.scan(/R|L/).count
end

def accum_h_count(fold)
  fold.scan(/T|B/).count
end

def last_fold(fold)
  h = fold.scan(/T|B/).last
  v = fold.scan(/R|L/).last
  [h, v]
end

def last_pos(fold)
  h, v = last_fold(fold)
  [toggle(h), toggle(v)]
end

def toggle(str)
  case str
  when ?R then ?L
  when ?L then ?R
  when ?T then ?B
  when ?B then ?T
  end
end

def punch(h_count, v_count, last_pos, punch_pos)
  return 0 unless last_pos.first && last_pos.last

  tl_based_punch_pos =
    case last_pos.join
    when 'TL'
      punch_pos
    when 'TR'
      [punch_pos.first, toggle(punch_pos.last)]
    when 'BL'
      [toggle(punch_pos.first), punch_pos.last]
    when 'BR'
      [toggle(punch_pos.first), toggle(punch_pos.last)]
    end

  h_offset, v_offset =
    case tl_based_punch_pos.join
    when 'TL' then [-1, -1]
    when 'TR' then [-1, 0]
    when 'BL' then [0, -1]
    when 'BR' then [0, 0]
    end

  h = ((2 ** h_count - 1) / 2.0).ceil + h_offset
  v = ((2 ** v_count - 1) / 2.0).ceil + v_offset

  h * v
end

DATA.each_line do |l|
  input, expect = l.scan(/"(.*)", "(.*)"/).flatten
  actual = solve(input).to_s
  unless actual == expect
    raise "input: #{input}, expected #{expect.inspect}, but got #{actual.inspect}"
  end
end

p 'passed! yey!'

__END__
/*0*/ test( "RRTRB-bl", "6" );
/*1*/ test( "R-tr", "0" );
/*2*/ test( "L-br", "0" );
/*3*/ test( "T-tl", "0" );
/*4*/ test( "B-tl", "0" );
/*5*/ test( "BL-br", "0" );
/*6*/ test( "LB-tl", "0" );
/*7*/ test( "RL-tl", "0" );
/*8*/ test( "BL-tl", "0" );
/*9*/ test( "TL-bl", "0" );
/*10*/ test( "RT-tr", "1" );
/*11*/ test( "TRB-tl", "0" );
/*12*/ test( "TRL-bl", "0" );
/*13*/ test( "TRB-br", "2" );
/*14*/ test( "LLB-bl", "2" );
/*15*/ test( "RTL-tr", "1" );
/*16*/ test( "LBB-tr", "0" );
/*17*/ test( "TLL-tl", "2" );
/*18*/ test( "RLRR-tr", "0" );
/*19*/ test( "BBTL-tl", "4" );
/*20*/ test( "TBBT-tr", "0" );
/*21*/ test( "LLBR-tl", "0" );
/*22*/ test( "LBRT-tl", "2" );
/*23*/ test( "RLBL-bl", "4" );
/*24*/ test( "BRRL-br", "3" );
/*25*/ test( "TBBTL-tl", "8" );
/*26*/ test( "TLBBT-br", "0" );
/*27*/ test( "LRBLL-br", "7" );
/*28*/ test( "TRRTT-br", "6" );
/*29*/ test( "BBBLB-br", "0" );
/*30*/ test( "RTTTR-tl", "4" );
/*31*/ test( "BBLLL-br", "6" );
/*32*/ test( "RRLLTR-tr", "16" );
/*33*/ test( "TTRBLB-br", "8" );
/*34*/ test( "LRBRBR-bl", "14" );
/*35*/ test( "RBBLRL-tl", "8" );
/*36*/ test( "RTRLTB-tl", "12" );
/*37*/ test( "LBLRTR-tl", "14" );
/*38*/ test( "RRLTRL-tl", "16" );
/*39*/ test( "TBLTRR-br", "12" );
/*40*/ test( "TTTRLTT-bl", "30" );
/*41*/ test( "TBBRTBL-tr", "15" );
/*42*/ test( "TRTRTLL-tr", "28" );
/*43*/ test( "TLLRTRB-tr", "24" );
/*44*/ test( "RLLBRLB-tr", "15" );
/*45*/ test( "LTLRRBT-tr", "32" );
/*46*/ test( "RBBRBLT-br", "21" );
/*47*/ test( "LLRLRLR-tr", "0" );
```
cut.c

問題はこちら
http://nabetani.sakura.ne.jp/hena/ord17foldcut/

他の解答例はこちら
http://qiita.com/Nabetani/items/ebd9d7deb30c57447806

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int chrcnt(const char* s, const char c)
{
	int cnt = 0;
	for(int i = 0; s[i]; i++) {
		if(s[i]==c) cnt++;
	}
	return cnt;
}

int chgcnt(const char* s, const char c1, const char c2)
{
	int cnt = 0;
	char c = c1;
	for(int i = 0; s[i]; i++) {
		if(s[i]==c1 && c==c1) {
			c = c2;
			cnt++;
		} else if (s[i]==c2 && c==c2) {
			c = c1;
			cnt++;
		}
	}
	return cnt;
}

int solve(const char* IN)
{
		// 縦線の数を計算
	int vert = (1<<(chrcnt(IN, 'R')+chrcnt(IN, 'L')))-1,	
		// 横線の数を計算
		hori = (1<<(chrcnt(IN, 'T')+chrcnt(IN, 'B')))-1,	
	
		// 左右の入れ替わりの回数算出
		chgcnt_vert = (strstr(IN, "r") != NULL) ? chgcnt(IN,'R','L'): chgcnt(IN,'L','R'),	
		// 上下の入れ替わりの回数算出
		chgcnt_hori = (strstr(IN, "t") != NULL) ? chgcnt(IN,'T','B'): chgcnt(IN,'B','T'),	
	
		// 穴が開く縦線が奇数か偶数か確認し、本数を算出
		v = ((chgcnt_vert&0x01)==0) ? vert>>1: (vert+1)>>1,	
		// 穴が開く横線が奇数か偶数か確認し、本数を算出
		h = ((chgcnt_hori&0x01)==0) ? hori>>1: (hori+1)>>1;	
	
	return v*h;	// 穴の数を算出
}

void test(const char* IN, const char* ANS)
{
	static int i = 0;
	int a = solve(IN);
	printf("%d\t%d\t%s\n",i++, a, (a == atoi(ANS)) ? "ok": "*** NG ***");
}

int main()
{
/*0*/ test( "RRTRB-bl", "6" );    
/*1*/ test( "R-tr", "0" );    
/*2*/ test( "L-br", "0" );    
/*3*/ test( "T-tl", "0" );    
/*4*/ test( "B-tl", "0" );    
/*5*/ test( "BL-br", "0" );    
/*6*/ test( "LB-tl", "0" );    
/*7*/ test( "RL-tl", "0" );    
/*8*/ test( "BL-tl", "0" );    
/*9*/ test( "TL-bl", "0" );    
/*10*/ test( "RT-tr", "1" );    
/*11*/ test( "TRB-tl", "0" );    
/*12*/ test( "TRL-bl", "0" );    
/*13*/ test( "TRB-br", "2" );    
/*14*/ test( "LLB-bl", "2" );    
/*15*/ test( "RTL-tr", "1" );    
/*16*/ test( "LBB-tr", "0" );    
/*17*/ test( "TLL-tl", "2" );    
/*18*/ test( "RLRR-tr", "0" );    
/*19*/ test( "BBTL-tl", "4" );    
/*20*/ test( "TBBT-tr", "0" );    
/*21*/ test( "LLBR-tl", "0" );    
/*22*/ test( "LBRT-tl", "2" );    
/*23*/ test( "RLBL-bl", "4" );    
/*24*/ test( "BRRL-br", "3" );    
/*25*/ test( "TBBTL-tl", "8" );    
/*26*/ test( "TLBBT-br", "0" );    
/*27*/ test( "LRBLL-br", "7" );    
/*28*/ test( "TRRTT-br", "6" );    
/*29*/ test( "BBBLB-br", "0" );    
/*30*/ test( "RTTTR-tl", "4" );    
/*31*/ test( "BBLLL-br", "6" );    
/*32*/ test( "RRLLTR-tr", "16" );    
/*33*/ test( "TTRBLB-br", "8" );    
/*34*/ test( "LRBRBR-bl", "14" );    
/*35*/ test( "RBBLRL-tl", "8" );    
/*36*/ test( "RTRLTB-tl", "12" );    
/*37*/ test( "LBLRTR-tl", "14" );    
/*38*/ test( "RRLTRL-tl", "16" );    
/*39*/ test( "TBLTRR-br", "12" );    
/*40*/ test( "TTTRLTT-bl", "30" );    
/*41*/ test( "TBBRTBL-tr", "15" );    
/*42*/ test( "TRTRTLL-tr", "28" );    
/*43*/ test( "TLLRTRB-tr", "24" );    
/*44*/ test( "RLLBRLB-tr", "15" );    
/*45*/ test( "LTLRRBT-tr", "32" );    
/*46*/ test( "RBBRBLT-br", "21" );    
/*47*/ test( "LLRLRLR-tr", "0" ); 
	return 0;
}
```
Three.jsで動画をテクスチャに指定する



[2015.05.21 追記]
どうやら最新版（r72）ではvideo要素をそのままテクスチャとして使う方法があるようです。
[サンプル](http://threejs.org/examples/#webgl_materials_video)もありました。

ざっくりとその記述だけ抜き出すと、こんな感じで非常に手軽に利用できます。

```js:videoTexture
video = document.getElementById( 'video' );

texture = new THREE.VideoTexture( video );
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
```

下の記事はその前に書いたもので、比較的低レイヤーでのやり方です。

-------------------------------------------

Three.jsのサンプルにあったものを抜粋。
基本的なフローは

1. video要素を生成（あるいは取得）
2. videoをキャプチャするcanvas要素を生成（あるいは取得）
3. canvas要素をtextureに指定
4. 生成したtextureを元にマテリアルを生成
5. loop updateの中でcanvasを更新し、さらにtextureオブジェクトの`needsUpdate`をtrueに指定

という手順で、あとは勝手にThree.jsが更新してくれる。


```videotexture.js
//video要素とそれをキャプチャするcanvas要素を生成
var video = document.createElement('video');
video.src = "some.mp4";
video.load();
video.play();

var videoImage = document.createElement('canvas');
videoImage.width = 480;
videoImage.height = 200;

var videoImageContext = videoImage.getContext('2d');
videoImageContext.fillStyle = '#000000';
videoImageContext.fillRect(0, 0, videoImage.width, videoImage.height);

//生成したcanvasをtextureとしてTHREE.Textureオブジェクトを生成
var videoTexture = new THREE.Texture(videoImage);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;

//生成したvideo textureをmapに指定し、overdrawをtureにしてマテリアルを生成
var movieMaterial = new THREE.MeshBasicMaterial({map: videoTexture, overdraw: true, side:THREE.DoubleSide});
var movieGeometry = new THREE.PlaneGeometry(10, 10, 4, 4);
var movieScreen = new THREE.Mesh(movieGeometry, movieMaterial);
movieScreen.rotation.y = THREE.Math.degToRad(90);

scene.add(movieScreen);

//loop updateの中で実行
if (video.readyState === video.HAVE_ENOUGH_DATA) {
    videoImageContext.drawImage(video, 0, 0);
    if (videoTexture) {
        videoTexture.needsUpdate = true;
    }
}
```
UIViewの子Viewをはみ出さなくするメソッド


```objc
UIView *parentView = [UIVIew alloc] init];
UIView *childView = [UIVIew alloc] init];

[view addSubview:childView];

[parentView setClipsToBounds: YES];
```

これでchildViewがはみ出したらその分は表示しなくなる。
簡単。
折って切る

@kei_q氏の解答 http://qiita.com/kei_q/items/e4be8c40b7472ab7673a のパクリになってしまいました。
今回は初の惨敗です。現地参加じゃなくてよかった。

```rb:hena17.rb
#!/usr/bin/env ruby
#http://qiita.com/Nabetani/items/ebd9d7deb30c57447806
#http://nabetani.sakura.ne.jp/hena/ord17foldcut/
STDOUT.sync=true
RIGHT={
	'bl'=>lambda{|t,b,l,r|b*l},
	'br'=>lambda{|t,b,l,r|b*r},
	'tl'=>lambda{|t,b,l,r|t*l},
	'tr'=>lambda{|t,b,l,r|t*r},
}
LEFT={
	'L'=>lambda{|t,b,l,r|[t,b,l+r+1,l+r]},
	'R'=>lambda{|t,b,l,r|[t,b,l+r,l+r+1]},
	'T'=>lambda{|t,b,l,r|[t+b+1,t+b,l,r]},
	'B'=>lambda{|t,b,l,r|[t+b,t+b+1,l,r]},
}
while gets
	l,r=$_.chomp.split('-')
	p RIGHT[r].call(*l.chars.reduce([0,0,0,0]){|s,e|s=LEFT[e][*s]})
end
```
Intellij のキモいインデントを直したかった

探すの意外と大変だったのでメモ

## 設定場所

Code Style > Scala > Wrapping and Braces

## 変更前

![Screen Shot 2014-01-10 at 12.57.15.png](https://qiita-image-store.s3.amazonaws.com/0/7196/ec84c626-5f94-b720-5f1e-d4d6b42fb12c.png)

## 変更後

![Screen Shot 2014-01-10 at 12.55.48.png](https://qiita-image-store.s3.amazonaws.com/0/7196/e88aa791-ce99-0396-14e6-faeabc74a095.png)
mcrypt extension is required


OS X Mavericksにアップデート後、phalconのフレームワークを使ってるサイトで掲題のエラーが出ました。

エラー文見る限り、mcryptが動いてないと思い、
infophp()を確認すると、案の定mcryptが読み込まれていませんでした。

そこで、php.iniで

```console
extension = mcrypt.so
```

と指定し、infophpを確認しましたが、それでも読み込まれない。

数時間悩みましたが、

###extension_dirでmcryptのパスが指定されていない。

というのが原因でした。

解決策は、

まずはコマンドでmcryptの位置を確認し、


```console
$ sudo find /usr -name mcrypt.so

/usr/local/Cellar/php54/5.4.15/lib/php/extensions/no-debug-non-zts-20100525/mcrypt.so
```
php.iniで

```console
extension_dir = "/usr/local/Cellar/php54/5.4.15/lib/php/extensions/no-debug-non-zts-20100525/"
```

と記述し、apacheを再起動して完了です。

```console
$ sudo apachectl restart
```



mcryptインストールしているのに、読み込まれていないという方は一度確認してみるといいかもです。
YeomanでChrome Extension開発環境を簡単作成

## 必要なもの
+ node.js, npm, 適当なJavaScript用のエディタ
自身の環境に合わせて適宜インストール!

+ Yeoman
[Yeoman](http://yeoman.io/)は、色々なJavaScript関連の雛形を自動生成してくれます.

```
# npm -g install yo
```

+ Chrome拡張用のgenerator
下記のコマンドでgeneratorをインストールしておく.

```
# npm -g install generator-chrome-extension
```

これでChrome拡張を作成するためのツール関連はセットアップ完了.

## プロジェクト作成

適当にディレクトリを作成する.

```
$ mkdir my-first-extension
$ cd my-first-extension
```

Yeomanのgeneratorを実行する.

```
$ yo chrome-extension
```

何か色々聞かれるけど、適当に答えていく.

```
[?] What would you like to call this extension? my-first-extension
[?] How would you like to describe this extension? My Chrome Extension
[?] Would you like to use UI Action? No
[?] Would you like to use the Options Page? No
[?] Would you like to use the Omnibox? (Please input keyword) 
[?] Would you like to use the Content Scripts (Not Programmatic)? Yes
[?] Would you like to use permissions? Yes
[?] "Tabs" permission: No
[?] "Bookmarks" permission: No
[?] "Cookies" permission: No
[?] "History" permission: Yes
[?] "Management" permission: No
```

上記では、Contents Script, 履歴へのアクセスのみを許可する設定としている.)

入力が完了すると、雛形の生成および、一通りのモジュールのダウンロードをしてくれる.

```
$ ls app
```

でmanifesto.jsonが作成されているのが確認できるはず.

## 動かしてみる
[Chromeの拡張機能画面](chrome://extensions)から、「パッケージ化されていない拡張機能を読み込む...」を選択して、プロジェクトディレクトリ/appを指定すればよい.
twitter botを作ってみる(第3回〜作成したスクリプトを自動実行する)


# cronを使って自動実行する

## crontab
 [前回](http://qiita.com/monhan/items/5dd2ae067aac73c08b9f)まででPHPのスクリプト自体はいったん動く状態までできました。
このスクリプトをcronで自動実行してみたいと思います。

cronが使用できる無料レンタルサーバもいくつかあるようです。
自分は未来サーバのコンパネからcronを登録してみたのですが、なぜか実行されませんでした。
ここはひとまず自分の開発環境(VMWare Fusion上のCentOS)にて実行します。

cronは以下のコマンドで編集できます。

```
s crontab -e
```

例えば5分に1回実行する、という場合はこんな感じ。

```
*/5 * * * * php -f /home/mtaji/TweetBot.php
```

登録後、確認は下記のコマンドで。

```
s crontab -l
*/5 * * * * php -f /home/mtaji/TweetBot.php
```

これで、一定時間ごとに作成したスクリプトが実行されます。

ただ、ここまでで作成したスクリプトですと、
何度も同じ文章を投稿してしまうので改良が必要ですが(^^;)


[twitter botを作ってみる(第1回〜twitteroauth導入編)](http://qiita.com/monhan/items/ba36e6a28ed9bbab6ec0)
[twitter botを作ってみる(第2回〜応用編-メッセージのランダマイズ)](http://qiita.com/monhan/items/5dd2ae067aac73c08b9f)
twitter botを作ってみる(第3回〜作成したスクリプトを自動実行する)
全テーブルのレコード件数を一度に取得するSQLを作成するSQL

```sql
select 'table1' as table_name, count(*) as count from table1 union all
select 'table2' as table_name, count(*) as count from table2 union all
select 'table3' as table_name, count(*) as count from table3 union all
select 'table4' as table_name, count(*) as count from table4 union all
select 'table5' as table_name, count(*) as count from table5
```

上記のようなSQLをつくるSQL

```postgres
with
  t as (
    select
      'select '''||tablename||''' as table_name, count(*) as count from '||tablename as query,
      casewhen lead(tablename) over (order by tablename) is not null then ' union all' else '' end as u
    from
      pg_tables
    where
      tableowner = 'foo'
  )
select
  query || u
from
  t
;
```
GPS情報含むExif情報の表示方法 Mac OS X Mavericks 10.9

撮影画像について保存されるメタデータの一つであるExif情報。Mac OS X上では「プレビュー」で従来通り簡単に確認できる。10.9上で確認すると「GPS」情報が独立したタブ内に表示されるようになっている。画像とともにどうぞ：

### プレビュー上でExif情報を確認する方法

- 画像を「プレビュー(.app)」で開き、[ツール] → [インスペクタを表示]

 ![Preview01.jpg](https://qiita-image-store.s3.amazonaws.com/0/12779/944e3e4e-4c1e-85be-e430-5c0022571281.jpeg)

- 詳細情報。左から2番目の「i」タブをクリックするとExif情報が表示される

 ![Preview02.jpg](https://qiita-image-store.s3.amazonaws.com/0/12779/a53a93b2-57d5-0c25-5c99-3a98b8fe162e.jpeg)

- 隣の [GPS] タブをクリックするとGPS情報が表示される

 ![Preview03.jpg](https://qiita-image-store.s3.amazonaws.com/0/12779/9fc9154c-53c3-462c-4403-b958d3bf138e.jpeg)

### Finder上でExif情報を確認する方法（GPS情報は表示されない）

- プレビューを開かなくても、Finder上で画像ファイルを選択し [ファイル] → [情報を見る] で一部のExif情報が確認できる

 ![Finder01.jpg](https://qiita-image-store.s3.amazonaws.com/0/12779/39df7340-c035-ab1a-35ae-38766bb51006.jpeg)

- この画面では、GPS情報等は表示されない
  - [ファイル] → [情報を見る] メニュー表示時に option キーを押下すると、[情報を見る] メニューが [インスペクタを表示] に変化する
  - ただし [インスペクタを表示] でもExif情報の表示内容は変わらない（GPS情報が追加で表示されたりはしない）

 ![Finder02.jpg](https://qiita-image-store.s3.amazonaws.com/0/12779/d44c917f-e133-c279-7102-8b6b8f51c035.jpeg)
twitter botを作ってみる(第2回〜応用編-メッセージのランダマイズ)

# CSVに定義したメッセージをランダムに投稿させる

[前回](http://qiita.com/monhan/items/ba36e6a28ed9bbab6ec0)作成したスクリプトは、固定のメッセージを一つ出力するのみでした。
これを改良し、複数のメッセージをランダムに出力するようにしたいと思います。

## 1.CSVを読み込むクラスを作成する
下記のような感じ。ここでは「lib」ディレクトリに配置しています。

```
s mkdir lib
s cd lib
s sudo vim CSVReader.php 

s sudo cat CSVReader.php 
<?php

class CSVReader{

    /**
     * CSVファイルを読み込む
     */
    public function read($csv){

        // CSVを読み込む
        $data = file_get_contents($csv);

        // 一時ファイルに書き込み
        $tmp  = tmpfile();
        $csv  = array();
 
        fwrite($tmp, $data);
        rewind($tmp);

        // CSVを読み込む
        while (($data = fgetcsv($tmp, 0, ',')) !== FALSE) {
            $csv[] = $data;
        }

        fclose($tmp);
 
        return $csv;
    }

}

```

## 2.前回作成した投稿スクリプトを拡張し、CSVのメッセージを投稿するようにする

下記の2点を追加
* 1で作成したCSVReaderクラスを読み込むように修正
* 読み込んだCSVから、メッセージをランダム(mt_rand(min, max))に出力するよう修正

例えば下記のようになります。

```
s sudo cat TweetBot.php 
<?php

    require_once(dirname(__FILE__).'/twitteroauth/twitteroauth/twitteroauth.php');
    require_once(dirname(__FILE__).'/lib/CSVReader.php');

    // developer info
    $consumerKey       = ‘XXXXXXXXXXXXXXX’;
    $consumerSecret    = 'XXXXXXXXXXXXXXX';
    $accessToken       = 'XXXXXXXXXXXXXXX';
    $accessTokenSecret = 'XXXXXXXXXXXXXXX';

    $oAuth = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);

    // oAuth認証を利用し、twitterに投稿する
    $TWITTER_STATUS_UPDATE_URL = "http://api.twitter.com/1.1/statuses/update.json";
    $method  = 'POST';
    $message = getMessage();

    var_dump($message);

    $response = $oAuth->post('statuses/update', array('status' => $message));

    // 結果出力
    var_dump($response);

    /**
     * 投稿メッセージを取得する
     */
    function getMessage(){

        $reader = new CSVReader();

        $csv = './lib/csv/test.csv';

        $csv = $reader->read($csv);

        $i = mt_rand(1, 4);

        return (isset($csv[$i][1])) ? $csv[$i][1] : '';
    }

?>
```

## 3.実行

```
s php TweetTest.php
s php TweetTest.php
```

![スクリーンショット 2014-01-09 17.26.47.png](https://qiita-image-store.s3.amazonaws.com/0/30307/13527b61-8a89-1564-87b9-28d5dbdbbdd2.png "スクリーンショット 2014-01-09 17.26.47.png")

うまくいったようです。
5分でできますねw

[twitter botを作ってみる(第1回〜twitteroauth導入編)](http://qiita.com/monhan/items/ba36e6a28ed9bbab6ec0)
twitter botを作ってみる(第2回〜応用編-メッセージのランダマイズ)
[twitter botを作ってみる(第3回〜作成したスクリプトを自動実行する)](http://qiita.com/monhan/items/db6468e5248cb23948bf)
『プログラミングHaskell』の関数型パーサーをStateTを使って書き直す

『[プログラミングHaskell](http://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0Haskell-Graham-Hutton/dp/4274067815)』の関数型パーサー(ソースコードは[ここ](http://www.cs.nott.ac.uk/~gmh/book.html#code)の"Functional parsing library"、"Expression parser"からダウンロードできます)を`StateT`を使って書き直すと、次のようになります。

```hs:MyParser.hs
import Control.Monad.State
type Parser a = StateT String Maybe a
runParser = runStateT
parse :: Parser a -> String -> Maybe (a, String)
parse p inp = runParser p inp

item :: Parser Char
item = do x:xs <- get
          put xs
	  return x
```

`Parser a`の定義から分かるようにモナドのインスタンスにするために、`>>=`を定義する必要はなくなります。

ここでテキストに合わせて`parse p inp :: [(a, String)]`になるように`type Parser a = StateT String [a]`にしてしまうと

```shell-session
ghci> parse nat "123"
[(123, ""), (12, "3"), (1, "23")]
```

になってしまいます。これは`(+++) = mplus`と定義されていることと、`[]`の`mplus`が`(++)`のシノニムになっているからで、実際に`+++`でリストの結合が起こっているところは`many`です。`Maybe`の`mplus`の定義は

```hs
Nothing `mplus` ys = ys
xs      `mplus` _  = xs
```

なので、今回の計算にちょうど合っています。あとは`eval`を次のように定義し直せば、正常に動作します。

```hs:MyParser.hs
eval :: String -> Int
eval xs = case (parse expr xs) of
            Just (n, "")  -> n
	    Just (_, out) -> error ("unused input " ++ out)
	    failure       -> error "invalid input"
```
PHPでスカラー型の強い型付け

```php
<?php
	$object = new stdClass();
	$object = '1' + 1;
	
	$boolean = ( '1' == 1 );
```

`$object`はint型の2、`$boolean`はtrueになり、Java出身者が憤死します。
PHPの型の挙動には色々と論がある人も多いですが、PHPの特徴だと思って諦めましょう。
まあ私はこういうの嫌いではないですが、推移律が成り立たないのはさすがにどうかと思う。

しかし時には、どうしても厳密に型を適用したいんだよ、という場合があるかもしれません。
そんなときのために[SplType](http://www.php.net/manual/ja/book.spl-types.php)です。

今のところデフォルトでは入ってないので[PECL](http://pecl.php.net/package/SPL_Types)から持ってきましょう。
Windows版のDLLも存在します。

```php
<?php
	$int = new SplInt(1);
	
	$int = 2; // 2
	$int++; // 3
	
	$int = 1.0; // Fatal error: Uncaught exception 'UnexpectedValueException'
	$int = 'a'; // Fatal error: Uncaught exception 'UnexpectedValueException'
	
	$a = $int + 10; // 13
	for($i=1; $i<$int; $i++){} // 問題なく動作
```

PHPがあたかもRubyのような強い型付けに！

`$int`は、intもしくはSplInt以外を代入しようとするとUnexpectedValueExceptionを発生します。
これで`$int`の型一意性が保証されることになりました。
逆に`$int`を演算に使う場合は、ただの整数と同じように扱えます。

型付けの対象としては、int以外にfloat、boolean、stringの各スカラー型、そしてEnum型が用意されています。
http://www.php.net/manual/ja/book.spl-types.php

ところで、

http://www.php.net/manual/ja/intro.spl-types.php
> スカラー型のタイプヒンティングの代替手段として使用できます。

って書いてあるのですが、あくまで代替のようで完全なタイプヒンティングとしては使えませんでした。

```php
<?php
	class HOGE{
		
		private $int;
		
		// setSplIntは呼び出し側でキャストしないといけない
		public function setSplInt(SplInt $int){
			$this->int = $int;
		}
		
		// setIntは概ね想定した動作だがタイプヒンティングではない
		public function setInt($int){
			$this->int = new SplInt($int);
		}
	}

	$hoge = new HOGE();

	$hoge->setSplInt(new SplInt(1));
	$hoge->setSplInt(1); // Argument 1 must be an instance of SplInt, integer given
	$hoge->setInt(2);
	$hoge->setInt(2.0); // Uncaught exception 'UnexpectedValueException'
```

まあ後者で作っておけば実質的には困らないと思います。
SICPを読むためにGaucheをVimから使えるようにした

社内でSICP(計算機プログラムの構造と解釈:Structure and Interpretation of Computer Programs)を読もうということで、SchemeはGaucheがいいという噂を元にVimで環境を構築してみました。

正直また読み始めだし、Emacsの方がいいよ！って噂を聞きつつも慣れ親しんだVimで環境を構築して見ます。

## GacuheのInstall
```shell-session
brew install gauche
brew install rlwrap
```

rlwrapは別にどっちでもいいですが、標準のgoshというコマンドから実行されるREPLだと、カーソルキーの↑で前の履歴を辿れなかったり、Ctrl+aで行頭、Ctrl+eで末尾などのターミナルでお馴染みの操作が使えなかったので入れてみました。

でも正直このあとVimからREPLを操作できるpluginを入れるので不要だったりしますが、VimからREPLを起動するまでもないときに重宝すると思います。

ちなみにREPLの起動は、

```
$ gosh
gosh> (+ 1 2)
3
```

rlwrapを使う場合は、

```
$ rlwrap gosh
```

です。

## vimrc
依存

- vimproc
- neocomplcache / neocomplete


```vim:vimrc
" gauche
NeoBundle 'aharisu/vim_goshrepl'
NeoBundle 'aharisu/vim-gdev'

<中略：neocomplateの設定とか>

let g:neocomplete#keyword_patterns['gosh-repl'] = "[[:alpha:]+*/@$_=.!?-][[:alnum:]+*/@$_:=.!?-]*"
```

## vimからREPLを実行する
ファイル名は*.scmだったらいいと思ってますｗ

```
$ vim sample.scm
```

vim_goshreplコマンドを実行します。

```
:GoshREPLWithBuffer
```

これにより、スクリプトにすでに記述した内容を読み込んだ状態でREPLが開きます。

![0DyqNxK9ZK.gif](https://qiita-image-store.s3.amazonaws.com/0/4194/1d14f8a4-1e05-23ca-76d9-fdd41a00c0a0.gif)

便利！！

## 参考
http://valvallow.blogspot.jp/2013/07/re-lisper-gauche.html
ImageMagickでアニメーションgifを扱う

よく忘れるのでメモ。

最適化されたアニメーションgif画像を連番pngへ変換

```shell-session
~$ convert -coalesce hoge.gif %02d.png
```

pngファイルを最適化しながら8コマ単位でgifアニメ画像に結合する

```shell-session
~$ convert -layers optimize -delay 8 *.png hoge.gif
```

結合するpngファイルの順番を指定したい場合

```shell-session
~$ convert -delay 5 -layers optimize 1.png 3.png ... hoge.gif
```
Go言語:Riakに書き込む


# この記事の目的

* Go言語でRiakに書き込むプログラムを作成する

# Riakとは?

* 分散型キーバリューデータベース
* RESTFul APIを通して読み書きする
* 単一障害点がなく耐障害性がある
* スケールが容易

# Riakのクライアントライブラリを入手する

```
go get github.com/tpjg/goriakpbc
```

# 実装する

```go:main.go
package main

import (
	"github.com/tpjg/goriakpbc"
	"log"
)

func main() {
	err := riak.ConnectClient("127.0.0.1:8087")
	
	if err != nil {
		log.Fatal(err)
	}

	bucket, err := riak.NewBucket("hoge")

	if err != nil {
		log.Fatal(err)
	}

	obj := bucket.NewObject("fuga")
	obj.ContentType = "application/json"
	obj.Data = []byte(`{"foo":"bar"}`)
	err = obj.Store()

	if err != nil {
		log.Fatal(err)
	}

	riak.Close()
}

```

# 実行する

```
go run main.go
```

# 書き込めた!

![rekon_v1_0_0-4.png](https://qiita-image-store.s3.amazonaws.com/0/889/8949e1cf-9053-5fb6-88aa-b81a2fefb582.png "rekon_v1_0_0-4.png")

ちなみにこの画面はRiakのGUI管理ツール[Rekon](https://github.com/basho/rekon)。Riakの開発元が作っている。
第17回オフラインリアルタイムどう書くの問題をRubyで解く

問題はこちらのリンクから
http://nabetani.sakura.ne.jp/hena/ord17foldcut/

```rb
class Paper
  def initialize
    @tl = [:s]
    @tr = [:s]
    @bl = [:s]
    @br = [:s]
  end

  def r
    @tl += @tr
    @bl += @br
    @tr = @tr.map{|e| {:s=>:dv,:dv=>[:dv,:dv],:dh=>:f,:f=>[:f,:f]}[e]}.flatten
    @br = @br.map{|e| {:s=>:dv,:dv=>[:dv,:dv],:dh=>:f,:f=>[:f,:f]}[e]}.flatten
  end

  def l
    @tr += @tl
    @br += @bl
    @tl = @tl.map{|e| {:s=>:dv,:dv=>[:dv,:dv],:dh=>:f,:f=>[:f,:f]}[e]}.flatten
    @bl = @bl.map{|e| {:s=>:dv,:dv=>[:dv,:dv],:dh=>:f,:f=>[:f,:f]}[e]}.flatten
  end

  def t
    @bl += @tl
    @br += @tr
    @tl = @tl.map{|e| {:s=>:dh,:dh=>[:dh,:dh],:dv=>:f,:f=>[:f,:f]}[e]}.flatten
    @tr = @tr.map{|e| {:s=>:dh,:dh=>[:dh,:dh],:dv=>:f,:f=>[:f,:f]}[e]}.flatten
  end

  def b
    @tl += @bl
    @tr += @br
    @bl = @bl.map{|e| {:s=>:dh,:dh=>[:dh,:dh],:dv=>:f,:f=>[:f,:f]}[e]}.flatten
    @br = @br.map{|e| {:s=>:dh,:dh=>[:dh,:dh],:dv=>:f,:f=>[:f,:f]}[e]}.flatten
  end

  def tl
    @tl.count(:f)
  end

  def bl
    @bl.count(:f)
  end

  def tr
    @tr.count(:f)
  end

  def br
    @br.count(:f)
  end
end

def solve(q)
  fold, cut = q.split('-')
  paper = Paper.new
  fold.chars.each{|e|
    eval('paper.'+e.downcase)
  }
  eval('paper.'+cut)
end

DATA.readlines.each do |line|
  no,q,a = line.chop.split(/\s+/)
  ans = solve(q)
  print no + "\t"
  print ans
  puts ans == a.to_i ? 'o' : 'x'
end
__END__
0	RRTRB-bl	6
1	R-tr	0
2	L-br	0
3	T-tl	0
4	B-tl	0
5	BL-br	0
6	LB-tl	0
7	RL-tl	0
8	BL-tl	0
9	TL-bl	0
10	RT-tr	1
11	TRB-tl	0
12	TRL-bl	0
13	TRB-br	2
14	LLB-bl	2
15	RTL-tr	1
16	LBB-tr	0
17	TLL-tl	2
18	RLRR-tr	0
19	BBTL-tl	4
20	TBBT-tr	0
21	LLBR-tl	0
22	LBRT-tl	2
23	RLBL-bl	4
24	BRRL-br	3
25	TBBTL-tl	8
26	TLBBT-br	0
27	LRBLL-br	7
28	TRRTT-br	6
29	BBBLB-br	0
30	RTTTR-tl	4
31	BBLLL-br	6
32	RRLLTR-tr	16
33	TTRBLB-br	8
34	LRBRBR-bl	14
35	RBBLRL-tl	8
36	RTRLTB-tl	12
37	LBLRTR-tl	14
38	RRLTRL-tl	16
39	TBLTRR-br	12
40	TTTRLTT-bl	30
41	TBBRTBL-tr	15
42	TRTRTLL-tr	28
43	TLLRTRB-tr	24
44	RLLBRLB-tr	15
45	LTLRRBT-tr	32
46	RBBRBLT-br	21
47	LLRLRLR-tr	0
```
plenvの導入



## plenvのインストール

以下のコマンドで、githubからplenvをインストールします。

```shell
$ git clone git://github.com/tokuhirom/plenv.git ~/.plenv
$ git clone git://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/
$ echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(plenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```

完了すると、plenvコマンドが使用できます。


## Perlのインストール

以下のコマンドで、使用できるPerlのバージョンが確認できます。
ずらっと表示されるのでlessで確認します。

```shell
$ plenv install -l | less
```

例えば、5.18.2をインストールしたい場合は、以下のようなコマンドになります。

```shell
$ plenv install 5.18.2
```

もし、名前を付けたい場合は「--as」オプションで指定できます。

```shell
$ plenv install 5.18.2 —-as for_dev
```

## Perlの切り替え

以下のコマンドで、インストールしたPerlのリストが確認できます。

```shell
$ plenv versions
* system (set by /home/uchiko/.plenv/version)
  5.18.2
  for_dev
```

切り替えの方法として、以下の２種類があります。

1. ディレクトリ毎に使用するPerlのバージョンを変更する(local)
2. 全体で使用するPerlのバージョンを変更する(global)

**1.の方法は、以下のコマンドで行います。**

```shell
$ plenv local 5.18.2
$ perl -v # バージョンの確認
```

このコマンドを実行したディレクトリに「.perl-version」というファイルが作成されます。


**2.の方法は、以下のコマンドで行います。**

```shell
$ plenv global 5.18.2
$ perl -v # バージョンの確認
```


## cpanmのインストール

以下のコマンドで、cpanmをインストールを行います。

```shell
$ plenv install-cpanm
```

現在選択しているPerlに、cpanmがインストールされます。


## 他の機能について

以下のコマンドで、ヘルプを確認。

```shell
$ plenv # ヘルプを表示
$ plenv help <command> # 各コマンドのヘルプを表示
```


## 個人的にplenvがperlbrewより良いと思う点

- ディレクトリ毎に使用するPerlを設定できるところ
- rbenvをたまに使うときでも使い方を忘れない

## 参考サイト

- http://blog.papix.net/entry/2013/06/04/081554
第17回オフラインリアルタイムどう書く rubyで


オフラインでリアルタイムに「どう書く」をやるイベント( http://atnd.org/events/46348 )の、ruby による実装例。

問題は「折って切る」という名前で、詳細は
http://nabetani.sakura.ne.jp/hena/ord17foldcut/
です。

他の方の解答は

http://qiita.com/Nabetani/items/ebd9d7deb30c57447806

から辿れると思います。

で。

```ruby
#!ruby 
def solve( s )
  fold,cut = s.split("-")
  x=[0.0, 1.0]
  y=x.dup
  fold.chars.each do |f|
    case f
    when 'R'; x[1]=(x[0]+x[1])/2
    when 'L'; x[0]=(x[0]+x[1])/2
    when 'T'; y[1]=(y[0]+y[1])/2
    when 'B'; y[0]=(y[0]+y[1])/2
    else raise "#{f} in #{s} : unexpected"
    end
  end
  [[x,/l/], [y,/b/]].map{ |xy, re|
    s = 1/(xy[1]-xy[0])
    if s==1
      0
    else
      c = (xy[re===cut ? 0 : 1 ] * s).round
      ( c.odd? ? s/2 : [s/2-1,0].max ).to_i
    end
  }.inject(&:*).to_s
end

$stdout.sync=true

DATA.map do |line|
  num, src, expected = line.split( /\s+/ )
  next true unless expected
  actual = solve( src )
  ok = actual==expected;
  puts "%s %s->%s ( %s )" % [ ok ? "ok" : "***NG***", src, actual, expected ]
  ok
end.all?.tap{ |ok| p ok }

__END__
0 RRTRB-bl  6
1 R-tr  0
45  LTLRRBT-tr  32
46  RBBRBLT-br  21
47  LLRLRLR-tr  0
```

いつも通り、テストデータの大半は省略。

もう少しコンパクトに書けるような気がしてならないんだけど、綺麗にする方法が思いつかない。

紙を折っていく時に机についたままになる矩形がどこに当たるのかを計算する。
あとは、得られた矩形がもとの折り紙の中で何マス目に当たるのかを計算すると偶数奇数とか考えれば穴の数がわかる。
という仕組み。

浮動小数点を使っているけど、2の整数乗 で割っているので、7回ぐらい折ったところで誤差は出ない。

20回とか折りたい場合は有理数にする。
RiakのGUI管理ツール4選！スクリーンキャプチャあり


# 1.[Rekon](https://github.com/basho/rekon) <small>推奨度★★★</small>

Riak以外必要としない(Javaやnode.jsなどが不要)HTMLベースのGUI管理ツール。下記のインストールコマンドを実行すると、Riakのストレージ上にRekonのソースコードやCSS、JavaScriptが配置され、ユーザはRiakの/buckets/rekon/keys/goを開くだけ。Riakの特性をうまく使ったなんとも目からうろこなプロダクト。


## インストール方法

```
curl -s -L rekon.basho.com | sh
```

## バケツ一覧画面

![rekon_v1_0_0.png](https://qiita-image-store.s3.amazonaws.com/0/889/afbea1a6-381b-cece-133d-8ecddf55ab4f.png "rekon_v1_0_0.png")


## キーの一覧画面

![rekon_v1_0_0-2.png](https://qiita-image-store.s3.amazonaws.com/0/889/e519a75e-679e-2da6-316c-320f47ac8d84.png "rekon_v1_0_0-2.png")


## キーの編集画面

![rekon_v1_0_0-3.png](https://qiita-image-store.s3.amazonaws.com/0/889/d7afc8f3-ee82-52e2-ddf5-ccc21b0d0b3d.png "rekon_v1_0_0-3.png")




# 2.[riak-admin](https://bitbucket.org/harmen/riak-admin) <small>推奨度★☆☆</small>

JavaベースのGUIツール。Rekonに比べると完成度はあまり高くない。

## インストール方法

[ダウンロードページ](https://bitbucket.org/harmen/riak-admin/downloads)からriak-admin-0.1.jarをダウンロードして開く。

## キーの一覧画面

![Riak_Admin.png](https://qiita-image-store.s3.amazonaws.com/0/889/c2abbb2d-b3fe-b987-1fb4-70ae713d0f26.png "Riak_Admin.png")


# 3.[riak-admin](https://github.com/frank06/riak-admin) <small>推奨度★☆☆</small>

これもRekon同様に、Riak上に管理ツールを構築するプロダクト。今日(2014/01/10)現在、[依存するサブモジュールが存在しない不具合](https://github.com/frank06/riak-admin/issues/5)が解消されておらず、動くところを確認することができなかった。


# 4.[Briak](https://github.com/johnthethird/Briak) <small>推奨度★★☆</small>

RubyのSinatraベースのGUIツール。管理したいRiakをホストとポートで指定することができる。

## Ruby1.8.7とSinatraが必要

```
gem install sinatra ripple
```

## インストール手順

```
git clone http://github.com/johnthethird/Briak.git briak
cd briak
ruby briak.rb
```

http://127.0.0.1:4567 を開くと管理画面に入ることができる。

## キー編集画面

![Briak_-_Browser_for_Riak.png](https://qiita-image-store.s3.amazonaws.com/0/889/6404059e-3c9a-c69c-4fa2-50e4756d9a10.png "Briak_-_Browser_for_Riak.png")
第17回オフラインリアルタイムどう書くの問題


オフラインでリアルタイムに「どう書く」をやるイベント( http://atnd.org/events/46348 )を行っています。

問題は「折って切る」という名前で、詳細は
http://nabetani.sakura.ne.jp/hena/ord17foldcut/
です。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。
バージョンの違いでMojo::Util::hmac_sha1_sumの値が変わる


以下、検証手順です。

```shell
$ cpanm -l l4.07 Mojolicious@4.07
$ cpanm -l l4.08 Mojolicious@4.08
$ perl -Il4.07/lib/perl5/ -MMojo::Util -e “warn Mojo::Util::hmac_sha1_sum(‘hogehoge’)”
9198d0e8b06d9ff1279ddec960b2a1c45009a46a at -e line 1.
$ perl -Il4.08/lib/perl5/ -MMojo::Util -e “warn Mojo::Util::hmac_sha1_sum(‘hogehoge’)”
a478b2ff74b5200faae05d0c9c48458e2e8ab0d1 at -e line 1.
```

ということで、
4.07以前でhmac_sha1_sumの値をDBなどに保持している状態で、
Mojoliciousをバージョンアップした場合、
意図した動作にならないかもしれないので注意が必要です。
Bitbucketのプロジェクト名を変更してgit remoteの再設定

Bitbucketのプロジェクト名を変更したら、ローカルからPUSHしようとすると、エラーになります：

>liubin:event liubin$ git push -u origin new_order_system
conq: repository does not exist.
fatal: Could not read from remote repository.

>Please make sure you have the correct access rights
and the repository exists.

プロジェクト名が変わったため、リモートURLも変わりました。

下記のコマンドでリモートURLを更新します。

`git remote set-url origin git@bitbucket.org:liubin0329/xxx.git`

これで無事に再PUSHできるようになりました。
多段scpっぽいことをsshとddで簡易に実現する

例えば踏み台経由で接続する必要がある本番サーバーのログファイルなどをとりあえずローカルに持ってきたいとき。
`ssh` 経由で `ssh` と `dd` を実行すると実現できる。

(ディレクトリや複数ファイルを転送する場合は[sshとtarを使えば実現できる](http://qiita.com/mazgi/items/2e665893b9c0434b8dae))

## 実行例

踏み台 `Ardbeg` を経由して、本番サーバー `Bowmore` にある `/etc/gentoo-release` というファイルをローカルに取得する。

```shell-session
[mazgi@BRUICHLADDICH] $ ssh Ardbeg ssh Bowmore 'dd if=/etc/gentoo-release' 2> /dev/null > gentoo-release
```

ファイル内容を検証してみる。

```shell-session
[mazgi@BRUICHLADDICH] $ ssh Ardbeg ssh Bowmore 'sha1sum /etc/gentoo-release' 2> /dev/null
353f7959473283c69f23618e9cb28d757bf1076a  /etc/gentoo-release
[mazgi@BRUICHLADDICH] $ shasum gentoo-release
353f7959473283c69f23618e9cb28d757bf1076a  gentoo-release
```

これで多段sshでもGentoo Linuxのバージョン確認できますね！

```shell-session
[mazgi@BRUICHLADDICH] $ < gentoo-release
Gentoo Base System release 2.2
```

なお、同じ内容の別ファイルを新しく作っているのでタイムスタンプやパーミッションは保持されない。
GitHubアカウントに登録している公開鍵からauthorized_keysを生成する

## 内容

GitHubアカウントに登録している公開鍵は https://github.com/${user_name}.keys から取得できるので、それをローカルのauthorized_keysにコピーする。複数人対応。

```sh:authorized_keys.cron
#!/bin/sh

GITHUB_USERS=(mochi udon soba)
DESTINATION=~/.ssh/authorized_keys

rm -rf "$DESTINATION"

for user in ${GITHUB_USERS[@]}
do
  curl -L https://github.com/${user}.keys >> "$DESTINATION"
done

chmod 600 "$DESTINATION"
```

上のスクリプトをサーバーの`/etc/cron.daily`辺りにでも置いておけば、後は定期的にGitHubアカウントに登録している公開鍵を取得してサーバーの`authorized_keys`を更新してくれる。

業務用で使うのは怖いが、個人用途のサーバーなら結構便利である。
Postfixのメールキューから指定の配信先メールだけ削除する

postsuperコマンドでALL以外でキューを削除するにはキューIDを指定しなければいけません。
postqueueコマンドでキューの内容から指定のアドレスを送信先とするIDの一時ファイルを作成してキュー削除をループさせます。


```shell-session:deletequeue
#!/bin/bash
#
# postfix mail queue delete script
# usage : bash deletequeue hoge@example.com
#
FILENAME="queueids.tmp"

if [ $# -lt 1 ];then
   echo "an argument mail address is required!"
   exit 1
fi

date
postqueue -p

postqueue -p | grep $1 > $FILENAME
sed -i 's/\s.*$//g' $FILENAME
sed -i 's/\*//g' $FILENAME

cat $FILENAME | while read line
do
  echo "Remove ${line}"
  postsuper -d $line
done
```

これだけなら簡単ですね。
実行の方法は下記の通り

```shell-session:実行例
bash deletequeue hoge@example.com
```

これでhoge@example.comから来たメールキューだけ削除することができます。
大量に送信され続けてしまっていて即止めるのが困難な場合はブロックが前提ですがdeferにたまってしまったメールの再送もよけておきたいならワンライナーでこれをしばらく実行し続ければとりあえず暫定対処できます。
deferだから重要なメールがないとも限らないのでその方が安全です。難点はタイミングによって一度送信トライされてしまうところですが。

```shell-session:実行例
while true; do bash deletequeue hoge@example.com; sleep 1; done
```

コマンドを終了したいときはCtrl+Cで終了します。
Time.nowとDate.todayをキーワード引数に対応させるgemを作った

多分、どっかにあるはずなのだが、探すより作るのが早いシリーズ。

現在時刻とか、既に存在しているTimeクラスのオブジェクトの時間だけを変えたものとか、秒以下を切り捨てたものを生成する時に、キーワード引数でスマートに書きたくなったので、gemにしてみた。
こういう事ばっかやってるから、Rubyのgemは玉石混交だとか言われてしまうのだが…。

[joker1007/keyword_arg_time](https://github.com/joker1007/keyword_arg_time "joker1007/keyword_arg_time")

## Usage

```ruby
require 'keyword_arg_time'

Time.now(hour: 10, min: 15, sec: 0) # => 2014-01-10 10:15:00 +0900

time = Time.local(2014, 1, 10)      # => 2014-01-10 00:00:00 +0900
time.copy(hour: 10, min: 15)        # => 2014-01-10 10:15:00 +0900

Date.today(mon: 3)                  # => <Date: 2014-03-10 ((2456727j,0s,0n),+0s,2299161j)>

date = Date.new(2014, 1, 10)        # => <Date: 2014-01-10 ((2456668j,0s,0n),+0s,2299161j)>
date.copy(day: 25)                  # => <Date: 2014-01-25 ((2456683j,0s,0n),+0s,2299161j)>
```

これ、ActiveSupportとかに入らんかなー。
もしくは、もっと良い名前で組込みメソッドとかにならんかなー。

追記:
`copy`の動作をする`change`というメソッドはちゃんとあった。流石ActiveSupport。
Rで起動引数のパース

Rでunixぽい起動引数のパースしてくれるライブラリoptparseのメモ。
殆ど、Pythonの同名ライブラリと同じ使い方。

スクリプト本体

```r:optparse.r
#!/usr/bin/env Rscript




library(optparse)




## make_optionでオプションの詳細を記述。それをリストにまとめる。
## オプションの記述方法は、Pythonのoptparseライブラリと殆ど同じ。
optslist <- list(
    make_option("--flag1",
                action="store_true",
                default=FALSE, 
                help="A Flag"), 
    make_option(c("-f", "--flag2"),
                action="store",
                default=FALSE,
                type="logical",
                help="A Flag"),
    make_option("--num",
                type="integer",
                default=1,
                help="A Number"),
    make_option("--raw-data",
                type="character",
                default="piyo",
                help="a string")
    )
parser <- OptionParser(option_list=optslist)
opts <- parse_args(parser)




## parse_argsで、起動引数の内容を含んだリストが取得出来る。
cat(sprintf("flag1=%s
flag2=%s
num=%d
raw-data=%s
",
            opts$flag1,
            opts$flag2,
            opts$num,
            opts[["raw-data"]]))




## 明示的にヘルプメッセージを出したい場合は、print_help
cat("\n\n\n--- help message ---\n")
print_help(parser)
```

出力

```sh
bash-3.2$ ./optparse.r --flag1 --num=101 --raw-data=foobar
flag1=TRUE
flag2=FALSE
num=101
raw-data=foobar



--- help message ---
Usage: ./optparse.r [options]


Options:
	--flag1
		A Flag

	-f FLAG2, --flag2=FLAG2
		A Flag

	--num=NUM
		A Number

	--raw-data=RAW-DATA
		a string

	-h, --help
		Show this help message and exit



```
scss positionのmixin

```
@mixin position ($value:0 0,$coord:top left,$pos:absolute) {
	position: $pos;
	$length: length($value);
	@if $length == 1 {
		#{nth($coord,1)}: $value;
	}
	@else if $length == 2 {
		#{nth($coord,1)}: nth($value,1);
		#{nth($coord,2)}: nth($value,2);
	}
}

/*指定なし*/
.a { 
	@include position;
}

.a {
	position: absolute;
	top: 0;
	left: 0;
}

/*位置の値を１つ指定*/
.b { @include position(10px); }

.b {
	position: absolute;
	top: 10px;
}

/*指定の位置１箇所を指定*/
.c { @include position(10px, right); }

.c {
	position: absolute;
	right: 10px;
}

/*位置の値を２つ指定*/
.d { @include position(10px 5px); }

.d {
	position: absolute;
	top: 10px;
	left: 5px;
}

/*指定の位置２箇所を指定*/
.e { @include position(10px 5px, bottom right); }

.e {
	position: absolute;
	bottom: 10px;
	right: 5px;
}
- というディレクトリに cd で移動する


やんごとなき事情で - というディレクトリで作業する必要が出てきたんだけど、

```bash
cd -
cd \-
cd -- -
```

等々で移動できず困った。

```
cd ./-
```

で解決した。美顔器さんに教えて貰った。
PHP+Subversion+Capistrano


## 概要
PHPのレガシーなプロジェクトをCapistranoでdeployする

## 環境
* Ruby 1.9.3
* Capistrano 2.x
* PHP
* Subversion

## 備考
Capistrano 3.xはSubversionに未対応のようなので、2.xを使う。
Rubyはrbenvなどを使い、1.9.3以降をインストールする。2.0でも大丈夫な模様。

## インストール
バージョンを指定するために、以下のようなGemfileを作成する。

```Ruby
source 'https://rubygems.org'
gem 'capistrano', '~> 2.0'
gem 'capistrano-ext'
gem 'capistrano_colors'
gem 'railsless-deploy'
```

bundleでインストールする。

```
$ gem install bundle
$ rbenv rehash
$ bundle install
$ rbenv rehash
```

## ひながた作成

適当なディレクトリを決めて、capifyでひながたを作る。Capfileやconfig/deploy.rbが生成される。

```
$ capify .
```

## 設定
基本的なタスクは内蔵されているので、config/deploy.rbに少し追記するだけでよい。
capistrano-extで複数の環境にも対応できる。
config/deploy.rbに共通の設定を記述し、config/deploy/以下に環境ごとのファイルを置く。

デバッグなどでローカルからローカルにdeployする場合は、copy_remote_dirを指定してファイル名を変更する必要がある。
ログをファイルに出力したいときはloggerの部分をコメントアウトする。

```Ruby:config/deploy.rb
require 'capistrano/ext/multistage'
require 'capistrano/logger'

set :default_stage, "staging"
set :application, “hoge"
set :scm, :subversion
set :deploy_via, :copy
set :copy_exclude, [".svn", "**/.svn"]
set :use_sudo, false
#set :copy_remote_dir, "/home/www/tmp"

set :ssh_options, {
  user: 'www-data',
  keys: %w(~/.ssh/id_rsa_www-data)
}

#output = './capistrano.log'
#custom_logger = Capistrano::Logger.new(:output => output)
#custom_logger.level = Capistrano::Logger::TRACE
#self.logger = custom_logger
```

個別の環境のタスク。
define文で定義されている定数をsedで無理やり書き換えてみた。

```Ruby:config/deploy/staging.rb
set :repository,  "https://hoge.com/svn/hoge/branches/hoge"
set :deploy_to, "/home/www/hoge-staging"
set :copy_cache, "./checkout/staging"

role :web, “localhost"
role :app, "localhost"
role :db,  "localhost", :primary => true
role :db,  "localhost"

def self.modify_constant(file, sym, val)
  options = "s%define.*['\\\"]#{sym}['\\\"].*%define('#{sym}', #{val});%"
  run "sed -i \"#{options}\" #{release_path}/#{file}"
end

namespace :deploy do
  task :restart, :except => { :no_release => true } do
    #do nothing.
  end

  task :finalize_update, :except => { :no_release => true } do
    self.modify_constant(‘config/database.php’, ’MYSQL_HOSTNAME', “’localhost'")
    run "mkdir -p #{release_path}/smarty/compile"
  end

  after "deploy:update", :except => { :no_release => true } do
    cleanup
  end
end

```

## 実行

defaultの環境の場合

```
$ cap deploy
```

環境を指定する場合

```
$ cap staging deploy
```

## 参考

https://github.com/capistrano/capistrano/wiki

http://kenkennote.com/blog/2012/06/06/deploy-with-capistrano/

http://qiita.com/mosson/items/1a4cfd01cb538f2d8f0e

http://d.hatena.ne.jp/kenjiskywalker/20121123/1353651895

http://stackoverflow.com/questions/14860584/define-custom-methods-for-capistrano

http://rochefort.hatenablog.com/entry/20110117/p1
setuptools>=0.8と言われた時

* [CentOS 6.5 の python-setuptools で pip が動かなくなった件 | CUBE SUGAR STORAGE](http://momijiame.tumblr.com/post/72664567612/centos-6-5-python-setuptools-pip)
と同じく、10.9でハマっていた。

```bash:対処の仕方
$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | sudo python
$ sudo easy_install pip
```

これで使えるようになります。
Windowsでcucumber実行時にSSLエラーが出た場合の対処法

* Windows環境でcucumberを実行したところ以下のようなエラーが出た

```
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
C:/Ruby193/lib/ruby/1.9.1/net/http.rb:800:in `connect'
C:/Ruby193/lib/ruby/1.9.1/net/http.rb:800:in `block in connect'
C:/Ruby193/lib/ruby/1.9.1/timeout.rb:55:in `timeout'
C:/Ruby193/lib/ruby/1.9.1/timeout.rb:100:in `timeout'
C:/Ruby193/lib/ruby/1.9.1/net/http.rb:800:in `connect'
C:/Ruby193/lib/ruby/1.9.1/net/http.rb:756:in `do_start'
C:/Ruby193/lib/ruby/1.9.1/net/http.rb:745:in `start'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:306:in `open_http'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:775:in `buffer_open'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:203:in `block in open_loop'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:201:in `catch'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:201:in `open_loop'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:146:in `open_uri'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:677:in `open'
C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:33:in `open'
```

## 対処方法
* SSL証明書を配置し、環境変数SSL_CERT_FILEにそのパスを入れる
 * SSL証明書は http://curl.haxx.se/ca/cacert.pem からDLする
  * cURLのサイト上で配布してるMozillaで利用している証明書らしい

### ソース
* http://igarashikuniaki.net/diary/20130617.html
* http://qiita.com/hotchpotch/items/12457815d5cee3723b97
PHPでLTSVフォーマットを扱う（Text-LTSVのご紹介）

[LTSV（Labeled Tab-separated Values）](http://ltsv.org/)、便利ですよね。PHPで簡単にLTSVフォーマットを扱えるライブラリを作って公開しているのでご紹介です。ライブラリはここにあります: https://github.com/hiroy/clover-text-ltsv

Composerでインストールできるようにしてあるので、Composerを使ってのインストールが一番簡単だと思います（PHPのファイルは1つだけですが）。

使い方は次のように。簡単にLTSVのフォーマットを扱えるので、ログ出力などと組み合わせて使うのもいいかもしれません。

```php
<?php
$ltsv = new Clover\Text\LTSV();

$values = $ltsv->parseLine("hoge:foo\tbar:baz");

$values = $ltsv->parseFile('log.ltsv');

$it = $ltsv->getIteratorFromFile('log.ltsv');
foreach ($it as $values) {
    // do something
}

$ltsv->add('hoge', 'foo')->add('bar', 'baz');
$line = $ltsv->toLine();
```

バグや機能追加については、GitHubからご連絡いただけたらうれしいです。
Rails4のexception_notificationでsessionの情報が表示されない

# Rails4では ExceptionNotification が session 情報を表示しない
エラーが起きた時にメールを飛ばしてくれる [ExceptionNotification](https://github.com/smartinez87/exception_notification) ですが、Rails4ではsessionの情報をちゃんと表示してくれません。（2014/01/09時点、version 4.0.1）

エラーメールのSessionの欄は下のようになっており、dataがうまく表示されていません。

```
-------------------------------
Session:
-------------------------------

 * session id: "abcdef123456789..."
 * data: #<ActionDispatch::Request::Session:0x007fc38b0f5fe0 ...>
　
```

# 解決法

これは [2013/12/9 の Pull Request](https://github.com/smartinez87/exception_notification/pull/192) で修正されていますが、versionは変わらず、4.0.1 のままなので、 `Gemfile` ではgithubのレポジトリを指定する必要があります。

```rb:Gemfile
gem 'exception_notification', "~> 4.0.1", :git => "https://github.com/smartinez87/exception_notification", :branch => "master"
```

これで表示されるはずです。
Xamarin.iOSバインディングで、コールバックインタフェースのプロトコルを定義する方法

[この辺](https://github.com/mono/monotouch-bindings/blob/master/GoogleMaps/binding/ApiDefinition.cs#L949)([diff](https://github.com/mono/monotouch-bindings/commit/82f85354c0398b17a247f2012003df6627b9aa05))とかの問題。

Xamarin.iOSバインディングで、Objective-Cのprotocolを移植するには、こんな感じに書くようです。

```csharp:ApiDefinition.cs
        [BaseType (typeof (NSObject), Name="GMSTileReceiver")]
        [Model]
        [Protocol]
        interface TileReceiver {

                [Abstract]
                [Export ("receiveTileWithX:y:zoom:image:")]
                void ReceiveTile (uint x, uint y, uint zoom, UIImage image);
        }
```
ディレクティブで[protocol]というのを書いておくと、アブストラクトクラスTileReceiverだけでなく、ITileReceiverというインタフェースも作ってくれて、それをプロトコルとして使えばいいようです。
が、このprotocolが標準APIの中でコールバックメソッドの引数になってたりするとちょっとウザいです。

```csharp:ApiDefinition.cs
                [Export ("requestTileForX:y:zoom:receiver:")]
                void RequestTile (uint x, uint y, uint zoom, TileReceiver receiver);
```

こんな書き方だと、飽くまでGMSTileReceiverプロトコルはTileReceiverではなくITileReceiverに結び付けられるので、APIが返してきたGMSTileReceiverはTileReceiverのサブクラスにはならないのでエラーになります。
メソッドの引数定義にITileReceiverと書いてしまうと、そんな型の定義はないと怒られてしまいます。
かといって、プロトコル定義の方の名前をITileReceiverにしても怒られるので、どうすればいいの、と頭を抱えましたが…。

結論を書くと、単に定義なしでITileReceiverというインタフェースもあるよ、と書いてやればいいだけでした。
全体を書くとこんな感じ。

```csharp:ApiDefinition.cs
        [BaseType (typeof (NSObject), Name="GMSTileReceiver")]
        [Model]
        [Protocol]
        interface TileReceiver {

                [Abstract]
                [Export ("receiveTileWithX:y:zoom:image:")]
                void ReceiveTile (uint x, uint y, uint zoom, [NullAllowed] UIImage image);
        }

        interface ITileReceiver {} <= これ！

        [BaseType (typeof (NSObject), Name="GMSTileLayer")]
        interface TileLayer {

                [Export ("requestTileForX:y:zoom:receiver:")]
                void RequestTile (uint x, uint y, uint zoom, ITileReceiver receiver);

                [Export ("clearTileCache")]
                void ClearTileCache ();

                [Export ("map")]
                MapView Map { get; [NullAllowed] set; }

                [Export ("zIndex", ArgumentSemantic.Assign)]
                int ZIndex { get; set; }

                [Export ("tileSize", ArgumentSemantic.Assign)]
                int TileSize { get; set; }
        }
```

後、NULLを認める引数は[NullAllowed]というのをつければいい、というのもこいつで覚えました。
X-SendFileを用いて静的ファイルをサーブ

# 情報の鮮度

* 2014-01-10時点
* Debian GNU/Linux 7.3 (wheezy)/Ubuntu 13.10
* Python 2.7 (apt-get経由)
* django 1.4〜1.5

# バックグラウンドとmod_auth_tkt の問題

こちらの続きです。
http://qiita.com/amedama/items/3f2197cadc1ea7d6374e

* djangoのWebサイト上に動的に増減するプロジェクトがあるとします
    * 例えばRedmineみたいなプロジェクト管理ソフトを作るとしましょ
* プロジェクトに参加しているユーザにだけ静的ファイルを見せたいことがあります
* このシナリオに mod_auth_tkt はマッチしません
    * TKTAuthToken の値を動的に変更するのが面倒というか、そのまんまだと割と無理というか……
    * Apacheの環境変数を %{ENV:SOMETHING} みたいに指定できないんですよね、実装みた限り。
    * 2.4 から Define が導入されたということで、使える、かも、しれませんが
    * 一瞬本気でmod_auth_tktを修正しようと思ったんですが、さいきん全然開発されてないのな。
* ていうか管理めんどいじゃー！
    * apacheの設定で使う定数とdjangoの定数を共有させてくれー

# X-SendFile

で、X-SendFileです。

これがResponseヘッダに含まれていると、WSGIアプリの配下のWebサーバ、つまり今回はApacheが、
ユーザに応答を返す前に勝手にそのパスを展開してユーザにファイルを送り始める、というもんです。
nginx周りの記事の方が多いのですが、べつにモジュール入れればApacheでも動きます。

パフォーマンスに関する評価は、……もちろんスルー。

DBにファイルが含まれてたりすると多分ダメです。

http://stackoverflow.com/questions/7296642/django-understanding-x-sendfile

Debian/UbuntuのApache2の場合は libapache2-mod-xsendfile を入れます。

    # prepare "@project_member_required" by yourself
    @login_required
    @project_member_required
    def download_project_file(request, project_name, file_name):
        response = HttpResponse()
        # prepare this function by yourself
        download_path = construct_path_from_file_name(file_name))
        response['X-Sendfile'] = download_path
        response['Content-Type'] = ''
        return response

上記の場合、

* ログインしてなければログイン画面が出ます。
* プロジェクトメンバーでなければ @project_member_required が怒ります (という風に作ります)
* ファイルがなければApacheがその場で怒ります。

Apacheの設定上で

    XSendFile on
    XSendFilePath /opt/yourproject/downloads

とかやると /opt/yourproject/downloads がホワイトリストに登録されます。
逆に言うと、パスの指定を間違えると何も送信されません。

参考: https://tn123.org/mod_xsendfile/

# おまけ
## django-sendfile (https://github.com/johnsensible/django-sendfile)

"django X-SendFile" のググり結果で先頭に出てくるのですが地雷です。
これはdjango上でファイルを読み込んで展開してコンテンツで返す実装で、効率的とは程遠いものです。

# 最後に

コメントをお待ちしております。
Gmail の仕様変更で表示されなくなったイントラネットの画像を表示するブックマークレット

Gmail が仕様変更して、メール内の画像を Google のプロキシを通じて表示するようになりました。
記事としては、[GoogleがGmailの添付画像を自動表示可能に。 プロキシサーバを介しての配信でセキュリティ確保。](http://www.life-gp.net/2013/12/googlegmail.html)とか、[Gmail、メッセージに含まれる画像を自動表示するよう変更](http://internet.watch.impress.co.jp/docs/news/20131213_627651.html)とか。

セキュリティの担保と利便性の向上っていう目的は分かるのですが、この措置により Google のプロキシがアクセスできないイントラネット上の画像が表示できない、という問題が発生しています。

…というのを解決するブックマークレット書きました。セキュリティを担保する、という Google の意志を尊重して、あえて自動化せずブックマークレットにしています。利用は自己責任で！
また、今のところ自分の目的では事足りていますが、もし画像の置換漏れがあれば、解説を参考に適宜追加したら良いと思います。

```js
javascript:(function(d,ex){NodeList.prototype.each=Array.prototype.forEach;d.$=d.querySelectorAll;d.$('img[src*="googleusercontent.com"]').each(function(e){e.src=e.src.replace(ex,"\$1")});d.$('*[style*="googleusercontent.com"]').each(function(e){e.style.backgroundImage=e.style.backgroundImage.replace(ex,"\$1")})})(document,/https?:\/\/.*\.googleusercontent\.com\/[^#]+#([^\)"]+)/);
```

解説

```js
// document オブジェクトと後で使う RegExp オブジェクトを受け取る
(function(d, ex){
	// NodeList が forEach 持って無いので Array から移植
	NodeList.prototype.each = Array.prototype.forEach; 
	// quarySelectorAll 長ったらしいので省略
	d.$ = d.querySelectorAll;
	// img 要素内の src 部分を置換
	d.$('img[src*="googleusercontent.com"]').each(function(e){
		e.src = e.src.replace(ex, "\$1");
	});
	// style の background で画像を指定しているところを置換
	d.$('*[style*="googleusercontent.com"]').each(function(e){
		e.style.backgroundImage = e.style.backgroundImage.replace(ex, "\$1");
	});
// 正規表現で Google のプロキシとその URL の後ろについているオリジナルの URL を取り出す
})(document, /https?:\/\/.*\.googleusercontent\.com\/[^#]+#([^\)"]+)/);
```
Test Driven Websites with jasmine and jQuery


# Articles
- [jasmine-jqueryというかloadFixturesが便利 ::ハブろぐ](http://havelog.ayumusato.com/develop/javascript/e309-jasmine_jquery_fixtures.html)

    - loadFixturesの紹介

- [HTML fixtures in Jasmine (using jasmine-jquery) | Test Driven Websites (TDD and BDD in RoR and JS)](http://testdrivenwebsites.com/2010/07/29/html-fixtures-in-jasmine-using-jasmine-jquery/)

    - jasmine-jqueryを使ってのjQueryプラグインのテスト方法


# Tutorial Videos
- 概要もチェックしていないがタイトルから気になるものだけメモ
- [13JavaScript Testing With Jasmine - Jasmine and jQuery - Jasmine-jQuery-Matchers - YouTube](http://www.youtube.com/watch?v=3Huh44nsZTw)
- [14JavaScript Testing With Jasmine - Jasmine and jQuery - Jasmine-jQuery-Fixtures - YouTube](http://www.youtube.com/watch?v=4YNaHE2VIa8)
- [15JavaScript Testing With Jasmine - AJAX and Workflow - Spies - YouTube](http://www.youtube.com/watch?v=voDU2pQvZm8)
findで直接where句を書く方法


find()でwhere句にSQL関数を使用したい場合、以下のようにと書くと「now()- interval 7 day」の部分が文字列になってしまう。

```php:SQL関数が文字列になってしまう例
$User->find('all',array(
    'conditions' => [
        'modified >'=> 'now()- interval 7 day'
    ]
));
```

SQL関数を使用したい場合は、findで直接where句の内容を書けば良い。書き方は以下の通り。

```php
// 7日以内に更新されたレコード
$User->find('all',array(
    'conditions' => [
        ['modified >now()- interval 7 day']
    ]
));
```