OmniAICreator/Qiita-1.07M huggingface dataset:
Androidでのアニメーション 基本① 画像を使ってパラパラ漫画風に


#AnimationDrawableを活用

音量のON / OFFを切り替えるボタンを想定。
ONのときには、アニメーションで音が出ていることをアピール。

##完成形
![animation_sample.gif](https://qiita-image-store.s3.amazonaws.com/0/61340/ce34e230-7770-59b9-cf92-24d5a8d8ab8c.gif "animation_sample.gif")


##drawableの設定

```res/drawable/animation_sound.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false"
    android:visible="true">

    <item
        android:drawable="@drawable/sound_on_max"
        android:duration="750" />
    <item
        android:drawable="@drawable/sound_on_min"
        android:duration="500" />
    <item
        android:drawable="@drawable/sound_on_mid"
        android:duration="500" />

</animation-list>
```

###パラメータ

|パラメータ|概要|
|:-:|:-:|
|android:oneshot|trueだと繰り返し無し。falseだとリピート|
|android:visible|初期状態での可視状態|
|android:duration|表示時間(ms)|

###参考画像

|ファイル名|画像|
|:-:|:-:|
|sound_on_max|![sound_on_max.png](https://qiita-image-store.s3.amazonaws.com/0/61340/82c3cb64-32dd-954c-628a-d7fa2e47ba65.png "sound_on_max.png")|
|sound_on_mid|![sound_on_mid.png](https://qiita-image-store.s3.amazonaws.com/0/61340/a994a8dd-d140-a089-efb3-ca436fc06939.png "sound_on_mid.png")|
|sound_on_min|![sound_on_min.png](https://qiita-image-store.s3.amazonaws.com/0/61340/598d3bb1-148c-fa95-c0bb-4f736ab4a130.png "sound_on_min.png")|
|sound_off|![sound_off.png](https://qiita-image-store.s3.amazonaws.com/0/61340/fb485dec-dd2a-891c-b494-8f433fb3aee8.png "sound_off.png")|

##Activityの設定

```MainActivity
public class MainActivity extends AppCompatActivity {

    private ImageView img;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        img = (ImageView) findViewById(R.id.imageView);
        img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (img.getBackground() instanceof AnimationDrawable) {
                    img.setBackground(ContextCompat.getDrawable(MainActivity.this, R.drawable.sound_off));
                } else {
                    img.setBackground(ContextCompat.getDrawable(MainActivity.this, R.drawable.animation_sound));
                    // AnimationDrawableを取得
                    AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
                    // アニメーションの開始
                    frameAnimation.start();
                }
            }
        });
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (img == null) {
            return;
        }
        if (img.getBackground() instanceof AnimationDrawable) {
            // AnimationDrawableを取得
            AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

            // アニメーションの開始
            frameAnimation.start();
        }
    }
}
```

参考までに！
github -> https://github.com/tttakaoka/AnimationDrawableForSound
####参考ページ
http://techbooster.jpn.org/andriod/ui/2192/
https://design.google.com/icons/#ic_volume_up
Raspberry Pi3自動ログイン設定変更&セキュリティ設定等

#やること
##rootのパスワード変更
`sudo passwd root`
確認含め2回入力

##新規ユーザーの追加

##piユーザー削除 or su権限削除

##SSHポート番号変更
`sudo vim /etc/ssh/sshd_config`

```console:/etc/ssh/sshd_config
# What ports, IPs and protocols we listen for
#Port 22
Port 49794 #任意のポート番号に変更
```

#自動ログインユーザ変更
[http://marshland.hatenablog.com/entry/2015/11/14/022345](Raspbian (Jessie)がいつの間にか来ていたので入れた_その1)
[Debian Jessie Wheezy 自動ログイン lightdm系](http://linux-suomi.net/modules/tinyd8/index.php?id=18)

#ファイアウォール（ufw）設定
`sudo apt-get -y install ufw`

デフォルトは拒否
`sudo ufw default deny`
sshポート許可
`sudo ufw limit 49794/tcp`
ntpポート許可
`sudo ufw limit 123/udp`
vpnポート許可
`sudo ufw limit 500/udp`
`sudo ufw limit 4500/udp`
稼働確認
`sudo ufw status`
Status: activeならOK

#参考
[Raspbian Jessieの基本セキュリティ設定を実施する](http://xn--u9j0md1592aqmt715c.net/raspbian-jessie-base-security/)
[RaspberryPiをRaspbianで使う場合の初期設定メモ（ユーザ追加）](http://qiita.com/R-STYLE/items/b481ba2d695ddf8bcee4)

気が向いたら後で編集
CentOS7 の変更点まとめ

# 【CentOS7 の変更点まとめ】
* CentOS7 で追加された変更点を逆引き index 風に記載していく

# ◇ サービス管理
## 1. systemctl (CentOS6:init)

# ◇ ネットワーク管理

## 1. ホスト名の管理 
* /etc/hostname の設定ファイルで変更行う
* CentOS6 の /etc/sysconfig/network では hostname ディレクティブを使用していたが、ファイルへ直接ホスト名を記載する方式へ変更されている。

```bash
vim /etc/hostname
hostname.domain.org
```

* hostnamectl コマンドで設定確認が可能

```bash
hostnamectl
   Static hostname: hostname.domain.org
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 949b0417370445449cd0bf3cac8f1164
           Boot ID: d05c1163f215400aa683f625ba50ceea
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-327.13.1.el7.x86_64
      Architecture: x86-64
```

## 2. ip (CentOS6:ifconfig)

## 3. ss (CentOS6:netstat)

## 4. nmcli (CentOS6:ifup/ifdown)

## 5. firewalld (CentOS6:iptables)
* CentOS6 の iptables が firewalld へ置き換えられている。

# ◇ クラスタ管理
## 1. Cluster (CentOS6:Corosync+Pacemaker+CMAN)
* CentOS6.5 以降 CMAN を追加した構成が推奨だった。  
  CentOS7 からは CMAN の機能が Corosync に FIX された為、Corosync + Pacemaker で動作する。
Let's Encryptで無料のSSL証明書を手に入れる

webサーバーのhttps化が完了したので、備忘録としてまとめます。
### 参考にさせていただいたページ
* [Let's Encrypt 総合ポータル](https://letsencrypt.jp/usage/)

* [Qiita.com -- 光の速さのWEBサーバー(nginx)をlet's encryptでSSL化及びHTTP/2化。ついでにセキュリティ評価をA＋にする。](http://qiita.com/sak_2/items/ff835b669c0a7e110b09)

上記を参考させていただきました。
### Let's Encryptとは

誰でも無料で使えるSSL/TLS証明書発行サービスです。
証明書の発行 / 更新をコマンドライン上から行うことができます。

注意事項としては、証明書の期限が取得してから**90日間**と、短期間になっていますので、期限が切れる前に更新を行う必要があります。
ただし、コマンドライン上から更新を行うことが可能ですので、cronを設定しておけば良いわけです。

### 作業環境

OS: CentOS 6.7
サーバー: さくらVPS

### STEP1: ポートを解放する

SSL証明書取得のためには80番と443番のポートを解放しておく必要があります。

* もしWebサーバー等が立ち上がっていて、ポートを占有している状況であれば、一旦停止します。
* `iptables`を確認し、ポートが解放されているか確認します。

* `vi /etc/sysconfig/iptables`
にて、iptablesの設定を確認し、80番と443番に関する記述がなければ、以下の通り、記述を追記します。

```
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
```
* 設定を読み込ませるため、`iptables`を再起動します。
`sudo /etc/init.d/iptables restart`

### STEP2: Let's Encryptクライアントのダウンロード、証明書の取得

* クライアントをダウンロードし、インストールします。

```
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt/
sudo ./letsencrypt-auto --help
```

* 証明書取得のため、以下のコマンドを実行します

`./letsencrypt-auto certonly -a standalone -d xxx.com(取得したい証明書のドメイン名)`

* 青い画面が立ち上がるので、メールアドレスを記述し、利用規約を確認し、'AGREE'を選択

* 正常に取得が完了すれば、以下の通り表示される

```
Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/xxx.com/fullchain.pem. Your cert will
   expire on 20xx-xx-xx. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.
```

以下のディレクトリに証明書の実体が作成されます。
`/etc/letsencrypt/archive/ドメイン名/`

以下のディレクトリに証明書のシンボリックリンクが作成されます。
`/etc/letsencrypt/live/ドメイン名/`

証明書の更新を行う際に、実体の方のファイル名が変更される可能性があるので、**サーバーに読み込ませる場合は、シンボリックリンクのパスを指定します。**
更新を行った際に、自動的に最新のファイルにリンク先が更新されるようです。


作成されるファイルの内容は以下の通りです。

* cert.pem: サーバ証明書
* chain.pem: 中間証明書
* fullchain.pem: サーバ証明書と中間証明書が結合されたファイル
* privkey.pem: 秘密鍵

### STEP3: 確かめる

ここでは、node.jsでサーバーを立てて確かめてみます。
以下のファイルを作成します。

```js:test.js
var https = require('https');
var fs = require('fs');
var ssl_server_key = '/etc/letsencrypt/live/xxx.com/privkey.pem';
var ssl_server_crt = '/etc/letsencrypt/live/xxx.com/cert.pem';
var port = 443;

var options = {
        key: fs.readFileSync(ssl_server_key),
        cert: fs.readFileSync(ssl_server_crt)
};

https.createServer(options, function (req,res) {
        res.writeHead(200, {
                'Content-Type': 'text/plain'
        });
        res.end("Hello, world\n");
}).listen(port);

```

* nodeサーバーを立ち上げます。
`sudo node test.js`

* httpsで対象のドメインにアクセスし、問題なく接続でき、ブラウザから警告がでなければ成功です。

念のためブラウザから証明書を確認してみます。成功すれば以下の通り表示されると思います。

<img width="935" alt="スクリーンショット_2016-05-04_12_53_30.png" src="https://qiita-image-store.s3.amazonaws.com/0/82381/de28e0f7-375b-05e2-91ba-154c10756ed5.png">


### STEP4: 証明書を定期的に更新するようにする

* 90日間で有効期限が切れてしまうので、cronで毎月1日に自動更新するようにセットします。

`crontab -e
`
* 以下の記述を追加し、保存します。

```
00 00 01 * * cd /クライアントのパス/letsencrypt;./letsencrypt-auto certonly -a standalone -d xxx.com --renew-by-default
```

これで、証明書の期限切れが防げます。

何かおかしな箇所がありましたら、コメントにてご指摘いただければ幸いです...
bundle install で毎回 --path=vendor/bundle するのが面倒なのをどうにかする

```bundle install ```するときにglobalなgemを汚したくないので、```bundle install --path=vendor/bundle```ってpathを指定すると思うのですが、一度設定すると2回目以降はpathの指定が要らないこともあって、新しいプロジェクトを始めるときについつい忘れがちです。

そんな場合は、

```
bundle config path vendor/bundle
```

ってしておくと、pathの指定をユーザ定義として ~/.bundle/config に覚えてくれるので便利です。

これでいつでも

```
bundle
```

するだけでよくなりました。

余談）
どうでもいいけど、最近作ったプロジェクト全部「vender」にtypoしてたよ恥ずかしい。
OSXのopenコマンドでよく使うオプション

macではコマンドラインからopenコマンドを使うことで様々なアプリケーションが開けます。
また、openコマンドは、ファイル、ディレクトリ、URLも開くことが可能です。

## 現在のディレクトリをFinderで開く

```
$ open .
```

## [-a] 特定のアプリケーションを開く。
`/Applications`以下にあるアプリはパスを書かずに実行可能。
また空白文字が入るアプリケーションはコーテーションで囲う必要がある。

```sh
$ open -a firfox
```

## [-n] すでに起動していても新しいインスタンスで起動する

```sh
$ open -a macvim -n
```

## [--args] 引数を渡す
Chromeをシークレットモードで起動

```sh
$ open -a "Google Chrome" -n --args --incognito
```
備忘録 - ビットの取り扱い

モーションコントロール系のソフトを作っている中で、ビット演算が多く、自習と備忘録。
間違いや、より良い手法がありましたらご指摘ください。

[2016/05/08: int → unsigned intへ変更しました]

#Cでのビット演算子
##AND
```c:
a = a&b;
a &= b;
```
| a | b | new a |
|:-:|:-:|:-----:|
| 0 | 0 |   0   |
| 1 | 0 |   0   |
| 0 | 1 |   0   |
| 1 | 1 |   1   |

ANDは両方が真である場合のみ、真を返し、それ以外は偽を返す。つまり、ビットが1&1の時のみ、1になる。ステータスワードなんかのビットを落とすときに使える。

##OR
```c:
a = a|b;
a |= b;
```
| a | b | new a |
|:-:|:-:|:-----:|
| 0 | 0 |   0   |
| 1 | 0 |   1   |
| 0 | 1 |   1   |
| 1 | 1 |   1   |

ORはどちらかが真であれば真を返し、両方が偽である場合のみ偽を返す。つまり、ビットのどちらかが1であれば、1を返す。ビットを立てるときに使える。

##XOR
```c:
a = a^b;
a ^= b;
```
| a | b | new a |
|:-:|:-:|:-----:|
| 0 | 0 |   0   |
| 1 | 0 |   1   |
| 0 | 1 |   1   |
| 1 | 1 |   0   |

XORは、片方が真、もう片方が偽である場合のみ真を返す。つまり、片方が1でもう片方が0である場合に、1を返す。ビットを反転させるのに使える。

##NOT
```c:
a = ~a;
```
| a | new a |
|:-:|:-----:|
| 0 |   1   |
| 1 |   0   |

NOTは真であれば偽を返し、偽であれば真を返す。つまり1なら0、0なら1を返す。ワードの各ビットへアクセスするというところでいくと、あんまり使いみちが思い浮かばない。。。重要なのは、論理演算子は(NOTに限らず)、全ビットが対象になるというところがミソ。

##ビットシフト
```c:
a<<b;    //左シフト
a>>b;    //右シフト
```
基本は操作対象変数aのビットをbだけそれぞれの方向にずらす操作。1ビットシフトの動きは次の通り。
左シフト：最上位ビットを捨て、残りのビットはひとつ上のビットへ移動。最下位ビットには0。
右シフト：最下位ビットを捨て、残りのビットはひとつ下のビットへ移動。最上位ビットには0(~~負数の場合は1が入るとか入らないとか。。。~~)。
(2016/05/08: 符号付きの場合の結果は不定とのご指摘をいただきました。ありがとうございました)

#よく使うビット演算
##特定ビットの取り出し
```c:
unsigned int GetBit(unsigned int word, unsigned int bitNum)
{
    //ターゲットのビットを最下位ビットまで持ってくる
    word >>= bitNum;
    //0x01とANDしてやる。最下位ビット以外はすべて0になり、最下位ビットはそのまま
    word &= 0x01;
    return word;

    //シンプルに書くならまとめて。#defineでもいいかもしれない。
    // return ( (word >> bitNum) & 0x01);

}

```
特定のステータスビットをチェックするのに使う。

##特定ビットON
```c:
unsigned int BitON(unsigned int word, unsigned int bitNum)
{
    unsigned int mask = 0x01;
    //対象ビット位置まで左シフト
    mask <<= bitNum;
    // maskとOR
    word |= mask;

    return word;

    // simpler...
    // return ( word |= ( 0x01 << bitNum ) );

}

```

##特定ビットOFF
```c:
unsigned int BitOFF(unsigned int word, unsigned int bitNum)
{
    unsigned int mask = 0x01;
    //対象ビット位置まで左シフト
    mask <<= bitNum;
    //mask bit反転
    mask = ~mask;
    // maskとAND
    word &= mask;

    return word;

    // simpler...
    // return ( word &= ~( 0x01 << bitNum ) );

}

```

##特定ビットの反転
```c:
unsigned int ChangeBit(unsigned int word, unsigned int bitNum)
{
    unsigned int mask = 0x01;
    //対象ビット位置まで左シフト
    mask <<= bitNum;
    // maskとXOR
    word ^= mask;

    return word;

    // simpler...
    // return ( word ^= ( 0x01 << bitNum ) );


}

```
フラグ代わりに使っているビットのON/OFFに使ったりする。

##ビットの連動
```c:
unsigned int InterlockBit(unsigned int inputState, unsigned int outputState, unsigned int inputBit, unsigned int outputBit)
{
    // ビットの取り出し
    unsigned int input = inputState & (0x01 << inputBit);
    unsigned int output = outputState & (0x01 << outputBit);

    // 状態比較して状態が異なればビット反転
    // inputとoutputのXORで状態が異なれば0x01のマスクができる
    // --> if (input != output){ outputState ^= (0x01 << outputBit) } と同じ処理になる
    outputState ^= ( (input ^ output) << outputBit );

    return outputState;
}

```
あるビットが変化したらそれに応じて別のビット列のビットを連動して変化させる。I/Oを管理しているような場合に入力が変化した場合に出力を連動させるときに使う。
Vimのコマンドで関数の結果をクリップボードにコピーしたり

よく使う小ネタ。
なんとなく公開しておきたくなったので雑にメモ。
一度実行してコマンドの履歴に入れておくと捗るのではないかと。

例えば、一番ありそうな応用方法として、次のように実行すれば今開いているファイルの名前をクリップボードにコピーできる。

```vim
let @+ = expand('%')
```

フルパスが欲しい場合はこう :point_down:

```vim
let @+ = expand('%:p')
```

おまけ: Windowsな方は`substitute`してバックスラッシュをスラッシュに変換しておくと\*nixな方に送るとき捗る。

```vim
let @+ = substitute(expand('%'), '\\', "/", "g")
```

（何もつけない`p`コマンドで貼り付けできる）無名のレジスタにコピーしたい場合は :point_down:

```vim
let @" = expand('%')
```

# 簡単な解説

Vim script（この場合コロン `:` で実行する奴と言い換えても構いません）では
`let`というコマンドで変数を宣言したり変数の値を書き換えたりできます。
実はこの`let`, Vimでコピペする時に使う、レジスターという領域を書き換えることもできるのです。

先ほどのように、名前が「`@` + 1文字」の変数を使うことで、`let`コマンドをはじめ、
Vim scriptからそのレジスターを読んだり書いたりできるようになっています。
例えばそのうち`@+`はクリップボードを表すレジスター（を読み書きする変数）です。
なので `let @+ = ...` でクリップボードを読み書きできます。

# あわせて読みたい

- :information_desk_person: 詳しくは `:help registers` とか `:help expand()` とかを御覧ください。
- [Set options or named registers with let - Vim Tips Wiki - Wikia](http://vim.wikia.com/wiki/Set_options_or_named_registers_with_let)
超単純なガチャロジックの一例


実際にゲームで使われているものではありません。
実際はRailsならRarityやCardはActiveRecord等使ってマスタ化されているかと。

```gacha.rb
require 'csv'

module Gacha
  class Main
    def self.execute
      first_deck = RarityDeck.new('rarity.csv')
      second_deck = CardDeck.new('card.csv', first_deck.lot.id)
      return second_deck.lot
    end
  end

  class RarityDeck
    def initialize(file_name)
      @file_name = file_name
    end
  
    def data
      base = CSV.read(@file_name)
      data = base.map{|b| Rarity.new(*b)}
      return data
    end
  
    def lot
      data = self.data.sort{|a, b| a.wait <=> b.wait}
      sum = self.data.inject(0.0){|s, d| s += d.wait}
      r = rand(0 ... sum)
      res = self.data.inject(0) do |s, d|
        s += d.wait
        if s > r
          break d
        end
        s
      end
      return res
    end
  end

  class Rarity
    attr_reader :id, :name, :wait
    def initialize(id, name, wait)
      @id = id.to_i
      @name = name
      @wait = wait.to_i
    end
  end

  class CardDeck
    def initialize(file_name, rarity_id)
      @file_name = file_name
      @rarity_id = rarity_id
    end

    def data
      base = CSV.read(@file_name)
      data = base.map{|b| Card.new(*b)}
      data = data.select{|d| d.rarity_id == @rarity_id}
      return data
    end

    def lot
      return data.sample
    end
  end

  class Card
    attr_reader :id, :rarity_id, :name
    def initialize(id, rarity_id, name)
      @id = id.to_i
      @rarity_id = rarity_id.to_i
      @name = name
    end
  end
end

```

実行にはrarity.csvとcard.csvが必要です。
csvと一緒に[githubに上げておきました](https://github.com/aono-sinya/simple_gacha_sample)。

見ていただいてわかるかと思いますが、これは単なる重みを付けた乱択なので、出現カードは激しく偏ります。
ただ、乱数生成ロジックを自社製することはあまりないと思うので、もしきれいにばらけるガチャがあったらそれこそ確率操作の疑いが……。
Raspberry Pi3にVPNサーバーとVNCサーバー立ててiPhoneから艦これするまでメモ（その2）

#流れ
OSインストール
↓
初期設定
↓
VPNサーバー立てる　←（その1）
↓
Chromiumインストール
↓
VNCサーバー立てる
↓
iPhoneから艦これ！　←この記事ではここまでやる

##Chromium DE 艦これ
[raspberry Pi3 でFlash](http://gantech3.hatenablog.com/entry/2016/04/20/004457)の通りやってく。

###Chromiumインストール
`wget -qO - http://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo apt-key add -`
`echo "deb http://dl.bintray.com/kusti8/chromium-rpi jessie main" | sudo tee -a /etc/apt/sources.list`
`sudo apt-get update`
`sudo apt-get install chromium-browser`

###pepper flashインストール

`wget http://os.archlinuxarm.org/armv7h/alarm/chromium-pepper-flash-12.0.0.77-1-armv7h.pkg.tar.xz`
`tar Jxf PepperFlash-12.0.0.77-armv7h.tar.xz`
`cd /usr/PepperFlash`
`chmod +x *`
`sudo cp * /usr/lib/chromium-browser/plugins`
`sudo vim /etc/chromium-browser/default`

```console:/etc/chromium-browser/default
#末尾に追記

#CHROMIUM_FLAGS=""
CHROMIUM_FLAGS="--ppapi-flash-path=/usr/lib/chromium-browser/plugins/libpepflashplayer.so --ppapi-flash-version=12.0.0.77 -password-store=detect -user-data-dir"
```

Chromiumを起動し、アドレスバーに
`Chrome://Plugins`
と入力。

Adobe Flash Player
- [x] 常に実行を許可する
チェックを入れる。

###艦これ起動確認
Chromiumを立ち上げて艦これをやってみるテスト。

##vncサーバーインストール
[Raspberry Pi 3でRaspbian Jessieをセットアップする方法](http://karaage.hatenadiary.jp/entry/2016/04/03/080000)の下の方のtightvncサーバ項参照。

ターミナルを起動して

`sudo apt-get update`
`sudo apt-get install tightvncserver`

`vncserver`
パスワード設定（6-8文字）
read-onlyのパスワードは入力せずEnter。

tightvncserverを起動する。
`vncserver :1`

自動起動スクリプト作成。
[参考：Raspberry Piの設定【VNCサーバ（tightVNC）の設定】](http://yamaryu0508.hatenablog.com/entry/2014/08/16/202441)
`sudo vim /etc/init.d/vncboot`

```console:/etc/init.d/vncboot
#! /bin/sh
# /etc/init.d/vncboot

### BEGIN INIT INFO
# Provides: vncboot
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start VNC Server at boot time
# Description: Start VNC Server at boot time.
### END INIT INFO

USER=pi
HOME=/home/pi

export USER HOME

case "$1" in
 start)
 echo "Starting VNC Server"
 #Insert your favoured settings for a VNC session
 su $USER -c '/usr/bin/vncserver :1 -geometry 1280x800 -depth 24' #クライアントに合わせた解像度に
 ;;

 stop)
 echo "Stopping VNC Server"
 su $USER -c '/usr/bin/vncserver -kill :1'
 ;;

 *)
 echo "Usage: /etc/init.d/vncboot {start|stop}"
 exit 1
 ;;
esac

exit 0
```

実行権限を変更し、自動起動登録し、再起動。
`sudo chmod 755 /etc/init.d/vncboot`
`sudo chkconfig --add vncboot`
`sudo chkconfig vncboot on`
`reboot`

###ルータ側でIP固定、ポート開放等
VNC接続のためにTCP/5901を開放。

###iPhoneにVNCクライアント入れて確認
自分はVNC Viewer使ってます。
やり方は割愛。

これで出先でもiPhoneから艦これができるはず！
（Android版来たら必要ないなんて言わないで）
[環境構築] Node.js on Ubuntu 16.04

Ubuntu 16.04が出たのでNode.js環境の構築手順をまとめます。
本記事はNode.jsのInstallation Guideに則っています。

### Step1

Node.js 6 をインストールします。

```
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs
```

### Step2

ビルドツールもインストールします。(npmからネイティブアドオンをコンパイルまたはインストールするため)

```
$ sudo apt-get install -y build-essential
```

以上。

[参考]
https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
ePubファイルをKindleで読む方法、かつKindle for PCで読む方法いまさらｗ

# いまさら Fireタブレットｗ
楽天のkoboとか買ってみたけど結局使ってなかった電子書籍、、AmazonでFireタブレットが安かったのでまた電子書籍なんか通勤途中に読んでみようかと買ってみた。そして[青空文庫](http://aozora.wook.jp/)図書でも読んでみようかと思ってePub形式のファイルをKindleで読むまでの手順。そしてまた自分めもｗ

# ePub形式のファイルをKindleで読み込める
[EPUBフォーマット](http://www.epubcafe.jp/home/aboutepub) International Digital Publishing Forum (IDPF) の意味だったんですね。しかもEPUBが正しいのか！！　で、[EPUBを読むには](http://qiita.com/nori_j/items/bd2616c606f95e00746f)さんの記事とおり、Kindle for PC をインストールしドラック＆ドロップで・・・mobi ・・・できない。つー、

# Kindle Previewerで mobi ファイル
まず[Kindle Previewer](http://www.amazon.co.jp/gp/feature.html?docId=3077677546)をダウンロード、インスコ。起動。。。。して、ドラック＆ドロップするだけｗ

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/f6e4d60b-d58e-c92f-e228-28c2c0eb1d45.png)

OKボタンを押下すると・・・

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/ee446714-bcd9-412e-ce45-9082ee5cfbe4.png)

ほうほう。読めるのですなｗ

# Kindleに転送
KindleタブレットをPCに接続してKindleの「documentsフォルダ」に.mobiファイルを入れればOK。簡単じゃｗ。

# Kindle for PC で読みたい
作成した .mobi ファイル、あれ？Kindle for PC にドラック＆ドロップしても読めない…。と思ったら方法みつけた。

Kindle for PCの「ツール」-「オプション」を選択。「コンテンツ」を選択し。コンテンツディレクトリを確認、このフォルダーに .mobi をコピーします。

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/b7a8d08c-d3d6-9038-b7a3-d2f7e265cb1b.png)

コピー終わったら。Kindle for PC を終了＆起動すると！！！
キター（漫画ばかりだ、俺w）

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/e7d9bad0-3f72-2940-896e-e758501a6854.png)

この方法だと他の端末と同期できないので面倒だけどとりあえず。読めるようになって満足！

# 参考
> [青空文庫](http://aozora.wook.jp/)
> [Adobe Digital Editions](http://www.adobe.com/jp/solutions/ebook/digital-editions/download.html)
> [電子書籍制作で揃えたいソフト一覧](http://epub.tmediacom.com/archives/103)
Python3で漢字の判定

Python3で文章に記号があるかどうかを判定したかったが、ブラックリストにすると思ったより大変そうだったので

- 数字
- アルファベット
- 平仮名
- 片仮名
- 漢字

のいずれかのみが続く文字かどうかを判定しようとした。

# はまりどころ

Unicode文字列で範囲指定することにした。（←そもそもの間違い）

Python2では、漢字は下記のようにすれば（ほぼ）判定できる。

```python
# Python2

import re
str = 'これは漢字を含みます'
re.search('[\xE4B880-\xE98CAC]', str)
```

Python3では正規表現中の文法が違う。

- `\x`ではなく`\u`で指定する
- UTF-8ではなくUTF-16で指定する

これを踏まえると

```python
# Python3

import re
str = 'これは漢字を含みます'
re.search('[\u4E00-\u9FD0]', str)
```

となる。Python2と同様に書こうとして

`SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-7: truncated \xXXXXXXXX escape`

というエラーが出てはまった。

# 最後に気づいた

これでよくね？

`re.search('[0-9a-zA-Zあ-んア-ン一-鿐]', str)`

# 参考

- http://ash.jp/code/unitbl21.htm
- http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/cjku_klist.html
truecryptで暗号化されたntfsのvolumeファイルをandroidにmountする


※root化必須です。

cryptoniteというtoolを使用します。
Android Terminal Emulatorも必要となります。
また今回はsudoでコマンドを打つので
sudo  for Androidも入れておきます。
cryptoniteをインストールすると
/data/data/csh.cryptonite/truecrypt
にtruecryptのバイナリがインストールされるのでこちらを使います。

次にAndroid Terminal Emulatorを立ち上げ以下のコマンドを入力します。
```shell-session
sudo truecrypt --filesystem=none --protect-hidden=no --keyfile= --fs-options="uid=1000,gid=1000,umask=0002" /sdcard/xxx.tc 
```
パスワード入力を求められるので入力します。
keyfileやpathは適宜置き換えてください。

これで/dev/block/loop*にmountされるはずなので
その後以下のコマンドでntfsでmountをします。
```shell-session
sudo mount_nfsd_fuse /dev/block/loop0 /storage/usbdisk3
```
これでmountできるはずです。

※以下トラブル情報
- Error: Failed to create a file or directory in a temporary directory.
Please make sure that the temporary directory exists, its security permissions allow you to access it, and there is sufficient disk space:
とのエラーがでる場合
起動するにはテンポラリフォルダの設定が必要なので
以下のフォルダを作成します。
```shell-session
mkdir -p /sdcard/Android/data/csh.cryptonite/
```
suになるとあったりなかったりとかあるので注意

- Error: Cannot convert from the charset 'encoding -1'!
との警告がでる。
今のとこ処理は継続できて問題ないようなので無視しています。
すこし気持ち悪いですが…
node6にてnpm publishに失敗する

**注意**
~~問題の切り分けができていません。~~あくまで、現時点での一時的処置です。

## 問題
node6に移行後、自作モジュールをnpmにpublishしたところpackage.jsonのfilesの内容が解釈されずにindex.jsがpublishされませんでした。

```json:package.json
// ...
  "files": [
    "index.js"
  ],
// ...
```

ディレクトリ構成は以下のような感じです。

```
.
├── index.js
├── license
├── node_modules
├── package.json
├── readme.md
└── test.js
```

## 対策

nodeのバージョンを5系に戻したら正しくpublishされました。
~~しかし、v6.0.0でもpublishがうまくいく時があり、どこに問題があるのかはっきりしていません。~~

~~原因がわかりしだい追記しますが、~~現時点ではv5.11.0あたりを使うのが無難そうです。


2016/05/04 11:58追記
コメントで教えてもらいましたが、他パッケージでも起きているnpmのバグのようです。修正されるのを待つかv5系でpublishするのがやはり無難だと思います。


## 参考
[npm publish missing index.js · Issue #5082 · npm/npm](https://github.com/npm/npm/issues/5082#issuecomment-215259699)
MacにPyenvを使ってAnacondaを入れる

## 手順
* pyenvをインストール
* anacondaをインストール

## 参照
本家を読みましょう。

[yyuu/pyenv@Github](https://github.com/yyuu/pyenv)

## pyenvをインストール

pyenvをインストール

```sh
brew install pyenv
```

.zshrcに追記

```sh
export PATH="$HOME/.pyenv/bin:$PATH"
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
```

## pythonをインストール

インストール対象を検索

```sh
pyenv install --list
```

インストール

```sh
pyenv install anaconda3-2.5.0
```

インストールされたことを確認

```sh
pyenv versions
```

globalに設定

```sh
pyenv global anaconda3-2.5.0
```

pythonのバージョンの確認

```sh
python --version
```
arukas.ioでNode-REDを動かす

[Arukas](https://arukas.io/)でNode-REDを動かす方法。

簡単なので記事を書くまでもないのですが、CMDのところを設定しないと動かないのにハマりました。logsコマンドでデバッグしようと思ったのですが、Arukas CLIにはlogsコマンドが無いんですね。

Imageはこちらを利用します。
https://hub.docker.com/r/cpswan/node-red/

Arukasのアプリ追加ウィザードで、Images, Port, CMDを画像のように設定します。App Nameはわかりやすいものを、EndpointはURLになるので、ユニークなものを設定します。
![スクリーンショット 2016-05-04 10.28.34.png](https://qiita-image-store.s3.amazonaws.com/0/20848/196b8ea6-9803-c8de-7ea5-742d87ea9fa3.png)

Images: cpswan/node-red
Port: 1880 tcp
CMD: /usr/local/bin/node-red

デプロイ中になり、１分足らずで起動します。
これだとflowを保存した後に、インスタンスを停止するとデータが消えてしまうので、次回外部DBに保存する方法を書きます。
Ubuntu 16.04 LTSにしたらeth0がなくなっていた件について

南波水測長「ありがてぇ。これで思い切りサーバ操作ができる」

ということで連休中にUbuntu12.04LTSのサーバを何台かアップグレードしようと思いました。
せっかく4月にUbuntu16.04LTSが出たので、systemdがなーとは思いましたが、サポートは長い方がうれしいので強行することに。

インストールしてファイアウォールの設定を始めようとしたらなんか変なんです。
/etc/interfacesは直してあるんですが、ifconfigするとおなじみのeth0やeth1がなくなってて、ens33とかenp3s1なんかになってる。

何これ、とぐぐりましたら、以下がヒット。15.10から命名規約が変わってたらしいです。
[Network interface name changes after update to 15.10 - udev changes](http://askubuntu.com/questions/689070/network-interface-name-changes-after-update-to-15-10-udev-changes)

Xenialのベータも長いこと使ってましたが、そっちはiptablesなんてほとんどいじってなかったので、全然気がついてなかったのでした。

旧サーバからスクリプトは引き継ぎたいので、上記記事に従ってデバイス名をeth0に戻す方向で変更します。
>$ nano /etc/udev/rules.d/10-network.rules    
>Add following line
>SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="aa:bb:cc:dd:ee:ff", NAME="net1"

ifconfigでMACアドレス調べて、空ファイルだった/etc/udev/rules.d/10-network.rulesにeth0からeth2まで書き足します(なぜかたくさんあるのですｗ)。

はい、再起動してこれでeth0に戻りました。
めでたしめでたし。

のはずなのですが、ifを3つ設定しようとするとなぜかeth2しか出てこない。なんですかこれ。バグなの？書式は死ぬほど確認したよ。でも何度再起動してもだめ。

[ネットワーク設定](https://wiki.archlinuxjp.org/index.php/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E8%A8%AD%E5%AE%9A)
の

>伝統的なデバイス名に戻す
eth0 などの伝統的なインターフェイス名に戻したい場合、次のコマンドで Predictable Network Interface Names を無効にできます:
#### ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules

をやってもだめ。

とうとうあきらめてスクリプトの方を直すことにしました。
まあ置換すればいいだけだけどね。

後日詳しく確認します。
/phpmyadminのBASIC認証対策してても,管理画面だしたくない。URL変えようぜ！

#よくあるサンプルが・・

```
server {
       server_name  ***;

        location /phpmyadmin {
                root /usr/share/phpMyAdmin;
                index index.php;
                }

             location ~ ^/phpmyadmin.+\.php$ {
                    ###### 中略 ######
         　　　　　  ・
           　　　　　・
           　　　　　・
　　　　　　　　　    ###### 中略 ######
  
                  }
        }#phpmyadmin
}#server
```

これに↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
BASIC認証つけますよと・・

```
location /phpmyadmin {
       #BASIC
       auth_basic "Restricted";
       auth_basic_user_file /etc/nginx/.htpasswd;
       # root /usr/share;
        root /var/www;
        index index.php;

       location ~ ^/phpmyadmin.+\.php$ {
             # fastcgi_pass unix:/var/run/php5-fpm.sock;
             fastcgi_pass   127.0.0.1:9000;
             fastcgi_index index.php;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             include fastcgi_params;
        }
     }#phpAdmin

```

大抵の人がこれの場合でログインできなくても管理画面（ログイン画面）が出てしまいます汗
これにIP制限とかもできますが・・
外からもアクセスしたい人や、IPが固定じゃない苦学生,制限できない事情がある方はURLを変えて隠そうぜ笑
IP制限してる人もURL変更しちゃおう


```
＃現在のphpmyadminのシンボルクリックへ移動して

cd /usr/share/nginx/html
ls -l
total 8
-rw-r--r-- 1 root root 537 Mar  4 06:46 50x.html
-rw-r--r-- 1 root root 612 Mar  4 06:46 index.html
lrwxrwxrwx 1 root root  21 Aug  6 10:50 phpmyadmin -> /usr/share/phpmyadmin

＃シンボルクリック名変更
sudo mv phpmyadmin hoge
```

```
# location/phpmyadmin {
location /hoge{
        #BASIC
        auth_basic "Restricted";
       auth_basic_user_file /etc/nginx/.htpasswd;
       # root /usr/share;
        root /var/www;
        index index.php;

       # location ~ ^/phpmyadmin.+\.php$ {
        location ~ ^/hoge.+\.php$ {
             # fastcgi_pass unix:/var/run/php5-fpm.sock;
             fastcgi_pass   127.0.0.1:9000;
             fastcgi_index index.php;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             include fastcgi_params;
        }
     }#phpAdmin

```

```
設定ファイル再読み込み
sudo service nginx reload
```

http://server_name/phpmyadmin/
ではエラーが出て
こうすれば自分が設定したserver_nameとhogeの部分でアクセスができるようになる！　　http://server_name/hoge/

できない人はシンボルクリックの権限、所有者とか変えてみてください。

```
#確認
ls -l
#変更
sudo chown ユーザ名 hoge

```

以上　未熟な大学生より。

>参考文献
Nginx と安全な phpMyAdmin ：https://websetnet.com/ja/install-and-secure-phpmyadmin-with-nginx-on-an-ubuntu-14-04/
BASIC認証：http://aratatool.com/app2/knowledge/knowledge/5
基本的なコマンドとCentOSの基本的なこと

# コマンド一覧
## ディレクトリ移動
`$ cd <dir`>
## 空のファイル作成
`$ touch <file>`
## ディレクトリ作成
`$ mkdir <dir>`
## ファイルコピー
`$ cp  <src_file> <dst_file>`
`$ cp -p <src_file> <dst_file>`
## ディレクトリコピー
`$ cp -r <src_dir> <dst_dir>`
## ファイル・ディレクトリ移動
`$ mv <src> <dst>`
## ファイルの削除
`$ rm <file>`
## 特定のディレクトリ配下全て削除
`$ rm -r <dir>`
## コマンドヘルプ
`$ man <command>`
`$ <command> -h`
`$ <command> --help`
## ファイル一覧
`$ ls -al`
`$ ll`
## ファイルの中身を見る
`$ less <file>`
`$ more <file>`
`$ cat <file>`
`$ vim <file>`
## 特定の文字列を検索したい
`$ grep <search_str> <file>`

# パイプ機能
あるコマンドの出力を別のコマンドの入力として渡すことができる

## httpd.confファイルの中から、「ServerName」という文字列がある行だけ出力したい
`$ cat /etc/httpd/conf/httpd.conf | grep ServerName`

## アクセスログから特定の日時だけを出力したい
`$ cat /var/log/httpd/access_log | grep <search_date`

# ユーザ切り替え
## 一般ユーザへの切り替え
`$ su - <user_name>`
## rootユーザへの切り替え
`$ su - `

# シェル変数と環境変数
## シェル変数
現在実行中のシェルにのみ有効な変数
`$ HOGE=hogehoge`

## 環境変数
シェルから実行したコマンド(子プロセス)にも引き継がれる変数
`$ HOGE=hogehoge`
`$ export HOGE`

# パッケージ(ソフト)のインストール
## パッケージについて
* パッケージはRPMというパッケージ管理システムで管理され、rpmコマンドで操作可能
* パッケージには依存関係が存在する
* 依存関係を把握して各パッケージを管理するのは大変
* そこら辺を自動で管理してくれたりするのがYumというパッケージ管理システム。yumコマンドで操作可能
* Yumは内部でRPMを使用している
* 基本的にはYumを使って各種パッケージをインストールする
* Yumでインストール出来ない場合はRPMで試してみる

## インストールされているパッケージ一覧
`# rpm -qa`
## rpmを使用したインストール方法
`# rpm -i <file>` ※事前にrpmファイルのダウンロードが必要
`# rpm -i <url>`
## yumを使用したインストール方法
`# yum install <package_name>`

# パッケージ管理システムを使用しないインストール方法
## 方法
インストールしたいパッケージのソースコードをダウンロードして、コンパイルする。

やり方は省きます。パッケージ管理システムによるインストールに比べ遥かに難しいし
インストールしたいパッケージによって細かいところで手順が異なる(大筋は一緒)
難しいけどインフラエンジニアはできて当たり前。

## どんなときに使うか
* リポジトリにないパッケージをインストールしたい
* 最新バージョンをインストールしたい
例外のハッシュをログに記録すると便利？というアイデア

多くの環境では例外が起きるとスタックトレースがログに記録される。メソッドの呼び出し階層が深くなるとスタックトレースも長くなり、数十行になることも珍しくない。

例外がログに記録される状況があったときに、その頻度を時系列に沿って追い駆けたい、ということがある。そのような場合、例外メッセージやスタックトレースの特徴的な文字列を元に検索するのが普通ではないだろうか。しかしその特徴的な文字列が本当にその例外からのみ起こるのか、確信が持てないことがある。もしかしたら、その文字列が別の箇所でロギングされているかもしれない。

スタックトレースのハッシュを生成してログに記録するようにすれば、例外の発生を一意に特定して、文字列が別の場所で起きていることを心配せずに検索できるのではないだろうか。

例外メッセージは具体的な値によって異なる文字列になることがありそう(たとえば `Unexpected mail address: abc` というメッセージで `abc` 部分が変わる場合など)なので、ハッシュする対象に加えないほうが良さそう。

https://github.com/tkawachi/exhash で Java の実装をしてみた。
これではスタックトレースのクラス名とメソッド名だけをハッシュする対象にしている。
行数を対象にしないことで、呼び出し階層を変更しないソースコードの変更があっても、同じハッシュ値になるようにしている。その代わり、呼び出し階層が同じで行番号が異なる例外は区別できない。1メソッドあたりの行数が十分に小さければ、区別できないことはさほど問題にならないだろう。

同レポジトリで logback 用の converter を作った。logback を使っているプロジェクトなら、依存の追加とログ設定ファイルの変更だけで、例外のハッシュをログに出力することができる。プログラムのソースコードを変更する必要はない。

（アイデアが実際のところ上手く機能するかはまだ試していない。）
Errbotのcrontabもどき

Errbotを使い始めた頃に、ボットらしく「毎日指定時間に喋らせる」をやろうとして色々試していた時のログなどを振り返り。

# Errbotにはcrontab的機能はなさそう

* [Errbotのサイトで検索してみる](http://errbot.io/en/latest/search.html?q=cron&check_keywords=yes&area=default)
* [Githubのリポジトリも検索してみる](https://github.com/errbotio/errbot/search?q=cron&type=Issues&utf8=%E2%9C%93)
* [Googleに聞いてみた](https://www.google.co.jp/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=errbot%20crontab)

いずれも、crontabに相当する機能はなさそう。Googleに至っては「Errbotなにそれ？errならわかるけど」みたいな検索結果しか返してくれない

# Errbotにあるスケジューリング機能

http://errbot.io/en/latest/user_guide/plugin_development/scheduling.html

crontabのように、「特定条件の時間に何かを実行する」仕組みは見当たらなかったのですが、
「定期的に何かを実行する」はスケジューリング機能として存在します。

```py:Errbotサイトの機能サンプル
from errbot import BotPlugin

 class PluginExample(BotPlugin):
     def my_callback(self):
         self.log.debug('I am called every minute')

     def activate(self):
         super().activate()
         self.start_poller(60, self.my_callback)
```

Errbotの起動時に配下のPluginをまとめてロードするのですが、インスタンス生成時に`activate()`メソッドを一回だけ実行します。
このタイミングで、`start_poller（）`を実行することで、一定間隔ごとにメソッドを実行できるように設定が可能になります。

サンプルコードの場合は、**１分間隔で`my_callback()`を実行してデバッグログをロギングする**挙動となります。


# スケジューリング機能をもとに、雑にcrontabもどきを実装してみる

試しに実装して、しばらく動かしていた一番雑なcrontabもどき

```py3:crontab.py
# -*- coding:utf8 -*-
from errbot import BotPlugin
from datetime import datetime


class Crontab(BotPlugin):
    """Crontab polling plugin for Errbot
    """
    def activate(self):
        super(Crontab, self).activate()
        self.start_poller(60, self.poll_crontab)

    def poll_crontab(self):
        self.log.debug('Run polling for crontab')
        user = self.build_identifier('@attakei')
        polled_time = datetime.now()
        if polled_time.strftime('%H:%M') == '13:00':
            self.send(user, 'そろそろお昼？')
```

ちょっと強引ですが、

* activate時には毎分単位でとりあえず`poll_crontab()`を呼ぶようにする
* poll_crontabの中では、
    * 呼ばれた時間を取得
    * 動かしたい時間に該当してたらメッセージを送信

という「動けばいいや」系なもの。

## 注意点した点１：メッセージの送り方

`@botcmd`デコレーターを使った命令の場合だと、メソッドは文字列を返せばそのままメッセージとしてくれるのですが、ポーリングされているメソッドが文字列を返しても何もしてくれないっぽく、`send()`を使って明示的にメッセージを送信していく必要があります。

## 注意した点２：じわりじわりと時間がずれる

どちらかというか、最終的に諦めた部分なのですが。

**時間が来る→実行条件を満たしているジョブを実行する**　ではなく、
**定期的に時間をチェックする→実行条件を満たしているジョブを実行する**　だからなのか、
しばらく放っておくと、じわりじわりとメッセージを送ってくる時間がずれていきます。（最大５９秒）

雑に動作確認できた分までだと、
* ポーリングを１分間隔から３０分間隔にして
* 秒が３０未満のときだけジョブ実行判定する

などにすれば、もうちょっとは楽かなとは思います。
wercker v2でrailsのテスト・デプロイまで

基本的には、[Dockerベースになったwercker v2でRailsアプリをCIしてSlackに通知、herokuにデプロイする手順 - Qiita](http://qiita.com/mikage014/items/b89b1113b4e88009da18) の内容どおりです。

## 最終のwercker.yml

```
box: ruby:2.3.0

services:
  - id: postgres
    env:
      POSTGRES_PASSWORD: secret_password

build:
  steps:
    - install-packages:
        packages: nodejs

    - script:
      name: Gem Nokogiri install
      code: bundle config build.nokogiri --use-system-libraries

    - bundle-install

    - rails-database-yml:
      service: postgresql-docker

    - script:
      name: echo ruby information
      code: |
          echo "ruby version $(ruby --version) running"
          echo "from location $(which ruby)"
          echo -p "gem list: $(gem list)"

    - script:
        name: Set up db
        code: RAILS_ENV=test bundle exec rake db:schema:load

    - script:
        name: rspec
        code: bundle exec rspec

  after-steps:
    # notify to Slack
    - wantedly/pretty-slack-notify:
        webhook_url: $SLACK_WEBHOOK_URL
        channel: test

deploy:
  steps:
    - heroku-deploy:
        install-toolbelt: true
        key-name: HEROKU_SSH_KEY
    - script:
        name: Update database
        code: heroku run rake db:migrate --app $HEROKU_APP_NAME

  after-steps:
    - wantedly/pretty-slack-notify:
        webhook_url: $SLACK_WEBHOOK_URL
        channel: test
```

## ハマったこと
- nokogiriがインストールできない
  - [CI wercker v2の使い方 - katlez’s blog](http://katlez.hatenablog.com/entry/2016/02/07/143127) を参考して、下記の部分を追加しました。

  ```
  - script:
    name: Gem Nokogiri install
    code: bundle config build.nokogiri --use-system-libraries
  ```
- js runtimeがない
  - 使うdockerのコンテナと関係あると思いますが、一応nodejsをインストールすることで解決できた

  ```
  - install-packages:
      packages: nodejs
  ```
- heroku デプロイでssh keyがデプロイ都度addされてしまう
  - `key-name`を設定したのに、毎回生成されて、結構はまった。解決ポイントは、`key-name`の値を指定するとき、環境変数を取得しにいくと思うが、一応`$`を要らないほうが正しいです。

    ```
    - heroku-deploy:
        install-toolbelt: true
        key-name: HEROKU_SSH_KEY
    ```

  - 公式の説明はこちらです。 [wercker - getting started - Heroku](http://devcenter.wercker.com/quickstarts/deployment/heroku.html) の`Using SSH Keys`のセクションのNoteに書かれてあります。
    - **Note: You should not prefix the key-name property with a dollar sign ($) or post-fix it with _PRIVATE or _PUBLIC.**

## 課題
- `nodejs`のインストールはまだ毎回走ってるようです。これを解決するためには、dockerのコンテナを作ってみてみたい
Java でリトライハンドラを実装する

# 概要
「[Ruby の retry-handler が激しく便利そうなので Java で実装してみた](http://yoshiori.hatenablog.com/entry/20120315/1331825419)」を読んで、そういう便利なものがあると知りました。せっかくなので、私も勉強を兼ねて見よう見まねで実装してみました。

## リトライハンドラの機能
例外が発生しうる処理をx回試行します。例外が発生しなければ1回で終了し、発生した場合は最大指定回数繰り返します。
HTTP アクセス等の、例外が発生しても成功するまで何回か繰り返してほしい処理で役に立ちます。

---
# 実装
[GitHub repository](https://github.com/toastkidjp/retry_handler/tree/73e0f1020729981d8113b60b35d81f3d54b54339)

Command を受け取るだけの interface を定義しておきます。

```java:Action
public interface Action {
    public void action(int retrying);
}
```

呼び出し側では繰り返したい処理を Action の action メソッド内に実装します。関数型インタフェイスとなっているので Lambda 式を使って記述可能です。

```java:attempt()
public void attempt() {
    for (int i = 0; i < maxRetry; i++) {
        try {
            action.action(i);
            return;
        } catch (final Exception e) {
            if (!suppressWarning) {
                e.printStackTrace();
            }
            sleep();
        }
    }
}
```

attempt() メソッドでは受け取った Command を実行します。何も起こらなければ試行を終了し、例外をキャッチしたら intervalMs で指定したミリ秒分停止して再度の試行を実施します。

---
# 使い方
## git clone & gradle jar
```cmd
$ git clone https://github.com/toastkidjp/retry_handler.git

$ gradle jar
$ mv build/libs/retry_handler-0.0.1.jar
```

## ビルドパスに「retry_handler-0.0.1.jar」を含め、ソースコード上で import する
```java
import jp.toastkid.libs.retry.Retry;
```

## 使う
static メソッドを呼ぶ方法とインスタンスを生成して使う方法と、2種類用意しました。

### static メソッドで使う

```java:use_static
Retry.attempt((i) -> {/* 繰り返したい処理 */}, 2, 1000L);
```

### インスタンスを生成して使う
ありがちですが build() してから attempt() を呼び出すのを忘れないでください。

```java:use_by_instance
new Retry.Builder()
    .setAction((i) -> {/* 繰り返したい処理 */)
    .setMaxRetry(3)
    .setIntervalMs(1000L)
    .build()
    .attempt();
```

---

# 感想
元の記事のように Runnable で実装した方が別スレッドでの実行等の拡張がやりやすくなってよかったかもしれません。
Mac で \ と ¥ の入力を快適に

このエントリーは過去に描いたものですが、今は PHPStorm などの JetBrains IDE でもちゃんと動作する素晴らしいエントリーがあります。
今は、その方法を使っています。いやー、快適。@kunit さんありがとうございます。

[JIS配列のMacで、バックスラッシュをさくっと入力する方法(JetBrainsのIDE対応)](https://qiita.com/kunit/items/f6ec7e159d93002bfc48)

----

以前に
[Macで\入力めんどくね？](http://qiita.com/martini3oz/items/e51911bfa72f172ce16b)
という記事を書きました。

これは Vim でバックスラッシュと円記号を入れ替えるというものでした。
プログラミングなどでは円記号を使うことはほとんどないので、修飾キーなしでバックスラッシュを入力できるととても使いやすいという話です。

その後、Vimmer な僕も、JetBrains の IDE を使うようになりまして、そこで Vim だけじゃなくて Mac 全体で変更することにしました。

で、その解決方法を  [Karabiner](https://pqrs.org/osx/karabiner/index.html.ja) にたよったわけですが（この記事の後半に残しておきます）、Sierra で Karabiner が使えなくなったという...

そしてまたいろいろ探したら、素晴らしい解決方法を見つけました。(2017/1追記)

[Macの英数入力で円記号とバックスラッシュを入れ替える](https://gist.github.com/yujiod/9823541)

~/Library/KeyBindings/DefaultKeyBinding.dict

```
{
    "¥" = ("insertText:", "\\");
    "~\\" = ("insertText:", "¥");
}
```

KeyBindings フォルダも標準では存在しないので、そこから作る必要があります。
しかし、
これをやるとブラウザなどでの入力では入れ替わるもののPHPStormとかでは入れ替わりませんでした。orz
うまいやりかたはないものか。


----
__以下、参考までに Karabiner での記述です。__

解決には [Karabiner](https://pqrs.org/osx/karabiner/index.html.ja) を使います。

- http://qiita.com/uchiko/items/f7ea7915c3953074b797

上記の記事なんかが参考になったんですが、逆に円記号の入力方法がなくなってしまいます。
探してみると、Shift+0 to JIS Yen という設定項目がありました。
その両方を設定すれば、\の入力が楽ちんになって¥も入力できます。

1. Karabiner の設定画面を開きます
2. 検索ボックスに yen と入力します
3. For Japanese のところに JIS Yen(¥) to Backslash(\) (except virtual machine) というのがあるのでそこにチェックを入れます
4. 少し下に Shift+0 to JIS Yen(¥) というのにもチェックを入れます

次の図を参考にしてください。

![SS 2016-05-04 9.28.52.png](https://qiita-image-store.s3.amazonaws.com/0/3788/2da7b3d6-87ad-a7a8-0ad0-b50ea11c3a06.png)

これで、¥ キーを押すとバックスラッシュが入力され、Shift+0 を押すと円記号が入力されるようになります。
Haskell版フォルダを指定してhttpで公開する簡易Webサーバー

```hs:server.hs
module Main where

import Network.Wai.Application.Static
import Network.Wai.Handler.Warp

port = 3001
dir = "/path/to/public"

main = run port $ staticApp $ defaultFileServerSettings dir
```

実行方法

```shell-session
$ stack install wai-app-static warp # Install dependencies
$ stack runghc server.hs # Start server
```
UE4でシーンデプス（OpenEXR）出力方法

#概要
エンジンの機能にスクリーンショットがあり、それが高機能でOpenEXR出力ができます。
それをEvent Tickで毎フレーム呼び出すとマチネなどで一枚一枚出力できます。
（シーンデプスを出力させたい、という場合に使うと良いです）
※マチネにある録画機能だと、通常の画面をPNGなどで出力はできますが、GBufferの出力が出来ません

#実際のノード
![HighResShot.png](https://qiita-image-store.s3.amazonaws.com/0/49072/b1d74aed-88c9-5eb5-cc56-76f679f1de6b.png)
「Execute Console Command」に
「HighResShot 2 Include Buffer Visualization Targets Write HDR format Visualization Targets」
と書き込むとOpenEXR出力できます。

#注意
毎パスレンダリングするため、かなり重いです

#公式ドキュメント
スクリーンショットの撮り方
https://docs.unrealengine.com/latest/JPN/Engine/Basics/Screenshots/index.html

#OpenEXRとは？
下記のサイトが参考になりますが、映像業界では標準的な画像フォーマットです。
http://gouohno.blogspot.jp/2014/06/try-openexr-in-3dsmax.html
https://ja.wikipedia.org/wiki/OpenEXR
http://www.openexr.com/
ofImageLoadSettingsについて

![参考画像](https://cloud.githubusercontent.com/assets/200899/9684569/5795f6ac-5353-11e5-95e2-257727e74bb8.png)

手前味噌ですが, 以前oF本家に投げてたPRがmergeされてたのでご紹介.

# `ofImageLoadSettings`?

FreeImageのjpegの読み込み時のオプション設定です.
 
0.9.3辺りから使えるはず.
 (0.10までお預けのようです. master branchには入っています)
(今後他のフォーマットにも拡張されるかも？)

## 使い方

```cpp
ofImageLoadSettings setting;
setting.accurate = true;
setting.grayscale = true;
ofImage image;
image.load(file_path, setting);
```

## なにこれ？

settingは現在4つの項目を持っています.

| プロパティ   | 効果 |
|:--|:--|
| `accurate` | `true`に設定すると読み込み時に精度重視で読み込む.<br>`false`のときは速度重視 |
| `grayscale` | `true`に設定するとグレースケールで読み込む |
| `separateCMYK` | `true`に設定するとCMYKでseparateしてくれるはず(あまり調べてない)|
| `exifRotate` | `true`に設定するとEXIF情報に合わせて回転してくれるはず(あまり調べてない)|

以上です.
グレースケールにしてくれるのとか結構便利そうな気がしない？

## `accurate`

そもそもこれを見つけた原因がoFでjpeg読み込むとなんか荒れない？って話をmotoishmzとしたことがきっかけ.
そもそもjpegって符号化されたデータの小さい成分無視しても大体見れる(大体上15%くらい読んだらとりあえず元の絵に近い物が出てくる)のでデコーダーによっては「小さい部分無視したら速くなって最高！」って言いながらそういう実装してるわけですね.

で, oFの内部で使われてるFreeImage調べてたらなんかそんな風なオプションあるぞと. これじゃん！
って思ったけどそれはofImage内で固定されてたのでその設定外出ししようぜ, と言って投げたのがこれのPRなわけです.

そんなことを踏まえるとどんだけ速度に差が出るんだよ！って気になりますよね.

```cpp
double d = 0.0;

d = ofGetElapsedTimeMillis();
setting.accurate = true;
for(std::size_t i = 0; i < loopNum; i++) {
    ofImage image;
    image.load(img_path, setting);
}
ofLogNotice("accurete") << long(ofGetElapsedTimeMillis() - d) * 0.001;
        
d = ofGetElapsedTimeMillis();
setting.accurate = false;
for(std::size_t i = 0; i < loopNum; i++) {
    ofImage image;
    image.load(img_path, setting);
}
ofLogNotice("not accurete") << long(ofGetElapsedTimeMillis() - d) * 0.001;
```

やってみました.
結果,

* 600x450の画像を1000回
  * accurete:     4.919
  * not accurete: 3.287 
     * 148%高速
* 1024x718の画像を1000回
 * accurate:     13.920
 * not accurate:  9.879
     * 140%高速
* 1920x1280の画像を1000回
  * accurate:     54.1
  * not accurate: 51.268
     * 105%高速

うーん.
大きくなってくるとそんなに劇的な変化は無いですね.
気持ち速い, くらい.
小さいファイルを大量に読み込むときは50%くらい速くなるって考えるとそこそこ？

ちなみにデフォは全部falseなので速い方です.
「jpegで作ったテクスチャが汚いぞ？」とか「背景に綺麗な夕焼けの写真を敷きたいのにジャギが気になるぞ？」って思った場合はお試しください.
load時の設定だけでそれ以降は速度に影響無いはずです.
UbuntuでMacのキーボードを使う時の設定

## 設定
1.iBusからFcitxに切り替える
2. 次の，前のソースへ切り替えを両方空にする．
3. 入力ソースに日本語，Mozc(Fcitx)を追加し，日本語を一番上にする．
4. sudo dpkg-reconfigure keyboard-configurationでキーボードを(Apple アルミニウムキーボード (JIS)，日本語，日本語，キーボード配置のデフォルト，コンポーズキーなしに設定する．
5. Fcitxの設定で全体の設定を開き，拡張オプションを表示にチェックマークをつけ，入力メソッドをオンにの項目にHiraganakatakanaを，入力メソッドをオンにの項目にMuhenkanを割り当てる．
6. Mozcの設定でキー設定を編集し，エントリー追加から，入力文字なし，Hiragana,ひらがなに入力切替，を追加する.
7. さらに入力キー順にソートし，Hiraganaが設定されている部分のコマンドをひらがなに入力切替に設定する．

## 環境
- MacBook Pro
- Parallels Desktop 11 for Mac
- Ubuntu 15.10

##最後に
疲れた

##追記
しばらく使ってるとどうも何かがおかしい気がする．改善点があれば教えてくださいお願いします．
jQueryのajaxでphpを呼び出す。(cakephp3)

#ajaxとcakephp3
自分用のただのメモ。

cakephp: 3.x (2016/04/2? 時点での最新版だったかな)
php: 7.0.0
jQuery: 2.2.6 (だったかな)
ここからcode

```js:ajaxtest.js
$(function() {
    $('#ajaxbutton').click (function () {
        $(this).text("押された");
        alert("押された");
        $.ajax({
            url: "http://localhost:8888/appname/controller/action",
            type: "post",
            dataType: "html"
        }).done(function (response) {
            $("#tag").html(response);
            alert("success");
        }).fail(function () {
            alert("failed");
        });
    });
});

```

これは、\$('#ajaxbutton').click...
はajaxbuttonっていうIDがついてるボタンがクリックされたらっていう処理です。
ボタンがクリックされると初めに\$(this).text("押された")でajaxbuttonIDがついてるところのテキストを”押された”に変えました。次に、alertで別windowでアラートします。それから、非同期通信をajaxで行います。

urlは実行する先です。cakephpで行っているので、実行したいコントローラーの関数のurlにします。
type:はpostとgetが選べますが、自分はよくわかりません。
datatype: はよくわからんけど、とりあえずこうしてるとうまくいってる。
done()は、urlから読み込みが成功すると実行され、failは失敗すると実行されます。
\$("#tag").html(response)はtagっていうIDをもっているところにresponseを埋め込みます。
responseはきっと、phpの実行結果。phpの実行結果はhtmlでかえってくるから。。

```html:test.html

<button id="ajaxbutton">ボタン</button>

<div id="tag">
  <!-- ここにAjaxで実行したphpの結果が書き込まれる。 -->
</div>

```

あと、cakephpでの注意点

\$this->autoLayerやら、$this->autoRenderなんかでよくわからん。
だからとりあえず、こうしとけばおけ。

```php:TestController.php
<?php

namespace App\Controller;
use App\Controller\AppController;

class TestController extends AppController {
    public function index () {
        $this->viewBuilder()->layout("");
        $this->render("index");
    }

    public function test () {
        $this->autoRender = false;
        if ($this->request->is("ajax")) {
            echo "ajax";
        } else {
            echo "not ajax";
        }
    }
}

?>

```

viewBuilderは読み込むLayerのctpを決めます。
render("index")はTemplate/Test/index.ctpを読み込みます。
これで、indexを実行すると、index.ctpに書かれてるhtmlファイルで出力します。

autoRenderをfalseにすると、その関数内で書いたやつのみhtmlで出力します。
テンプレはいらないってことです。このtestですと、echoだけ表示されます。

is("ajax")はajaxで呼ばれた時、trueを返します。
これで、ajaxのときとそうでないときでわけれます。

cssのメモ
なんかbootstrap使いやすい。けど、ナビゲーションバーがちょっと。。。って感じがする。
materialUIっていうのもいいかもしれない。

しぬほど関係ないけど、jsで関数のプロットができた。。
どっかから拾ってきた、、、
g("block")をはずすと、ズームとか移動とかできる。

```html:plot.html
    <div>
        <iframe src="http://graph.tk/" id="my_graph" style="width:500px;height:400px">
</iframe>
<script>
var my_graph=document.getElementById("my_graph");

my_graph.onload=function(){
    function g(m){
        my_graph.contentWindow.postMessage(m,"http://graph.tk");
    };
    g("add:x^3+1");
    g("add:e^x");
    g("block");
    g("center:1,2");
    g("scale:2");
}
</script>

//Methods include: add, block, empty, scale, translate, center


    </div>

```

どうでもいいけど、jqueryわからないから、いろいろと調べてるんだけど、どれも関数のなかに関数書いててネストがめちゃくちゃきもちわるいことになってる。
【メモ】プログラミングで意識すること

【メモ】
プログラミングの鉄則の一つとして「同じ処理は二度書かない」ということが言えると思います。なぜなら、同じ事をやる処理が2箇所で書かれていたら、そこを修正するとき、2箇所とも修正しなければなりません。
http://www.objective-php.net/basic/extend
コンピュータ囲碁の作成

#コンピュータ囲碁
コンピュータ囲碁の作成メモ。
今回は碁盤の作成のみ

#結果画像
![スクリーンショット 2016-05-04 03.56.39.png](https://qiita-image-store.s3.amazonaws.com/0/67439/accf3d43-f82d-bf1d-1486-8214f2f1b97d.png)
※
#ソースコード

```py
# -*- coding:utf-8 -*-
# データ構造
KOMI = 6.5
BOARD_SIZE = 9				# 碁盤の大きさ
WIDTH_SIZE = BOARD_SIZE + 2 # 盤外を含めた碁盤の横幅 11
BOARD_MAX  = WIDTH_SIZE * WIDTH_SIZE # 121

WALL = 3	# 盤外

# 碁盤

board = [
		3,3,3,3,3,3,3,3,3,3,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,0,0,0,0,2,0,0,0,0,3,
		3,0,0,0,0,0,0,0,1,0,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,0,0,0,0,0,0,0,0,0,3,
		3,3,3,3,3,3,3,3,3,3,3,
		]

# board = [0 for i in range(0,BOARD_MAX)]
# 一行目を盤外にする
for i in range(0,WIDTH_SIZE):
	u_wall = i
	b_wall = BOARD_MAX - WIDTH_SIZE + i
	board[u_wall] = WALL
	board[b_wall] = WALL
for i in range(1,WIDTH_SIZE):
	l_wall = i*WIDTH_SIZE
	r_wall = l_wall+BOARD_SIZE+1
	board[l_wall] = WALL
	board[r_wall] = WALL


dir4 = {-1,1,+WIDTH_SIZE,-WIDTH_SIZE} # 右左上下への移動
hama = [0,0]
kifu = [0 for i in range(0,1000)]
ko_z = 0
all_playouts = 0

# (x,y)を１次元配列表記に変換 ただしx,y:0〜8
def get_z(x,y):
	return (x+1) + (y+1)*WIDTH_SIZE
# 上の逆
def get_x_y(z):
	return (z%WIDTH_SIZE,z/WIDTH_SIZE)

# 一次元配列を(x,y)に変換
def get81(z):
	if z==0:
		return 0
	y = z/WIDTH_SIZE
	x = z- y*WIDTH_SIZE
	return x*10+y

def flip_color(col):
	clo = 3 - col

storn = ["・","🔴 ","⚪️ "]
def print_board():
	print " ",
	for x in range(1,BOARD_SIZE+1):
		print "%d " %x,
	print ""
	for y in range(0,BOARD_SIZE):
		print y+1,
		for x in range(0,BOARD_SIZE):
			print storn[board[get_z(x,y)]],
		print ""

print_board()
```
##github
https://github.com/Tsunehiko511/python_Go_origin

#参考図書
<a  href="http://www.amazon.co.jp/gp/product/4320123271/ref=as_li_tf_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4320123271&linkCode=as2&tag=simanezumi104-22">コンピュータ囲碁 ―モンテカルロ法の理論と実践―</a><img src="http://ir-jp.amazon-adsystem.com/e/ir?t=simanezumi104-22&l=as2&o=9&a=4320123271" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
htmlでinput type="file"に値が入った時に別のinput type="file"を作る方法

jQueryの基礎だけわかっていれば以下3つである程度理解できる
htmlで<input type="file">に値が入った時に別の<input type="file">を作る方法
https://teratail.com/questions/21471
↓
$(':file')の意味がわからない！
http://js.studio-kingdom.com/jquery/selector/file_selector
↓
:lastの意味が分からない！
http://semooh.jp/jquery/api/selectors/%3Alast