OmniAICreator/Qiita-1.07M huggingface dataset:
CircleCI 2.0でRe:VIEWの原稿をビルドする

CircleCI 2.0が登場し、Dockerイメージを使ってビルドできるようになりました。
C92や[技術書典3](https://techbookfest.org/event/tbf03)に向けて執筆されている方でもRe:VIEWを使っている方がいると思います。
vvakameさんが作成したRe:VIEW用のイメージがあるので、CircleCI 2.0でRe:VIEWの原稿をビルドしてみました。

- サンプルのリポジトリ: https://github.com/mstssk/ReVIEW_CircleCI_Sample

## 解説

やったこととしては以前書いた[WerckerでRe:VIEWの原稿をビルドする](http://qiita.com/mstssk/items/86ec2aa32e845b7df8ec)という記事のCircleCI 2.0版です。

GitHubとCircleCI間の連携については、特別なことは何もしていないので本記事では割愛します。
公式のドキュメントなどを参照してください。

### 設定ファイル

設定ファイルは20行未満になりました。並列処理したりしたいわけではないので[Workflow](https://circleci.com/docs/2.0/workflows/)は使っていません。
Dropboxへのアップロードの部分はオプションなので、ビルドするだけならもっと短くなります。

```.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: vvakame/review
    steps:
      - checkout
      - run:
          name: Build PDF
          command: rake clean pdf
          working_directory: ./articles
      - store_artifacts:
          path: ./articles/book.pdf
          destination: book.pdf
      - run:
          name: Upload to Dropbox
          command: ./upload_dropbox.sh ./articles/book.pdf ${DROPBOX_TOKEN}
```

### 使用するコンテナ

```
image: vvakame/review
```

vvakameさんが作ったRe:VIEWのビルド用Dockerイメージです。
https://hub.docker.com/r/vvakame/review/

### PDFをビルド

```
- run:
    name: Build PDF
    command: rake clean pdf
    working_directory: ./articles
```

Re:VIEWでPDFをビルドします。
今回はRe:VIEWの `review-init` コマンドで環境を初期化しました。Rakefileができるので、ここではそのままrakeコマンドでビルドしています。
もちろん、他のビルドツールでreview-pdfmakerや他のRe:VIEWのサブコマンドを使ってもよいです。
PDFだけでなくHTMLやEPUBなどをビルドすることも出来ます。


### 成果物の保存

CIでビルドしたPDFファイルなどの[成果物を保存](https://circleci.com/docs/2.0/artifacts/)できます。
ビルドの結果画面のArtifactsタブからダウンロードできます。

```
- store_artifacts:
    path: ./articles/book.pdf
    destination: book.pdf
```

`path` 対象のファイルを指定しています。
`destination` は保存後のファイルパスを指定するオプションです。 pathだけだと、元ファイルのパスそのままに `root/project/articles/book.pdf` という深いパスで成果物画面に出てきてしまい使いづらいので、指定しています。

ちなみにpathとdestinationには環境変数は使えないようです。ファイル名をタイムスタンプにしたかったんですが、今回は諦めています。

### Dropboxにアップロードする

CircleCIの画面上から保存したPDFをダウンロードしてもよいですが、Dropboxに自動でアップロードするようにしておくと便利です。
複数人で執筆している場合は、他の都合がいいファイル共有ツールを使ってもよいでしょう。

```
- run:
    name: Upload to Dropbox
    command: ./upload_dropbox.sh ./articles/book.pdf ${DROPBOX_TOKEN}
```

[./upload_dropbox.sh](https://github.com/mstssk/ReVIEW_CircleCI_Sample/blob/master/upload_dropbox.sh)は[Dropbox API v2](https://www.dropbox.com/developers/documentation/http/documentation)にファイルをアップロードするスクリプトです。

`${DROPBOX_TOKEN}`は事前に発行しておいたDropboxのAPIトークンです。CircleCIのリポジトリ設定で、環境変数として登録してあります。
APIトークンは[Dropboxの開発者向けページ](https://www.dropbox.com/developers)で自分のアプリを作成して発行しておきます。
ImageHashで同じ画像を持つフォルダを検出する

#目的
スクレイプ先が同一ソースから記事を作成している場合、タイトルが違う同じ画像をダウンロードしてしまうことがある．
タイトルが違うが中身が全く同じ画像フォルダを検出し，削除したい．

#使用環境
windows10
Anaconda python3.6.1
jupyter notebook

#参考url
[Python の類似画像ライブラリ ImageHash を Windows で使う](http://aquasoftware.net/blog/?p=985)

#ImageHashとは
画像の情報をハッシュ化する際に、 画像の大きさや微妙な違いには目を瞑って同じような画像は同じダイジェスト値、似たような画像は似たようなダイジェスト値を得たい場合に用いられる類似画像ライブラリ．
画像の拡張子やサイズによらず類似度を判定してくれる．

# モジュールのインストール
Anacondaの場合ImageHashのみのインストールで終了する．

```py3:py
pip install numpy
pip install scipy
pip install Pillow
pip install PyWavelets
pip install ImageHash
```

#コード

```py3:compimages.py
from PIL import Image,ImageFile
import imagehash,os
from glob import glob
#サイズの大きな画像をスキップしない
ImageFile.LOAD_TRUNCATED_IMAGES = True

#2つの画像のハッシュ値の差分を出力
def d_hash(img,otherimg):
    hash = imagehash.phash(Image.open(img))
    other_hash = imagehash.phash(Image.open(otherimg))
    return hash-other_hash
#画像サイズの小さい方を検出する
def minhash(img,otherimg):
    hash_size = Image.open(img).size
    otherhash_size = Image.open(otherimg).size
    if hash_size<otherhash_size: return 0
    else: return 1
    
#作業フォルダを指定
directory_dir = r'C:\Users\hogehoge\images'
#フォルダリスト、フォルダパスを取得
folder_list = os.listdir(directory_dir)
folder_dir = [os.path.join(directory_dir,i) for i in folder_list if len(os.listdir(os.path.join(directory_dir,i))) >2 ]

#画像リスト、パスを取得
img_list = [os.listdir(i) for i in folder_dir]
img_list_count = [ len( i ) for i in img_list ]
#二重内包表記でフォルダごとの画像リストを作る
img_dir = [ [ os.path.join(dir,list[i]) for i in range(count) if list[i] in 'jpg' or 'png']  for (count,dir,list) in zip(img_list_count, folder_dir, img_list) ]



i = 0
length = len(img_dir)
delete_file = []

#d_hash(),minhash()でフォルダごとの画像を比較
while i < length:
    #進捗状況
    print('i = ',i+'/'+length)
    for j in range(i+1,length):
        #breakへのフラグ
        switch = 0
        for k in img_dir[j]:
            #ハッシュ値の差分が10以下なら同一の画像として認識
            if d_hash(img_dir[i][1],k)<10:
                print(folder_list[i]+' | vs | '+folder_list[j])
                #画像サイズの小さい方のパスをdeleteリストに保存
                if minhash(img_dir[i][1],k) == 0:
                    delete_file.append(folder_dir[i])
                else: delete_file.append(folder_dir[j])
                i += 1
                switch = 1
                break
        if switch != 0:break
    i += 1

#削除したいフォルダパスの表示
print(delete_file)

#続けて削除したい場合
#import shutil
#for i in delete_file:
#   shutil.rmtree(i)
```
#実行結果
最初のフォルダは時間がかかるが，iの増加に伴い比較フォルダ数が漸減するため，処理が半分まで進めば，フォルダごとの画像比較量も半分まで減る．
とはいえ100のフォルダに10枚画像が含まれているとしてループ総数は**50500回**.
threadingモジュール等で並列処理できるならば今後実装したい．
Laravel5.5: セッションの保存にRedisを使う (ローカル環境)

セッションの保存先を、デフォルトのファイルからRedisへ変更します。
ただし、これは必須ではありません。保存先がファイルのままでも全く問題ありません。
:link: [Redis](https://readouble.com/laravel/5.5/ja/session.html#driver-prerequisites)


# 親記事
[Laravel 5.5で基本的なCRUDを作る - Qiita](http://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# Redisのインストール
まずは元となるRedisとGUIツールのRDMをインストールします。詳しくは下記を。
:link: [(過去記事) Windows: PhpRedisとPredisの使用準備](http://qiita.com/sutara79/items/6ad3b824cfe017da9148)

これ以降は下記の接続設定を前提として進めます。

- ホスト: `127.0.0.1`
- ポート: `6379`
- 認証: なし


# Predis
## 使用準備
```text:PowerShell
# Composerでインストールする
> composer require predis/predis
```

```sh:.env
# セッションの保存先をfileからredisへ変更
SESSION_DRIVER=redis

# デフォルトのままでOK
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
```

## 動作確認
セッションをファイルに保存していた時と同じように、ごく普通に[sessionヘルパ](https://readouble.com/laravel/5.5/ja/session.html#retrieving-data)を使えます。
下記のようにルートを追加してブラウザで`http://(ドメイン)/test-session`にアクセスすると、`こんにちはこんにちは!!`と表示されます。

```php:routes/web.php
Route::get('test-session', function () {
    session(['foo' => 'こんにちはこんにちは!!']);
    return session('foo');
});
```

RDMで確認します。
下記のように`laravel:<セッションID>`というキー名で、Laravel内で使われている他のセッションとともに保存されています。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/27816/2ef56b45-1a7a-94db-a5c5-5727b56d8ca5.png)


# PhpRedis
PhpRedis自体のインストールについては、先ほども挙げた下の記事をご覧ください。
:link: [(過去記事) Windows: PhpRedisとPredisの使用準備](http://qiita.com/sutara79/items/6ad3b824cfe017da9148)

Laravelで使用するには、`client`を`phpredis`に変えるだけです。

```diff:config/database.php
     'redis' => [

-        'client' => 'predis',
+        'client' => 'phpredis',
```

動作確認のため、先ほどのページをリロードしてみてください。
以前と変わらずにセッションを使えるはずです。
試しに`php.ini`でPhpRedisを無効にしてApacheを再起動してページをリロードすると今度はエラーとなるので、セッションの保存にPredisではなくPhpRedisが使われていることが分かります。
Laradock v5.5.2 で一度docker-compose upしちゃった後に、v5.5.1に戻しても、MySQLが起動しない問題

Laradockがv5.5.2になって、MySQL8.0対応になってしまったため、なんだか色々トラブる

ということで、先日投稿した以下でもv5.5.1でタグ指定して`git clone`するような記載に変えましたが、一度、v5.5.2で`docker-compose up`してしまうと内部的に持っているデータの一部がMySQL8.0形式になってしまい、v5.5.1に戻しても、MySQLが起動してこないです。

 - [Laradock on macでLaravelの開発環境をサクッと整備 - Qiita](http://qiita.com/yamazaki/items/d8b583a0fee70cadfc7b)

で、この問題に遭遇した際、`docker-compose logs`を実行してログを確認したところ、以下のようなエラーが出ていたので原因は分かったものの... どう対処すれば良いかがわからず、ググりまくり

```
mysql_1                | 2017-07-19T15:35:24.694417Z 0 [ERROR] InnoDB: Unsupported redo log format. The redo log was created with MySQL 8.0.1. Please follow the instructions at http://dev.mysql.com/doc/refman/5.7/en/upgrading-downgrading.html
mysql_1                | 2017-07-19T15:35:24.694473Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
mysql_1                | 2017-07-19T15:35:25.296412Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
mysql_1                | 2017-07-19T15:35:25.296496Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
mysql_1                | 2017-07-19T15:35:25.296521Z 0 [ERROR] Failed to initialize plugins.
mysql_1                | 2017-07-19T15:35:25.296535Z 0 [ERROR] Aborting
mysql_1                | 
mysql_1                | 2017-07-19T15:35:25.296593Z 0 [Note] Binlog end
mysql_1                | 2017-07-19T15:35:25.296717Z 0 [Note] Shutting down plugin 'CSV'
mysql_1                | 2017-07-19T15:35:25.301788Z 0 [Note] mysqld: Shutdown complete
```

でも、なかなか直接的な解決方法が見つからず...

GitHubのlaradockのIssueを覗いて見たら、同様の事象で困っている人を発見

 - [ERROR 1146 (42S02): Table 'information_schema.SCHEMATA' doesn't exist #1047 - laradock/laradock - GitHub](https://github.com/laradock/laradock/issues/1047#issuecomment-315495659)

冷静に考えれば、redo logってことはmysql自体のデータに起因していることには気づきそうなので、あとは、Laradockの設定を辿っていければ、いずれは解決できただろうけれど...

後、先ほど、別のQiitaの記事からリンクされていることに気づいて、おそらく、似たような原因ではないかと思われる人が、データ削除して復旧できたとの投稿を見つけた。

 - [LaradockでMySQLがどうしても立ち上がらない人あつまれー！ - Qiita](http://qiita.com/lala_fell/items/d4bd1340a5cc7dfcfcb4#_reference-b91c966ddfb5ebd0c928)

Laradockの場合、複数のインスタンスを使い分けるような場合、データファイルが共有されるってことになりそう... だとすると、コレ、`.env`での`DATA_SAVE_PATH=~/.laradock/data`の指定は、インスタンスごとに別れるようにした方が良さそう
Antergosをインストールしました。日本語入力（fcitx-mozc）はどうすれば設定出来るでしょうか？

Antergosをインストールしました。表示は日本語で出ているのですが、日本語入力（fcitx-mozc）はどうすれば設定出来るでしょうか？

【行った手順】
1. # pacman -S fcitx-im fcitx-configtool fcitx-mozc
 
2. .xprofileファイルの設定
$nano ~/.xprofile を下記のように追加編集
 
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=”@im=fcitx”
 
3. Logoutして、再度Login

おわかりの方は教えてください。
【Linux】ディレクトリ配下のファイルに含まれる文字を検索するコマンド

カレントディレクトリ配下の全てのファイルに対して、ある文字列が含まれているかを検索する方法

■大文字小文字を区別して検索する場合
find ./ -type f -print | xargs grep '[検索する文字]'

■大文字小文字を区別しないで検索する場合
find ./ -type f -print | xargs grep -i '[検索する文字]'

使用例
![スクリーンショット 2017-07-23 14.38.32.png](https://qiita-image-store.s3.amazonaws.com/0/192949/39e5e7a6-4f34-617b-dfb4-eee5d094f4f6.png)

※ Readme.txt の内容

```
0123
Test
```

※ test.txtの 内容

```
0123
test
test0123
4567
0123test
Test
89
```
BigQueryの日付テーブルにおける、日付指定リファレンス　


#はじめに
BigQueryの日付を付与したワイルドカードテーブルから、日付を指定するクエリをリファレンスとして記載しています。
Standard SQLを使用します。

<font color="Red">→ 日付算術演算子やLAST_DAYファンクションが使えるようになったので、新しい投稿を作成しました。[こちら](https://qiita.com/Bacchus/items/db3ef900dbc10132d1a8)</font>

##クエリリファレンス
###前日

```sql
#standardSQL
SELECT
  *
FROM
  `ds.table_P*`
WHERE
  _TABLE_SUFFIX = FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 1 DAY))
```

###前月
前月の1日から最終日。
前月１日、前月末日を指定する場合には、このBETWEENのFROMかTOが使えます。

```sql
#standardSQL
SELECT
  *
FROM
  `ds.table_P*`
WHERE
  _TABLE_SUFFIX BETWEEN 
  FORMAT_DATE("%Y%m%d", DATE_TRUNC(DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 1 MONTH), MONTH))
  AND FORMAT_DATE("%Y%m%d", DATE_SUB(DATE_TRUNC(CURRENT_DATE('Asia/Tokyo'), MONTH), INTERVAL 1 DAY))
```

少し短い記述。文字列比較なので、31日が無い月の指定も31の記述で大丈夫です。気持ち悪く感じなければ。

```sql
#standardSQL
SELECT
  *
FROM
  `ds.table_P*`
WHERE
  _TABLE_SUFFIX BETWEEN 
  FORMAT_DATE("%Y%m01", DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 1 MONTH))
  AND FORMAT_DATE("%Y%m31", DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 1 MONTH))
```

###前年

```sql
#standardSQL
SELECT
  *
FROM
  `ds.table_P*`
WHERE
  _TABLE_SUFFIX BETWEEN 
  FORMAT_DATE("%Y%m%d", DATE_TRUNC(DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 1 YEAR), YEAR))
  AND FORMAT_DATE("%Y%m%d", DATE_SUB(DATE_TRUNC(CURRENT_DATE('Asia/Tokyo'), YEAR), INTERVAL 1 DAY))
```

###前週
日曜日〜土曜日の指定。
DATE_TRUNCは、DAYOFWEEKが指定出来ません。

```sql
#standardSQL
SELECT
  *
FROM
  `ds.table_P*`
WHERE
  _TABLE_SUFFIX BETWEEN 
  FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL EXTRACT(DAYOFWEEK FROM CURRENT_DATE('Asia/Tokyo'))+6 DAY))
  AND FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL EXTRACT(DAYOFWEEK FROM CURRENT_DATE('Asia/Tokyo')) DAY))
```

##注意点
- CURRENT_TIMESTAMP()を使うと、タイムゾーン指定が出来ないので、DATE型やDATETIME型を使用しています。
- テーブルのプレフィックスには注意が必要です。公式ドキュメントに記載があります。
https://cloud.google.com/bigquery/docs/wildcard-tables#best_practices
例えば、table_20170727とtable_tmp_20170727というテーブルがあった場合、table_*を指定すると両方のテーブルが一致してしまうためです。そのため、パーティションを示す"_P"を付けることにしました。

#参考
日付文字列変換など覚え書き

```sql:
#standardSQL
SELECT
  FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', CURRENT_TIMESTAMP()), --UTC
  CURRENT_DATETIME('Asia/Tokyo'), --JST
  STRING(CURRENT_TIMESTAMP(), 'Asia/Tokyo'), --日本(+9H)
  STRING(CURRENT_TIMESTAMP(), '+8') --中国など(+8H)
```

https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#supported-format-elements-for-datetime

- 接頭辞「#standardSQL」を指定すると、WEB UIでLegacySQLのチェックを外さなくてもStandard SQLとして実行されます。
コンポーネントテストのお話

# はじめに

前回、[ここ](http://qiita.com/mwakizaka/items/91b8f18c4750a92838c2)でテスト自動化の投稿をしたので、
続きとして書いてますが、おそらく単一投稿として読めるかと思います。
[単体テストの話](http://qiita.com/mwakizaka/items/bf49ec15a616d21d30a2)と重複する部分が多いので、書いてないことはそちらを見てもらえればよいかなと思います。
さして内容はないです、えへへ。

# コンポーネントテストとは
場所によって呼び方変わるかと思いますが、いわゆる結合テストの位置付けのもの。
チーム開発の場合、自分たちの結合テストが何を担保するのか、話し合ったほうがいいでしょう。
逆に、それ以外に関しては単体テストと基本同じだと考えてます。
さて、結合テストの担保範囲はおそらく以下の5パターンが考えられるのではないでしょうか。
1. プロダクトコード内部のインタフェース間の結合
2. プロダクトの構成要素(e.g. DB)との結合
3. 別組織/別ベンダのプロダクトとの接続部分
4. 外部公開する機能のインタフェースの動作確認
5. 複数クラスを組み合わせて実現される機能の動作確認

1, 2, 3が接続の確認であるのに対して、4, 5は意味ある1機能と見なしてテストする点で異なってますね。
4はAPIのテストをイメージしてもらえれば良いかなと。
ちなみに、実践アジャイルテストで紹介されていたテスト自動化のピラミッドにおける
コンポーネントテストもおそらくこの5つ目のことではないかと思います。
各プロジェクトの性質や組織文化にあった定義を使うかITa、ITbみたいに複数使い合わすのが良いかなと思います。

ただし、3つ目はやりすぎると(自分たちの責任の範囲外の)他プロダクトの検証になりかねないので注意が必要です。
他プロダクトのSLAや、自分たちのプロダクトに要求される品質レベルを鑑みて判断するのも良いですし、
あとは、自分たちのプロダクトと外部ベンダのプロダクトの責任範囲を明確化する意味で検討自体はしても良いかもしれません。


# 参考
http://endok.hatenablog.com/entry/2014/06/08/215043
[実践アジャイルテスト](https://www.amazon.co.jp/実践アジャイルテスト-テスターとアジャイルチームのための実践ガイド-Architects-Archiveソフトウェア開発の実践-Gregory/dp/4798119970)
単体テストのお話

# はじめに

前回、[ここ](http://qiita.com/mwakizaka/items/91b8f18c4750a92838c2)でテスト自動化の投稿をしたので、
続きとして書いてますが、おそらく単一投稿として読めるかと思います。
なお、TDD界隈の単体テストの話ではなく、普通の品質保証の話なのでご注意ください。
基本的に[JUnit入門](https://www.amazon.co.jp/JUnit実践入門-~体系的に学ぶユニットテストの技法-WEB-PRESS-plus/dp/477415377X)をとても参考にしてます。

# 1. 単体テストとは
- クラスやメソッドを対象としたプログラムを検証するためのテスト
- ソフトウェアテストにおける最も粒度の小さいテストレベル

# 2. 進め方
こんな感じで進めるのがよいのかなと。
1. テストの実装対象を決める
2. ホワイトボックステストの技法など駆使してパターンを網羅する
3. テスト実装する
4. レビュー

実際にレビューまで出来るかはプロジェクトの忙しさ次第ですが、
テストの網羅性やアサートのロジック(何を以ってテストOKとするか)を
見たい人も一定数いるのではなかろうかと思います。

# 3. 対象とすべき箇所・分量
とても厳しいカバレッジ基準が設けられているプロジェクトは特に悩まなくていいかもですが、
そうでない場合は、ユニットテストに限らずよく悩むかなと。
テスト自動化のピラミッド的には分厚くしないといけないテストレベルではありますが、
実際のところ、時間的余裕がない場合もあるので、その時はROIやリスクの観点から判断が必要です。
ただし、個別にやる／やらないを判断する時間があるなら、その時間でテスト実装したほうがいいので、
もう少しざっくりとした判断基準として考えられるのは以下のようなものです。

## やったほうがいい
- コメントが必要な程度に複雑なロジック
    - If文がネストしている(モノによってはリファクタリングが必要な気がしますが)
    - 複雑な計算ロジック・オブジェクトを扱う
- 多くのオブジェクトから依存関係のあるロジック

## やらなくていい
- データの受け渡しのためのモデルクラス(e.g. Java Bean)
- MVCモデルにおけるViewの部分等、人の目で見たほうがいいもの
- その他、非常に手間のかかる割に効果が薄い箇所

# 4. 単体テスト実装のポイント
## 不安定なテストを避ける
不安定なテストが混じっていると、まずはそのテストへの関心が薄れます。
そして、本当のテストNGへの関心が薄れてしまうという、狼少年問題が発生します。
	
この原因の1つとしてはテスト対象が現在時刻に依存している場合等が考えられます。
その場合は、Mock/Stubを使うなどして安定させると良いでしょう。
もう1つはテストないしテスト対象が実行環境に依存している場合が考えられます。
例えばファイルパスがハードコーディングされている場合等です。
プロダクトコード及びテストの安定稼働のためには、
特定の実行環境に依存しない実装を心がけましょう。

## 問題の局所化
一つのテストケースに多くのテスト条件やassertを入れてしまうと、
テストNGの時に疑うべき箇所が増えてしまい、問題の特定に時間がかかります。
そのため、なるべくシンプルなテスト条件・assertにする方が好ましいです。

## 独立したテスト
テストケースの実行順序に依存しないテストが好ましいです。
こうしておくと後々、テストを並列実行させやすくなります。

## 不明瞭なテストを避ける
ここは「テスト」を「コード」という単語に置き換えてもらえれば理解いただけるかと思いますが、
テストも可読性が大事だということです。具体的にはテストの前提条件、テストの手順、
assertの処理が明確に分かれた、短いテストコードが好ましいです。
よく練られたテストケースは、テスト対象のコードの使い方を説明する
ドキュメントとしても機能するため、他の人が読むことを意識して書くと良いでしょう。

# 5.アサートするもの
- テスト対象メソッドの返り値
- テスト対象クラスの内部状態
- テスト対象が依存する特定メソッドの呼び出し回数
- テスト対象が依存する特定メソッドを呼び出した時の引数

# 6. まとめ
自動テストはやはり繰り返し実行することが前提です。
そのため、長く付き合うことを考えると単体テスト実装のポイントは
押さえたほうが良いなと思います。

なお、ここで書いたのは基本的な話なので、こまい話は[こちら](http://qiita.com/mwakizaka/items/f713319dd542ae2975a9)をどうぞです。

# 参考

[JUnit入門](https://www.amazon.co.jp/JUnit実践入門-~体系的に学ぶユニットテストの技法-WEB-PRESS-plus/dp/477415377X)
kotlinで簡単な曜日検索

月と日にちを入力したらその曜日を出力する簡単なもの


```Kotlin:karender.kt
import java.util.Scanner

fun main(args: Array<String>) {
    val monlist = listOf(31,28,31,30,31,30,31,31,30,31,30,31)
    var t = 0
    val input = Scanner(System.`in`)
    println("月を入力(例 7)")
    var month : Int = input.nextInt()
    println("日を入力(例 23)")
    val day : Int = input.nextInt()
    month = month-1
    for(i in 1..month){
        t =  t + monlist[i-1]
    }
    val ans : Int = day + t
    when(ans % 7){
        1 -> println("日曜")
        2 -> println("月曜")
        3 -> println("火曜")
        4 -> println("水曜")
        5 -> println("木曜")
        6 -> println("金曜")
        0 -> println("土曜")
    }
}
``` 

```:実行結果
月を入力(例 7)
7
日を入力(例 23)
24
月曜
```

kotlinはjavaに比べて楽になった部分もあった(小並感)
テスト自動化 躓くところあれこれ

# はじめに

テスト自動化を始めたら、色々躓きがあるかと思いますが、それをまとめてみました。
今後も躓いたら定期的にアップデートしていこうと思います。
今の所、単体テスト、結合テスト、機能テスト等の区別は特にしていません。

# コピペの氾濫

コピペの原因による。もちろん、本当にコピペしただけのテストコードは
問題ありすぎですが、何らかの意図があってのものなら仕方がないかなと。
例えばテストケースはシンプルに保ちたい(i.e. if文を入れたくない)、
よってデータ駆動テストは使いたくない、なら納得しますね。
ただし、テストケースが網羅されているかどうかは気にしたほうがいいですね。

# Statist or Behaviourist

[ここ](http://endok.hatenablog.com/entry/2014/06/08/215043)の方が丁寧に書いてくださってますが、ようはMock/Stubを使って、
テスト対象の依存オブジェクトをどう検証するかということです。
Mock/Stubを使うと、依存オブジェクトから独立したテストを作れて、実行速度も早くできますが、
依存オブジェクトとの結合時や依存オブジェクトの変更に脆くなりやすいと言われています。
そのため、特別な理由がない限りは使わないほうが良いと思います。

# 何%のカバレッジを目標とするべきか

カバレッジはテストによってプロダクションコードがどの程度実行されたかを表す指標です。
よって、ある特定の機能が丸々ごっそり抜けていることを指し示す指標ではないですし、
意味あるテストが為されていることを指し示す指標でもありません(意図的にあげることは簡単なので)。
この前提を踏まえた上で、記述すると80%から90%程度に設定するプロジェクトが多いようです。
あとはプロジェクトのQCDSやプロダクトの性質(ユニットテストしやすいかどうか)に
よって調整する感じでしょうか。

# スローテスト問題

開発を進めていくとユニットテストの数も比例して増えていきますが、
だんだん無視できなくなるのがその実行時間です。
比較的先進的な現場では、プルリクをwebhookして
ユニットテストを自動実行させてると思いますが、
その実行時間が30分とかになったらおそらく待てないですね。

そんな時にどうするかですけど、対策として以下の4つがあります。
##1. テスト実行環境を強化する
札束でしばくとよいということですね。プロジェクトの予算との相談でしょうか。
「人件費より高いコストはない」という意見もありますが、ポンッと出してくれる現場でなければ、
スペックの良いマシンをレンタルしてきて比較実験をする必要がありそうですね。

##2. テストを並列で実行する

こちらは複数のマシンを使ってテストを実行するということですね。
この時気にするべきは以下の2点です。
    a. テストケースは任意の順番で実行できること。
    b. テストケース間でリソース(e.g. 何かしかのグローバル変数やDBのデータ)を共有していないこと。
テストを分割して実行するには、何らかのツールを導入したり、作成・設定が必要になるかもしれません。
なるべく管理上煩雑にならないものが好ましいかと思います。

##3. テストの実行時間を短くする

この方法では遅いテストケースを丹念に調べ上げて、1つずつ実行時間を短くします。
具体的には以下のような作業でしょうか。
a. テストデータの共有(共有フィクスチャ)
b. リアルオブジェクトをモックオブジェクトに変換
c. パフォーマンスを考慮したテストコードを書く
ただし、それぞれテストケースの独立性の低下、テストの安定性及び
テストコードの可読性とのトレードオフになってきますし、
そもそも作業自体にリスクが伴うので、基本的には最終手段と考えたほうがよいです。

##4. 実行するテストを絞り込む
作ったテストを潔く廃棄するか、実行頻度を下げるという方法です。
対象になるのはさほど重要でなかったり、重複していたり、
特に実行時間のかかるテストケースです。
個人的にはこれが一番適用しやすいと思いますが、
どのテストケースを廃棄して、どのテストケースの実行頻度を下げるか等、
チーム内で何らかの基準を作って、管理しやすい形にまとめておく必要がありそうです。

# 参考

http://endok.hatenablog.com/entry/2014/06/08/215043
[JUnit実践入門](https://www.amazon.co.jp/JUnit実践入門-~体系的に学ぶユニットテストの技法-WEB-PRESS-plus/dp/477415377X)
実践アジャイルテストで立ち返るテスト自動化の基本的なお話

# はじめに

みなさん、テストしてますかーー？

今日は[実践アジャイルテスト](https://www.amazon.co.jp/実践アジャイルテスト-テスターとアジャイルチームのための実践ガイド-Architects-Archiveソフトウェア開発の実践-Gregory/dp/4798119970)、という本の内容に沿って
テスト自動化の基本的な話を書きたいと思います。

ちなみに、[実践アジャイルテスト](https://www.amazon.co.jp/実践アジャイルテスト-テスターとアジャイルチームのための実践ガイド-Architects-Archiveソフトウェア開発の実践-Gregory/dp/4798119970)なんていう名前のついた本書ですが、
テスト自動化の内容に関しては、ウォーターフォールな開発でも普通に
適用できるんじゃないかなと思いました。

# 1. テスト自動化のモチベーション

人は何故、テスト自動化をするのでしょうか。本書は次の通り書いています。

- 手動テストは時間がかかりすぎる
- 手作業は間違いを起こしやすい
- 自動化は人々を自由にし、最高の仕事を行えるようにする
- 自動化されたリグレッションテストはセーフティネットを提供する
- 自動化されたテストはより頻繁にフィードバックを与えることができる
- 自動テストがプロダクトコードの生きたドキュメントになる
- テストの自動化は投資上の十分な見返りがある

各主張の詳細は本書に譲るとして、では何でもかんでも自動化すればいいかというと、そうでもないですね。
機械に任せるに相応しいテストレベルというものがありますし、
テストを自動化するために払えるコストにも限りがあるわけです。
それら踏まえて、繰り返し実行する価値のあるテストレベルを選びましょう、
というのが、次のアジャイルテストの4象限です。

# 2. アジャイルテストの4象限

本書では、様々な目的で実施されるテストを4象限に分類をしています。
それが下図のアジャイルテストの4象限です(アジャイルでなくても参考になると思ったのはさて置き)。
![アジャイルテストの4象限.png](https://qiita-image-store.s3.amazonaws.com/0/114437/5dd02f09-c4db-7a9a-c949-7109c583e710.png)

図では、各テストが何視点であるかが整理されています。
Q3には自動化のラベルがつけられていませんが、実際には、幾つかのテスト
(e.g. テストデータやユーザシナリオの準備)ではツールの利用が有効と書かれています。

# 3. テスト自動化のピラミッド

テスト自動化は各象限で利用することが可能ですが、テスト自動化に対して払えるコストは限られています。
テスト自動化のピラミッドは、テスト自動化を進めるべきテストレベルとその分量を
指し示すモデルであり、テスト自動化のROIを高めるために役に立ちます。
![テスト自動化のピラミッド.png](https://qiita-image-store.s3.amazonaws.com/0/114437/e2a32f2b-ed47-f6aa-71a2-4530e5bfd7aa.png)

この中間層のキャプションが少しわかりにくいので補足しますが、
本書によるとこれは、例の4象限のQ2の大半が含まれるようです。
例えば「ストーリー」テストや「受入」テスト、
単体テストに比べて大規模な機能集合をカバーするようなテスト等が含まれるようです。

この図のメッセージは以下のようなものです。

a. 下層のテストレベルにできる限り多くのテストを押し込める。
b. 如何に多くの自動テストがあっても、大半のシステムには手動テストが必要

さて、aの理由ですが、それは以下のようなものです。
1. 高速で素早いフィードバックがもたらされる
2. 実装コスト、メンテナンスコストが低い
3. テストが安定して動作する
4. スコープが狭いため、テストNG箇所の特定がしやすい

さて、bに関してですが、先ほどアジャイルテストの4象限で見たとおりですね。
探索的テストやユーザビリティテスト等、そもそも人でしかできないことがまだまだたくさんある、ということです。

# 4. まとめ

まとめます。本稿のメッセージは以下の3つです。

1. 繰り返し実行する価値のあるテストを自動化する。
2. そのために低レイヤーな単体テストを手厚くしよう。
3. 自動テストと手動テストを同格には扱わない。

次はピラミッドの各階層のテストについて書いていければと思ってます。
GAEへのデプロイ作業の自動化(RakeTask)


##環境
* ruby歴 初心者
* rails5
* ruby 2.4.1p111

##これはなに？
GAEにデプロイする際に、rake コマンドで staging 環境、production 環境で処理分岐できる task を書いてみました。
自動化といっても必要なファイルなどはまだ手動ダウンロードになってしまっているのですが、認証とプロジェクトの切り替えまで自動化したと言った感じです。

※ gcloud にアカウント認証情報がない場合は、途中でブラウザが開くので認証を行います。

config 設定自体を切り替える方法があるようですが
RakeTask での実現方法がわからなかったので
もし、できる方法があるのならば教えて頂けると助かりますm(_ _)m


##実装
```ruby:deploy.rake
namespace :deploy do
  desc "deploy to staging"
  task :staging do

    sh 'gcloud config set app/cloud_build_timeout 3600'
    sh "gcloud auth login #{ENV.fetch('DEPLOY_ACCOUNT_STAGING')}"
    sh "gcloud config set account #{ENV.fetch('DEPLOY_ACCOUNT_STAGING')}"
    sh "gcloud app deploy --project #{ENV.fetch('DEPLOY_PROJECT_STAGING')} --verbosity=info"
  end

  desc "deploy to production"
  task :production do

    sh 'gcloud config set app/cloud_build_timeout 3600'
    sh "gcloud auth login #{ENV.fetch('DEPLOY_ACCOUNT_PRODUCTION')}"
    sh "gcloud config set account #{ENV.fetch('DEPLOY_ACCOUNT_PRODUCTION')}"
    sh "gcloud app deploy --project #{ENV.fetch('DEPLOY_PROJECT_PRODUCTION')} --verbosity=info"

	//誤作動しないように gcloud の設定を staging 環境に戻しておきます。
    sh "gcloud config set account #{ENV.fetch('DEPLOY_ACCOUNT_STAGING')}"
  end
end

```

staging 環境へのデプロイ

```
bundle exec rake deploy:staging
```

production 環境へのデプロイ

```
bundle exec rake deploy:production
```

##課題
改善ポイントは、staging 環境、project 環境時それぞれに必要なファイルをダウンロードしてきて所定の位置に配置できるようにすることです！

現状、わざわざ GCS へアクセスして秘匿情報を取得してきて配置するフローになってしまっています。

##学んだこと
* gcloud コマンドでの環境切り替え

##参考
* [gcloud confing configurations コマンドでconfig設定を切り替える](http://qiita.com/kumanoryo/items/1fbd5302fc68a3980b5e)
* [[GAE]gcloudにおけるアカウント管理Add Star](http://d.hatena.ne.jp/noazoh/20150109/1420789296)
* [gcloud のリファレンス](https://cloud.google.com/sdk/gcloud/reference/?hl=ja)
Ruby 参照、浅いコピー、深いコピー


配列に対しての参照渡し、浅いコピー、深いコピーについてのメモ。

## 参照渡し
`=`を使用して配列の複製を行う。

```ruby:参照
a1 = "ruby java python".split
#参照渡し
a2 = a1
puts "a1：#{a1}"
puts "a2：#{a2}"
#配列オブジェクトが同じか確認
p a1.equal?(a2)
p a1.object_id
p a2.object_id
p a1[0].equal?(a2[0])
p a1[0].object_id
p a2[0].object_id
#配列に対して変更
a1.sort!
#配列内容の確認
puts "a1：#{a1}"
puts "a2：#{a2}"
#要素の値に対して変更
a1[0].capitalize!
#配列内容の確認
puts "a1：#{a1}"
puts "a2：#{a2}"
```
```:実行結果
a1：["ruby", "java", "python"]
a2：["ruby", "java", "python"]
true
70328621736780
70328621736780
true
70328621736740
70328621736740
a1：["java", "python", "ruby"]
a2：["java", "python", "ruby"]
a1：["Java", "python", "ruby"]
a2：["Java", "python", "ruby"]
```
配列もその中の要素も元の`a1`と変わらないことがわかる。
配列に対して`sort`を実行すると`a2`にも影響を受け
`a1`の要素0に対して`capitalize`を実行すると`a2`にも影響している。

![refBf.jpg](https://qiita-image-store.s3.amazonaws.com/0/188887/1ed24a9b-9ddb-a0f0-c63e-96d40789e449.jpeg "refBf.jpg")

↓↓↓　処理実行後　↓↓↓

![refAf.jpg](https://qiita-image-store.s3.amazonaws.com/0/188887/ed7cf1e3-287a-2a17-9311-cdea697a74b9.jpeg "refAf.jpg")


## 浅いコピー
`dup`を使用して配列の複製を行う。

```ruby:浅いコピー
a1 = "ruby java python".split
#浅いコピー
a2 = a1.dup
puts "a1：#{a1}"
puts "a2：#{a2}"
#配列オブジェクトが同じか確認
p a1.equal?(a2)
p a1.object_id
p a2.object_id
p a1[0].equal?(a2[0])
p a1[0].object_id
p a2[0].object_id
#配列に対して変更
a1.sort!
#配列内容の確認
puts "a1：#{a1}"
puts "a2：#{a2}"
#要素の値に対して変更
a1[0].capitalize!
#配列内容の確認
puts "a1：#{a1}"
puts "a2：#{a2}"
```
```:実行結果
a1：["ruby", "java", "python"]
a2：["ruby", "java", "python"]
false
70363447026880
70363447026740
true
70363447026860
70363447026860
a1：["java", "python", "ruby"]
a2：["ruby", "java", "python"]
a1：["Java", "python", "ruby"]
a2：["ruby", "Java", "python"]
```
配列のオブジェクトが違うことがわかる。
そのためソートを実行すると`a2`には影響がない。
ただし要素の値に関しては同一のものを参照しているため
`capitalize`を実行すると`a2`も値が変更されている。

![shallowCopyBf.jpg](https://qiita-image-store.s3.amazonaws.com/0/188887/2b09520a-f244-ae2c-6a93-11e7d3dc5889.jpeg "shallowCopyBf.jpg")

↓↓↓　処理実行後　↓↓↓

![shallowCopyAf.jpg](https://qiita-image-store.s3.amazonaws.com/0/188887/3546dbc2-63e5-da6a-b8ed-e8cdb04c8d9a.jpeg "shallowCopyAf.jpg")


## 深いコピー
`Marshal`を使用して配列の複製を行う。

```ruby:深いコピー
a1 = "ruby java python".split
#深いコピー
a2 = Marshal.load(Marshal.dump(a1))
puts "a1：#{a1}"
puts "a2：#{a2}"
#配列オブジェクトが同じか確認
p a1.equal?(a2)
p a1.object_id
p a2.object_id
p a1[0].equal?(a2[0])
p a1[0].object_id
p a2[0].object_id
#配列に対して変更
a1.sort!
#配列内容の確認
puts "a1：#{a1}"
puts "a2：#{a2}"
#要素の値に対して変更
a1[0].capitalize!
#配列内容の確認
puts "a1：#{a1}"
puts "a2：#{a2}"
```
```:実行結果
a1：["ruby", "java", "python"]
a2：["ruby", "java", "python"]
false
70194731237460
70194731242700
false
70194731241740
70194731242800
a1：["java", "python", "ruby"]
a2：["ruby", "java", "python"]
a1：["Java", "python", "ruby"]
a2：["ruby", "java", "python"]
```
配列とその要素いずれも同一でないことがわかる。
よって`sort`も`capitalize`のどちらの実行も`a2`に影響がない。

![deepCopyBf.jpg](https://qiita-image-store.s3.amazonaws.com/0/188887/4fd4984b-dd85-4358-be42-a908e5b8a9a0.jpeg "deepCopyBf.jpg")


↓↓↓　処理実行後　↓↓↓

![deepCopyAf.jpg](https://qiita-image-store.s3.amazonaws.com/0/188887/0f8d664c-083c-149c-857c-2c1e1bc7d346.jpeg "deepCopyAf.jpg")
numpy > numpy.ndarray.flags

```txt:動作環境
Python3 (ideone)
```

https://stackoverflow.com/questions/22053050/difference-between-numpy-array-shape-r-1-and-r
を見ていて以下を見つけた。

```py3
>>> a.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
```

試してみた。

http://ideone.com/l9jCC7

```py
import numpy as np
 
val = np.arange(12)
print(val.flags)
```

```txt:run
  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
```

https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flags.html


### link

[技術英語 > The OCM memory map can be reorganized so that it’s completely [contiguous] > continuous: 時間的連続 / contiguous: 地理的連続](http://qiita.com/7of9/items/c63ea0378b07aafcb95f)
numpy > reshape > 新しいviewを作成する

最近読んでいる本の中でviewについて書かれていた。

以下のリンク先でもviewについて書かれている。

https://stackoverflow.com/questions/22053050/difference-between-numpy-array-shape-r-1-and-r

> answered Feb 27 '14 at 16:26
Gareth Rees
...
> If we [reshape](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html) an array, this doesn't change the data buffer. Instead, it creates a new view that describes a different way to interpret the data. So after:

```py
>>> b = a.reshape((3, 4))
```
Aurora小ネタ／MySQLレプリケーションでのしくじりポイント

先に、**[オンプレMySQL～RDS for MySQL／Aurora間のレプリケーションにおけるタイムゾーン設定](http://qiita.com/hmatsu47/items/c8b573ec4839ca1e7394)**という記事を書きましたが、それ以外にもAuroraでのMySQLレプリケーションでいくつか問題に遭遇しましたので、書き残しておきます。

# しくじり1. そもそもレプリケーションが開始できない

Auroraがマスターになるケースで、

 * バイナリログの出力をON（MIXEDまたはROW）にした
 * バイナリログの保存期間も設定した（mysql.rds_set_configurationプロシージャで）
 * スレーブに対してREPLICATION SLAVE・REPLICATION CLIENT権限を付与した
 * スレーブ側でCHANGE MASTER TOコマンドはエラーにならずに通った

にもかかわらず、スレーブ側でSTART SLAVE後にレプリケーションが開始されない場合、セキュリティグループやNACL、ルートテーブル、（オンプレ環境にレプリケーションする場合）オンプレ側のファイアーウォールポリシーなどのネットワークの問題ばかり気にしがちですが（実際、そちらに原因があることも多い）、

**「MySQLのレプリケーションで設定可能なマスターホスト名は60文字までである」**

という制限に引っかかっていることもあります。

 * **[MySQL 5.6 リファレンスマニュアル／13.4.2.1 CHANGE MASTER TO 構文](https://dev.mysql.com/doc/refman/5.6/ja/change-master-to.html)**（ページ末尾の表を参照）

東京リージョンでAuroraのクラスターエンドポイント（IPアドレスではなくFQDN指定で）を使う場合、

 * 読み書き可能 : **【クラスター識別子】.cluster-XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com**
 * 読み取りのみ : **【クラスター識別子】.cluster-ro-XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com**

ということで、クラスター識別子以外の文字数が、前者で54文字、後者で57文字もあります。

つまり、**「クラスター識別子を極端に短く設定しないと、クラスターエンドポイントをMASTER_HOSTに指定できない」**（指定できるけど動かない）ということになります。

このクラスターエンドポイント、パブリック公開しない（＝プライベートIPアドレスが返る）場合でも外部から引くことができるので（RFC的にどうなの？というツッコミは一旦置いておいて）、オンプレ環境のスレーブサーバーとVPN等経由でレプリケーションする場合にも便利なのですが、こういうトラップもありますので、注意しましょう。

なお、最初のほうにさらっと、

 * バイナリログの保存期間も設定した（mysql.rds_set_configurationプロシージャで）

と書きましたが、この設定を忘れると（何事もなくレプリケーションを開始できてしまうのですが）予期せぬタイミングでレプリケーションが続行不能になる可能性があるため、こちらも注意が必要です（単位は日数ではなく時間＝hours）。

**8/1追記：**
コメントをいただきましたので補足します。
この件について回避策は書かなかったのですが（理由は**「状況によって最適解が変わってくるから」**です。極端な話、「特定のインスタンスのIPアドレスを直接指定する」というのが最適なケースもあると思います）、コメント欄に参考になる情報へのリンクを載せておきましたので、必要であればご覧ください。

# しくじり2. レプリケーションが途中で止まる

こちらも、原因は色々ありますが（レプリケーションを開始するときのマスター／スレーブの状態に差があった、読み込むバイナリログの開始ポジションを誤った、マスター側／スレーブ側でアクセス権限に差があるのに、うっかりマスター側にしか存在しないユーザーを変更／削除しようとした、など）、

**「Auroraでは、MySQL（5.6）の既知のバグが全てフィックスされているわけではない」**

点に注意が必要です。

私の場合、MySQLのBug #69861（MySQL 5.6.15でBug #17234370とともにフィックス）に引っかかって、

**[1]オンプレ ⇒ [2]Aurora ⇒ [3]オンプレ**

の環境で、**[3]オンプレ**へのレプリケーション時に**「LAST_INSERT_ID()の実行結果が0になる」**不具合に遭遇しました。

 * **[Bug #69861 | LAST_INSERT_ID is replicated incorrectly if replication filters are used](https://bugs.mysql.com/bug.php?id=69861)**

**[2]のAuroraでバイナリログの形式をMIXEDからROWに変更**することで解決しましたが、このようなレアなユースケース（まさか、AuroraをMySQLレプリケーションの「中継サーバー」に使うとは、AWSの中の人も思わない…？）で問題になるようなバグはフィックスされていない可能性があるので、本家MySQLのChangelogとAuroraのバグフィックス情報を見比べて確認しておいたほうが良いでしょう。

 * **[Amazon Aurora データベースエンジンの更新により修正された MySQL のバグ](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Aurora.DatabaseEngineUpdates.MySQLBugs.html)**

**[参考]**

 * **[Amazon Aurora : パラメーターから見るその詳細(Percona Data Performance Blogより)](https://yakst.com/ja/posts/3550)**（Yakstによる翻訳記事）


**2018/4/19追記：**
Bug #69861はバージョン1.17（2018/3/13リリース）でFixされました。

 * **[Amazon Aurora MySQL データベースエンジンの更新 (2018-03-13)](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/AuroraMySQL.Updates.117.html)**

---

**【おまけ】**
Amazon Aurora関連投稿記事へのリンクを集めました。

 * **[Qiitaに投稿したAmazon Aurora関連記事](http://hmatsu47.hatenablog.com/aurora)**
共通鍵暗号の暗号モード CTRについて


共通鍵暗号（ブロック暗号）の暗号モードには、特徴が異なるものがいくつか存在しますが、その中でも今回はCTRモード（Counter Mode）について掘り下げて記事にしたいと思います。
まずは、簡単に各モードの特徴について比較した上で、CTRモードのメリット・デメリットをまとめます。

# 暗号モードの特徴一覧

|モード|ランダム位置からの暗号化|ランダム位置からの復号|パディング要否|
|:----|:----|:----|:----|
|ECB|<font color="DeepPink">可能</font>|<font color="DeepPink">可能</font>|必要|
|CBC|不可|<font color="DeepPink">可能</font>|必要|
|CFB|不可|<font color="DeepPink">可能</font>|<font color="DeepPink">不要</font>|
|OFB|不可|不可|<font color="DeepPink">不要</font>|
|CTR|<font color="DeepPink">可能</font>|<font color="DeepPink">可能</font>|<font color="DeepPink">不要</font>|

* ランダム位置からの暗号化/復号というのは、任意のブロックに対して暗号化/復号できるかを表していて、これが可能な場合、暗号処理の並列化を行うことが出来ます。
* パディング要否というのは、平文がブロック長の倍数になっていない場合にパディングが必要かを表しています。
* CTRモードはスペック上最強に見える。

# CTRモードについて

## 暗号化の仕組み

Wikipediaより

![CTRモード暗号化](https://upload.wikimedia.org/wikipedia/commons/thumb/4/4d/CTR_encryption_2.svg/640px-CTR_encryption_2.svg.png)

![CTRモード復号](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/CTR_decryption_2.svg/640px-CTR_decryption_2.svg.png)

* Nonceとは使い捨ての乱数のこと([ノンス - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8E%E3%83%B3%E3%82%B9))
* ブロックごとにCounterを1ずつインクリメントして使うのが一般的。
* ノンスの桁数は特に決まっていない。（と思われる。）カウンター値がループしてしまわないような桁数を選ぶ必要がある。
* ノンスの受け渡し方法については記載を見つけられなかったが、恐らく暗号文の送信側か受信側のどちらかが生成した乱数を、暗号化の度に受け渡して共有するのだと思われる。

## 特徴
現在ではCBCモードと同様によく使われるモードである。

### メリット
- パディングが不要である。
- ブロックを任意の順番で暗号化/復号できる。（並列処理ができる）
- 復号する場合でも、暗号化アルゴリズムをそのまま利用するので、プログラムでの実装が簡単になる。
- ビット単位のエラーがある暗号文を復号した場合、平文の対応するビットのみがエラーになる。

### デメリット
- 暗号文ブロックをビット反転すると、対応する平文ブロックがビット反転する。

### 効率性
- CTRモードは、ECBやCBCモードとほぼ同程度に効率的である。

# 参考元
[暗号利用モード - Wikipedia](https://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%88%A9%E7%94%A8%E3%83%A2%E3%83%BC%E3%83%89#Electronic_Codebook_.28ECB.29)
[第4回暗号勉強会 ブロック暗号のモード - Google スライド](https://docs.google.com/presentation/d/1xxAtkuP3s_OysDWxLaMDOZQLn-0dfTqXiPnTpM3Gvsg/edit#slide=id.p)
[ブロック暗号の利用モード - Security Akademeia](http://akademeia.info/index.php?%A5%D6%A5%ED%A5%C3%A5%AF%B0%C5%B9%E6%A4%CE%CD%F8%CD%D1%A5%E2%A1%BC%A5%C9)
[ブロック暗号を使った秘匿を目的にした 利用モードの技術 ... - CRYPTREC](https://www.cryptrec.go.jp/estimation/rep_ID0205.pdf)
[AESのCTRモード(TLSとDTLS用) - まどぎわBLOG](http://mdgw.hateblo.jp/entry/20080207/1202392517)
[JCEでAES/CTRを試してみた - まどぎわBLOG](http://mdgw.hateblo.jp/entry/20080209/1202574181)
[【暗号化】ブロック暗号のモードまとめ (比較表付き) - Qiita](http://qiita.com/shoichi0599/items/6082b765c1257b71985b)
機械学習論文読みメモ_80


[Professor Forcing: A New Algorithm for Training Recurrent Networks](https://arxiv.org/abs/1610.09038), NIPS2016
Teacher forcing algorithmでは、RNNにおいて観測シーケンスを用いて学習を行い、テスト時には1つ前の入力に基づいた予測値を入力として用いたmulti-step samplingを利用する手法である。
本論ではこれを発展させたProffesor forcing algorithmを提案する。
この手法ではadversarial domain adaptationを応用し、観測シーケンスを用いた場合とmulti-step samplingを用いた場合のRNNのダイナミクスが一致するように学習を行う事とする。
この手法は正則化として効果がある。
またテスト時に生成されるデータの現実性も改善される。

[IMPROVING STOCHASTIC GRADIENT DESCENT WITH FEEDBACK](https://arxiv.org/abs/1611.01505)
目的関数からのフィードバックを利用したstochastic gradient descentの改善手法を提案する
この手法は目的関数の相対的な変化を追い、それに基づいて学習率を動的に変化させる。
このアイデアに基いて従来のadam最適化を拡張する。

[Understanding Deep Neural Networks with Rectied Linear Units](https://arxiv.org/abs/1611.01491)
ReLUに基づいたdeep netで表される関数について研究する。
本論では全体最適解に収束可能な多項式時間のアルゴリズムを提案する。
これは、関数が連続な区分線形関数により表される場合において成り立つ。
この証明のために区分線形な幾何を扱うtropical geometryの結果を用いる事ができる。
これによれば、区分線形関数は一層のdeep netで表現可能で、そのサイズに関するboundも導出可能である。
一方でsmoothにparameterizeされた関数を表すには指数関数的なサイズ増加が必要である事もわかった。
機械学習論文読みメモ_79


[Universal Correspondence Network](https://arxiv.org/abs/1606.03558)
geometricあるいはsemantic matchingのための手法としてdeep learningに基づく新たなフレームワークを提案する。
従来手法はパッチベースの類似度計算により擬似的にCNNを用いて計算を行っていた。
本論では、deep learningによりgeometricあるいはsemantic matchingを可能にした特徴表現を学習する。
新たに提案するcorrespondence contrastive lossを用いた学習により計算のreuseを可能にし、高速な学習を実現した。
またpatch normalizationを模擬するspatial transformor netを用いる事で性能を大幅改善出来た。

[Learning to Pivot with Adversarial Networks](https://arxiv.org/abs/1611.01046)
データ生成プロセスに関連した推論問題は常に不確かさを抱えている。
いくつかの説明力の高いデータ生成モデルが存在する事は、そもそも対象システムの曖昧さを示唆している。
データ生成モデル族をパラメタライズするnuisance paramterに対する影響の受けにくさを示すpivotという指標を導入する事でよりロバストな推論を可能にした。
本論ではadversarial netを用いる事で推論モデルにおけるpivot propertyを向上させる事を可能にした。
結果学習されるモデルは結局最適性とnuisance parametersに対する独立性のトレードオフになり、その中でもminimaxの解が得られた。

[Natural-Parameter Networks: A Class of Probabilistic Neural Networks](https://arxiv.org/abs/1611.00448), NIPS2016
Neural networkにおいてデータが十分でない場合、学習時に過剰適合に陥りやすい。
そのための対処法としてbayesian neural networkを用いる事は一つの手段である。
また別の問題として、データに応じて重みはニューロンの分布を適応的に変える事は難しい。
この対処としてはprobabilistic graphical modelが有効である。
上記問題に同時に対処する新たな手法として本論ではlight-weightなbayesian NNとしてnatural-parameter networks(NPN)を提案する。
NPNは任意の指数分布族を用いて重みやニューロンのモデル化を可能にする。
NPNが従来手法と異なる部分として、分布を入力とし、決定的に各層へfeedforwardさせる点がある。
この時マッチング計算のために分布を実際に生成（サンプリング？）する事のみが必要となるため効率的である。
これにより、中間層のuncertaintyも捉える事が可能になる。
機械学習論文読みメモ_78


[Synthesizing the preferred inputs for neurons in neural networks via deep generator networks](https://arxiv.org/abs/1605.09304)
DNNの構造を理解するための手法をして、各ニューロンがどのような特徴表現を獲得したかを見る事が一つの方法である。
このような手法の一つにあるニューロンのactivationを最大化させるような入力を探索するactivation maximization(AM)がある。
本論ではこの手法に対して、deep generator network(DGN)を用いた事前分布を用いて入力生成を行う事で性能を大きく改善させた。
このDGNは、現実的な入力を生成可能で、各ニューロンが獲得した特徴を理解可能な形で生成でき、また再学習する事なしに新たなデータセットに対しても利用する事が可能で、結果高い性能を持つ生成モデルと考える事ができる。

[Unsupervised Anomalous Vertices Detection Utilizing Link Prediction Algorithms](https://arxiv.org/abs/1610.07525)
ネットワーク構造内における異常なverticesを検出する手法を提案する。
このモデルは2層構造のmeta-classifierであり、ネットワークのトポロジーに基いて抽出される特徴を用いる。
まず始めにlink prediction classifierによりネットワーク内のedgeの存在確率を高精度で予測する。
続いて、その結果を用いてあるvertexがたくさんの存在確率の低いリンクを持っている場合に異常と判定を行う。

[Iterative Refinement of the Approximate Posterior for Directed Belief Networks](https://arxiv.org/abs/1511.06382), NIPS2016
Recongnition networkを用いたvariational methodsは事後分布の近似手法として注目されてきている。
しかしながら事後分布の表現手法としては、まだまだその表現能力に関して制限が大きく。結果モンテカルロ推定において分散が大きくなってしまう。
本論ではこの問題に対処するための手法としてinterative refinement procedureを提案する。
これにより分散を抑えた勾配推定が可能になる。
機械学習論文読みメモ_77


[Find Your Own Way: Weakly-Supervised Segmentation of Path Proposals for Urban Autonomy](https://arxiv.org/abs/1610.01238)
Weakly supervisedな運転可能領域セグメンテーション手法を提案する。
データ収集車の走行ルート情報を利用する事で、走行データに対して自動でアノテーションを行う事が可能である。
こうして得られたデータとラベルを利用する事でセグメンテーションモデルを学習する。
実際の推定においては、フロントモノラルカメラのみからリアルタイムで走行ルートを推定可能である。

[InfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets](https://arxiv.org/abs/1606.03657)
情報理論ベースのgenerative adversarial networkとしてInfoGANを提案する。
このモデルは教師なし学習が可能であり、対象のdisentangleされた表現を獲得可能である。
このモデルは、adversarialな目的関数だけでなく、観測と小さなサブセットの潜在変数との間で相互情報量を最大化する。
この潜在変数からサンプリングされた値に基づきデータが生成されるが、通常は特に構造を持たない確率分布に基いて潜在変数をサンプリングするのに対して、明確に対象のセマンティクスに対応した確率分布が学習される事になる。
この相互情報量に関する下界を導出し利用する事で、効率的な学習が可能になる。
例えばMNISTのデータに対して学習を行う事で、書き方のスタイルと数字のスタイルを分離してそれぞれの潜在変数にて学習する事が出来た。

[HYPERNETWORKS](https://arxiv.org/abs/1609.09106)
一つのhypernetworkと呼ばれるネットワークを用いる事で、新たなネットワーク構造とその重みを生成する。
この手法は生物学的に知られているgenotypeとphenotypeとの関係を抽象化している。
この手法はまたend-to-endで学習可能なため、従来手法とくらべて高速である。
本論の目的は、RNNやCNNで知られるような層間にweight sharingが行われているようなネットワークを用いるに対して有用な構造としてhypernetworkを提案する事にある。
提案したhypernetworkは一方でweight sharingがないようなLSTMを生成可能で、このネットワークがstate-of-the-artの性能を出す事ができた。
またCNN構造に関しても、画像認識タスクにおいて少ないパラメータ数でstate-of-the-artへ匹敵する性能を出す事が可能である。
機械学習論文読みメモ_76


[Convexifed Convolutional Neural Networks](https://arxiv.org/abs/1609.01000)
CNNにおけるparameter sharingを凸性仮定した構造の上で取り入れるconvexified convolutional neural networkを提案する。
非線形活性化関数をRKHS上のベクトルとみなす事で、CNNのパラメータは低ランク行列としてみなす事が可能になる。
この事で最適化問題は凸最適化問題へ緩和させる事が可能になる。
2層CNNに対してこの手法を用いる事で、汎化誤差が最適なCNNに収束する事を証明した。
さらに多層なCNNに関しては層毎の学習を行う事、実験的にbackpropagationによる最適化の場合と並ぶ性能を出す事が出来たい。

[Sequential Ensemble Learning for Outlier Detection: A Bias-Variance Perspective](https://arxiv.org/abs/1609.05528)
従来あまり提案されてこなかったアンサンブル手法を用いた異常検知手法を提案する。
この手法は従来手法と比較してbias-variance双方を低減する事が可能である。
分類問題と異常検知問題は異なった問題であるにもかかわらず、Bias-varianceトレードオフの文脈で考えた場合において似たような扱いが可能になる。
この時は異常検知は片方のラベルが観測されていない場合の2値分類問題とみなしてbias-variance分解が可能である。
本論で提案する逐次的なアンサンブル手法であるCAREは、中間結果を利用する2ステージの構成となっている。
従来手法は、互いに独立なdetectorの各結果を並行に出力しそれらを単純にアンサンブルするのに対して、本手法はさらに逐次的に結果をアンサンブルさせる。
これはまた逐次的に異常を除去する事でモデル改善にも利用される。

[Enabling Dark Energy Science with Deep Generative Models of Galaxy Images](https://arxiv.org/abs/1609.05796)
宇宙に膨張に関わりがあるとされるダークエネルギーに関する理解は重要である。
この研究のためには、遠くにある銀河の構造をできる限り正確に推定する事が大事である。
しかし従来手法で誤差を回避するために、正確なキャリブレーションが要求される。
キャリブレーションを正確に行うためには大量の銀河画像が必要である。
この目的のためにadversarialな目的関数を利用して学習したconvolutional generative modelを提案する。
これによって生成される高精度な画像を利用する事で、高コストな実際画像の取得数を低減する事が可能になる。
Railsのログローテーション


syslog(SyslogLogger)を使う方が良いのかな？という感じもしましたが、とりあえずログの肥大化だけなんとかできれば良かったので、logrotateを使ってみました。ubuntuだと、以下のファイルを置くだけ。

``` /etc/logrotate.d/rails
/var/www/app1/current/log/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  copytruncate
}

/var/www/app2/current/log/*.log {
  :(省略)
}
```

試しに動かしてみるには以下のようにコマンドを実行します。

```
sudo /usr/sbin/logrotate -f /etc/logrotate.conf
```

##　参考URL
https://stackoverflow.com/questions/4883891/ruby-on-rails-production-log-rotation
https://gorails.com/guides/rotating-rails-production-logs-with-logrotate
Eclipse 4.6.3 に Spring Tool を入れるには?

# はじめに

EclipseでSpring Frameworkを使った開発をするにはどうすればよいかという質問を受けたので、導入部分としてSpring Toolを入れる方法を書いてみた。

# 用意するもの

- Eclipse 4.6.3 (Pleiadesで日本語化されたもの)

# 操作 

## メニュー「ヘルプ」→「Eclipseマーケットプレース」を選択。 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19974/16ef5ab7-11ed-ebf8-ff7a-0333479c7cf7.png)

##「検索」ボックスに「Spring tool Suite」と入力。
## 「Go」を選択。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19974/276323ac-59c7-bd9f-e1f9-c6d126e21651.png)

## Spring ツールを「インストール」

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19974/f9f3230a-7f09-4c86-6088-e98a572e194d.png)

## 「確認」を選択。

しばらく待つ。

## 「ライセンスのレビュー」で各ライセンスを確認する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19974/6ca1c4d0-8318-38c5-80c8-e779782dcab2.png)

## 問題なければ「使用条件の条項に同意します」を選択、「完了」を選択。

「ソフトウェアのインストール」が始まるので再起動を促されるまで待つ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19974/4b4d6cc0-2e87-4b36-e2ee-3a278e6a4225.png)

## 「再起動しますか?」で「はい」を選択。

## 「ようこそ」が表示されたら、完了

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19974/95407375-396f-3542-3cba-fc964310e44b.png)

左上の「復元」ボタンを選び、開発を開始する。


# 他の手段

Spring Tool Suiteを直接installするという手もある。
https://spring.io/tools

# 参考文献
https://www.amazon.co.jp/dp/4798041564
Viewをタップした時にRipple Effectをさせる。


結論から言うと、 ViewのレイアウトXMLの属性値に以下の1行を加えればokです。
APIレベル21以上のOSの端末であれば、タップされた際に波紋のように反応するようになります。

```Java
android:background="?android:attr/selectableItemBackground"
```
 

 例えば、EmptyActivityの「Hello World!」のTextViewに適用させるときはこんな感じになります。

```Java
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.h_ujikawa.myapplication.MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
```
 


(ブログにも書いています。)
[カブトムシのつぼ](http://namaninotiteti1026.hatenadiary.jp/entry/2017/07/22/222958)
VBSの日付順ソートと世代管理

ごあいさつ

はじめまして、ほげほげおじさんです。
仕事で使ったコマンドだとか備忘録をまとめたいなぁと思っていたところ、このサイトに出会いました。

今回は仕事で初めてVBSを使ってフォルダのローテーションをすることになり、以下に思い出を残したいと思います。

■前提条件
1.フォルダ自体は別プログラムで月ごとに作成される。
2.作業によるフォルダ更新はOK
3.世代管理は必ず作成日付が新しいフォルダを2世代分のこす。

■事前に用意しておくもの
1.設定ファイル(sample.txt)
＝＝＝＝＝設定ファイルの中身＝＝＝＝＝
BakFol="E:\Backup"
BakLen=2
GenNum=3
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

2.作成日付と更新日付を変える魔法
Powershell起動
Set-ItemProperty E:\Backup\01 -Name CreationTime -Value '2017/01/01 00:00:01'
Set-ItemProperty E:\Backup\02 -Name CreationTime -Value '2017/03/01 00:00:01'
Set-ItemProperty E:\Backup\03 -Name CreationTime -Value '2017/05/01 00:00:01'
Set-ItemProperty E:\Backup\04 -Name CreationTime -Value '2016/07/01 00:00:01'
Set-ItemProperty E:\Backup\05 -Name CreationTime -Value '2016/09/01 00:00:01'
Set-ItemProperty E:\Backup\06 -Name CreationTime -Value '2016/11/01 00:00:01'
Set-ItemProperty E:\Backup\test -Name CreationTime -Value '2017/02/01 00:00:01'

Set-ItemProperty E:\Backup\01 -Name LastWriteTime -Value '2017/01/01 01:00:00'
Set-ItemProperty E:\Backup\02 -Name LastWriteTime -Value '2017/03/01 02:00:00'
Set-ItemProperty E:\Backup\03 -Name LastWriteTime -Value '2017/05/01 03:00:00'
Set-ItemProperty E:\Backup\04 -Name LastWriteTime -Value '2016/07/01 04:00:00'
Set-ItemProperty E:\Backup\05 -Name LastWriteTime -Value '2016/09/01 05:00:00'
Set-ItemProperty E:\Backup\06 -Name LastWriteTime -Value '2016/11/01 06:00:00'
Set-ItemProperty E:\Backup\test -Name LastWriteTime -Value '2017/02/01 12:00:00'

■スクリプト(test.vbs)
Option Explicit

Const conCNF = "C:\tmp\sample.txt"
Const adDBTimeStamp = 135
Const adVarWChar = 202

Dim FSO
Dim ADOR
Dim GF

Dim Path
Dim Created
Dim LastModified
Dim SubFolder

Dim BakLen
Dim GenNum

On Error Resume Next

Set FSO = CreateObject("Scripting.FileSystemObject")
Set ADOR = CreateObject("ADODB.Recordset")

ExecuteGlobal FSO.OpenTextFile(conCNF).ReadAll()

Set GF = FSO.GetFolder(BakFol)

ADOR.Fields.Append "Path", adVarWChar, 255
ADOR.Fields.Append "Created" , adDBTimeStamp
ADOR.Fields.Append "LastModified" , adDBTimeStamp
ADOR.Open

'サブフォルダの情報をゲット
For Each SubFolder In GF.Subfolders
    If Len(SubFolder.Name) = BakLen Then
        ADOR.AddNew
        ADOR.Fields("Path").Value = SubFolder
        ADOR.Fields("Created" ).Value = SubFolder.DateCreated
        ADOR.Fields("LastModified" ).Value = SubFolder.DateLastModified
        ADOR.Update
    End If
Next

' 作成日時順(昇順)でソート
'ADOR.Sort = "Created ASC, Path"

' 作成日時順(降順)でソート
ADOR.Sort = "Created DESC, Path"

' 更新日時順(昇順)でソート
'ADOR.Sort = "LastModified ASC, Path"

' 更新日時順(降順)でソート
'ADOR.Sort = "LastModified DESC, Path"

' 変数調整
GenNum = GenNum - 1

' 3世代目のバックアップフォルダ(レコード)に進む
'ADOR.MoveFirst
ADOR.Move(intGenNum)

' 3世代目以降のバックアップフォルダを削除
Do Until ADOR.EOF
  FSO.DeleteFolder(ADOR.Fields("Path").Value)
  If Err.Number <> 0 Then
    Wscript.Quit 1
  End If
  WScript.Echo ADOR.Fields("Path").Value & vbCrLf & _
               ADOR.Fields("Created").Value & vbCrLf & _
               ADOR.Fields("LastModified").Value
  ADOR.MoveNext
Loop

ADOR.Close

On Error Goto 0

Set FSO = Nothing
Set ADOR = Nothing
Set GF = Nothing

WScript.Quit 0

■参考サイト
http://itemy.net/?p=406
http://bayashita.com/p/entry/show/76
Heat Map for  Grid Search with Matplotlib


## Grid Search
http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html
First, for grid search method, you need to select which parameters are used for the optimization and define parameter sets. 

```
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer

learner = RandomForestClassifier(random_state = 2)
n_estimators = [12, 24, 36, 48, 60]
min_samples_leaf = [1, 2, 4, 8, 16]
parameters = {'n_estimators': n_estimators, 'min_samples_leaf': min_samples_leaf}
```

In this case, AUC is used as a scorer. Thus, you need to create you own scorer for AUC.

```
def auc_scorer(target_score, prediction):
    auc_value = roc_auc_score(prediction, target_score)    
    return auc_value

scorer = make_scorer(auc_scorer, greater_is_better=True)
```

Finally, you can define Grid Search Object.

```
grid_obj = GridSearchCV(learner, parameters,  scorer)
```

## Heat Map
http://scikit-learn.org/stable/auto_examples/svm/plot_rbf_parameters.html
To create a heat map, you need to have 2 dimentional matrix at first. From Grid Search Object, you can retrieve all prediction results corresponding to grid search parameter set. In the example below, all result are put into `scores` .

```
scores = grid_obj.cv_results_['mean_test_score'].reshape(len(n_estimators),len(min_samples_leaf))
```

Note: `scores` contains the following array.

```
[[ 0.91803961  0.92444425  0.9264368   0.92730609  0.92808348]
 [ 0.91263539  0.91757799  0.91892211  0.91957058  0.91950196]
 [ 0.90143663  0.90590379  0.90669241  0.90751479  0.90758263]
 [ 0.89168321  0.89370183  0.89414698  0.89497685  0.89506426]
 [ 0.88276445  0.88386261  0.88380793  0.88408826  0.88448689]]
```

Then, you can use `scores` for plotting a heat map.

```
plt.figure(figsize=(8, 6))
plt.subplots_adjust(left=.2, right=0.95, bottom=0.15, top=0.95)
plt.imshow(scores, interpolation='nearest', cmap=plt.cm.hot)
plt.xlabel('n_estimators')
plt.ylabel('min_samples_leaf')
plt.colorbar()
plt.xticks(np.arange(len(n_estimators)), n_estimators)
plt.yticks(np.arange(len(min_samples_leaf)), min_samples_leaf)
plt.title('Grid Search AUC Score')
plt.show()
```

Finally, you can plot a heat map like below.

![image](https://qiita-image-store.s3.amazonaws.com/0/186167/ba0f5bbc-afa1-88ea-0a22-7c4dbd94352a.png)
BigQueryのバッチデータ投入の特徴

下記記事のメモ。画像はリンク先から参照。
https://medium.com/google-cloud/paying-it-forward-how-bigquerys-data-ingest-breaks-tech-norms-8bfe2341f5eb

BigQueryはDremelとColossus、そしてBorgとJupiterネットワークと連携し、ユニークなアーキテクチャをしている。BigQueryでのデータロード特徴は以下のとおり。

# バッチデータ投入にクエリ能力を消費しない
データ投入にはリソース(データ転送する際のネットワーク、暗号化や最適化、暗号化するためのCPUやRAM、データを書き込むためのI/O)が必要になる。HadoopやRedshiftなどでは、データ投入するのにクラスタのリソースが消費され、データ分析に影響がでる。
BigQueryではバッチ投入に使用されるリソースはクエリのリソースとは分離されてる。そのため、どれだけ大量のデータを投入しても、データ分析には影響がない。

![スクリーンショット 2017-07-23 8.49.36.png](https://qiita-image-store.s3.amazonaws.com/0/95399/eee60c88-b5f2-af41-a8f2-ffb9b358b43b.png)

# バッチ投入は無料
BigQueryのバッチ投入にはコストがかからない。Redshiftではクラスタを用意しないとデータ投入できないのでコストがかかり、AthenaだとS3上のファイル作成と管理のオーバーヘッドがある。

# アトミックなデータロード
ロードに失敗する場合は100%データが失敗、すなわち中途半端にデータが残ることがないので、失敗したときのクリーンアップ処理が必要ない。ロードに失敗した場合はリトライすればよい。

# BigQueryはロードに大量のCPUとRAMを消費する 
BigQueryではクエリのリソースをデータロード時に消費しないが、裏では大量のリソースを使ってデータをロードしている。Capasitorストレージフォーマットは継続的にデータ全体をプロファイリングし最適化するため大量のリソースをデータロード時以外にも使用している。

# データ投入は無制限
BigQueryはクォータを持っており、デフォルトでは1日当たり数十TBのデータが投入が可能である。いくつかの顧客は1日当たり1PBを超えるデータをロードしている。

# Federated Queryは有償のバッチロードである 
BigQueryはGCSのデータに対して直接クエリをかけることができる。このクエリは通常と同じようにクエリコストがかかる。クエリをかけた結果をBigQueryにロードすることができる。ある意味、有償のバッチロードである。