OmniAICreator/Qiita-1.07M huggingface dataset:
【言語別】複数行の標準入力→int型配列 の高速化(Tips)

【言語別】複数行の標準入力→int型配列 の高速化(Tips)

最近[paiza](http://paiza.jp/)とか[codeiq](https://codeiq.jp/)がマイブームなのですが、[POH1](https://paiza.jp/poh/ec-campaign)でI/Oで色々つまづいたので、言語別にそこそこ高速だと思われるプログラムを載せてみます。

標準入力1000000行の配列化＆数値変換です。
(他のプログラムとの比較とかはないです。ごめんなさい。）

変数名とか色々まとまってません！

### C,C++
```cpp
#include <cstdio>
#include <vector>
#include <string>
#include <iostream>

static const int N = 1000000;
static char _buf[10*N];
int read_int(){
    static uint64_t c=0;

    int r=0;
    while( _buf[c] >= '0' && _buf[c] <= '9' ){
        r = r*10 + _buf[c++]-'0';
    }
    c++;
    return r;
}

int main(){
    /* C++ライクに書いてみた。がとても遅い。
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::vector<int> v(N);
    std::vector<int>::iterator it=v.begin();
    while(std::cin >> *it++);
    */

    fread(_buf,1,sizeof(_buf),stdin);

    int lines[N];
    for(int i=0;i<N;i++){
        lines[i] = read_int();
    }

    return 0;
}

```

### C＃
```c#
using System;

class Io {
    const int N=1000000;
    const int SIZE=N*10;
    static byte[] buf=new byte[SIZE];
    static int count=0;

    static int read_int(){
        int r=0;
        while(buf[count] >= '0' && buf[count] <= '9' ){
            r = r * 10 + buf[count++] - '0';
        }
        count++;
        return r;
    }

    public static void Main(string[] args){
        Console.OpenStandardInput().Read(buf,0,SIZE);

        int[] lines=new int[N];
        for(int i=0;i<N;i++){
            lines[i] = read_int();
        }
    }
}
```

### Java
```java
class Main {
    static final int N=1000000;
    static final int SIZE=N*10;
    static byte[] buf=new byte[SIZE];
    static int count=0;

    static int read_int(){
        int r=0;
        while(buf[count] >= '0' && buf[count] <= '9' ){
            r = r * 10 + buf[count++] - '0';
        }
        count++;
        return r;
    }

    public static void main(String[] args){
        try{
            System.in.read(buf,0,SIZE);
            int lines[] = new int[N];
            for(int i=0;i<N;i++){
                lines[i] = read_int();
            }
        }catch(Exception e){
            System.err.println(e);
        }
    }
}
```

### Ruby
```rb
lines = $stdin.read.split(?\n).map(&:to_i)
```

### Perl
```pl
=pod こちらは思ったより遅かった。。。
my $input = do { local $/; <> };
my @lines = split(/\n/,$input);
=cut

my @lines = ();
while(<>){
    push(@lines,int($_));
}
```

### Python
```py
import sys
_to_i=int
lines = map(_to_i,sys.stdin.read().splitlines())
```

### PHP
```php
<?php
/* これも思ったより遅かった。。。
$stdin = file_get_contents('php://stdin');
$lines = array_map(intval,preg_split('/\n/', $stdin));
*/
$lines = array();
while(($v = intval(fgets(STDIN)))){ 
    array_push($lines, $v);
}
?>
```

## 実行速度
最後に言語別の実行速度です。
（OS:Mac OS 10.9.1, CPU:Intel Core i5 2.9GHz)

| 言語 | 実行速度(timeコマンドのuser) |
|:-----------|------------:|
| C,C++       |        0.0022s |
| C#       |        0.046s |
| java     |      0.077s |
| perl       |       0.181s |
| ruby         |          0.257s |
| python    |     0.504s |
| php    |     0.590s |

## もっと速く...
なる方法を知っている方教えて下さい。お願いします。
EC2にApacheとPHP(mod_php)をインストールしたメモ


ちょっとした動作の検証のためにAWSのEC2(標準のAmazon Linux AMI)へApacheとPHP(mod_php)をインストールしてみたのでメモ。無設定ならたったこれだけの手順。
これなら自分でサーバとか維持せずに、必要な時に構築すればいいなー。

## Apacheインストール&起動

```
$ sudo yum -y install httpd
$ sudo service httpd start
```

## PHPインストール

```
$ sudo yum -y install php
```

## mod_phpの設定

は特にいらず。`/etc/httpd/conf.d/php.conf` にデフォルトで記載されてる。

Apacheを再起動。

```
$ sudo service httpd restart
```

以上。
Arrayのメソッドまとめ②

# 追加

```
hoge = [1, 2]
fuga = [3, 4, 5]
```

`<<`
配列内配列になる(破壊的)

```
hoge << fuga
　#=> [1, 2, [3, 4, 5]]
　hoge #=> [1, 2, [3, 4, 5]]
```

`+=`
配列内配列にならない(破壊的)

```
hoge += fuga
　#=> [1, 2, 3, 4, 5]
　hoge #=> [1, 2, 3, 4, 5]
```

配列内配列は配列で追加される	

```
hoge += [[6, 7], 8]
　#=> [1, 2, [6, 7], 8]
```

無理矢理配列内配列にする	

```
hoge += [fuga]
　#=> [1, 2, [3, 4, 5]]
```

`+`
配列内配列にならない(非破壊的)

```
hoge + fuga
　#=> [1, 2, 3, 4, 5]
　hoge #=> [1, 2]
```

# 重複抜き出し

```
hoge = [1, 2, 3, 4, 5]
fuga = [1, 3, 5, 7, 9]
mogu = [1, 1, 2, 2, 9]
nigo = [7, 5, 3, 2, 1]
```

`&`
重複する値を集めた配列を返す
`hoge & fuga #=> [1, 3, 5]`
複数あってもひとつずつしか返さない
`hoge & mogu #=> [1, 2]`
先に指定した配列の順に見ていくので順序が違うと戻り値も違う

```
hoge & nigo #=> [1, 2, 3, 5]
nigo & hoge #=> [5, 3, 2, 1]
```

# その他操作

`-`
特定の物を取り除く(複数指定可)

```
['あ', 'え', 'い', 'う', 'え', 'お', 'あ', 'お'] - ['あ', 'え']
　#=> ['い', 'う', 'お', 'お']
```

`uniq`
重複したものを取り除く
初出の要素だけ残る

```
['あ', 'え', 'い', 'う', 'え', 'お', 'あ', 'お'].uniq
　#=> ['あ', 'え', 'い', 'う', 'お']
```

`index`
引数の値と一致する最初の位置(0始まり)を返す / なければnil

```
['あ', 'え', 'い', 'う', 'え', 'お', 'あ', 'お'].index('え') #=> 1
['あ', 'え', 'い', 'う', 'え', 'お', 'あ', 'お'].index('ふ') #=> nil
```

`in_groups_of`
ブロックなし：引数の数だけの配列の配列を返す / 足りない部分はnil

```
[1,2,3,4,5,6,7].in_groups_of(3)
　#=> [[1, 2, 3], [4, 5, 6], [7, nil, nil]]
```

ブロックあり：引数の数だけの配列を返す / ブロックなし＋eachのイメージ

```
[1,2,3,4,5,6,7].in_groups_of(3) { |group| p group }
　#=> [1, 2, 3]
　　　[4, 5, 6]
　　　[7, nil, nil]
```

`flatten`
配列内配列をなくす	

```
[[1, 2, 3], [4, 5, 6], 7].flatten
　#=> [1,2,3,4,5,6,7]
```
Arrayのメソッドまとめ①

# sort

`colors = ['red','purple','blue','pink']`

ブロックなし：昇順

```
colors.sort
　#=> ["blue", "pink", "purple", "red"]
```

ブロックで指定

```
colors.sort{|a, b| a[0] <=> b[0]}
　#=> ["blue", "pink", "purple", "red"]
```

ブロックで指定（逆順）

```
colors.sort{|a, b| b[0] <=> a[0]}
　#=> ["red", "purple", "pink", "blue"]
```

複数条件
`<=>`は-1,0,1を返すので、0の場合（同じ場合）は`||`で繋がれた次の条件でソートさせる

```
colors.sort do |a, b|
　(a[0] <=> b[0]).nonzero? || (a[1] <=> b[1])
end
　#=> ["blue", "pink", "purple", "red"]
```



# insert
`insert({位置}, {値},...)`

基本：１つ目の引数の箇所に2つ目以降の値を挿入する

```
[1, 2, 3].insert(2, 9)
　#=> [1, 2, **9,** 3]
```

複数も可

```
[1, 2, 3].insert(2, 8, 9)
　#=> [1, 2, **8, 9,** 3]
```

不足分はnilが入る

```
[1, 2, 3].insert(5, 6)
　#=> [1, 2, 3, **nil, nil, 6**]
```


# 置換
`array = [1, 2, 3]`
`[{位置}, {数}] = {値} `


{位置}番目から{数}個の値を{値}に置換する
破壊的。戻り値は{値}

```
array[0, 1] = 9
　#=> 9
array
　#=> [9, 2, 3]
```

複数も可

```
array[2, 1] = 7, 8, 9
　#=> [7, 8, 9]
array
　#=> [1, 2, 7, 8, 9]
```

配列内配列にはならない

```
array[2, 1] = [7, 8, 9]
　#=> [7, 8, 9]
array
　#=> [1, 2, 7, 8, 9]
```

{数}と{値}の個数が合わなくても良い
{数}の分の値が消されて{値}が追加される
{数}は元の配列の個数を超えていても良い

```
array[1, 3] = 9
array
　#=> [1, 9]
```

{数}を０にすれば、挿入になる

```
array[1, 0] = 9
array
　#=> [1, 9, 2, 3]
```
【python】web開発準備（仮想環境の構築、pyramidインストール）

###前回のおさらい

[前回](http://qiita.com/ichi913/items/8d529a8fd27182098d79)、virtualenvの導入まで終わらせたわけだけれども、
冷静に読み返してみると全く進んでないね。
今回でpyramidの起動くらいまでしたいんで、どんどん進めて行こう。

###仮想Python環境構築

とりあえず、virtualenvを使用して仮想Python環境を作成するところからスタート。

_※ 仮想Python環境ってのは、同じマシン上に複数のPython環境の設定ができる。
みたいなイメージ。呼び出し環境ごとにバージョンだって変えられるという便利なシロモノです。_

下のコマンドでsampleという名前で新しい仮想Python環境を作成

```shell-session
$ virtualenv --no-site-packages sample
```

作成したsampleディレクトリに移動し、その中でpyramidをインストールすることによって
仮想環境にpyramidが入るみたい。すごく便利。

```shell-session
$ cd sample
$ bin/easy_install pyramid
```

これでpyramidのインストールが完了。
Pythonの環境周りの勉強になったし、今回も進んでないのは気にしない！
mrubyからQtを呼ぶ

mrubyでQtを使えないかなーとずっと試行錯誤していたら、やっと、[わたしのqtbindingsのforkにあるmrubyブランチ](https://github.com/take-cheeze/qtbindings/tree/mruby)が実用段階になってきました。
基本的に、qtbindings（メンテナンスが継続されているQtRubyのフォーク）をmrubyに移植したものですが、mrubyに標準でないようなメソッドやモジュールを使っているrubyコードをC++で置き換えてあります。その関係で、C++11を使用しているので、ビルドするとき若干ややこしくなっています。
まずは、ビルド手順ですが、いきなり通常のmrubyではビルドできません。mrubyではrubyの様にRDataに独自のgcマーカーを使えないので、[わたしのmrubyリポジトリのrdata_gc_markerブランチ](https://github.com/take-cheeze/mruby/tree/rdata_gc_marker)を使用する必要があります。とりあえず、擬似的なシェルスクリプトでビルドする方法を書きます。

```shell-session
# 以下に進む前にqt qscintillaのsmokeパッケージをインストールします。その２つがインストールできれば、Qtのパッケージも自動的にインストールされるはずです。
export CXX="ccache clang++ -std=c++11" # 適当なC++11を使えるコンパイラを指定します。
cd 適当なディレクトリ/
git clone --branch mruby "https://github.com/take-cheeze/qtbindings.git"
cd qtbindings/
git clone --branch rdata_gc_marker "https://github.com/take-cheeze/mruby.git"
./build.sh
```

環境によっては、このインストール手順でビルドできない場合があるかもしれないのでそのときは、 *build.sh* や *build_config.rb* を編集してください。また、DBusやQScintillaが不要な場合は *qtbindings/mrbgem.rake* でそれら２つに関係ある部分を消していいです。
これでbuild.shの実行が終わったら、指定した適当なディレクトリの下に *qtbindings/mruby/bin/mruby* がビルドできてるはずです。
その後、動いているのかの確認のためにその実行ファイルで、 *qtbindings/examples/minimal.rb* を実行します。 *"Hello World!"* とだけ表示するウィンドウが出てくるだけのスクリプトですので、その目で *"Hello World!"* を確認してください。以下の様なウィンドウ（OS Xで実行した場合です）が表示されれば成功です。ちなみにウィンドウの閉じるボタンを押せばちゃんと終了します。
![スクリーンショット 2014-01-30 23.30.11.png](https://qiita-image-store.s3.amazonaws.com/0/6515/bc5517d0-afcd-3a8b-e1c3-d7787c714541.png)
ガンガン生成されるデバッグログがうざったい場合はスクリプトの先頭に以下の行を追加してください。まだまだ開発途中なのでデフォルトの状態だと生成できる最大の量を生成します。ログを少し細かく制限したい場合は、qtbindings/mrblib/_qtruby.rbにあるDebugChannelモジュール内のフラグで調整できます。

```rb
Qt::Internal.debug = 0
```

以上が、現在のmruby-qtをビルドしてとりあえず動かすまでの手順です。内部の構造などは、追々記事にできたらと思います。
storyBoard上でcollectionViewCell設定したのにcustomCellが反映されない時のハマりどころ


```
//StoryBoardでcustomCell使う時は以下をコメントアウト
//[self.collectionView registerClass:[#自作customCellクラス class] forCellWithReuseIdentifier:@"cellidentifier"];
```

参考URL
"ios - UILabel in custom UICollectionViewCell always null, can't update text - Stack Overflow"
http://stackoverflow.com/questions/15824225/uilabel-in-custom-uicollectionviewcell-always-null-cant-update-text

コードで書き切ろうとしてやっぱstoryBoradで作ろうとした時に陥りがち
Vagrantのプラグイン、何入れてたっけ…。

表題のように、『何入れてたっけ？』という時の確認。単純に、vagrant listで取れます。

```source:bash
% vagrant plugin list
sahara (0.0.16)
vagrant-hostsupdater (0.0.11)
vagrant-vbguest (0.10.0)
vagrant-vbox-snapshot (0.0.4)
```

以上、本題の『何入れてたっけ？』の確認は終了。

以下は入れているプラグインの説明を載せておきます。
また、なかなか良い **プラグイン一覧表**があったので、これも末尾に載せておきます。


## 入っているものの確認
### sahara & vagrant-vbox-snapshot

どっちも仮想マシンのスナップショットを取るプラグインです。
今のところ、こんな使い分けです。

- saharaは、スナップショット作成時に名前の明示が要らないので、出来上がった仮想マシンで自動でテストを実施する際に使ったりします。
 - 自動テスト実施前にsandbox onし、テスト実施。テスト終了後にsandbox rollbackでもとに戻す感じ。

- snapshotは、いわゆる普通のスナップショット機能をコマンドラインで実施するもの。
 - ベースのVMに対して少しずつ変更を加えて、状態をチェックして仕上げていくような場合に使っています。
 - たとえば、プロビジョニング用の手順を１つずつ適用していく際に、snapshotを取って確認するなど。

### vagrant-hostsupdater

最近入れてみたら、便利でした！
特に、仮想マシンでWebアプリケーションを立ち上げ、ブラウザでホスト側からチェックする場合に **『名前』**で参照できるようにしてくれます。

### vagrant-ip-show

Vagrantに割り当てあてられているIPアドレスを表示してくれるプラグインです。

- https://github.com/rogeriopradoj/vagrant-ip-show
- ソースコードはシンプルなので、プラグイン作成の参考になりそう (rubyで書かれています)

```
$ vagrant ip-show

10.xxx.xx.xxx
192.168.33.10
```



```
# Vagrantfileの設定例
config.vm.hostname = "vagrant-wp.local"
config.vm.network :private_network, ip: 192.168.33.10
```
このような設定で vagrant upすると…

```
# vagrant upの出力を一部のみ抜粋
# config.vm.hostnameに従い、仮想マシンの/etc/sysconfig/networkや/etc/hostsが変更。
[default] Setting hostname...
[default] Configuring and enabling network interfaces...
[default] Mounting shared folders...
[default] -- /vagrant
# 今度は、ホストOS側の /etc/hosts も書き換えてくれます！
[default] Checking for host entries
[default] adding to (/etc/hosts) : 192.168.33.10  vagrant-wp.local  # VAGRANT: ac7b4da77acdbfcc9c07b97ebf253ea9 (default) / 723da5b5-fa2b-45ce-88c2-b89db67b2e8f
```

- やってること
 - config.vm.hostnameに従い、仮想マシンの/etc/sysconfig/networkや/etc/hostsが変更される。
 - ホストOS側の/etc/hosts にも、エントリを追加してくれる。
 - 必要に応じ、ホスト側ではrootのパスワードを聞かれて、sudoで/etc/hostsを変更。

vagrant haltで仮想マシンを停止する際は、ホスト側の/etc/hostsから登録を勝手に外してくれます。

```
% vagrant halt
[default] Attempting graceful shutdown of VM...
[default] Removing hosts
# この場合はsudoのパスワードを聞いてきて、/etc/hostsのエントリを外します
Password: 
```

### vagrant-vbguest

ゲストOS側とホストOS側のGuestAdditionを揃えてくれるプラグインです。

### vagrant-ip-show

Vagrantに割り当てあてられているIPアドレスを表示してくれるプラグインです。

- https://github.com/rogeriopradoj/vagrant-ip-show
- ソースコードはシンプルなので、プラグイン作成の参考になりそう (rubyで書かれています)

実行のサンプルです。

```
$ vagrant ip-show

10.xxx.xx.xxx
192.168.33.10
```

## Vagrant pluginの一覧

vagrant useful pluginで検索したら、HITしたURLを載せておきます。（かなりたくさん！）
上記に上げたものと同等のプラグインでも、いくつか実装があるんですね！

- https://github.com/mitchellh/vagrant/wiki/Available-Vagrant-Plugins

ゲストOS / Windows用のVagrant pluginがあるみたいなので、これも試してみようかと思います。

## Vagrant plugin開発について

こちらに基本の情報があります。実装はrubyベース。ただいま勉強中です！

- PLUGIN DEVELOPMENT BASICS
 - https://www.vagrantup.com/docs/plugins/development-basics.html
Xcode のビルドログの詳細を確認する方法

通常、Xcode でビルドした結果のウォーニングやらエラーやらは、
左ペインの Issue Navigator で見ることが多いと思いますが、
一連のビルド処理の流れを時系列的なログとして確認したいこともあると思います。
（例：独自のシェルスクリプトを加えたビルドフローを作っている場合）

そんなときは、Command+8 キーで現れる Log Navigator を使いましょう。

ビルド処理の全体の流れを見れて便利！
古いiScroll内で該当する要素のclickイベントが2回呼ばれる場合の対処法

onBeforeScrollEndメソッドに下記を設定。

```js
onBeforeScrollStart: function(e){
    if ($(e.target).closest('無視したい要素のクラス名')) {
       e.preventDefault();
    };
}
```
JavaScriptで、ブラウザデフォルトの確認ダイアログを使う方法

簡単な内容ですがメモ。

まずはHtml側。formタグの中に " return 'jsの関数名' " を入れておきます。
引数は入力したいメッセージなど入れるといい感じです。
m9(^Д^)ﾌﾟｷﾞｬｰのところにメッセージを入れる感じです。
下の例では、メッセージの他にも引数をとっています。
（[% u.nickname %]みたいなやつは、PerlのTT2のディレクティブです）

```html:form
<form action="[% path('/hoge/?i=request&target_id=' _ u.id) %]" method="POST" onSubmit="return confirmPugyaa('m9(^Д^)ﾌﾟｷﾞｬｰ', '[% u.nickname %]')">
  <input type="hidden" name="target_user_id" value="[% u.user_id %]" />
  <div class="info">
    <input type="submit" value="申請" class="send" />
  </div>
</form>
```

次にJavaScriptの方。
関数名はhtmlのformで指定したものと同じにします。

```js:confirm
function confirmPugyaa(msg,target){
	if(window.confirm(target + "さんに" + msg + "します。\nよろしいですか？\n")){
		return true;
	}else{
		return false;
	}
}
```

ブラウザで申請ボタンを押すとこんなダイアログが出ることになります。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/18705/bf07f9d6-c5ad-afde-90f4-7d086eec721c.png)

以上、簡単なメモでした。
tigの画面をアニメGIFで紹介してみる（ファイル編集・差分の削除・revert編）

[tigの画面をアニメGIFで紹介してみる（ブラウズ編）](http://qiita.com/yoshikazusawa/items/93653a6aa2013b3c3396) の続編です。

今回はgitの歴史操作をtigで行う実例をご紹介します。

使うツールは[前回](http://qiita.com/yoshikazusawa/items/93653a6aa2013b3c3396)と同じです。
使うリポジトリは説明のために新規作成しました。

# ファイルを編集してコミットする

既存のファイルのtypoを直してコミットする過程です。
![tig-fix-typo-with-keyview](http://f.cl.ly/items/1q312x231s0s3E283R3k/tig-fix-typo-with-keyview.gif)

1. mainビューからコミットを選びtypo発見
1. diffビューから`e`でエディタ起動（筆者環境ではvim）
1. typoを修正してvimを終了
1. mainビューで`R`を押して画面リフレッシュし差分を確認
1. `S`でstatusビューに遷移し、差分のあるファイルを`u`にてstageに上げる(`git add`に相当）
1. `C`で`git commit`の実行、コミットメッセージを書いて保存
1. commitの反映を確認

# 編集していた差分を元に戻したい

ワークディレクトリで差分が生まれたけれど元に戻す過程です。
![tig-status-revert-change](http://cl.ly/image/1o1N1r0H1h0q/tig-status-revert-change.gif)

1. ステージされていない謎の空行差分を確認したため消したい
1. `S`でstatusビューに遷移し、元に戻したいファイルにカーソルをあてて`!`
1. mainビューに戻って、差分が消えていることを確認

# 間違ったコミットをrevertしたい

何かを勘違いして生まれたコミットをrevertする過程です。
tigの標準キーバインドではgit revert相当の割り当てはないため、.tigrcで以下を定義しておきます。

```
bind main V !?git revert %(commit)
```

キーバインド設定の記法については拙作の[やけに丁寧なtigの設定ガイド（キーバインド概論編）](http://qiita.com/yoshikazusawa/items/3eaa6db78fa348d38bfe)も参考にしてください。

![tig-revert-commit](http://f.cl.ly/items/03382G3u0e1z1c1k0Z3O/tig-revert-commit.gif)

1. tigの紹介文を書いていたつもりがGitHubになっていたのでrevertしたい
1. mainビューでrevertしたいコミットにカーソルを合わせて`V`で`git revert`を実行
1. revert コミットメッセージを記述して保存
1. mainビューで反映を確認


以上になります。
xcodeprojで*.xcodeprojを操作してみる

[xcodeproj](http://rubygems.org/gems/xcodeproj) というgemをつかうと、*.xcodeprojをRubyからいじれるようだ。たとえば以下のようにすると、プロジェクトのビルド前に任意のスクリプトを実行するフェーズをつくることができる。

現実のプロダクトでは、CocoaPodsなどで使っているよう。

```rb
#!/usr/bin/env ruby
require 'xcodeproj'
project = Xcodeproj::Project.open(*Dir.glob('*.xcodeproj'))

PHASE_NAME = "Do something wonderful"

project.targets.each do |target|
  next if target.build_phases.any? do |phase|
    phase.respond_to?(:name) && phase.name == PHASE_NAME
  end

  phase = project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
  phase.name = PHASE_NAME
  phase.shell_script = "echo do something with ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/your.file"
  target.build_phases.unshift(phase)
end

project.save()
```
CentOS6.xにてnginxの最新版をインストールする手順


## nginx公式ページからyumリポジトリのURLをコピー

公式ページはここ。
http://nginx.org/en/linux_packages.html#stable

「CentOS 6」ってリンクがあるので、URLをコピー。現時点でのURLはこれ（2014/01/30）。まぁ変わらないと思うけど。

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

## CentOSにてリポジトリを登録
先ほど取得したURLを使って、yumリポジトリをCentOSに登録。

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

下記ファイルが`/etc/yum.repos.d/`配下につくられる。

```nginx.repo
# nginx.repo

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

## nginxをyumでインストール

あとは普通に。。。

```
# yum -y install nginx
```

バージョン確認。

```
# nginx -v
nginx version: nginx/1.4.4
```

## nginxを起動

あ、これだけなんだ。

```
# nginx
```

- - -
> Blog URL : http://www.utano.jp/ (Syntax Error.)
ViewControllerで戻るボタンのタップを検知する


ViewControllerによって自動で生成された戻るボタンをユーザーに押された時の処理を検知したいときに調べたメモ。みなさんもユーザーのログ関係でそういうことをしないといけない要件があったりするのではないかなと。

StackOverflowみるといくつか方法があった
http://stackoverflow.com/questions/5217992/back-button-callback-in-navigationcontroller-in-ios

3つ紹介しておく。

## viewWillDisappear:時に判定

viewWillDisappear:時に自分自身がnavigationControllerのコンテナに追加されているかを判定することによって検出できる

```objc
- (void)viewWillDisappear:(BOOL)animated
{
    if (![self.navigationController.viewControllers containsObject:self]) {
        //戻るを押された
        NSLog(@"back");
    }
    
    [super viewWillDisappear:animated];
}
```

viewWillDisappear:はライフサイクルとして動作しているメソッドなので、戻るを押されてこのViewControllerがpopされた後に動作するためこの判定でも検知はできるが、下記のようなお約束の上で成り立っている

- ViewControllerがpopされた
- popされたから画面から消える
- 画面から消えるからviewWillDisappear:が動作する
- ViewControllerが破棄される

仕様上、popされた際に必ずviewWillDisappear:が起きるわけではなく、画面の表示が無くなった際に動作するので順番的には妥当っぽく見える。

上手く説明できないけど、ライフサイクルに依存するのは少し綱渡り的な気がするし人に教える時はこの方法はやめとくかな。

Appleのリファレンスを調べると、ライフサイクルを使う方法にはもうひとつやり方がある。それはisMovingFromParentViewControllerプロパティを調べるやり方で、このプロパティ自体の説明としても妥当な使い方をしている

```objc
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    
    if (self.isMovingFromParentViewController) {
        //親から削除されているかどうかなので戻るだけでなく閉じても判定
        NSLog(@"isMovingFromParentViewController");
    }
    
}
```

ただ、これは戻るボタンのタップ以外に、この親ViewControllerがモーダルの場合には「戻るボタン」だけでなく閉じても動作して同じように判定してしまう。

## didMoveToParentViewController:で判断

didMoveToParentViewController:メソッドはコンテナがViewControllerを追加した後にその追加されたViewControllerで実行される。これを使えばpopされたとこを検知できるので戻るを判定できる（モーダルで閉じるにしても動作しない）。


```objc
//追加もしくは削除された後に動作する
- (void)didMoveToParentViewController:(UIViewController *)parent
{
    if (![parent isEqual:self.parentViewController]) {
        NSLog(@"back");
    }
}
```

最初self.parentViewControllerはnilだろうしnilかどうかで判断すればいいのでは...と思ったがこのメソッドの前に他のコンテナに追加されnilでないこともあるんだろう。

また、削除された時はdidMoveToParentViewController:の引数parent自体がnilのはずなのでparentがnilだったら削除されてると判断できなくもない気がする。より厳密さを求めて特定の親ViewControllerを比較したいためにisEqaul:メソッドで比較しているのだと思う（ただ戻るを押した際の動作的にはnilとnilの比較になっていた）。

didMoveToParentViewController:ってどんなんだっけとググったら昔書いた自分のメモがあった
http://qiita.com/yimajo/items/a5e16fa0f9c332a55ccf
php+gearman+supervisiorをインストールして使ってみた。


Gearman
================================================

インストール（peclのインストールのためにgccを入れる場合には少し時間がかかる）

		yum install php-gearman* *gearman*
		pecl install gearman

設定

		vi /etc/php.ini
		extension=...

DB作成（メモリかsqliteにするほうがいいかと思いつつ。。）

		CREATE DATABASE gearman;
		CREATE TABLE queue ( 
		    unique_key VARCHAR(255),
		    function_name VARCHAR(255),
		    priority INT,
		    data LONGBLOB,
		    when_to_run BIGINT,
		    unique key (unique_key, function_name)
		);

		vi /etc/sysconfig/gearman
		OPTION=" -q MySQL --mysql-user=… --mysql-password=… --mysql-db=gearman --mysql-table=queue "

ログローテートとかchkconfigとか

		chkconfig ...
		/var/log/gearman.log {
		       missingok
		       weekly
		       notifempty
		       nocompress
		}


supervisior
================================================

いんすと。。（後述だがpipでインストールする）

		yum install supervisor

せってい。。

		vi /etc/supervisord.conf
		[program:…-01]
		略
		[program:…-02]
		略

ろぐろーてーととか、、

		略

やってみてどうだったかとか
================================================

苦労したのがsupervisior。
複数プロセスの設定で、設定ファイルがバージョンでだいぶ違ったりsocketファイルのファイル権限とか。。
やりやすさで、yumのバージョンで、多分ちょっと古いやりかたを採用。numprocとか使いたかった。。
あとはfuelPHPからきゅーしました。

追記：

この後、exit 1などの終了コードでプロセス監視が途絶えてしまうことが課題となり、pip installで3.0をインストールして、オプション設定することで対応できた。easy_installではなくpipでinstallしたらうまくいった気がいする。今回virtualenvは使わなかった。numprocをつかえるようになって便利になって良かった。

追記：

gearmanのcpuの占有がタスクが無くても大きくなっていたかもしれない。
バッチでのタスクを無くしても占有率が高かった。
再起動したら解消された。まあ、移行したからいらないんだけど。

追記：

service supervisord restartだと失敗するときがある。
プロセスの再起動だけならsupervisorctl restart hoge

supervisorctl status 子プロセスの様子を見る
supervisorctl stop 子プロセスを停止する
supervisorctl start 子プロセスを開始する
supervisorctl restart 子プロセスを再起動する
supervisorctl reload Supervisord自体を再起動する
supervisorctl reread 設定ファイルを読みなおして変更を反映させる
supervisorctl avail 全プロセスの情報を表示

参考：
PHP+Kestrel+Supervisorでお手軽タスクキューイング
http://blog.asial.co.jp/875

http://cultureeen.hatenablog.jp/entry/2014/05/11/155933
http://yulii.net/entries/54
http://qiita.com/yushin/items/15f4f90c5663710dbd56
RSpecとSequel(あと、少しのruby-oci8/ruby-plsql)でデータベースにBDDする最小構成

SequelはRubyのORMです。
ActiveRecordと違い、Sequelは依存関係がほとんど無いため、環境に悩まされる事が少ないと思われます。
そのため、PL/SQLの実行結果や、テーブルの値をRSpecで検証するといった事が軽量にできるようになります。

今回は`V$DATABASE`テーブルからPLATFORM名の取得/検証と、`DBMS_UTILITY.DB_VERSION`パッケージによるDBバージョンの取得/検証を行います。

## RSpec / Sequel 環境構築 ##

```bash
$ mkdir $W
$ cd $W
$ bundle init
$ cat << EOT >> Gemfile
gem "rspec"
gem "sequel"
gem "ruby-oci8"
gem "ruby-plsql"
EOT
$ bundle install --path vendor/bundle
$ bundle exec rspec --init
```

## specファイル / Rakefile ##

べた書きしてます。実際に使うときはDRY化してください。

```Rakefile.rb
require "bundler"
Bundler.setup
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new("spec")
```

```spec/all_spec.rb
require "bundler"
Bundler.require

RSpec.configure do |config|
  config.before(:suite) {
    DB = Sequel.connect("oracle://scott:tiger@hostname/dbname")
    plsql.connection = OCI8.new("scott", "tiger", "//hostname/dbname")
  }
end

describe "Oracle Database" do
  context "with platform name" do
    it { expect(DB.from("v$database").get(:platform_name)).to start_with "Solaris" }
  end

  context "with DBMS_UTILITY.DB_VERSION package" do
    subject { plsql.dbms_utility.db_version }
    its(:size) { should eq 2 }
    its([:version]) { should start_with "10.2.0" }
  end
end
```

## RSpec実行 ##

```bash
$ bundle exec rake spec
/Users/ma2shita/.rbenv/versions/2.0.0-p353/bin/ruby -S rspec ./spec/all_spec.rb
...

Finished in 0.10275 seconds
3 examples, 0 failures
```

## 拡張方法 ##

`db/migrate/*.rb` や `db/seeds.rb` でDB操作が必要ならば、このようになります。

```Rakefile.rb
namespace :db do
  task :migrate do
    Sequel.extension :migration
    Sequel.connect("oracle://scott:tiger@hostname/dbname"){ |db| Sequel::Migrator.run(db, "db/migrate")}
   end

   task :seed do
     load "db/seeds.rb"
   end
end
```

## 検証環境 ##

* rbenv (0.4.0-89-g14bc162)
* ruby (2.0.0-p353)
  * bundler (1.5.2)
  * rspec (2.14.1)
  * ruby-oci8 (2.1.6)
  * ruby-plsql (0.5.0)
  * sequel (4.6.0)

## 参考資料 ##

* Sequel
  * [jeremyevans/sequel](https://github.com/jeremyevans/sequel)
  * [Ruby - 既存のテーブル用のマイグレーションファイルをSequelで作成する - Qiita [キータ]](http://qiita.com/futoase/items/9c76b2a50ba31f866f16)
* ruby-oci8 / ruby-plsql
  * [ruby-oci8 - トップページ](http://ruby-oci8.rubyforge.org/ja/)
  * [rsim/ruby-plsql](https://github.com/rsim/ruby-plsql)
* RSpec
  * [Ruby - rake spec で spec/ 以下のテストを実行させるための最小限の設定 - Qiita [キータ]](http://qiita.com/kyanny/items/afbb010ea1182478cb27)
  * [Ruby - RSpecのshouldはもう古い！新しい記法expectを使おう！ - Qiita [キータ]](http://qiita.com/awakia/items/d880250adc8cdbe7a32f)
  * [Better Specs { rspec guidelines with ruby }](http://betterspecs.org/jp/)
* etc
  * [DBMS_UTILITY](http://docs.oracle.com/cd/E16338_01/appdev.112/b56262/d_util.htm#i1002631)

## あとがき ##

Qiita初投稿。コードブロックのファイル名に`Rakefile`って書いてもファイル名認識されないのが切ない。
配列

## 配列とは何か?
変数だと以下のような物を↓


```js
var fruit1 = 'みかん';
var fruit2 = 'リンゴ';
var fruit3 = 'ぶどう';
```

配列だと下の様に扱える！

```js
var fruit = ['みかん', 'りんご', 'ぶどう'];
```


## 配列の実際の使い方
•配列要素の取得

`配列名[インデックス]`で取得出来る。

実際に「ボンクラーズ」でやってみよう。

```js
var bonkura = ['とも', 'おおさか', 'さかき'];
var tomo = bonkura[0];
var osaka = bonkura[1];
var sakaki = bonkura[2];
document.write(tomo); //=> とも
document.write(osaka); //=> おおさか
document.write(sakaki); //=> さかき
```

![配列3.png](https://qiita-image-store.s3.amazonaws.com/0/35975/92b56825-1e77-c57e-7247-5a929483c528.png "配列3.png")

「みかん、りんご、ぶどう」でやると以下。

![配列01.png](https://qiita-image-store.s3.amazonaws.com/0/35975/71acd963-ec06-15ee-acb9-a463ada34af3.png "配列01.png")

ちなみに「インデックス」は[0]番から始まります。


•値の更新は以下(2番目が"おおさか"に変わってる)

```js
var bonkura = ['滝野智', '春日歩', 'さかき'];
bonkura[1] = 'おおさか'
document.write(bonkura);
```

![配列02.png](https://qiita-image-store.s3.amazonaws.com/0/35975/f05893de-824d-fd9f-8e83-e9cb1f7ec2f2.png "配列02.png")

## 配列の要素数
配列の要素は .lengthで取得できる。

`配列名.length`

例えば「ボンクラーズ」の要素数の取得なら↓

```js
var bonkura = ['とも', 'おおさか', 'さかき'];
document.write(bonkura.length);  //=> 3
```


![配列要素数.png](https://qiita-image-store.s3.amazonaws.com/0/35975/ac7f14a8-9c64-e6d2-31c4-b85a6e019cc6.png "配列要素数.png")

実際にどうゆう時に使うかと言えば、、
「最後の要素の値」を取得したいとき等があげられる！
「あずまんがの仲良し６人」でやってみよう。


```js
var azumanga = [
	'ちよ',
	'おおさか',
	'さかき',
	'とも',
	'みずはら',
	'かぐら'
	];
var lastIndex = azumanga.length - 1;
var lastElement = azumanga[lastIndex];
document.write(lastElement); //=> かぐら
```


![要素数_最後の値取り.png](https://qiita-image-store.s3.amazonaws.com/0/35975/95c2d10e-7558-b210-9090-2c43f833fb55.png "要素数_最後の値取り.png")

と「かぐら」が表示されました。
[Rails]既存のMySQLテーブルに接続する方法


別のアプリケーションで使っていたテーブルをRailsでデータ引っ張ってきたい時の方法。
※Rails4.0.2 Ruby2.0.0で確認


Railsでプロジェクト作って。。。

`rails new アプリケーション名`

MySQLに接続はいつもどおりのmysql2

```Gemfile
gem 'mysql2'
```

```database.yml
development:
  adapter: mysql2
  encoding: utf8
  database: database
  username: name
  password: pass
  host: localhost
  port: 3306
  pool: 5
  timeout: 5000
```

とりあえず`$ bundle install`後に`$ rails s`で起動確認しておく


こっから本番。
schema.rbにMySQLのテーブル情報を書き込みたいので、

`$ rake environment -v -t RAILS_ENV=development db:schema:dump`

とする。
そうすると、schema.rbにMySQLのテーブル情報が書き込まれていることが確認できます。

その後、モデルを作成。
作成したモデルと標準のテーブル名が違う場合は、

```test.rb
class Test < ActiveRecord::Base
  self.table_name = "test"

end
```

とすると、testsというようなテーブル名じゃなくてもデータを取得できます。

```test_controller.rb
def test
	test = Test.where(["name = ?", "hoge"])
	p test
end
```

こんな感じ。
Rubyでわりかし簡単にCSVからSIMAに変換する

調査士会で会員向けに配布された、測地成果2011変換済みの街区基準点データをSIMA形式(CSV)に変換します。
SIMA形式(CSV)では文字コードがShift-JISとされているのでスクリプトもShift-JISで作成すると不幸にならないと思います。

```rb
pName = 4
x = 6
y = 7
dName = File.basename(ARGV[0],".*")

sima = <<EOF
G00,00,#{dName},
Z00,/* 座標データ */,
Z01,2,
A00,
EOF

open(ARGV[0]) do |file|
   file.each_with_index do |line, i|
      if line =~ /\t/
         arry = line.split("\t")
      else
         arry = line.split(",")
      end

      arry.each do |elem|
         elem.strip!
      end

      if arry[x] && (arry[x][-1] =~ /[0-9]/)
         sima = sima + "A01,#{i + 1},#{arry[pName]},#{arry[x]},#{arry[y]},,\n"
      end
   end
end

sima = sima + "A99,\n"

open(dName + ".sim", "w") do |file|
   file.write sima
end
```

たまに空行があったり項目名が何度も出てきたりするのは`if arry[x] && (arry[x][-1] =~ /[0-9]/)`のくだりで弾けていると思います。
スクリプトをcsv2sim.rbと保存した場合下記の様に実行すると入力したCSVと同じディレクトリに`さいたま市.sim`というファイルが作成されます。

```
ruby -Ks csv2sima.rb さいたま市.csv
```

測量計算ソフトには座標テキストファイルを読み込む機能があるのでその機能を使って読み込むとRubyを使わなくても座標を展開できます。

今回は38ファイル全部を変換したかったのでスクリプトを組んだわけです。
PowerShellから下記のようなコマンドを叩くとディレクトリ内のCSVを一括でSIMAに変換してくれます。

```ps1
Get-ChildItem -Name *.csv| Where-Object { ruby -Ks.\csv2sim.rb $_ }
```

`pName`、`x`、`y`の変数に適切な数字を当て込めば別の座標データCSVでもSIMAにできるかもしれません。
ただし、測地成果2011の9系以外のデータの時は`Z01,2,`の行を削除するか適切な値に変更しないといけないので注意が必要です。
Vagrantfileを日本語訳してみました（Pull Request歓迎！）

Vagrantfileを日本語訳してみました：

[Vagrantfile-jp](https://github.com/weed/p140125-Vagrantfile-jp/blob/master/Vagrantfile)

まだVagrant始めたばかりなので、おかしいところが多々あると思います。お気づきの点は是非pull requestして下さい。よろしくお願いします。

-----
ブログやってます：[weed software 開発者ブログ](http://weed.cocolog-nifty.com/wzero3es/)
【jQuery】チェックされたチェックボックスを取得する

##チェックされているチェックボックスのvalueを配列で取得

```html:html
<input type="checkbox" class="area" value="kantou">関東
<input type="checkbox" class="area" value="touhoku"> 東北
<input type="checkbox" class="area" value="hokkaidou"> 北海道
```

```js:jquery
area = $('[class="area"]:checked').map(function(){
  //$(this)でjQueryオブジェクトが取得できる。val()で値をvalue値を取得。
  return $(this).val();
}).get();
//mapの結果がjQueryオブジェクトの配列で返ってくるので、get()で生配列を取得する。

console.log(area);
//['kantou','touhoku']のような形で取得できる。
```

##チェックされているチェックボックスのvalueをクエリストリング形式で取得

```js:jquery
area = $('[class="area"]:checked').map(function(){
  return 'area[]=' + $(this).val()
}).get().join('&');

console.log(area);
//=>クエリストリング形式で取得できる。 area[]=kantou&area[]=tohoku
```

```js:jQueryでサーバへpost
$.ajax({
  url:url,
  type:'post',
  dataType:'json',
  data:area //そのままPOSTする
})
.done(function( data, textStatus, jqXHR ) {
  //省略
})  

```

```php:cakephp
//リクエストが配列形式なのでそのままin条件に使用できる
$area= $this->request->data('area');

var_dump($area);
/*
array(2) {
  [0]=>
  string(3) "kanto"
  [1]=>
  string(3) "tohoku"
}
*/

$res = $this->find('all',[
  'conditions'=>[
    'area'=>$area
  ]
]);
四則演算

(1)簡単な足し算
`var result = 10 + 20;`
`document.write(result);`-------=> 30

(2)変数を利用した場合
`var x = 10`
`var y = 20`
`var result = x + y;`
`document.write(result);`--------=> 30

(3)5つの四則演算
最初に3つの変数を定義
`var x = 10;`
`var y = 4;`
`var result;`

`// 足し算`
`result = x + y;`
`document.write(result); //=> 14`

`// 引き算`
`result = x - y;`
`document.write(result); //=> 6`

`// かけ算`
`result = x * y;`
`document.write(result); //=> 40`

`// 割り算`
`result = x / y;`
`document.write(result); //=> 2.5`

`// 割り算の(あまり)`
`result = x % y;`
`document.write(result); //=> 2`

## 計算の優先順位

`var x = 10;`
`var y = 3;`
`var z = 5;`

`// かけ算の方が優先される`
`document.write(x + y * z); //=>25`

`// ()内が優先される`
`document.write((x + y) * z); //=>65`

## 自分自信を演算する場合

`var x = 10;`
`x = x + 5;`
`document.write(x);`---------=>15

## インクリメント(増加)とデクリメント(減少)
自分自身に1足すには「x++」、1引くには「x--」と表記する。
`var x = 10;`
`x++;`
`document.write(x);`---------=>11

## 数値と文字列の扱い方
文字列と数値の扱い違いについて
「+で連結した場合」で検証してみる。

① 数値の場合
`var x = 10;`
`var y = 20;`
`var result = x + y;`
`document.write(result);`-------=> 30

② 文字列の場合
`var x = '10';`
`var y = '20';`
`var result = x + y;`
`document.write(result);`-------=> 1020

③ 数値に文字列を結合した場合
`var x = 10;`
`var y = '20';`
`var result = x + y;`
`document.write(result);`-------=> 1020 ↓

![数値に文字列.png](https://qiita-image-store.s3.amazonaws.com/0/35975/d11f7458-d106-ba48-3758-9fdee42f7b8d.png "数値に文字列.png")
CentOSにLAMP環境を構築する


CentOSにLAMP環境をつくって、`http://www.example.com`でWebサイトを公開したい。という場合にやることの手順。

## L - Linux(CentOS)
(・∀・)


## A - Apache

Apacheをインストール

```
# yum -y install httpd
```

起動。

```
# /etc/rc.d/init.d/httpd start
```

サーバ起動時にApacheを起動するようにしておく。

```
# chkconfig httpd on
```

これでローカルのブラウザ等で`http://www.example.com`にアクセスするとApacheのデフォルトページが表示されるはず。

`httpd.conf`は、`/etc/httpd/conf/httpd.conf`にある。

デフォルトのDocumentRootは、`/var/www/html/`になってる。

## M - MySQL

MySQLのインストール、起動、自動起動設定。

```
# yum -y install mysql-server
# /etc/rc.d/init.d/mysqld start
# chkconfig mysqld on
```

とりあえずここまで。あとは動作確認でテーブル作ったりします。

## P - PHP

PHPをインストール。

```
# yum -y install php
```

勝手に`/etc/httpd/conf.d/php.conf`ってファイルを作ってくれて、Apache再起動でPHPが使えるようになる。（たぶん。いつのまにかあったけど、このタイミングでできたんだと思う）

```php.conf
<IfModule prefork.c>
  LoadModule php5_module modules/libphp5.so
</IfModule>
<IfModule worker.c>
  LoadModule php5_module modules/libphp5-zts.so
</IfModule>

AddHandler php5-script .php
AddType text/html .php

DirectoryIndex index.php
```

続けて、PHPからMySQLを操作できるようにphp-mysqlモジュールをインストールする。

```
# yum -y install php-mysql
```

以上で必要なものは全てインストール完了。

## 動作確認

### 1. MySQLに動作確認用のデータベースを用意する

まずはログイン。

```
# mysql -u root
```

rootアカウント（mysqlの）はパスワードは未設定なので、上記コマンドでそのままログインできる。

ログインできたら、データベースの一覧を確認。

```
mysql> show databases;
```

たぶん、[test]というデータベースがあると思うので、それを使わしてもらう。使用するデータベースをtestに変更。

```
mysql> use test
```

[sample]というテーブルを作成。

```
mysql> create table sample (id integer, name varchar(30));
```

テーブル一覧を確認。

```
mysql> show tables;
```

[sample]テーブルができてたら、2件ほどデータを入れておく。

```
mysql> insert into sample values(1, 'kagawa');
mysql> insert into sample values(2, 'honda');
```

データを確認。

```
mysql> select * from sample;
```

insertしたデータが表示されれば、データベースの準備はこれで終わり。quitコマンドでmysqlからログアウト。

```
mysql> quit
```


### 2. サンプルスクリプトをつくる

次に、PHPのスクリプトをドキュメントルートに置く。

```
# cd /var/www/html/
# vi index.php
```

まずは、PHPのHello World的なphpinfoを表示。

```php:index.php
<?php
	phpinfo();
?>
```

上記スクリプトを保存して、`http://www.example.com`にアクセスしてみるとphpinfoが表示されるはず。

ここまでで、Apache上でPHPが動いてることが確認できる。

うまくいったら、いよいよMySQLに接続。

`index.php`を以下のとおり修正。

```php:index.php
<?php
    $con = mysql_connect('localhost', 'root', '') or die('error(connect)');

    mysql_select_db('test', $con) or die('error(select_db)');

    $sql = 'select * from sample';
    $result = mysql_query($sql, $con);

    while ($row = mysql_fetch_array($result)) {
        echo $row['id'] . ' : ' . $row['name'] . '<br />';
    }

    mysql_close($con);
?>
```


### 3. サンプルスクリプトを実行

`http://www.example.com`にアクセス。以下の結果が表示されればLAMP環境構築は終わり。

```
1 : kagawa
2 : honda
```


※ MySQLのユーザ／パスワード設定は別途やっといてください。

- - -
> Blog URL : http://www.utano.jp/ (Syntax Error.)
シェルスクリプトで時間計算を一人前にこなす

# 時間の計算もShellScriptの泣き所だった

シェルスクリプトが敬遠される理由の一つ。それは時間の計算機能が弱いところだ。例えば、

* 今から一週間前の年月日時分秒は？（それより古いファイルを消したい時など）

* Ya年Ma月Da日とYb年Mb月Db日、その差は何日？（ログを整理したい時など）

* この年月日は何曜日？（ファイルを曜日毎に仕分けしたい時など）

といった計算が簡単にはできない。dateコマンドの拡張機能を使えばできるものもあるが、できるようになることが中途半端なうえに、OS間の互換性がなくなる。これを解決する方法がこのTipsだ。

# UNIX時間との相互変換ができれば一気に解決

前述のような日時の加減算や2つの日時の差を求めるなどといった時は、一旦[UNIX時間](http://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93)に変換して計算し、必要に応じて戻せばよいことはご存知のとおり。曜日を求めるのだって、UNIX時間変換の値を一日の秒数(86400)で割って得られた商を、さらに7で割って余りを見ればよい、ということもお分かりだろう。

だが、そのUNIX時間との相互変換が面倒だった。なのでコードを書いてみた。一度コードさえできあがってしまえばあとはそれを使うだけ。必要なシーンで以下のコードをコピペして使ってもらえばいい。

## 日常の時間 → UNIX時間

UNIX時間への変換は、フェアフィールドの公式から導出される変換式にあてはめるだけなので簡単だ。

```sh:DateTime2UNIXtime
echo "ここにYYYYMMDDhhmmss" | # date '+%Y%m%d%H%M%S'などを流し込んでもよい
awk '{
  # 年月日時分秒を取得
  Y = substr($1, 1,4)*1;
  M = substr($1, 5,2)*1;
  D = substr($1, 7,2)*1;
  h = substr($1, 9,2)*1;
  m = substr($1,11,2)*1;
  s = substr($1,13  )*1;

  # 計算公式に流し込む
  if (M<3) {M+=12; Y--;} # 公式を使うための値調整
  print (365*Y+int(Y/4)-int(Y/100)+int(Y/400)+int(306*(M+1)/10)-428+D-719163)*86400+(h*3600)+(m*60)+s;
}'
```

## UNIX時間 → 日常の時間

これはさっきのよりもちょっと面倒。公式使って一発変換とかできないものかと調べたけどそういうのは無いらしい。glibcのgmtime()関数を参考につくってみた。

```sh:UNIXtime2DateTime
echo "ここにUNIXtime" |
awk '{
  # 時分秒と、1970/1/1からの日数を求める
  s = $1 % 60;  t = int($1/60);
  m =  t % 60;  t = int( t/60);
  h =  t % 24;
  days_from_epoch = int( t/24);

  # 年を求める
  max_calced_year = 1970;              # To remember every days on 01/01 from
  days_on_Jan1st_from_epoch[1970] = 0; # the Epoch which was calculated once
  Y = int(days_from_epoch/365.2425)+1970+1;
  if (Y > max_calced_year) {
     i = days_on_Jan1st_from_epoch[max_calced_year];
     for (j=max_calced_year; j<Y; j++) {
       i += (j%4!=0)?365:(j%100!=0)?366:(j%400!=0)?365:366;
       days_on_Jan1st_from_epoch[j+1] = i;
     }
     max_calced_year = Y;
  }
  for (;;Y--) {
    if (days_from_epoch >= days_on_Jan1st_from_epoch[Y]) {
      break;
    }
  }

  # 月日を求める
  split("31 0 31 30 31 30 31 31 30 31 30 31", days_of_month);  # 各月の日数(2月は未定)
  days_of_month[2] = (Y%4!=0)?28:(Y%100!=0)?29:(Y%400!=0)?28:29;
  D = days_from_epoch - days_on_Jan1st_from_epoch[Y] + 1;
  for (M=1; ; M++) {
    if (D > days_of_month[M]) {
      D -= days_of_month[M];
    } else {
      break;
    }
  }

  # 結果出力
  printf("%04d%02d%02d%02d%02d%02d\n",Y,M,D,h,m,s);
}'
```

コードを読むと、年計算がなぜわざわざ配列なのかと思うかもしれないが、これは後々の拡張用。大量のUNIX timeデータを一気に扱うとなった時のため。まぁ、あまり気にしないでおいてもらいたい。

# コマンド化したのも置いておいたよ

毎回いちいちソースの中にコピペするのは面倒くさいというあなたのために、[utconvという名でコマンド化](https://github.com/ShellShoccar-jpn/misc-tools/blob/master/utconv)したものを用意したのでよかったら使ってもらいたい。

しかもこちらはかなりきっちりやっていて、 **タイムゾーンを考慮した相互変換** までやっている。

# そして最後に申し上げておきたい

**「無いものは作れ！」** と。簡単にできる他言語に移行するばかりじゃなくてね。自分で作れば理解も深まるし、自由も利くし……。由緒正しいUNIXの教本にも、そんなようなことが書いてあるらしい。

ちなみに、この時間計算ができるよになると、シェルスクリプトは **自力でCookieが焼けるようになり、** そしてさらに **HTTPのセッション管理ができるようになる。** 詳しくは下記のTipsで。

* [シェルスクリプトおばさん(43)の手づくりCookie](http://qiita.com/richmikan@github/items/fd4e75f54238182de717)

* [シェルスクリプトによるCGIのセッション管理](http://qiita.com/richmikan@github/items/ee77911602afc911858f)
makeするたびにC++で書かれたサーバを立ち上げ直す試み

やること
========================================
C++で書かれたサーバのバイナリが更新されるたびに自動でサーバを立ち上げ直すbashスクリプトを作る。

動機
========================================
日常的にコーディングはvim/cmake/makeを使用しています。C++などで書かれたネイティブコードのサーバ開発だとローカルでは「コード書く → サーバ落とし → make → サーバ立ち上げ → お試し →  （はじめにもどる）」というサイクルになります。そしてこのサーバの落とし・立ち上げがとても煩わしい。

Java/Scalaなどに代表される最近の環境だとビルドするたびにそこら辺はやってくれるんだけど・・・。

さりとて機能満載の総合開発環境も好きになれないのでbashスクリプトでなんとかしようというお話。

inotifywait
========================================
inotifywaitはファイルやディレクトリを監視しアクセス、削除、生成などのイベントを通知するツール。Linuxのシステムの機能であるinotifyと仕組みをコマンドラインユーティリティ化したもの。

Ubuntuでは sudo apt-get install inotify-tools でインストールできる。inotify-toolsをインストールするとイベント通知ではなく統計収集コマンドであるinotifywatchなどもインストールされる。

それぞれのコマンドについてはmanを参照してください。

スクリプト
========================================

```bash
#!/bin/bash

# Ctrl-Cでこのスクリプト自体が落ちるように登録しておく。
trap exit ERR

while true ; do
	# サーバー起動
	# 初回起動でバイナリ自体が存在しなかった場合のためファイルの存在を確認する。
	if [ -e source/server-bin ] ; then
		source/server-bin &
	fi

	# サーバーのプロセスIDを保存する。
	server_pid=$!

	# 立ち上げたことの表示する。
	date
	echo server_pid $server_pid

	# inotifywaitのプロセスIDの保存場所を作る。
	watch_pid=`tempfile`

	# inotifywaitでバイナリができるディレクトリを監視する。
	# 
	# inotifywaitの性質上、生成・削除を繰り返すバイナリ自体を監視することはできない。
	# そのため、バイナリの生成の監視はgrepを使って行う。
	# サーバのファイル名 server-bin が生成されたイベントを表す "CREATE server-bin" が
	# マッチするまで入力を受け、マッチしたらgrepを抜ける。
	# 
	# パイプ前段のプロセスをkillするためにはプロセスIDを保存しておいてkillを呼ばなければいけない。
	# そのため、先の一時ファイルにプロセスIDを保存するコードを加えておく。
	(inotifywait -m -e create source 2>&1 & echo $! > $watch_pid) | grep -q -m 1 "CREATE server-bin"

	echo watch_pid $(<$watch_pid)

	# サーバーとinotifywaitをkillして終了を待つ。
	kill $(<$watch_pid)
	kill $server_pid
	wait

	echo "updated"

	# 即座に立ち上げ直すと、実行権限の付与に間に合わない場合があるためsleepを入れておく。
	# たぶん1秒で十分
	sleep 2
done
```

これで
========================================
コード書く、makeする、サーバにアクセスする。というサイクルができた。
左端のn段のハノイの塔を最小回数で右端に移動させるときの最初の一手について

n段のハノイの塔を最小回数で移動させるには、まず最小回数でn-1段の円盤を全て中央に移動させてから、左端にある一番大きな円盤を右端に、そして再び最小移動回数で右端に移動させれば良い。a nをn段のハノイの塔の移動回数とするとa n = 2 * a (n - 1) + 1ということになる。また、明らかにn=1のときは1回が最短なので、この漸化式を解けば、最小回数は分かる。

最小の移動回数の数値自体には、今は興味がなくて、最小回数のときに一番小さな円盤をどこへ移動させるかということに興味がある。そこで、上の考え方をそのままHaskellのコードにしてみた。

# ソースコード

```hs:hanoi.hs
import Control.Monad.Writer

size :: [[a]] -> Int
size = foldr (\ xs n -> length xs + n) 0
move :: [[Int]] -> (Int, Int) -> Writer [String] [[Int]]
move xss (from, to) = return([move_ xs y (from, to) i| (xs, i) <- zip xss [0..]])
                      where (y:_) = xss !! from
move_ :: [Int] -> Int -> (Int, Int) -> Int -> [Int]
move_ [] y (from, to) i = if i == to then [y] else []
move_ (x:xs) y (from, to) i |i == from = xs
                            |i == to   = (y:x:xs)
                            |otherwise = (x:xs)

hanoi :: Int -> Writer [String] [[Int]]
hanoi n = hanoi_ n [[0..(n-1)], [], []] (0, 1, 2)
hanoi_ :: Int -> [[Int]] -> (Int, Int, Int) -> Writer [String] [[Int]]
hanoi_ 0 xss (from, work, to) = return(xss)
hanoi_ n xss (from, work, to) = do xss' <- hanoi_ (n-1) xss (from, to, work)
                                   xss''  <- move xss' (from, to)
                                   tell [show(xss'') ++" (" ++ show(from) ++ " -> " ++ show(to) ++ ")"]
                                   xss''' <- hanoi_ (n-1) xss'' (work, from, to)
                                   return(xss''')
show_hanoi :: Int -> IO ()
show_hanoi n = mapM_ putStrLn $ snd $ runWriter (hanoi n)

test :: Int -> IO ()
test n = mapM_ putStrLn $ take n $ map (head . snd . runWriter . hanoi) [1..]
```

# 実行結果
![hanoi_haskell.PNG](https://qiita-image-store.s3.amazonaws.com/0/227/970fbdb9-47d4-39dd-dce2-437b16820c75.png)
`show_hanoi n`でn段のハノイの塔の最小回数になる移動方法を示します。テストとして`show_hanoi 4`を実行しましたが、動いているようです。`test n`は1段からn段までのはじめの1手を標準出力しますが、`test 7`をした限りだと、『nが奇数ならば右端に、偶数ならば中央へ移動する』というのが答えになりそうです。

# 証明

『奇数段は右端に、偶数段は中央へ移動する』をn上の帰納法で証明します。まず、n = 1, 2の場合はすでに確認しているので、n段を帰納の仮定として、n+1段の場合を考える。

## n+1段

`hanoi_`の定義から`hanoi_ (n+1)..(from, work, to)`が呼ばれると(`from = 0, work = 1, to = 2`)、`hanoi_n .. (from, to, work)`、`hanoi_ (n-1)..(from, to, work)`と呼ばれていって、最終的に`hanoi_ 1 (from, work', to')`が呼ばれ、このときの`to'`が移動先になる。`hanoi_`の定義から`to'`はtoとworkをn回入れ替えたものなので、nが奇数ならば`to' = work = 1`で中央、nが偶数ならば右端になる。よって(n+1)が奇数ならば右端で、偶数ならば中央。
Sencha Touch のバリデーションメッセージを日本語化

Sencha Touch のバリデーションメッセージを日本語化してみました。

使用したのは Sencha Touch 2.3 です。

Sencha Touch 2.3 では、組み込みのバリデーターが6つあるので、それぞれのメッセージを上書きします。

```js
Ext.data.Validations.setPresenceMessage("が未入力です"); 
Ext.data.Validations.setLengthMessage("の長さが範囲外です");
Ext.data.Validations.setFormatMessage("の形式が不正です");
Ext.data.Validations.setInclusionMessage("は有効な値ではありません");
Ext.data.Validations.setExclusionMessage("は有効な値ではありません");
Ext.data.Validations.setEmailMessage("は有効なEメールアドレスではありません");
```

組み込み方法などについては、以下のページを参照してください：

[Sencha Touch 2.3: ラベルやメッセージを日本語化する方法 - ITアドベンチャー](http://shimotori.github.io/blog-it/2014/01/30/1-sencha-touch-make-messages-japanese/)
変数

ここでは

```js
var name = '鈴木一郎';
document.write(name);
```

を使って変数の取り扱いについて進めてみる。

重要なのは
`var name = '鈴木一郎';`
で設定した変数`name`は`''`や`""`でくくらない。
↑(文字列として認識して`name`と出力されてしまう)

うまくやれば、下のようになる。
![変数01.png](https://qiita-image-store.s3.amazonaws.com/0/35975/ab916ef7-ecf4-7cc9-7147-8c7bbf0458b1.png "変数01.png")

`var`を使って箱を作ることを「変数の定義」、`=`を使って箱にデータを入れることを「代入」と言います。
また、変数を定義してデーターを代入することを「変数にデータを保存」するとも言う。

## 変数に代入出来るデータの種類
以下５タイプに分類される。


```js
var str = 'string';         //文字列
var num = 100;              //数値
var arr = ['a', 'b'];       //配列
var obj = { a: 'b' };       //オブジェクト
var fun = function() {};    //関数
```


## 変数の値の更新

```js
var name = '春日歩';
name = 'おおさか';
document.write(name);
```

上記の様にすると最終的には

![変数02.png](https://qiita-image-store.s3.amazonaws.com/0/35975/fe9b3afe-11f4-52ce-820d-e5ea594866aa.png "変数02.png")

「春日歩→おおさか」へ変更(更新)されてる。
ARC環境での強参照／弱参照とNSHashTableの怪

NSHashTableというクラスがある。

https://developer.apple.com/library/mac/documentation/cocoa/reference/NSHashTable_class/Introduction/Introduction.html

簡単に言うと、これはNSMutableSetと同じような振る舞いをしながらも、コンテンツに対して弱参照を持つことができるというコンテナだ。FoundationのコンテナクラスであるNSArray,NSSet,NSDictionaryは、原則としてコンテンツに対して強参照を持つ。これがどういうことかというと、あるコンテナに格納したオブジェクトのもとのオーナー（強参照を持っていた）オブジェクトが開放されても、コンテナ自体が開放されない限りコンテナ内のオブジェクトは開放されないということである。多くの場合はこれでいいのだが、都合の悪いこともある。

例えば、複数のデリゲートオブジェクトを保持する場合。原則としてデリゲートオブジェクトをプロパティやメンバで保持する場合は、weak属性を使う。何故かと言うと、通常デリゲートを使用する場合は、デリゲートプロトコルの実装者がデリゲートの呼び出し元をインスタンス化してその所有権を持つ（強参照を持つ）ことになる。モーダルViewControllerに対してのデリゲートなどがよくあるパターンだ。そして、デリゲートの呼び出し元（この例ではModalViewController）がデリゲート先（PresentingViewController）に対して強参照を持ってしまうと、 **循環参照（Retain Cycle）** が発生する。ARC環境では2つ以上のオブジェクトが相互に強参照を持つと、どちらも永遠に開放されずにメモリリークが起きる。なので、呼び出し元から呼び出し先への参照をweakにすることで、呼び出し元のretain countが0になった時（modalが閉じられた時）に適切に開放されることになる。

しかし、この場合だと任意の個数のデリゲートオブジェクトに対応できない。そういう場合はどうするか。まず思いつくのがNSArrayで管理する方法だ。だが先に述べたようにNSArrayはコンテンツに対して強参照を持ちながらオブジェクトを保持する。その場合、先の例とは逆のパターン、つまり、デリゲートの呼び出し元よりも先にデリゲートの呼び出し先が開放されるような場合に、間接的に循環参照が起きる。呼び出し元が保持しているNSArrayが呼び出し先を強参照しているため、実質的に呼び出し元が呼び出し先すべてを強参照していることになるからだ。

そのような場合、コンテナに対しては強参照（メンバなどで）を持っておきたいが、中身のオブジェクトに対しては弱参照を持ちたいと思うのが自然だ。NSHashTableはそんなときに使うクラスである。

詳しい使い方は

http://dev.classmethod.jp/smartphone/ios-weakreference-collection/

などを見るとよいと思う。

…そしてここからが本題。
以下のようなテストコードがある。このコードは一見パスしそうな空気を感じるが、一箇所だけ失敗するところがある。さて、どの行か？

```objc

- (void)testHashTable
{
    NSHashTable *hashTable;
    hashTable = [NSHashTable weakObjectsHashTable];
    @autoreleasepool {
        NSObject *weakobj1 = [NSObject new];
        NSObject *weakobj2 = [NSObject new];
        [hashTable addObject:weakobj1];
        [hashTable addObject:weakobj2];
        [hashTable addObject:self];
        XCTAssert(hashTable.count == 3, @"コンテンツは３つのはず");
    }
    XCTAssert(hashTable.count == 1, @"@autoreleasepoolから抜けているのでweakobj1/2への参照が消えているはず");
    XCTAssert(hashTable.allObjects.count == 1, @"〃");
    
    XCTAssert([hashTable.anyObject isEqual:self], @"hashtableのコンテンツはselfのみのはず");
    XCTAssert([hashTable.allObjects.firstObject isEqual:hashTable.allObjects.lastObject], @"〃");
    
    for (id obj in hashTable.allObjects) {
        XCTAssert([obj isEqual:self], @"hashtableのコンテンツはselfのみのはず");
    }
    for (id obj in hashTable) {
        XCTAssert([obj isEqual:self], @"〃");
    }
}

```

答えは以下。

![スクリーンショット 2014-01-30 15.29.55.png](https://qiita-image-store.s3.amazonaws.com/0/3209/c6f4cf0b-9b33-b477-c6e4-c5c085f4b5fd.png)

(　ﾟдﾟ) ・・・ 
 　 
 (つд⊂)ｺﾞｼｺﾞｼ 
 　 
 (；ﾟдﾟ) ・・・ 
 　 
 (つд⊂)ｺﾞｼｺﾞｼｺﾞｼ 
 　　_, ._ 
 （；ﾟ Дﾟ） …！？

まったく理由は分からないが、hashTable.count と hashTable.allObjects.countの値が違うのだ。ちなみに前者は3,後者は1である。この時点でweakobj1/2は解放済みなので、いわずもがな後者が正しい。ならば実際はまだweakobj1/2が開放されていないのかと疑うと、それも違う。以降のコードでhashTableが保持しているオブジェクトがselfだけだとわかる。ならば呼び出しの順番が悪いのか？と考えて問題の行を最後に回してみる。以下が結果。

![スクリーンショット 2014-01-30 15.34.40.png](https://qiita-image-store.s3.amazonaws.com/0/3209/2238a3c4-2fee-f626-4c29-2839f66d6254.png)

![](http://tiqav.com/18A.jpg)

**~完~**
Docker上でRedmineをすぐに使い始める

Docker上でRedmineをすぐに使い始める
===

はじめに
---
飛ぶ鳥を落とす勢いのDockerですが、まだまだ本番環境には使うのは怖いです。
今のところは開発用のRedmine動かすのに使うくらいがちょうどよさそうです。
あらかじめ配布されているコンテナイメージを使って素早くDocker上のRedmineを使い始めてみます。

構成
---
今回はVagrantでCoreOSを立ち上げて、CoreOS上にRedmineのコンテナを立ち上げる構成とします。

Vagrantのインストール
---
本記事ではVagrantのインストールの詳細は割愛します。
"vagrant インストール" などで検索してみてください。

CoreOSのイメージダウンロード
---
CoreOSはDockerのホストOSとして必要最小限の機能だけを持った軽量なOSです。
githubにCoreOSのVagrantファイルがあるので落としてきます。

```bash:ホストPC
$ git clone https://github.com/coreos/coreos-vagrant/
```

Vagrantのポートフォワーディング設定
---
CoreOSを立ち上げる前にVagrantのポートフォワーディングの設定をしておきます。
今回はCoreOSの80番ポートをホストPCの3000番ポートにマッピングしてます。

```rb:Vagrantfile
config.vm.network :forwarded_port, guest: 80, host: 3000
```

CoreOSの立ち上げ
---
Vagrantを使ってCoreOSの入っているイメージを立ち上げて、SSHでつなぎます。

```bash:ホストPC
$ vagrant up
$ vagrant ssh
```

SSHでCoreOSにつながるはずです。

Redmine入りコンテナイメージの取得
---
[Redmineがすでにセットアップされているコンテナイメージ](https://index.docker.io/u/sameersbn/redmine/)を配布してくださっている方がいますので、ありがたく使います。
docker pullでコンテナイメージを取得します。

```bash:CoreOS
$ docker pull sameersbn/redmine
```

なお、プロキシの設定が必要な場合は下記の感じで環境変数の設定をしてdockerを再起動してからpullしてください。

```bash:CoreOS
$ sudo systemctl set-environment HTTP_PROXY=http://proxy.example.com:8080/ & sudo systemctl stop docker.service & sudo systemctl start docker.service
```

Redmineコンテナの立ち上げ
---
取得したコンテナイメージからコンテナを立ち上げます。

```bash:CoreOS
$ docker run -d -p 80:80 sameersbn/redmine
```

なお、-p 80:80というのはCoreOSとRedmineコンテナとの間のポートフォワーディング設定です。
CoreOSの80番にアクセスすると、Redmineコンテナの80番につながります。

Redmineが正常に起動して、ポートフォワードでつながっているか確認します。

```bash:CoreOS
wget http://localhost/ --no-proxy
```

RedmineのトップページっぽいHTMLが取得できたらOKです。

なお、起動しきる前にアクセスすると500エラーが返ってきます。
少し待ってから確かめてみてください。

ブラウザからアクセスしてみる
---
ホストのPCのブラウザから下記を開いてみてください。

```bash:ホストPC
http://localhost:3000/
```

無事Redmineのログイン画面が表示されたら終了です。

なお、上で2回ポートフォワーディングの設定をしているので、最終的には下記の感じでつながってます。

```
ホストPC:3000 → CoreOS:80 → Redmine:80
```

終わりに
---
ハードウェアをエミュレートするVirtualBoxあたりだと、VMに割り当てたメモリは使ってなくても消費してしまいますが、Dockerなら使っている分のメモリだけ消費します。
なので、より効率的なリソース消費で、何十個も量産的にRedmineを立ち上げられます。

Redmineは開発チームごとにたくさん立てられるのが理想なので、Dockerとの相性がいいと言えるのではないでしょうか。
JavaScriptで月末日を取得する

## 概説
タイトルの通り、JavaScriptで月末日を取得します。

## 今月の末日を取得する

```js:JavaScript
var dt = new Date(); // 「今日」のインスタンスを取得
console.log(dt); // Thu Jan 30 2014 00:00:00 GMT+0900 (東京 (標準時)) 

console.log(new Date(dt.getFullYear(), dt.getMonth() + 1, 0)); // Fri Jan 31 2014 00:00:00 GMT+0900 (東京 (標準時))
```

## 先月の末日を取得する

```js:JavaScript
console.log(new Date(dt.getFullYear(), dt.getMonth(), 0)); // Tue Dec 31 2013 00:00:00 GMT+0900 (東京 (標準時))
```

## 翌月の末日を取得する

```js:JavaScript
console.log(new Date(dt.getFullYear(), dt.getMonth() + 2, 0)); // Fri Feb 28 2014 00:00:00 GMT+0900 (東京 (標準時))
```

## 参考URL
[JavaScriptで月末日を取得する方法](http://knt45.hatenablog.com/entry/20120810/1344608033)
[JavaScriptで指定した年月の月末日を取得する](http://d.hatena.ne.jp/necoyama3/20090823/1251037238)
[JavaScriptで月末日を取得する](http://d.hatena.ne.jp/onering/20080619/1213858973)
IE（開発者ツール）でのコンソールログ


chromeやら、他のブラウザは「console.log」でconsole APIが使える。

で、IEは動かないのでいろんなサイトを見たけど、使えないって情報しかない。

とりあえずIE11では「console.info」でconsole.logと同等の事が出来た。
他のバージョンは不明。

クロスブラウザを前提にするなら、処理を分けねばならない？
オリジナルのラッパーを作るのが良さげ。

chromeはconsole.infoが使えるみたい。
いちいち調べるのがまずめんどくさい...
MacのChromeでLiveReloadのアイコンが分かりづらいので色を変更する

![ss.png](https://qiita-image-store.s3.amazonaws.com/0/8920/1d7f0fb6-e646-b033-6ec5-64f6f71d785f.png)

実際のサイズは小さいので非常に分かりづらいです。

MacのTerminalなどに以下を入力するとフォルダが開きます。

```shell-session
find $HOME'/Library/Application Support/Google/Chrome/Default/Extensions' | grep 'livereload' | xargs -I % dirname % | xargs -I % open '%'
```

以下の画像をダウンロードして名前を元のものと同じに変更し置き換えます。
IconActive.png ![IconActive.png](https://qiita-image-store.s3.amazonaws.com/0/8920/72c6a4cd-8c3d-0e25-67fb-721b58691ca5.png)
IconEnabled.png ![IconEnabled.png](https://qiita-image-store.s3.amazonaws.com/0/8920/c457c4ed-ecc6-b778-f596-ea104b20a381.png)
IconUnavailable.png ![IconUnavailable.png](https://qiita-image-store.s3.amazonaws.com/0/8920/22e6921e-7ccb-cf15-5aa8-20e63e069155.png)

Chromeを再起動すると反映されます。