OmniAICreator/Qiita-1.07M huggingface dataset:
エクセルで reverse-complement

2010

プライマー云々の表についての雑用。
大まかな所は VBA を使わずに、

* 大文字化 => `=upper("塩基配列")`
* 長さ => `=len("塩基配列")`
* A,C,G,T の数 => `=len("塩基配列") - len(substitute("塩基配列","A",""))`
* tm値 =>　`=if("長さ">18,"最近接塩基対法の計算式"," Wallace 法の計算式")`

てな具合に実装出来たのだけど、reverse-complement だけは、面倒臭そう。

仕方ないので、VBA するが、絶対忘れるのでメモ。
それと、ドロップダウンリストの実装方法も。

## reverse-complement
開発 => 挿入 => 標準モジュール [^1]


[^1]: Alt + F11

で、以下を貼りつけて「終了して Excel(ry へ戻る」[^2]

[^2]: Alt + Q


```vba:どこぞで拾ったの
Function revcomp(c)
    Dim i As Long
    Dim newstr As String
    i = Len(c)
    For i = i To 1 Step -1
        Select Case UCase(Mid(c, i, 1))
            Case "A"
            newstr = newstr & "T"
            Case "C"
            newstr = newstr & "G"
            Case "G"
            newstr = newstr & "C"
            Case "T"
            newstr = newstr & "A"
        End Select
    Next
    revcomp = newstr 
End Function
```
もちろん保存は、"マクロ有効ブック"

で、使い方は、セル選択して

```excel:
=revcomp("塩基配列")
```

* 戻り値はプロシージャ名にセットする事で戻る
	* `sub` と `function` の違いは戻り値の有無
* `for i = i to 1 step - 1`  は逆順カウントのお約束
	* `next` を忘れそう
* `mid` は文字列抽出
* `select case` で select 文
* `&` で連結

### メモ

* `reverse` は、 `StrReverse`
* 後は、 RegExpオブジェクト関連を調べて `tr///` 辺りを。


## ドロップダウンリストの編集方法

1. データタブの「データの入力規則」を実行
2. 入力値の種類からリストを選択
3. 元の値の所
	* 右端のアイコンをクリックで GUI にて範囲指定
	* 文字列をカンマ区切りで
console.log,timerのないブラウザのデバック

古いブラウザはconsole.logやtimerがないので不便です。
特にパフォーマンス問題などが発生した場合、調査したいけどロガーもタイマーもないでは全くやる気がおきないです。

何度かそんなことを経験して毎度alertを仕込んできたのですが、
いい加減うんざりしてきたので、console.logとconsole.timerを自作しました。

基本的にはwebkitの仕様にしたがったつもりです。細かい動きは抜けているかもしれません。
conosleオブジェクトがない場合は、HTMLに吐き出すようにしています。

console.timeやerrorなどが個別にない場合は
console.logを使って出力するようにしています。

```js
        //生成したdivに出力
        window.console.log = function(value){
            var html = "";
            var i= 0;

            for(i;i<arguments.length;i++)
            {
                html += arguments[i];
            }

            div.innerHTML += html + "</br>";
        };

        window.console.error = window.console.log;
        //タイマーを開始
        window.console.time = function(key){
            window.time || (window.time = {});

            window.time[key] = new Date().getTime();
        };

        //タイマーを終了
        window.console.timeEnd = function(key){
            window.time || (window.time = {});

            var processTime = +new Date() - window.time[key];
            window.console.log("Time " + key + ":" + processTime + "msec");

            delete window.time[key];
        };
```

全体はこちらです。

https://github.com/coa00/ieConsoleTimer

IE7,8あたりで動作確認をしました。それなりに動いています。
スタイルは好きに編集してもらうのがいいと思います。

依存ファイルもなく単体で動くようにつくったのでscriptタグにはっつけてもらえば単体で動きます。bodyタグのなかで呼んでください。

8年も前のブラウザが未だ現役とか本当切ない。
8年前のブラウザで8年後のサイトをみたら、それは色々あるに決まっている！
HashSetのcontainsメソッドについて

標準の[JavaDoc](http://docs.oracle.com/javase/jp/8/docs/api/)にはこう書かれてるんすよ。

> 指定された要素がセットに含まれている場合にtrueを返します。つまり、このセットに、(o==null ? e==null : o.equals(e))となる要素eが含まれている場合にのみtrueを返します。

つまりオレオレクラスを使ったHashSetでcontainsしたいときは、オレオレクラスにequalsだけオーバーライド実装すればいいと思うじゃないですか？
ところが残念、hashCodeもオーバーライド実装しないと正しく動かないんですねぇ～～～～～～

[ひしだまさんのところ](http://www.ne.jp/asahi/hishidama/home/tech/java/object.html#equals)でequalsをオーバーライドするならhashCodeもオーバーライドせなあかんよ～って書かれてるのはこういうことだったんですねぇ～～～～～～～～
JavaDocにちゃんと書いておいて欲しいですねぇ～～～～～～～～
JavaDocは大切ってことですねぇ～～～～～～～～～
Raspberry Pi遊んでみた (基本設定編)

# この記事のゴール
ラズパイ買ってから、OSインストールして無線でネットできるところまで。

![pi_skitch.png](https://qiita-image-store.s3.amazonaws.com/0/72808/59b2e8aa-8d5d-b65c-4f88-62751d27945c.png)

# Why Raspberry Pi?
- 家にあったから。
    - Arduinoは一度遊んでみたことあるので、比較してみようかなというのもある。

# やったこと

## 必要なものの準備
- Raspberry Pi本体
    - 今回は貰い物のModel B
- SDカード
    - コンピュータにおける不揮発性記憶装置ポジション
        - ここにOS入れる
    - 今回は(最終的に)16GBを使用
- ディスプレイ
    - HDMI対応してるヤツを。
        - 初期設定時くらいしか使わないので、専用のを買う必要ナシ。
- HDMIケーブル
    - 映像出力用。
    - 試してないが、音声も出力できる模様(HDMIだもんね)
- USBケーブル(A - microB?)
    - 給電用。iPhoneの充電用のACアダプターと繋げて使う。
    - PC経由だと電圧足りなくて起動しない、はず。
- 無線Wifiのドングル
    - 今回有線を使わない予定なので、必須。
        - 何か相性あるっぽいけど、[このあたり](http://denshikousaku.net/raspberry-pi-wifi-lan-usb)を参考にすれば良いかと。
- USBキーボード
    - 初期起動時に必要。
        - 最終的に別端末からSSHログインできるようにするので、いらなくなる。

## あったら便利なものの準備
- USBハブ
    - デフォだとWifiドングルとキーボードでポートが埋まる。
- USBマウス
    - X Windowで遊びたいなら。

## いざインストール
基本的に、[こじ研（Raspberry Pi） - 宮城大学](http://www.myu.ac.jp/~xkozima/lab/raspTutorial1.html)に沿って作業。

1. SDカードにOSを書き込む
    - [NOOBS](http://www.raspberrypi.org/downloads/)を使うのも手。
        - 実際にRaspbian入れるときは、これ使った。
2. SDカードをRaspberry Piに差し込んで起動
3. 手順に沿ってインストール
4. 何かこまごま設定

## 基本環境の設定
1. shとかvimの設定
    - 通常のLinux同様に設定可能なので、ご自由に。
2. 無線Wifiの設定
    - 参考ページに沿って作業。
3. リモートログインの設定
    - 参考ページに沿って作業。
    - とりあえずMac(Yosemite)とiPad(iOS 8.2)でログインできることを確認。

## 途中ハマったところ
#### インストールクソ遅い
- SDカードの転送速度のせいなのか、かなり時間がかかる印象。
    - まぁインストール開始したら放置すればいいんですけどね。

#### SDカード(4GB)で試したら、Raspbian入れたことには残容量が酷いことに･･･
- X Windowとか使わないコンポーネント消せばある程度空く。

#### 起動中にUSBキーボードを抜き差しするとrebootする
- 多分抜き差しの瞬間に電圧(電流?)が落ちて、駆動に必要なパワーが一時的に落ちたものと推測


## Tips的なもの
#### リモートログインできるところまで行くと、ディスプレイもキーボードも不要になる
起動した時点でWifiに繋がってるので、そこからはリモートログインしてやりたい放題できる。
つまり、普通(?)のサーバのように運用できる。


# おわりに
つぎはLEDやタクトスイッチなど、基本的なセンサ/アクチュエータで遊んでみる。
=>　LED光らせてみた。[Raspberry Pi遊んでみた (Lチカ編)](http://qiita.com/IsaoTakahashi/items/f59cb21f1202fade3d4f)
ReactiveCocoaでテスト(createSignalで作ったsignalのテスト)



createSignalでSignalを生成するロジックを作っていく場合、テストに悩んだので記録を残します。


```objective-c:test.m

//sampleSignalがテスト対象

-(void) testsampleSignal {

    XCTestExpectation *expectation = [self expectationWithDescription:@"t"];
    
    RACSignal *t = [RACSignal defer:^RACSignal *{
        return [self sampleSignal];
    }];
    
    [t subscribeCompleted:^{
        [expectation fulfill];
    }];
    
    
    [self waitForExpectationsWithTimeout:30 handler:^(NSError *error) {
    //後始末処理
    }];
    
}
```
手軽に画像付きツイートができる組み合わせを考えてみた


##スマホの文字入力が苦手なひと向き

今まではツイートに画像を付けたいときには、スマホを使ってツイートしていた。

だが、Twitter中継を頼まれる機会があったのです。
楽にツイート出来る組み合わせを考えてみました。

用意するもは、
・Mac
・Webカム
・三脚（Webカムを取り付けると便利。必須ではない）
・アプリ（Mac標準のPhoto Booth）
・Twitterアカウント

![photo1.jpg](https://qiita-image-store.s3.amazonaws.com/0/34551/5be87358-3895-c8ac-fcb9-bbd374df1090.jpeg "photo1.jpg")

アプリはこんなアイコンです。
![photo2.jpg](https://qiita-image-store.s3.amazonaws.com/0/34551/fc06e1ba-b88f-65b2-733b-65ecfa802c12.jpeg "photo2.jpg")

---

#準備

先ずはじめに、MacにTwitterのアカウントを設定します。
システム環境設定の中のインターネットアカウントを用いて登録する。（詳細は省略）

![photo3.png](https://qiita-image-store.s3.amazonaws.com/0/34551/b13f1383-f348-a06c-287e-5f0213dc8ec6.png "photo3.png")

---

次にPhoto Boothを起動し、編集メニューの「新しい項目を自動反転」にチェックを付ける。これを忘れると撮影した画像が左右反転したままになってしまうので重要です。

![photo5.png](https://qiita-image-store.s3.amazonaws.com/0/34551/cad30b4d-18be-c383-ee77-c21a324f3017.png "photo5.png")

---

最後に、Macにカメラを接続する。長時間行うならACアダプタも使った方がよいです。

---

#撮影


赤いカメラの形をしたアイコンの部分をクリックします。
およそ３秒のカウントダウンの後に撮影が行われます。
（このとき音が出るのでスピーカーはミュートにすることをおすすめ！）
しかし、３秒も待ったらシャッターチャンスを逃してしまいます。
そこで、optionキーを押しながらクリックすると瞬時に撮影ができます。
（ショートカットキーもあります）

![photo6.png](https://qiita-image-store.s3.amazonaws.com/0/34551/e7cd9838-1255-b28d-654a-cc7b85a2f3d4.png "photo6.png")

撮影されると、下の部分に反転した画像が並びます。

![photo7.png](https://qiita-image-store.s3.amazonaws.com/0/34551/fb543c50-5ec8-6743-3b46-5fb797170259.png "photo7.png")

※ここで、先ほどの反転する設定を忘れているとプレビューと同じ反転した画像が撮影されてしまいます。

---

#ツイート

いよいよツイートです。
撮影した画像をクリックすると左上にバッテンが表示されます。このバッテンを押すと画像を削除できます。

選択されているものは縁が強調表示されます。

![photo8.png](https://qiita-image-store.s3.amazonaws.com/0/34551/0536192e-8652-d585-654d-631bb2aa00cf.png "photo8.png")

この状態で、上にあるこのボタンをクリックします。

![photo9.png](https://qiita-image-store.s3.amazonaws.com/0/34551/36f12ae2-6c33-d961-9fc6-8b03ee0c3e2d.png "photo9.png")

そして表示された一覧からTwitterを選択。

![photo10.png](https://qiita-image-store.s3.amazonaws.com/0/34551/e3f4fabd-8546-8f53-d771-e489da25f6fb.png "photo10.png")

このような画面が表示されるので、文書を入力してツイート！

![photo11.png](https://qiita-image-store.s3.amazonaws.com/0/34551/b943aeee-3f85-7231-bc0d-e6f21524ee3d.png "photo11.png")

Macに複数のTwitterアカウントが登録されているときには、画像の左上の辺りに選択するコントロールが表示されます。
（この例では表示されていない）

![photo12.png](https://qiita-image-store.s3.amazonaws.com/0/34551/fade8410-fefe-274f-87c6-2da6909a62ab.png "photo12.png")

---

いかがだったでしょうか？
リストに `sequence` を適用する、とは


リストに `sequence` を適用してみた結果に混乱したので整理しておく。

```hs
sequence [[1], [2], [3]] -- [[1,2,3]]
```

はて、果たして、`sequence` 関数は何をやっているんだろう。リスト内のリストを結合するだけ？

## 関数の定義

```hs
-- | Evaluate each action in the sequence from left to right,
-- 
and collect the results.
sequence       :: Monad m => [m a] -> m [a] 
{-# INLINE sequence #-}
sequence ms = foldr k (return []) ms
            where
              k m m' = do { x <- m; xs <- m'; return (x:xs) }

instance  Monad Maybe  where
    (Just x) >>= k      = k x
    Nothing  >>= _      = Nothing

    (Just _) >>  k      = k
    Nothing  >>  _      = Nothing

    return              = Just
    fail _              = Nothing

```

ここで局所関数 `k` は `m a` と `[m a]` をとって `m [a]` を返す関数であることがわかる。この操作を使って、`foldr` で畳み込むのが `sequence` ということになる。

対象が `Maybe` モナドの場合、次のような結果となりわかりやすい。**失敗するかもしれない文脈** を除いた値をリストにしている。

```hs
sequence [Just 5, Just 100] -- Just [5,100]
sequence [Just 5, Nothing, Just 100] -- Nothing ( Nothing から値を取ろうとして fail が呼ばれる )
```

リストモナドの場合、例えばこのようになる。

```hs
sequence [[1], [2], [3]] -- [[1,2,3]]

sequence ["abc", "ABC"] -- ["aA","aB","aC","bA","bB","bC","cA","cB","cC"]

sequence [ "ab", "", "ef"] -- [] ( 空リストから要素を取ろうとして fail が呼ばれる )
```

そう、リストモナドの文脈は **非決定性計算** なので、その文脈を維持して外側のリスト内の各要素を後ろから結合することになる。ゆえに、外側のリスト内の各要素（これもリスト）の要素数を掛け合わせた分だけ、結合した結果がたくさん出来上がる。

外側のリスト内の各要素の要素数が、それぞれ 1 なら、結合した結果がひとつだけできる。これで冒頭のはてなが消えた。

ちなみに、リスト内包表記だと次のような感じで同じように書ける。

```hs
[[x,y] | x <- "abc", y <- "ABC"] -- ["aA","aB","aC","bA","bB","bC","cA","cB","cC"]
```

## えっと・・
整理していたら、当たり前のような気がしてきた。
InstallShield LE for VisualStudioをいろいろ試したので備忘録

# 動作環境
* Windows 8.1
* VisualStudio 2013
* InstallShield Limtied Edition

# 基本的な使い方
1. ソリューション→追加→新しいプロジェクト
 * InstallShield Limited Edition Projectを選択
 * インストールされてなければ「InstallShield Limited Edtionの有効化」が表示されるのでインストール
* project assistantに従って項目を埋めていく
* ビルド→ソリューションのビルド

# 基本的なオプション
## Application Information
![スクリーンショット 2015-03-25 17.05.54.png](https://qiita-image-store.s3.amazonaws.com/0/10833/45b482a9-c270-d837-45b3-8ecda1b25d81.png)

入力欄通り上から会社名、アプリケーション名、バージョン、会社URLを入力

## Installation Requiements
特に何も指定しなかった。
Windowsのバージョン指定やIE、Officeの依存等を指定できるっぽい。

## Installation Architecture
特に何もしなかった。
よく読んでないけどInstallShield LEではほとんど何もできない？

## Application Files
![スクリーンショット 2015-03-25 17.14.22.png](https://qiita-image-store.s3.amazonaws.com/0/10833/e796ebf1-f299-f23f-026b-e3f7e0619d04.png)
Add Project Outputsから、インストーラに何を含めるのかを選択

* ”プライマリ出力”ってのがいわゆるバイナリのことっぽい
* **言語のスタティックリソースを持っている場合”ローカライズされたリソース”を含めないとローカライズされず嵌まった**

## Application Shortcuts
![スクリーンショット 2015-03-25 17.17.55.png](https://qiita-image-store.s3.amazonaws.com/0/10833/0472dff4-68ae-28e5-e49c-506d63b87c17.png)
ショートカットを作れる。

* バイナリのショートカットを造るなら、"New"で出てきたダイアログから、ProgramFilesFolder→会社名ディレクトリ→My Product Name→app.プライマリ出力
* デフォルトでショートカット名が"build"になってるので適当に修正しないと悲しい

## Application Registry
特に何もしなかった。

## Installation Interview
インストーラで何を表示するか選択できる。

* 会社名とユーザ名の入力を求めるダイアログはいらないのでNoにしておいた。

## General Information
![スクリーンショット 2015-03-25 17.08.06.png](https://qiita-image-store.s3.amazonaws.com/0/10833/2a2a6c2a-1263-90b2-1035-b691c6e3ce7c.png)

General

 * Product Code
  * これをビルドの度に書き換えないと、インストール時に「すでにインストール済み」って怒られる。書き換えはKeyをクリックするとValueの右に出てくる"{..}"をクリックすると行ける。
 * Setup Language
  * インストーラを日本語にできる
 
Software Identification Tag

 * Use Software Identification Tag
  * "No"にしないとビルドエラーが出る。要調査。

# その他メモ

* Product Codeを変えないとアップデートできないインストーラになるが、変えてインストールするとコントロールパネルの「プログラムと機能」に同じ名前のアプリが増えていく。要調査。
* アプリケーションのビルド構成をA,B二種類使い分けたい場合、アプリケーション側プロジェクトのプロパティからアセンブリ情報で、アセンブリバージョンを上げないとインストーラが上書きしてくれない。（Aがすでにインストールされた状況で、Bを上書きしたい場合）

# ToDo

* マイナーアップデートをスマートにやる方法
dockerのコンテナ実行時にLANGなどの環境変数を設定する方法


#初めに
わかってみれば、当たり前で簡単なのですが、結構ハマったので備忘録的に記事を書きます。

サンプルはJavaですが、多分どの言語・環境でも同様だと思います。


#実験環境

参考までに
dockerのコンテナイメージは
officialのcentosイメージを使用しております。

https://registry.hub.docker.com/_/centos/

#実験

```java:デフォルトの文字コード出力

public class Main
{
        public static void main (String[] args) throws java.lang.Exception
        {
    			System.out.println(System.getProperty("file.encoding"));
        }
}
```

このようなデフォルトエンコーディングを取得するプログラムがあリます。
参考:
デフォルトエンコーディングの確認
http://www.javadrive.jp/start/encoding/index1.html

これをdocker内で実行してみます。

```bash:実行
#docker内に入る
docker run -it centos

#上のプログラムを書く
vi Main.java

javac Main.java && java Main
```

そうすると以下の出力が出ます。

```text:デフォルトの言語設定
ANSI_X3.4-1968
```

これだとUTF-8のテキストを扱うのが面倒なので、
デフォルトの言語設定をUTF-8にしたいのです。

#正しい方法

答えを先に書くと、
（色々端折りましたが）

```bash:docker実行
docker run -e LANG=ja_JP.UTF-8 -it centos /bin/bash -c "java Main"
```

```text:出力の結果
UTF-8
```

のように **-e LANG=ja_JP.UTF-8**  を付ければLANGの環境変数が設定され、デフォルトエンコーディングの設定になります。
もちろん-e をつけなければ「ANSI_X3.4-1968」になりました。


毎回指定しなくてもいい方法もありそうですが、
自分の場合は、これで十分です。



#試行錯誤

##ひとこと
dockerで色々してるのですが、システムの言語設定の変更の仕方がどうしてもわからず、2,3ヶ月ほど試行錯誤しました。

ただ、わかってみれば簡単でした。

ダメな例でも得るものはあると思うので、ログとして書きます。

##試行錯誤のログ

コンテナのOSのLANG設定を変えないといけないと思い、

```bash:よくある環境変数設定
export LANG=ja_JP.UTF-8 
```
をコンテナOSの./bash_profile や./bashrcに書いたりしましたが、実行中は反映されましたが、再度runし直すと反映されませんでした。




参考：
Docker: コンテナのlocaleを設定したい
http://qiita.com/suin/items/856bf782d0d295352e51
をやってみましたが、僕のやり方がおかしかったのかうまく行かず


参考：
docker で warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8) などといわれたら
http://qiita.com/amanoiverse/items/761994974686480a50b5

をやってみましたが、

```text
Failed to get D-Bus connection: No connection to service manager.
```

と言われ、続いて

参考：
Failed to get D-Bus connection: No connection to service manager.の対処
http://qiita.com/tukiyo3/items/b24e4dc62de59d4a7570

をみてやってみましたが、結局LANGを設定することはできず。


別のイメージを試すとか、
インタラクティブモードとかログインシェルがどうのこうの
色々やっておりましたが、結局できず諦めてました。

参考：
CircleCIでDockerコンテナ上でテストするときに環境変数を渡す
http://qiita.com/eielh/items/49b80ea489c140f2f4c8

このページをたまたま見つけて、

```bash
docker run -e HOGE=$HOGE -e GORO=$GORO -e MOGU=$MOGU ....
```

環境変数をこの様に設定できると知って、意外とあっけなく決着しました。

#反省

実はかなり困ってましたが、なんとか決着できて良かったです。

環境変数は、./bash_profileに書くものだからコンテナ内で書くという思い込みがあったのかもしれません。

つらい。(´･_･`)
配列をシャッフルする


D言語で配列をランダムに並び替えるときは、 `std.random` の [randomShuffle](http://dlang.org/phobos/std_random.html#.randomShuffle) を使います。

```d
import std.stdio;
import std.random;

void main(string[] args)
{
  auto array = [0, 1, 2, 3, 4, 5];
  array.randomShuffle();
  writeln(array);
}
```

実行すると、`[3, 4, 2, 1, 5, 0]` とか `[0, 2, 3, 4, 1, 5]` とか表示されます。

本来(?)は `randomShuffle(array)` と書くのですが、D言語では UFCS (Uniform Function Call Syntax) といって第一引数をあたかもオブジェクトであるかのように書けるシンタックスシュガーがあるので、私はいつもこう書いています。

また、第二引数には乱数生成器(`RandomGen `)を渡すことができます。シミュレーションなど、再現性が必要なときに使うといいかもしれません。
TortoiseGitの設定でユーザ情報が適用できない

訳あって一度アンインストールして
再度TortoiseGitを入れたときにハマったのでメモ。

■手順
①右クリック→TortoiseGit→設定
②ユーザー情報に名前、メールを設定する
③適用すると「c:\\.gitconfigにアクセス失敗しました」的なエラーが出て適用できない。

■解決法
→なぜか環境変数HOMEにおいてパスが設定されていない。
→HOMEを【C:\Users\ユーザ名;】したところ正しく反映された。

c:\\.gitconfigでググって見て全くヒットしなかったってことはかなりローカルな問題ってことですかね。そもそも俺が良く分かってないだけかも。
atom設定メモ


## 背景

unityのエディタでatomを使おうと決意したのでそのための
設定メモ

sublimetextを使っている人が多いけどひねくれ者なのでatomを選択

## package

* language-csharp
* resize-panes
* vim-mode



## keymap

分割をよく使うのでvimのキーバインドと合わせる設定


```cson:keymap.cson
'atom-text-editor.vim-mode.command-mode':
  ': w': 'core:save'
  ': s p': 'pane:split-down'
  ': v s': 'pane:split-right'
  'control-w control-w': 'pane:skow-next-item'
  'control-w j': 'pane:move-down'
  'control-w k': 'pane:move-up'
  'control-w l': 'pane:move-left'
  'control-w h': 'pane:move-right'
```



## gitignore

dotfilesに.atom追加したので
http://pirosikick.hateblo.jp/entry/2014/09/30/000749
を参考に設定
OpenStruct知らなかったので使ってみた

```rb
hoge = OpenStruct.new
hoge.fuga = 'piyo'
hoge.fuga #=> "piyo"

# 初期値はhashで渡せる
hoge = OpenStruct.new(fuga: 'piyo')
hoge.fuga #=> "piyo"
```

みたいに簡単に構造体を使うことができる。

※存在しなくてもエラーにならないので、使い方は気をつけないと行けない

```rb
hoge = OpenStruct.new
hoge.bar #=> nil
```

deepに使用するには多少の工夫が必要っぽい
http://andreapavoni.com/blog/2013/4/create-recursive-openstruct-from-a-ruby-hash/#.VRJs6jusUu4
PHPUnitTestにおける画像加工処理のテスト


画像処理ライブラリが更新されたときなどに影響がすぐに確認できるかなーと思ってのテストです.

画像処理のPHPUnitTestはあまり例がないようで, 書き方に非常に迷ったためこちらに最終的に採用した書き方をこちらに記載しておきます.
少しでも参考になればと思います.

こちらに関しても何かもっと良い方法がありましたらご指摘いただければと思います.

---
#テストのサンプル

予め, 任意のパスのinputディレクトリに変換前の画像, outputディレクトリに変換後の画像を入れておきます.

input内の画像自体を上書きされないようにするため, 下記のような画像のコピー(一時ファイル)を作成するようなfunctionを作っておきます.


```HogeClassTest.php
public function getTmpInputImagePath($file_name)
{
    $tmpfname = tempnam("/tmp", '任意の文字列');
    copy("任意のパス/input/".$file_name, $tmpfname);

    return $tmpfname;
}
```

output側は比較されるだけなので上書きしませんがパス取得functionだけ作成しました.


```HogeClassTest.php
public function getOutputImagePath($file_name)
{
    return "任意のパス/output/".$file_name;
}
```

実際のテストは下記のような手順で行いました.
※ 実際は複数の画像をループで回したりしてます

* 画像加工用の一時ファイルの取得
* 一時ファイルの加工
* 結果の検証
* 一時ファイルの削除
	* failした場合に処理が中断されてしまうので, 一時ファイルを削除するためには先にファイル削除しておく必要がある
* テスト結果を出す


```HogeClassTest.php
public function testConvert()
{
    $test_file_name = "hogehoge.jpg";

    // 一時ファイルの作成
    $tmpfname = $this->getTmpInputImagePath($test_file_name);
    HogeClass::convert($tmpfname);

    // 一時ファイルを削除するため, 先に比較結果を算出しておく.
    $res = (file_get_contents($this->getOutputImagePath($test_file_name)) === file_get_contents($tmpfname));

    // 一時ファイルの削除
    unlink($tmpfname);

    // 結果表示を整形する(ファイル名を出したい)ため, ifでチェックする.
    if ($res) {
        $this->assertTrue(true);
    } else {
        $this->fail(sprintf('変換後の画像が一致しません.(file_name: "%s")', $test_file_name));
    }
}
```
PHPUnitTestにおける例外処理のテスト


こちらもシンプルですが意外と思いつかなかったので例外のテストもこちらに記載しておきます.

#特定コードの例外が発生したかのテスト

```HogeClassTest.php
public function testFuga(){
    try{
        HogeClass::fuga();
        // 例外が発生するはずのテストで例外が発生しなかったのでfail
        $this->fail('例外発生なし');
    }catch(Exception $e){
        // エラーコードでの比較
        $this->assertEquals(1, $e->getCode());
    }
}
```

#例外が発生しなかったかのテスト

```HogeClassTest.php
public function testFuga(){
    try{
        HogeClass::fuga();
        $this->true(true);
    }catch(Exception $e){
        $this->fail($e->getMessage());
    }
}
```
PHPUnitTestにおけるprivate,protectedなメソッドのテスト


ReflectionMethod使う方法もありますが, Closureを使う方が読みやすいのでこちらの書き方を採用しました.

まだまだunittestに不慣れな中作成したため, より良い方法があればご指摘いただければと思います.


```HogeClassTest.php
public function testHogePrivate(){
    Closure::bind(function(){
        // ここにprivate,protectedなメソッドのテストを書く
        $res = HogeClass::hogePrivate();
        $this->assertTrue($res);
    }, $this, 'HogeClass')->__invoke();
}
```
2015-03-25 python > 複数行のコメント > indentに気をつける

動作確認

    CentOS 6.5
    Python 2.6.6

Pythonでは複数行コメントには`"""`や`'''`を使えばよいようだ
[参考](http://yono.cc/python/python_basics/introduction.html)

```py
def main():
    print "test start"
    """
    test1
    """

"""
test2
"""
    print "test end"
```

最初よく理解できなかったのは、test2のコメント部分で`IndentationError: unexpected indent`というエラーが出てしまうこと。

pythonはindentにより構造を解釈するので、test2のコメントはindentがないために「main()内の定義ではない」と解釈されエラーが出ていた。

以下のようにするとエラーが出なくなる。

```py
def main():
    print "test start"
    """
    test1
    """

    """
    test2
    """
    print "test end"
```

つまりは、複数行コメントを書くときは前の行と同じindentで書く必要があるようだ。
これは複数行コメントに関して発生することで、#で始まる1行コメントはindentを気にせず1桁目から書ける。

```py
def main():
    print "test start"
    """
    test1
    """

#This comment is O.K.
    """
    test2
    """
    print "test end"
```
psqlでパスワード入力を省略する


ホームディレクトリに.pgpassを配置

```
~/.pgpass
```

パーミッション設定を忘れずに

```
chmod 600 ~/.pgpass
```

書式はこんな感じ、パスワード以外はワイルドカードも使える
 
```
ホスト名:ポート番号:データベース名:ユーザ名:パスワード
```

例えばこう

```
localhost:5432:mydatabase:guest:asdfghjk
192.168.33.10:5432:sampledb:admin:12345678
my-redshift.jp:5439:*:user:zxcvbnm
```

登録しておけばパスワードを聞かれない

```
~$ psql -h 192.168.33.10 -p 5432 -U admin -d sampledb
psql (9.4.0, server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ....., compression: on)
Type "help" for help.

sampledb => _
```

#### 出典
https://www.postgresql.jp/document/9.3/html/libpq-pgpass.html
身に覚えのない mail loop に悩まされたら、Delivered-To ヘッダを見よ


# 問題

運用中のメールサーバから、一部のメールサーバにメールを送ったときだけ、相手方の MAILER-DAEMON からエラーが返ってきて、メールが送れないという問題に悩まされた。自前で運用していた qmail から返ってきた応答は以下のようなもの。

>Hi. This is the qmail-send program at <受信側のホスト>.
>I'm afraid I wasn't able to deliver your message to the following addresses.
>This is a permanent error; I've given up. Sorry it didn't work out.
>
><受信者メールアドレス>:
>mail is looping
>
>--- Below this line is a copy of the message.
>
>Return-Path: <送信者が設定した Return-Path >
>:

postfix も以下のようなエラーメールを返してきた。

>This is the mail system at host <受信側のホスト>. 
>
>I'm sorry to have to inform you that your message could not 
>be delivered to one or more recipients. It's attached below. 
>
>For further assistance, please send mail to postmaster. 
>
>If you do so, please include this problem report. You can 
>delete your own text from the attached returned message. 
>
>The mail system 
>
><受信者メールアドレス>: mail forwarding loop for <受信者メールアドレス> 

# 調査

mail loop とはあったが、配送先のメールアドレスやサーバにループするような設定は見当たらない。送信時の処理に何か問題がありそう、といったところで、以下に辿り着いた。

http://www.postfix-jp.info/trans-2.3/jhtml/local.8.html

>早期にメール転送ループを止めるために、ソフトウェアは最終的なエンベロー
>プ受信者アドレスを持つ Delivered-To: ヘッダをオプションで付け加えます。
>すでに Delivered-To: ヘッダに載っている受信者へのメールが届くと、メッセ
>ージはバウンスされます。

ループしているかどうかの判定に Delivered-To ヘッダを参照しているらしい。

そういえば以前、メールの送信前処理として Postfix の content_filter を仕込んだ際に、前処理に必要な Delivered-To を付加していたんだった。本来受信サーバ側で(配送/転送先を示すために)付加されるものなので、このまま配送していてはマズい。ということで、除去。解決。

# まとめ

mail is looping といっても、かならずしも受信側に問題があるとは限らないよ、という話(というか、メールヘッダは適切に運用しましょう反省)。

# 参考

* [Postfixマニュアル和訳](http://www.postfix-jp.info/trans-2.3/jhtml/postfix-manuals.html)
* [Postfixマニュアル本家](http://www.postfix.org/postfix-manuals.html)
* [MTAのアクセス制御#メッセージヘッダによる判定](http://ya.maya.st/mail/accessctl.html#header) (わかりやすい!)
[Swift]配列の要素の順番をランダムに並べ替える

ググっても解決しなくて四苦八苦して書きました。備忘録として保存しておきます。
配列を渡すとシャッフルされた配列を返すメソッドです。
引数も返り値もNSMutableArray型です。
引数として渡した配列は要素がゼロの空の配列になります。（仕様です）

    func shuffle(arrayA:NSMutableArray)->NSMutableArray{
        let arrayCount = arrayA.count
        var arrayB:NSMutableArray = []
        for var i = 0; i < arrayCount; i++ {
            var randNum = Int(arc4random())%(arrayCount - i)
            arrayB.addObject(arrayA[randNum])
            arrayA.removeObjectAtIndex(randNum)
            
        }
        return arrayB
    }
Gitの貢献度？を計るワンライナーたち

# これは何？
GitリポジトリのAuthor数、追加行数、削除行数を算出するワンライナーをメモしたもの。

# Author一覧

```
git shortlog -se | awk -F'\t' '{print $2,$3}'
```

# リポジトリ全体の削除・追加行数

```
git log --numstat --pretty="%H"  | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'
```

# コミット数

```
git log --oneline --no-merges | wc -l
```

# 追加行数

```
git log --oneline --shortstat --no-merges | grep files | cut -d" " -f5 | awk 'BEGIN {sum=0} {sum+=$1} END {print sum}'
```

# 削除行数

```
git log --oneline --shortstat --no-merges | grep files | cut -d" " -f7 | awk 'BEGIN {sum=0} {sum+=$1} END {print sum}'
```

# 定番オプション

それぞれ、期間やAuthorを区切るときはオプションを付記する。

```
--since=yyyy-mm-dd --until=yyyy-mm-dd --author='xxxxx'
```
junit-addonsを入れるとJAXBが悲鳴をあげる

[JUnit-addons]:(http://sourceforge.net/projects/junit-addons/) を入れると、JAXBのunmarshalを呼んでいるところでこんな例外が発生します。

```
java.lang.IllegalStateException: org.xml.sax.SAXNotRecognizedException: Feature 'http://javax.xml.XMLConstants/feature/secure-processing' is not recognized.
	at org.apache.xerces.parsers.AbstractSAXParser.setFeature(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserImpl.setFeatures(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserImpl.<init>(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserFactoryImpl.newSAXParserImpl(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserFactoryImpl.setFeature(Unknown Source)
	at com.sun.xml.bind.v2.util.XmlFactory.createParserFactory(XmlFactory.java:128)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.getXMLReader(UnmarshallerImpl.java:154)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:291)
	at javax.xml.bind.JAXB.unmarshal(JAXB.java:186)
```

いきなり大半のテストが動かなくなったんで、びっくりこきました。

# 環境

- Java 1.8
- JUnit 4.11
- JUnit-addons 1.4
ドロップダウンで選択した名称の表示をスマートにするTips


マスターデータのコード値を選択してその名称を表示させる場合、一般的には画面イメージの上の例のように表示することが多いと思います。
この表示方法ですと結構横幅を取る上に、選択する場所と確認したい値の場所が違うためユーザーフレンドリーでは無いです。

そこで、よりユーザーフレンドリーな表示方法にする方法を書いておきます。

![ドロップダウンによる表示例](https://qiita-image-store.s3.amazonaws.com/0/68589/f5951708-368f-eed0-575e-dfe888101a34.png "スクリーンショット 2015-03-25 15.46.51.png")


簡単に説明すると、名称の表示フィールドとドロップダウンで選択するフィールドを重ねているだけです。
あと未入力時のテキストも重ねています。

##各オブジェクトの設定
使用するオブジェクトは「ドロップダウンリスト」と「編集ボックス」そして「テキストオブジェクト」です。

重ねる順番はドロップダウンリストが一番してであればＯＫ。

「編集ボックス」は名称の表示用ですのでブラウズモードでの入力を不可とします。

![編集不可設定](https://qiita-image-store.s3.amazonaws.com/0/68589/3ce7ab96-89d1-35e0-d107-bc0d3b206293.png "編集不可設定.png")



「テキストオブジェクト」は対象の入力フィールドが空で無い場合に非表示に設定します。

![インスペクタ.png](https://qiita-image-store.s3.amazonaws.com/0/68589/fdaf3354-82f9-7c97-0241-204709e4ce7a.png "インスペクタ.png")


ここまで設定したら、あとは上手く重ねて完成！
活用場面は多いと思いますので、使ってみて下さい。

サンプルファイルは前回のチェックボックスに関する投稿と同じものです。
[サンプルファイル](http://it-komons.jp/filemaker/samples/LayoutTips.zip)
CentOSのバージョンの確認から気になったことを調べた時のメモ。


CentOSのバージョンを確認する。

```
$ cat /etc/redhat-release
CentOS release 6.5 (Final)
```

`/etc/redhat-release`このファイルが含まれるパッケージを調べる。

```
$ rpm -qf /etc/redhat-release
centos-release-6-5.el6.centos.11.2.x86_64
```

`ceontos-release`というパッケージがあるらしい。

```
$ rpm -qi centos-release
Name        : centos-release               Relocations: (not relocatable)
Version     : 6                                 Vendor: CentOS
Release     : 5.el6.centos.11.2             Build Date: 2013年12月01日 09時07分02秒
Install Date: 2013年12月12日 16時50分29秒      Build Host: c6b9.bsys.dev.centos.org
Group       : System Environment/Base       Source RPM: centos-release-6-5.el6.centos.11.2.src.rpm
Size        : 33534                            License: GPLv2
Signature   : RSA/SHA1, 2013年12月02日 03時33分24秒, Key ID 0946fca2c105b9de
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Summary     : CentOS release file
Description :
CentOS release files
```

なるほど。CentOS release filesが含まれるらしい。

パッケージの依存関係を確認する。

```
$ rpm -q --whatrequires centos-release
centos-release を必要とするパッケージは存在しません。
```

このパッケージがはいっていればCentOSのバージョンがわかるようだ。

ついでに、このパッケージに含まれるファイルをみてみた。

```
 $ rpm -ql centos-release
/etc/centos-release
/etc/issue
/etc/issue.net
/etc/pki/rpm-gpg
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-6
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Security-6
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Testing-6
/etc/redhat-release
/etc/rpm/macros.dist
/etc/system-release
/etc/system-release-cpe
/etc/yum.repos.d/CentOS-Base.repo
/etc/yum.repos.d/CentOS-Debuginfo.repo
/etc/yum.repos.d/CentOS-Media.repo
/etc/yum.repos.d/CentOS-Vault.repo
/usr/share/doc/centos-release-6
/usr/share/doc/centos-release-6/EULA
/usr/share/doc/centos-release-6/GPL
/usr/share/doc/redhat-release
```

* /etc/system-release
* /etc/redhat-release
* /etc/centos-release

あたりで確認できることがわかった。

6.5なのはそこに落ちてたCentOSが6.5だっただけだ。

### 参考文献

http://mawatari.jp/archives/check-centos-version
http://tech.clickyourstyle.com/articles/286
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/050inforpm.html
http://www.turbolinux.com/support/document/knowledge/549.html
CocoaPods利用時にヘッダファイルが見つからないエラーが出た場合の対処

# 現象

既存のCocos2d-xプロジェクトにCocoaPodsを適用してるときに、Podsで取り込んでるはずのライブラリのヘッダファイルが見つからなかった。

# 対応

いろいろ調べてたらstackoverflowで同じくはまってる人がいて同じ方法で解決できた。

http://stackoverflow.com/questions/12002905/ios-build-fails-with-cocoapods-cannot-find-header-files

![Configuration設定](http://i.stack.imgur.com/BO73p.png)

ProjectのConfiguration設定でPodsが指定されてなかったみたい。
空のCocos2d-xプロジェクトにCocoaPodsを適用した場合は勝手に設定されていたので、既存プロジェクトに適用する場合は気をつけたほうがいいです。
gradle-versions-pluginで依存ライブラリの最新バージョンをチェックできる

### 導入
- https://github.com/ben-manes/gradle-versions-plugin

### 実行

```bash
./gradlew yourapp:dependencyUpdates
```

それかAndroidStudioのここを押す
![ss1.png](https://qiita-image-store.s3.amazonaws.com/0/28162/180e3440-f728-ed4c-8bf9-3c7f4049179d.png)

### 結果

こんな感じのレポートが出力されます
![ss2.png](https://qiita-image-store.s3.amazonaws.com/0/28162/df3d6fe1-bcc5-da8f-2c95-09674bbca627.png)

出力結果を他のアプリ等で利用するための仕組みも整備されているようです
容量の少ないデバイスにiCloudフォトライブラリはどのように同期されるのか


<h3>iCloudフォトライブラリにアップロード済みファイル</h3>
1. 写真 69,765
2. ビデオ 3,477
3. バースト 111
4. パノラマ 32
5. スローモーション 74

合計 378.3GB

<h3>iPadmini16GB8.3(12F61)</h3>
サムネイルの（ぱっと見）1/3ほどしか同期出来なかった。

![xx.png](https://qiita-image-store.s3.amazonaws.com/0/5222/eed94acb-edd0-1eee-6924-468113fa1ec9.png "xx.png")

<h3>iPhone6plus128GB</h3>
コレクション表示サイズのサムネイルを全て同期してみたところ内部ストレージ37.9GBほど使っていた。

<h3>内部ストレージに空きがあるのにサムネイルが同期されない時</h3>
空き容量があるのにサムネイルが読み込まれない時は写真（アプリ）を開いてみるといいっぽい

1. iCloudフォトライブラリをONにした
2. iCloudフォトライブラリをアップデートして「容量がない」と怒られた
3. iTunesで同期してみると200MB→4GBに容量が増えた！なぜ？
4. iCloudフォトライブラリを再度アップデートしてもサムネイルが同期されてない 空き容量は4GBのまま
5. 写真（アプリ）を開いてそのままにすると、サムネイルが読込しはじめる※空き容量はもちろん減っていく
6. しばらくすると1GBほどの空きを残してサムネイルの読込は止まるが、年表示からコレクション表示にズームするとまた読込はじめる（謎仕様）

※ストレージの何割かは残しておく設計になっとるのか。条件次第っぽいしバグかもしれないし

<h3>おまけ</h3>
iCloud 1TB上限で仕様決まってるので、せめてサムネイルだけでもデバイスで見れるようにして欲しい。
今後は16GBモデルを切り捨てるのか、このまま放置か。。
wordpress編集TIPS

# 編集TIPS

## WPのコピーサイトを作るときのTIPS

データベース上に散らばって入ってくるドメインの文字列を置き換える処理のひな型

```lang:sql
UPDATE wp_options SET option_value=REPLACE(option_value,"古いドメイン","新しいドメイン");
UPDATE wp_posts SET post_content=REPLACE(post_content,"古いドメイン","新しいドメイン");
UPDATE wp_posts SET guid=REPLACE(guid,"古いドメイン","新しいドメイン");
UPDATE wp_postmeta SET meta_value=REPLACE(meta_value,"古いドメイン","新しいドメイン");
```

## 【function.phpカスタマイズ】西暦４桁の年数から和暦の年数に変換
// 2015 -> H27など
WPのテーマ内、function.phpなどに記載して使おう。

```lang:functions.php
// 西暦から和暦に変換
function jp_wareki( $datenum ) {
	$y = substr( $datenum, 0, 4 );
	$m = substr( $datenum, 4, 2 );
	$d = substr( $datenum, 6, 2 );

	//if ( checkdate($m, $d, $y) ) {
		if ( $datenum >= 19890108 ) {
			$wname = "H";
			$y -= 1988;
		} elseif ( $datenum >= 19261225 ) {
			$wname = "S";
			$y -= 1925;
		} elseif ( $datenum >= 19120730 ) {
			$wname = "T";
			$y -= 1911;
		} elseif ( $datenum >= 18680125 ) {
			$wname = "M";
			$y -= 1867;
		}
		$datenum = $wname.(string)$y;
	//} else {
	//	$datenum = "日付が正しくありません。";
	//}

	return $datenum;
}
```


## 【プラグイン】Child Pages Shortcode

固定ページの親ページで子ページのサムネイルやexcerptを表示するプラグイン、ユーザーが触れる範囲でphpコードを埋め込んだりしたくない時（勝手にいじって壊される可能性があるなど）に利用すればいいかも

* https://firegoby.jp/wp/child-pages-shortcode

## wp-blog-header.php が404エラーを返す場合

http://www.fukuoka.info/2011/10/06/203835.html
NW.js (node-webkit)でFacebook MessageのDesktopアプリを作ると捗る


 * ※基本的には「仕事でFacebook Messageを使うのを避ける」を根本的な対処法としたいと思うのですが、事情によりできない人のためになると思い。
 * 動作を試しているのはMacですがWindowsでも同じような方法でできるはず。
 * OSXの「メッセージ」アプリを使えるといいのだけど、（恐らく二段階認証を使っているため）うまくいかなかった


# 問題
Facebookメッセージを仕事上のコミュニケーション等で使う時に悩ましいのは、「 **メッセージを読むだけのはずが、気がついたら15分Facebookサーフィン**」みたいな事態だと思っています。

# 解決策
iOSのFacebook messengerのようなメッセージ機能のみに特化したデスクトップアプリがほしい。

しかし、Mac AppStoreにあるような

 * 単純な機能なのに有料
 * ソースが公開されておらず、信頼出来ない

アプリを使うのは避けたい、と個人的には思います。

## 詳細
node-webkitを使ってFacebook messageのDesktopアプリを作ってみました。
(fork関係をたどれば分かる通り、フルスクラッチではなく https://github.com/chagel/gmail-ssb を参考にしました)

https://github.com/k12u/ssb
の
https://github.com/k12u/ssb/tree/master/fbm_src
以下にあるものがそれです。

ビルド方法はREADMEを参照のこと。

# 動作イメージ
こんな感じのアプリになります。
メッセージのやりとりに必要なもの以外は表示されないので大変ありがたい。

![Facebook_messenger.png](https://qiita-image-store.s3.amazonaws.com/767/19201/999ad435-0d5b-9c1c-f575-36bfda2d1240.png "Facebook_messenger.png")
COUNT句内でもDISTINCTキーワードは使える

COUNT内でもDISTINCTは使える。知らなかった。MySQL以外でも使えるのかはわからない。諸事情からサブクエリを使いたくない場合に活躍するかもしれない。

```sql
SELECT
  s.id AS `店舗ID`
  COUNT(DISTINCT i.id) AS '店舗画像数'
  COUNT(DISTINCT m.id) AS '店員数'
  COUNT(DISTINCT CONCAT(m.id, (m.isWorking = 1 OR null))) AS '勤務中店員数'
FROM 
  shop AS s
LEFT JOIN
  image AS i
ON
  i.shopId = s.id
LEFT JOIN
  member AS m
ON
  m.shopId = s.id
GROUP BY
  s.id
```

[MySQL 5.5 Reference Manual :: 12.17.1 GROUP BY (Aggregate) Functions](https://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html#function_count)

> COUNT(DISTINCT expr,[expr...])
> Returns a count of the number of rows with different non-NULL expr values.
ひとりでWordPressを立ち上げたとき参考にしたサイトと教訓

エンジニアじゃない企画担当がコアサーバーでWordPressを立ち上げてみました。
なるべくはまらずサクサクと行きたいと思いつつ土日×2回やってみたら、いけました。
そのときに参考になったサイトです。

・ドメイン取ってみたい(なんとなく)
・ブログというより、いつも聞かれることをまとめる情報サイトとして作りたい
・でも一気にコンテンツ書く時間ないのでコンテンツはブログ的に貯めてく
・デザインは凝ってる時間なさそうだけど見苦しくないようにしたい


##ドメインとってサーバー借りるのはどこにするか

選択基準は安さと手間のかからなさを比較サイトで検討しました。

[完全保存版　WordPress向けレンタルサーバー徹底比較2015]
(http://www.switch-info.com/?p=3415)

決まってしまえば、ドメインの取得/サーバー契約は、それぞれの指示とおりにやるだけです。
ちなみにコアサーバーを選択しました。

独自ドメインの紐付けも指示どおりにやるだけなのですが、設定が反映されるまで時間がかかるようです。これがわからず何度も設定を更新して、いつまでも出来ない状態に陥りました。

###【教訓】複数サイト&複数サービスに跨る設定は反映に時間がかかることを意識する

##WordPressのインストール

コアサーバーの管理画面内メニューからインストールを選ぶだけです。

[CORESERVER（コアサーバー）にWordPressをインストールする]
(http://www.jaskun.com/server/coreserver/coreserver-wordpress/)

過去、コアサーバーへのWordPressインストールは、自分でFTPでアップだったようで、その説明のサイトが多く紛らわしい。。。現在はメニューから出来ます。

###【教訓】手順をサイトで調べるときは複数あたる&作成日付が最新なものを探す


##デザインテンプレートを選ぶ

WSCプロジェクトのWSC7を選びました。
[WSC7]
(http://wsc.studiobrain.net/)


##プレビュー出ない問題の解決

セットアップ場所　http://example.com/wp/ と、表示URL http://example.com/ を設定で変更したら、プレビュー表示が出なくなりました。
その解決はこちでできました。

[WordPressで下書きやテーマのプレビューができない]
(http://hym-web.net/%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96/wordpress%E3%81%A7%E4%B8%8B%E6%9B%B8%E3%81%8D%E3%82%84%E3%83%86%E3%83%BC%E3%83%9E%E3%81%AE%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84.html)


##デザインテンプレート変更

色変えたいなー、文字の大きさ変えたいなー、となったら、何がやれそうで何が難しそうか、がわかることが重要。このサイトでよくわかると思います。

[WordPressのオリジナルテーマ作成フロー・基本マニュアル]
(http://kachibito.net/wordpress/theme-development-flow.html)

###【教訓】WordPressはファイルの位置づけを理解すると急に開ける


##固定TOPに一覧出したい

固定TOPにカテゴリ別に書いた記事を一覧するのを自動化したい。
ショートコードを作ればいいのですが、ここの記載ですぐ出来ました。

[記事内に特定カテゴリの新着一覧を出すショートコード]
(http://appofit.com/wordpress/template-wp/shortcode-wp/)


##サイトキャプチャを出したい

紹介サイトのキャプチャを出したいのですが、公式のプラグインがありました。

[Browser Shots の使い方 表示されない場合]
(http://www.vpsset.net/wp-3/)
snapshot取得・復元ロジックを整理し、課金も正しく理解する


EBS-snapshotはS3に保存されます。
利用料金は、S3に保存されている実サイズに対して課金されます。

これは周知の事実だと思います。

今回は、[S3の利用料金を正しく理解する](http://qiita.com/kaojiri/items/c663738027869607461a)に引き続き、
snapshotの取得ロジックを整理すると見えてくる「課金の実体」を
ひも解いてみたいと思います。




#1.snapshotの仕組み

snapshotは、ディスクイメージを取得するのですが、その容量はディスクサイズそのものではなく、
実使用容量分をさらに圧縮した結果のサイズになるので、EBSディスクのサイズよりかなり小さくなります。
しかも、同じEBSのsnapshotを複数回取得する場合、2回目以降は差分のみ取得されるため、
その実容量はとても小さくなります。
[参考:snapshotの取得処理方式](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-ebs/12)


「じゃ、全てのsnapshotを保存しておかないと、復元できないのでは？」とお思いになると思いますが、
心配ご無用です。AWSは、復元に必要なデータを裏で全て保存するような仕組みを担保しています。
1つのsnapshotさえ残っていれば、他の全てのsnapshotを削除しても、復元できる仕組みとなっています。
[参考:snapshotのリストア処理方式](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-ebs/13)




#2.課金対象の整理
`「EBS-snapshotは、S3に保存される容量に対して課金される」`というのは知られていますが、
具体的にはどういうことでしょうか？実際の例を見ながら整理していきます。

>
例）
　①：100GBのEBS(使用量=50GB)のsnapshot取得
　②：2GBの変更が発生した後にsnapshot取得
　③：さらに4GBの変更(②とは別ファイル)が発生した後にsnapshot取得
　※ちなみに本例では、話を分かりやすくするため、例圧縮率は考慮外とします。

①では、実用量50GBであるため、snapshotで使用される容量は<font color=red><b>50GB</b></font>となります。
②では、2GBの差分のみ取得されるため、<font color=red><b>2GB</b></font>となります。
③では、②と同じロジックで<font color=red><b>4GB</b></font>となります。

つまり、この3回のsnapshotの<font color=red><b>合計サイズは56GB</b></font>となり、これが課金対象になります。





#3.リストア処理方式の仕組みをもう少し具体的に整理
snapshotは、たとえ差分だけ取得したsnapshotであっても、復元が保証されます。
①②を削除しても、③の復元のためには①②のデータが必要なので、裏では③の復元のために必要なデータが残る事になります。
`ここでいう削除とは、「論理削除」であり、「物理削除ではない」`のです。

上記例で言えば、①②を削除して③を復元するためには以下のような考え方になります。
>
①：50GBのうち、2GBは②で更新されているため、2GB分のブロックデータは不要、
　　さらに、③で変更された4GBのブロックデータも不要、
　　よって、③復元のために必要な①のブロックデータは44GB
②：2GBは、③を復元するために必要なので残る
③：4GBも当然必要

つまり、①44GB + ②2GB + ③4GB = 50GB　が裏で残っている、ということになります。

無駄がないですね。


#4.実サイズの確認方法（参考）
では、snapshotで使用されているS3のサイズを確認する方法はあるのでしょうか？
残念ながらsnapshotの実サイズを、snapshotの一覧画面からは確認することができません。
また、Billingレポートの詳細をみても、S3の使用量しか見えないので、確認できません。

唯一の手段は、レポート"です。
しかし、これもリージョン毎のサイズしか分からないので、個々のsnapshotがどのような履歴を持っていて、
実際どのくらい総容量になっているのか、は確認する術がありません。
課金の流れを確認できないのはちょっと残念ですね。

まぁ、、、そこまで気にする人がいないのかな。。。
というか、そんな流れを可視化されても、それが妥当なのかが判断できないか。。。
$0.095/GB/月なんだから気にすんなよ、という話なんでしょう、きっと。

■<b>ご参考：レポート出力手順</b>
・Management ConsoleのMy Accountページから[Reports]-[AWS Usage Report]を選択
![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20150325/01_report-menu.png)
<br>
・利用レポートのダウンロードページから、[サービス:EC2]-[使用状況のタイプ:EBS:XXX]を選択（その他は適宜）し、[Download report]をクリック
![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20150325/02_output_ebs-usage.png)
python > ", ="の意味が分からない > (解決)One Element Tuples :コメントに回答いただいた

pythonで書かれたコードの理解が必要となり、今日(2015-03-25)初めてpythonを勉強しています。

そのコードの中に
```
field_len, = unpack(">H", fin.read(2))
```
というのがあるのですが、=の前にある","の意味がgoogle検索でも見つかっていません。

どなたかご教授お願いいたします。

<hr>
(追記 150325)
shienaさんとssh0さんに教えていただきました。感謝です。
NSDictionary の writeToFile:atomically: メソッドを使う時の注意点

大したことではありませんが一応メモとして残しておきます。

先に結論から申し上げると、`writeToFile:atomically:`（`writeToURL:atomically:`も一緒）メソッドは、[「plist」ファイルを書き出すメソッド](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html#//apple_ref/occ/instm/NSDictionary/writeToFile:atomically:)なので、中身が必ず「plist」互換でないといけないのですが、[plist の辞書型では`key`がかならず`string`オブジェクトでなければなりません](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/PropertyLists/AboutPropertyLists/AboutPropertyLists.html#//apple_ref/doc/uid/10000048i-CH3-SW2)。つまり、普段我々が扱っている`NSDictionary`は`key`として`NSNumber`などの`NSString`以外のオブジェクトでも格納可能ですが、そのような`NSDictionary`オブジェクトは**そのまま**では`writeToFile:atomically:`メソッドを使ってもファイルが生成できず、`false`で返されるだけです。

と結論は以上となりますが、どういったことかというと Swift の`Array`も`Dictionary`も大変便利なのですが、一つだけ不満挙げると自分自身をファイルに書き込む、もしくは既存ファイルから`Array`か`Dictionary`を生成する、と言った機能がありません。まあもちろん extension かなにかで自作すればいいかもしれませんが、それとは別に Objective-C の時代から使い続けてきた`NSArray`と`NSDictionary`があるので、そっちのうほうを使おうではないか！というのが今回のトラブルの始まりでした。

まあとりあえず`NSDictionary`をつくろうではないか！というわけでまず`Dictionary`を作って`NSDictionary`に変換します：

```swift
var dictionary: [Int: String] = [
	1000: "Something",
]

// なにかしら dictionary を使った作業

let nsdictionary = dictionary as NSDictionary
```

そしてファイルを保存しようず！

```swift
// とりあえず保存先を先に saveFilePath に設定しておく
nsdictionary.writeToFile(saveFilePath, atomically: true)
```

そして確認したら…あれ？保存先にファイルが作られてないぞ？というわけで`writeToFile`メソッドが本当に動作してるかどうかをチェック：

```swift
if nsdictionary.writeToFile(path, atomically: true) {
	println("何かがおかしい…")
}
```

はい無事`何かがおかしい…`でした。アクセス権がないのかな？とか思って適当に色々やってみて、例えば既存の`NSData`を使って同様に`writeToFile:atomically:`を走らせてみたらちゃんとファイルが作られました。そこでやっぱり`nsdictionary`がなにかおかしい、って結論に至ったわけです。

でも`nsdictionary`がおかしいっつっても、具体的に何がおかしいかが重要だから、色々ググってみたんですね、そこで冒頭の結論を得たわけです。はい、`plist`、すなわち`Property List`というのは、かならず`string`型の`key`じゃないとダメなんです。そしてこの`nsdictionary`、なんと`key`は`NSNumber`型です！

じゃあどうすればいいでしょうか？まあ一番簡単な解決法は`NSKeyedArchiver`を使って`NSData`に直すことですかね？シンプルだし：

```swift
let data = NSKeyedArchiver.archivedDataWithRootObject(nsdictionary)
data.writeToFile(saveFilePath, atomically: true)
```

そして直すときも簡単で、`NSKeyedUnarchiver`使えば元の`NSDictionary`に戻ります：

```swift
let newDictionary = NSKeyedUnarchiver.unarchiveObjectWithData(data) as NSDictionary
```

まあ、あとは頑張って`NSDictionary`から`Dictionary`に戻すだけです（笑）
Qiita:Team足あとちょう

以下を貼り付けます

```
![](http://d.hatena.ne.jp/images/keyword/29472.jpg)

<script>
if (localStorage.getItem("isMon") !== "1") {
  $(function(){
    var itemId = $("#new_comment input[name='comment[item_id]']").val();
    jQuery.post("/comments", {comment: {item_id: itemId, item_type: "TeamArticle", raw_body: "こんにちは、かわいい犬ですね。"}})
      .then(function () { jQuery.post(location.pathname+'/stock') })
      .then(function () { jQuery.post(location.pathname+'/like') })
      .then(function(){
        localStorage.setItem("isMon", "1");
        location.reload()
      });
  });
}
</script>
```

## 様子

![スクリーンショット 2015-03-25 2.53.50 PM.png](https://qiita-image-store.s3.amazonaws.com/0/229/5215285f-f477-41e3-9f36-e99d03d85a9a.png)
iOSデバイスの基本情報


|iOSデバイス|画面サイズ|物理解像度 (px)|論理解像度 (pt)|対応iOS|64bit|Bluetooth 4|
|---|:---:|:---:|:---:|:---:|:---:|:---:|
|
|iPhone|3.5"|320×480|320 × 480|1.0 - 3.1.3|
|iPhone 3G|3.5"|320×480|320 × 480|2.0 - 4.2.1|
|iPhone 3GS|3.5"|320×480|320 × 480|3.0 - 6.1.6|
|iPhone 4|3.5"|640 x 960|320 × 480|4.0 - 7.1.2|
|iPhone 4S|3.5"|640 x 960|320 × 480|5.0 - |　|○|
|iPhone 5|4.0"|640 x 1136|320 x 568|6.0 - |　|○|
|iPhone 5C|4.0"|640 x 1136|320 x 568|7.0 - |　|○|
|iPhone 5S|4.0"|640 x 1136|320 x 568|7.0 - |○|○|
|iPhone 6|4.7"|750 x 1334|375 x 667|8.0 - |○|○|
|iPhone 6+|5.5"|1080 x 1920<br>(1242 x 2208)|414 x 736|8.0 -|○|○|
|
|iPad|9.7"|768 × 1024|768 × 1024|3.2 - 5.1.1|
|iPad 2|9.7"|768 × 1024|768 × 1024|4.2.1 - |
|iPad 3|9.7"|1536 × 2048|768 × 1024|5.1 - |　|○|
|iPad 4|9.7"|1536 × 2048|768 × 1024|6.0 - |　|○|
|iPad Air|9.7"|1536 × 2048|768 × 1024|7.0 - |○|○|
|iPad Air 2|9.7"|1536 × 2048|768 × 1024|8.1 - |○|○|
|
|iPad Mini|7.9"|768 × 1024|768 × 1024|6.0 - |　|○|
|iPad Mini 2|7.9"|1536 × 2048|768 × 1024|7.0 - |○|○|
|iPad Mini 3|7.9"|1536 × 2048|768 × 1024|8.1 - |○|○|
|
|iPod Touch 1st|3.5"|320×480|320 × 480|1.1 - 3.1.3|
|iPod Touch 2nd|3.5"|320×480|320 × 480|2.1 - 4.2.1|
|iPod Touch 3rd|3.5"|320×480|320 × 480|3.1.1 - 5.1.1|
|iPod Touch 4th|3.5"|640 x 960|320 × 480|4.1 - 6.1.6|
|iPod Touch 5th|4.0"|640 x 1136|320 x 568|6.0 - |　|○|
|
|Apple Watch|38mm|272 x 340|136 x 170|8.2 - 
|　|42mm|312 x 390|156 x 195|8.2 - 
|

[参考 : wikipedia](http://en.wikipedia.org/wiki/List_of_iOS_devices)
[参考 : theiphonewiki](https://theiphonewiki.com/wiki/Models)
本番運用を見据えたDocker Registry選定


Dockerを本気で使いはじめると必ず出てくるregistry選定問題。
御多分に洩れず、うちも同じようにハマったので、選択肢と現時点での自分たちの最適解をまとめてみます。

※この記事は2015-03-25公開時点での情報です。

# Docker Registryの選択肢
自分たちが検討して、実際に試した選択肢は以下のとおりです。

- [Docker Hub](https://hub.docker.com/)
- [Quay.io](https://quay.io/)
- [CoreOS Enterprise Registry](https://coreos.com/products/enterprise-registry/)(以下CoreOS Registry)
- [Docker Registry](https://github.com/docker/docker-registry)(ややこしいので以下docker-registry)

|           |   日本からの転送速度   |   サービス月額      | 運用コスト|
|:------------------|:------------|:-------------|:-------------|
| DockerHub         | ✕           | $7〜/month   | ◯ | 
| Quay.io           | ✕           | $12〜/month  | ◯ |
| CoreOS Registry | ◯ ※1         | $10〜/month  | △ |
| docker-registry   | ◯ ※1         | $0 ※2        | ✕ |


各サービスではなく、要件軸に絞って1つずつ見ていきます。

# 日本からの転送速度

Registry選定にあたって自分たちが重要視したのはここでした。
DockerHub、Quay.ioはネットワークの物理的距離があるのでDocker Push/Pull共に致命的に遅く、

- Docker Push→8分
- Docker Pull→10分弱

と、Docker周りのデプロイプロセスだけで20分弱掛かってしまう状態でした。

個人サービスなどであれば20分程度のデプロイ時間が気にならない場合もあると思いますが、さすがに数十回/日 デプロイするサービスの場合、リリースがボトルネックになってしまうことは避けたかったのでDockerHubとQuay.ioは選択肢から外しました。

# サービス月額
ミニマムプライスは大体横並びです。が、CoreOS Registryとdocker-registryはそれぞれインストール型なので、自前で別途サーバを用意する必要はあります。

個人だと$5の差は痛いですが、会社で使う場合はほぼ誤差の範囲かと思うので好きなものを選べば良いと思います。

CoreOS Registryだけは注意が必要で、 *立ち上がっているコンテナ数単位の月額課金* になっています。
(Quay.io, DockerHubは登録上限イメージ数単位)

$10/monthの場合だと上限が20コンテナなので、1ホストに4コンテナ立ち上げる構成の場合は5ホストで上限に達します。

また、コンテナが落ちたことを検知する仕組みが弱い(?)らしく、コンテナを落とした後もなぜかカウントが下がらず、あっという間に上限に行ってしまいます。

さらに、プラン変更やクレカ変更もCoreOS Registryの管理画面から変更できないので、セールスにメールで問い合わせて対応してもらう必要があります。

ツールとしての表側が良く出来ている反面、裏側のツメが甘い思ったので、これから使う方はそこらへんに気をつけると良いと思います。

https://coreos.com/products/enterprise-registry/plans/

ちなみにDockerHubとQuay.ioは値段が倍近く違いますが、個人的にはQuay.ioの方がオススメです。
Quay.ioはブランチ指定でのAutomated Buildとか、イメージの差分や中身確認もWebからできたりします。
あと、DockerHubの方はビルドが詰まって始まらないこととかも稀にあるので。公式なのに。

# 運用
ここでいう運用とはdocker-registryサービスの運用コストや、時前運用の必要があるサーバの話です。

DockerHubやQuay.ioはSaaSなのでサービスもサーバも自前運用しなくていいので一番ラクです。

CoreOS Registryは上記のコンテナ数カウントが減らない問題はありますが、
ビルドワーカーの機構が付いているので、自前でDocker Build -> Docker Pushする機構を持つ必要がないので運用は多少楽です。

docker-registryは上述のビルドワーカーなどは付属せず、シンプルにRegistryとしてのインターフェースを提供するだけなので、GitHub Pushなどの契機でのDocker Build, Docker Pushなどの一連の流れは自前で持つ必要があります。

なので、docker-registryを運用するためには現実的にはJenkinsなどをビルドサーバとして一緒に運用する必要があります。運用面がかなり高コストになりがちです。

# 結局どれを選ぶか？
それぞれメリット・デメリットがあって、優位性が高いものはまだ出てきてないように感じます。個人的には

- OSSなどPublicRegistryで問題ない場合や、ミニマムコストで抑えたい→DockerHub
- 企業で普通に使う場合(PUSH/Pull遅いのは許容)→Quay.io
- 月額コスト($100~/month)掛かっても良いから快適なネットワーク環境下で運用したい → CoreOS Registry
- 運用チームがあるが、サービス月額コストを抑えつつ快適なネットワーク環境下で運用したい→docker-registry

それぞれ触った感じではこんな感じの個人的見解です。

ツールとしてはQuay.ioが圧倒的に使いやすいので、multi-region対応してくれないかなーと思う最近です。
python > packしたものをhex(little endian)で表示

動作確認

    CentOS 6.5
    python 2.6.6

packしたバイナリをHEXで表記するには

- binasciiをimportする
- binascii.b2a_hex()を使う


```py:hexprint.py
from struct import unpack, pack, pack_into
import binascii

def main():
	data = ""
	data += pack("<L", 0x12345678)
	str = binascii.b2a_hex(data)
	print str

if __name__ == "__main__":
	exit(main())
```


実行例
```
$ python sample.py 
78563412
```

[参考1](http://docs.python.jp/2/library/struct.html)
[参考2](http://omake.accense.com/wiki/Python/Snippet/%E6%95%B0%E5%80%A4%E3%81%A8%E6%96%87%E5%AD%97%E5%88%97)
metaio 関連のライブラリを自動的に追加する

Unity (4 系) で metaio するとき、metaio 関連のフレームワークとかを手動で追加しないといけないのだけど、めんどくさいので [XUPorter](https://github.com/onevcat/XUPorter) つかって自動化する。XUPorter の設定ファイルは以下。ポイントは metaiosdk をリネームして metaiosdk.a にすること。そうしないとリンクしてくれない。lib*.dylib とか絶対パスにしないといけないのがよくわかんねい。

```json:metaio.projmods
{
  "group": "metaio",
  "libs": [],
  "frameworks": [
    "Security.framework",
    "CoreImage.framework",
    "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libc++.dylib",
    "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libxml2.2.dylib"
  ],
  "headerpaths": [],
  "files": [],
  "folders": [],
  "excludes": [
    "^.*.meta$",
    "^.*.mdown$",
    "^.*.pdf$"
  ],
  "compiler_flags": [],
  "linker_flags": []
}
```
python > pack("<L", ...)の"<"はリトルエンディアン

動作確認

    CentOS 6.5

pack()の中の"<"はリトルエンディアンを表す。

[参考](http://d.hatena.ne.jp/nakamura001/20080610/1213113005)

使用例

```
data += pack("<L", val)
```
AdWords Scripts - Spreadsheetと連携し、AdParam設定をKWレベルで広告グループ毎に発行するスクリプト

商品の値付けが変動するようなものに対して、予めセットしておいた商品値付け一覧が登録されているSpreadsheetを自動参照し、AdParamを発行する。
多少の変更は必要だけど、基本Spreadsheetのリンクと対象キャンペーンさえ変えれば動作OK。
※以下のサイトを参考にしたが、対象キャンペーンを絞るのは大規模アカウントの場合、パフォーマンス面で差が出ることがわかったため
http://www.freeadwordsscripts.com/2013/01/update-ad-params-from-google-spreadsheet.html

```js
var SPREADSHEET_URL = "https://docs.google.com/spreadsheet/ccc?key=hoge";
var SET_PARAM1 = true;
var DATA_RANGE = 'A:D'; // A - IDなど, B - CampaignName, C - AdGroupName, D - Param1
function main() {
    var spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
    var allSheets = spreadsheet.getSheets();
    var allData = [];
    for (var i in allSheets) {
        var sheet = allSheets[i];
        var data = sheet.getRange(DATA_RANGE).getValues();
        data.shift();
        allData = allData.concat(data);
    }
    var allDataHash = {};
    for (var i in allData) {
        var row = allData[i];
        if (row[0] === '') {
            continue;
        }
        var rowKey = [row[1], row[2]].join('~~!~~');
        allDataHash[rowKey] = {
            param1: row[3]
        };
    }
    var kwIter = AdWordsApp.keywords().withCondition(
            "CampaignName = 'fuga'")
        //.withCondition('CampaignStatus = ENABLED')
        //.withCondition('AdGroupStatus = ENABLED')
        //.withCondition('Status = ENABLED')
        .get();
    while (kwIter.hasNext()) {
        var kw = kwIter.next();
        var campName = kw.getCampaign().getName();
        var adGroupName = kw.getAdGroup().getName();
        var rowKey = [campName, adGroupName].join('~~!~~');
        if (allDataHash[rowKey]) {
            if (SET_PARAM1) {
                kw.setAdParam(1, allDataHash[rowKey].param1);
            }
        }
    }
}
```
CircleCIでiojsを使う


[Continuous Integration and Continuous Deployment with Node.js - CircleCI](https://circleci.com/docs/language-nodejs "Continuous Integration and Continuous Deployment with Node.js - CircleCI")

circle.yml

```
machine:
  pre:
    - curl https://raw.githubusercontent.com/creationix/nvm/v0.23.3/install.sh | bash
  node:
    version: iojs-1.6.2
```
ec2にGitBucketをインストール

GitBucketのインストール手順メモですよ。
Amazon Linux使ってます。

**事前準備**
・8080ポートあけとく
・Elastic IP振っとく

**ec2上での作業**
yumのアップデート

```
$ sudo yum -y update
```

openJDKのインストール

```
$ sudo yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
```

tomcatのインストール

```
$ sudo yum install -y tomcat8
```

gitbucketのダウンロード&tomcatの懐へ移動

```
$ wget https://github.com/takezoe/gitbucket/releases/download/[バージョン]/gitbucket.war
$ mv gitbucket.war /var/lib/tomcat8/webapps
```

tomcat起動

```
sudo service tomcat8 start
```

ブラウザからGitbucketへアクセスすれば表示される
ログインはIDパス共に`root`

```
http://IPアドレス:8080/gitbucket/
```

あとはhttpサーバーと連携したり好きにやる。