OmniAICreator/Qiita-1.07M huggingface dataset:
自社のQAエンジニアって何をしているのかとテスト文化を根付かせるには

# 長いタイトルになってしまいましたが「自社のQAエンジニア」って何をしているのか？？

![FireShot Capture 004 - 自社のQAエンジニアって何をしているのかとテスト文化を根付かせるには - QAエンジニア blog - qatest.hatenablog.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/910178f5-dc7e-64fc-3fbc-273cead03855.png)
この画像は特に文章との関連はありません。

基本は、**「リリースマネージャ」** が居なければ、そこを巻き取るところから。

1.リリースフローの策定とフローの更新
2.リリース計画の作成と関連部署との調整
3.外部折衝やメンバーの管理とスケジュール管理（マネージャがいない場合）
4.メンバー採用計画をする（マネージャがいない場合）
5.メンバー採用の面接をする（マネージャがいない場合）
6.テスト計画書を作る（一つ作ればよい）
7.テスト設計書を作る
8.テスト仕様書を作る
9.テスト実施をする（ブラックボックスは基本テスターがやるが）バックエンドのテスト（ ログ確認や、プロキシツールを使用したパラメータの書き換え、負荷テスト、簡単なセキュリティテスト、ボリュームテスト）
10.テスト実施報告
11.不具合管理分析
12.不具合の傾向を分析しテスト設計に
13.テストツールの選定
14.不具合管理指標を用いたリリース判定
15.テスト自動化（SETエンジニアが居なければ）仮想環境を構築しCIで朝と夕に、リグレッションテストできるような仕組みをつくる
16.ドキュメントの整備
17.テストデータの作成
18.検証端末の管理（バージョンや機種）
 

# テスト文化を根付かせるには
:point_up:特にスタートアップやベンチャー企業
 
1.開発者と単体テストルール作成を行う
2.単体テストでOKになったもの以外、やり直しさせる
3.不具合管理指標を作りリリース判断の材料にする
4.直交表を用いた組み合わせテストを実施
5.QA主催の勉強会を実施し、開発者の苦手な部分を一緒に考える
6.単体テストでスルーした時のコストを提示する（1件、1万ですよとか）
7.不具合が出たときの状況を共有し、損害や影響度がどうなるか想定してみる
8.テストを実施した時と、しない場合の不具合件数を調査する
9.全ての品質（プロジェクト品質、スケジュール品質、作業品質、コミュケーション品質、ドキュメント品質、開発品質、リリース品質、運用品質）に対しての振り返り
10.テストは全てQAがやるものではなく、開発エンジニア、PMにも協力してもらい進める。
11.テストフローを作成し、開発が担保すべきレンジ、QAが担保すべきレンジを明確化し、リリースまで進める。
 
いろいろあります！！
「どうぶつの森ポケットキャンプ」で使われているOSSライブラリ

- The POCO C++ Libraries
    - https://github.com/pocoproject/poco
- Protocol Buffers
    - https://github.com/google/protobuf
- MiniJSON
    - https://gist.github.com/darktable/1411710
- OpenSSL
    - https://github.com/openssl/openssl
- protobuf-net
    - https://github.com/mgravell/protobuf-net
- UniRx
    - https://github.com/neuecc/UniRx
- Facebook SDK for Unity
    - https://github.com/facebook/facebook-sdk-for-unity
- Unity UI Samples
    - https://github.com/tsubaki/Unity_UI_Samples
- StringBuilderTemporary
    - https://github.com/wotakuro/StringBuilderTemporary
- adjust Unity SDK
    - https://github.com/adjust/unity_sdk
- Flatbuffers
    - https://github.com/google/flatbuffers
- iTween
    - http://www.pixelplacement.com/itween/index.php
- EASING EQUATIONS
    - http://robertpenner.com/easing/
    - https://code.google.com/archive/p/wpf-animation/
- Firebase-Unity
    - https://github.com/firebase/Firebase-Unity
- Google Play Games plugin for Unity
    - https://github.com/playgameservices/play-games-plugin-for-unity
- UGUI Unity
    - https://bitbucket.org/Unity-Technologies/ui
3行でRailsを動かすためだけVMを用意する Vagrantfile

# 使い方
`vagrant`と`git`が使えるマシンで以下を実行するだけ。(Windowsで動きました)

```bash
git clone https://gist.github.com/b77a90d54ae695bf325500e1b90df118.git your_vm_name
cd your_vm_name
vagrant up
```

# 中身
QiitaはGistをペタっと貼れないので下のリンクから見てください。
Vagrantfileから起動時にprovision.shを実行するだけのやつです。
[Vagrantfile (only for run Rails 5) (OS: Ubuntu 14.04, Software: rbenv, Ruby 2.4.1, Node.js, SQLite3)](https://gist.github.com/redshoga/b77a90d54ae695bf325500e1b90df118)

# 参考にした記事
下のものほぼまんまです。vagrantユーザーで実行させる方法がわからずに詰んでいたから助かりました!
[Vagrantのprovisioningでrbenvを使ってrubyをインストールする](https://qiita.com/masayuki14/items/1cb1aba4242d77b88503)

シェルスクリプトをほぼ知らなかったので助かりました。
[シェルスクリプト(bash)のif文とtestコマンド([])自分メモ](https://qiita.com/toshihirock/items/461da0f60f975f6acb10)

# 宣伝
フォローお願いします。 :tiger: [@redshoga](https://twitter.com/redshoga)
ちょっとずつ読むドメイン駆動設計 第三部 より深い洞察へ向かうリファクタリング 第十章 しなやかな設計3 副作用のない関数

# これまでの第十章
- [序章](https://qiita.com/YasuhiroKimesawa/items/c240451e6746497fd446)
- [意図の明白なインターフェース](https://qiita.com/YasuhiroKimesawa/items/988ed817de9aac785633)

# 副作用のない関数

## 2種類の操作
- クエリ・・・システムから情報を取得する操作
- コマンド・・・システムに何かしらの変更を与える操作

上記の2種類の操作がある中で、問題になるのは「コマンド」です。

## 副作用

たとえば、あるコマンドを実行し、システムの状態を変更した後に、同じコマンドを同じように実行したらエラーになってしまったり、別の状態になってしまうとかありますよね。
こういう状態を**副作用**と言ったりします。

これがまた、コマンドから複数のメソッドを呼び出していたりすると、コマンドを実行したところ、どういう結果になるのかがわからなくなります。

## 副作用のない関数

ただ、コマンドを利用しないわけにはいきませんので、副作用の起こさないように実装することが大事になってきます。
同じコマンドを同じように実行したら同じ値が返って来る操作を**関数**といいますね。

関数を利用すれば、テストもしやすくなりますし、操作の中身もわかりやすくなるはずです。

## どう実装するか

①． コマンドとクエリを分ける。同じ操作で２つのことをしない

コマンドとクエリを一緒におこなわないこと。クエリでドメインの中身を変更しないこと。コマンドでクエリの結果を返さないことです。

②. オブジェクトを変更するのではなく、処理の結果を反映した新しい値オブジェクトを返す

[値オブジェクト](https://qiita.com/YasuhiroKimesawa/items/8d539d8ecdce2665bc20)のところでも読みましたが、オブジェクトを不変にすること。

"ロジックや演算"と"状態の変更"の操作を分離し、"ロジックや演算"を値オブジェクトへ移動する。"状態の変更"は新しい値オブジェクトを返す。

こうすれば、副作用がない（何度実行しても同じ値が返る）関数を実装できます。

実際、よく実施しているリファクタリングではありますが、こうして整理すると納得感が増しますね。

## 問い合わせと更新の分離[[リファクタリング](https://www.amazon.co.jp/dp/427405019X)]

MartinFowlerも同じことを言っていますね。リファクタリングのパターンにも含まれています。
pythonコードまとめ（初級）

#目的・概要
pythonの勉強をし始めた。
本を読んでコードを打つだけでは不安なのでポイントとなるコードをここにまとめる

#基本

```py
#コメント

#複数行に渡る文字列
a="""
こんにちは
こんばんは
"""

#変数(型宣言不要)
a=10

#文字列中の変数の挿入
a="""
こんにちは
こんばんは
{0}
{1}
""".format(a, b)

#入力（文字列型）
a=input("入力してください")

#if分岐
if a==10:
    a+=1
else:
    a-=1

#繰り返し(0-9までが印字)
for i in range(10):
    print(i)
```

#リスト型etc.

```py

#リスト
b = [1,2,3,4,5]

#リストを使った繰り返し(1-5までが印字)
for i in b:
    print(i)

#リストの結合
a = b + c

#スライス
a = [10, 20, 30, 40]
a[1:3]
>>>[20, 30]

#タプル
c = (1,2,3,4,5)

#集合型
d = {1,2,3,4,5}

#辞書型
e = {"一月":1, "二月":２, "三月":3}

#キー一覧の取得（listに変換の必要あり)
e.keys()

#値の一覧の取得（listに変換の必要あり)
e.values()
```


#関数について

```py
#基本形
def add(a, b)
    '''docstring'''
    c = a+b
    return c

#docstringを確認
help(add)
```

#終わりに
まだまだ勉強しないといかんですね
Visual Studio Codeでmarkdownを書くときに便利な組み合わせ見つけたから晒す

# 履歴

- 2018/5/6
    - Markdown Preview Enhancedを追加

# 目的

個人的にVSCodeでmarkdownを記述する際に良さげな組み合わせを見つけたのでメモ。
"もっといいのあるよ" 提案歓迎。

# VSCodeのmarkdown系拡張機能

以下を利用してる。

- [Auto-Open Markdown Preview](https://marketplace.visualstudio.com/items?itemName=hnw.vscode-auto-open-markdown-preview)
- [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
- [Paste Image](https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image)
- [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
- [Markdown Preview Enhanceed](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)


Markdown all in oneも入れてるけど、全くもって使いこなせてないので一旦外してる。

## Auto-Open Markdown Preview

markdownファイル(.md)を開くと自動でプレビューしてくれる拡張機能。

![Kobito.5Zb1T8.png](https://qiita-image-store.s3.amazonaws.com/0/40692/395ce7b8-2b0b-64d1-fd53-36b782c1aed1.png "Kobito.5Zb1T8.png")

## markdownlint

Lintしてくれるだけ、なくてもいいかも。

## Markdown Preview Mermaid Support

markdown中にmermaid.jsで記述した図を挿入できる。

![Kobito.AntAhP.png](https://qiita-image-store.s3.amazonaws.com/0/40692/e061f518-81f5-baac-32b9-5be34383e9a1.png "Kobito.AntAhP.png")

mermaid.jsについてはこちらを参照。
- https://mermaidjs.github.io/
- [mermaid.jsが素晴らしいけどなかなか使ってる人見かけないので実例晒す(追記あり)](https://qiita.com/uzuki_aoba/items/a01f8b0b52ced69c8092)


## Paste Image

クリップボードに取り込んだ画像をpngに変換してmarkdown中に貼り付けられる機能。
デフォルトではファイルはmarkdownのファイルと同一ディレクトリに保存。

macの場合は 
1. Ctrl + Shift + Command + 4 で範囲選択してスクショ取得&クリップボードに取り込み
2. Option + Command + v でmarkdownファイル中に貼り付け


![Kobito.XaKMqG.png](https://qiita-image-store.s3.amazonaws.com/0/40692/30271340-b4ac-1a9b-d06e-0f29beddbb71.png "Kobito.XaKMqG.png")

## Markdown PDF

markdownのファイルをPDFに変換。
(PDFの確認には、vscode-pdfを使って確認)

# Markdown Preview Enhanced

デフォルトの動作よりも大分軽快かつ、アウトライン表示などもあって使いやすいかも。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/bc06c175-4bdf-0d9d-670c-6f5333759b2b.png)
YYPHP#16 イベントレポート「Laravelらしい書き方、PHP5.1環境の作り方、Laravelのコードを追う、Vue.js、CakePHP」

これは2017年11月22日に開催したPHPerイベント[YYPHP#16]のイベントレポートです。

[YYPHP]は一言で「PHPerの部室」です。PHPについて、雑に、ゆるく、ワイワイ話し合う集いです。毎回お題を決めずに雑談を出発点にいろいろなことを突発的にやります。集まった人でコードリーディングをすることもあれば、一緒に開発ツールを触ってみたり、フレームワークについての情報交換をすることもあります。開催は**毎週**水曜19:00に高田馬場にて。

[YYPHP#16]: https://yyphp.connpass.com/event/70012/
[YYPHP]: https://yyphp.connpass.com/

## 参加者

* 8名
* PHP歴の分布
    * 10年〜: 3名
    * 3年: 1名
    * 数ヶ月: 2名
    * 1年ちょっと: 1名
    * 1年弱: 1名

## Cakeのすごいところ

* 日本語の情報が多い(Cake2)。Cake3は少ない？

## Laravelらしい書き方

* Controllerに来る前にバリデーションできる
    * アクションがシンプルにできる
    * [バリデーション 5.2 Laravel](https://readouble.com/laravel/5.2/ja/validation.html)
    * [Laravelバリデーション指南書：フォームリクエストを使おう - Qiita](https://qiita.com/sakuraya/items/abca057a424fa9b5a187)
* クエリービルダーをController
* 機能ごとにディレクトリ(名前空間)を分けて、MVCをつくるのがおすすめ。

## PHP in Dockerのリモートデバッグ(Linux環境) 

* [Debug PHP in Docker with PHPStorm and Xdebug](https://gist.github.com/chadrien/c90927ec2d160ffea9c4)
* Macの人はこっちのほうが参考になりそう。
    * [PhpStorm + Docker for Mac（docker-compose）での PHPUnit と Remote Debug の設定 - Shin x Blog](http://blog.shin1x1.com/entry/setup-test-and-debug-on-phpstorm-and-docker-for-mac)

ホスト側にIPアドレスのエイリアスを貼る:

```
sudo ifconfig en0 alias 10.254.254.254 255.255.255.0
```

コンテナの中から疎通するかテスト:

```bash
docker-compose exec php sh
apt-get intall netcat
nc 10.254.254.254 9000
```

## PHP5.1環境の作り方

* PHPをコンパイルして入れる
* Dockerfileを検索してそれを参考にするのが早いと思う。
* [レガシーなLAMP+memcacheシステムのDockerFileを書いてみた - Qiita](https://qiita.com/terui-yuki/items/e19c3a281b567a66d7d4)

## Laravelのコードを追う

* Authのロジックを追ってみる
    * AliasLoaderがエイリアスをロードしている
        * 実体名で探せない場合は、ルール下で自動的に読み込まれたりしているので、分からない場合はそういう部分を探してみる
    * "function guard" でgrepして本体を探す

## Vueのインスタンス

* どういう粒度で作ればよいか

## Laravelの勉強法

* Laracast
* 公式のドキュメント
* [Laravel Book and Learning Center | Learning Laravel](https://learninglaravel.net/)
    * Laravelのチュートリアル

## その他

* 家族でSlack
    * LINEがいや
    * 家族でウォッチしているブログの更新通知を受け取ったり
    * LINEはPCがしょぼい


## 参加者の感想「今回参加してよかったことは何ですか？」

* 新しくシステムを作るのにLaravelを使おうかなと思っているのでLaravelの使い方をなんとなくだが見ることができたのはよかった
* 予想以上にいろいろ聞ける
* コードレビューを頂けたので良かった
* 楽しかった

## YYPHPは毎週やってます

PHPについてワイワイ話したい方は、[YYPHPのイベント情報](https://yyphp.connpass.com/)をチェックしてみて下さい。

以上、YYPHPのレポートでした。次回もワイワイやっていきたいと思います！ では、また来週！
jQuery 1.0の頃の世界と今を比較してみる

時代が進みすぎた結果、今となっては存在感も薄れていくjQueryですが、数年前まではJavaScriptライブラリの王道と言っていい地位を占めていました。では、時計の針をjQuery誕生の頃まで戻して、どんな位置付けだったか見ていきましょう。

# jQueryがリリースされた頃の世界

jQueryの初リリースは2006年とのことですが、この頃Webブラウザ界はどんな世界線だったのか振り返ってみましょう。

* Internet Explorer…7のリリースが2006年後半
* Firefox…1.0、1.5、2.0
 * Netscape…8（Mozillaベース）
* Safari…2.0
* Chrome…**誕生前**（初版が2008年）
* iPhoneもAndroidもリリース前

ということで、時代はIE vs Netscapeのブラウザ戦争が片付いた結果、「ブラウザごとにAPIも何もかも違う」という状況はひとまず解決したものの、まだまだDOM実装にはブラウザごとの差異がある、というような環境でした（IEに`addEventListener`が登場したのは、IE 9での話です）。そして、要素の検索メソッドも`getElementById`、`getElementsByName`、`getElementsByTagName`ぐらいしかなく、IE 6ではXHRも`ActiveXObject`として実装されている、というように、現代の水準からすればない物づくしでした。

# jQuery 1.0の水準

現在のjQueryサイトでも[1.0からあったもの](http://api.jquery.com/category/version/1.0/)を抽出できますが、そこで揃っていたメソッドは、現在のjQueryと基本的に同じようなものです（後から追加された機能もちょくちょくありますが、`.closest`が1.3から、`Deferred`や`.prop`が1.6から、`.on`が1.7からという感じです）。

* セレクタ1つでエレメントの検索ができる`$()`
* DOMのルールに従って正しくバブリングし、ブラウザを問わず同じ形でセットできるイベント（※）
* エレメントに結びつけてもメモリリークしない、イベントハンドラやデータ構造（※）
* スッキリとメソッドチェーンで書ける利便性
* `window.load`より早いタイミングで動作する、`$(関数)`
* 便利に使えるAjax関数

この時代背景を踏まえれば、当時のjQueryがどれだけ便利な存在だったか、想像できることかと思います。

# 現代に至る変化

さて、このjQueryが提供していた利便性ですが、ブラウザ自体の進化により、次第に魅力を減じていくこととなります。セレクタは`document.querySelectorAll`でブラウザネイティブの取得ができるようになり、IEもDOMをしっかり実装していった結果、ブラウザごとの実装をjQueryで吸収する必要も減ってきました。アニメーションもCSSアニメーションのほうが負担が軽いということで、jQueryのをゴリゴリ使う時代でもなくなっています。


`$(関数)`も`DOMContentLoaded`としてブラウザイベントとして取れるようになる、jQueryのクラス系のメソッドと同様なものが`classList`に実装される、[`.closest`がネイティブ実装される](https://qiita.com/jkr_2255/items/3fecd90513affa02d515)など、jQueryに影響を受けたと思しきDOMの実装すら存在するようになっています。

このようにして、「クロスブラウザ」と「便利なメソッド」の利点がなくなっていき、そして仮想DOMが全盛となって直接DOM操作すること自体がバリバリ行われるものではなくなってきた中、jQueryに残ったものは「メソッドチェーン」、「簡潔なメソッド名」と「jQueryプラグイン」ぐらいかな、という感じです。
文字列連結の+と加算の+

###文字列連結の+と加算の+
JavaScriptの+は、文字列連結に使うときと、加算に使うときがあるので、気をつけてください。
例えば、以下のようなコード

```Javascript
var name = 'Daisuke';
var age = 38;

console.log(name + age);//Daisuke38
```
ここでは、ageが文字列に変換されて、nameと連結されています。
それに対して、

```JavaScript
var name = 'Daisuke';
var age = 38;

console.log(age + age);//76
```
+の両側ともに数字であるので、加算されています。
では、以下のようなコードはどうなるでしょうか？

```JavaScript
var age = 38;
var isJapanese = true;

console.log(age + isJapanese);  //39
```
加算されてしまいましたね。isJapanese がtrueなので、１に変換されて加算されました。
では、true falseを文字列に変換するにはどうすれば良いか。こういう手もありそうです。

```JavaScript
var age = 38;
var isJapanese = true;

console.log(age + '' + isJapanese);//38true
```

あとは、toString()や、String(isJapanese)を使う手もあるようです。
Java7について調べたこと

# 概要
「1.4」で止まってたJavaの知識をバージョンアップするため
Java7,8,9について学習しています。
今回は「7」で追加された機能について調べた事のみを記載します。

# 調べたこと

## ダイヤモンド演算子
インスタンス生成時にジェネリクスを省略できるようになりました。

```java
List<Map<String, List<String>>> gyunyu = new ArrayList<>();
```

## NIO2
ファイルシステム関連のAPIが追加されました。
### ファイルの読み込み
```java
try {
  Path path = Paths.get("gyunyu.txt");
  List<String> list = Files.readAllLines(path, Charset.forName("UTF-8"));

  for (String gyunyu : list) {
    System.out.println(gyunyu);
  }
} catch(IOException e) {
  e.printStackTrace();
}
```

### ファイルの書き込み
```java
try {
  List<String> list = new ArrayList<>();
  list.add("レモン牛乳");

  Path path = Paths.get("gyunyu.txt");
  Files.write(path, list, Charset.forName("UTF-8"), StandardOpenOption.APPEND);
} catch (IOException e) {
  e.printStackTrace();
}
```

- java.nio.file.Path
インタフェース。ファイルまたはディレクトリのパスを特定するために使用できるオブジェクト

- java.nio.file.Paths
Pathオブジェクトを生成するためのクラス
 - `Paths.get(URI uri)`　：　指定された URI を Path オブジェクトに変換

- java.nio.file.Files
ファイルまたはディレクトリに関する処理を集めたクラス
 - `Files.readAllLines(Path path, Charset cs)`　：　ファイルからすべての行を読み取る
 - `Files.write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options)`　：　テキスト行をファイルに書き込む

- java.nio.file.StandardOpenOption
ファイルの操作方法が定義されている列挙型のクラス
 - `StandardOpenOption.APPEND`　：　ファイルの先頭ではなく最後に書き込む

## try-with-resources
`try-with-resources`文を使う事で、ファイル・データベースへのアクセスで記述していた`close()`を書かなくて良くなりました。
記述し忘れによるメモリリーク防止、ちょっとだけ手間が省けるようになりました。

```java
try(BufferedReader reader = new BufferedReader(new FileReader("gyunyu.txt"))) {
			String line = null;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
```

`java.lang.AutoCloseable`か`java.io.Closeable`インターフェースを実装するクラスであれば、`try-with-resources`文が使えます。

```Gyunyu.java
public class Gyunyu implements AutoCloseable {
  public void make() {
    System.out.println("コーヒー");
  }	
  @Override
  public void close() throws Exception {
    System.out.println("牛乳 !!!");
  }
}
```

```java
try (Gyunyu gyunyu = new Gyunyu()) {
  gyunyu.make();
} catch (Exception e) {
  e.printStackTrace();
}
```

![Clipboard02.png](https://qiita-image-store.s3.amazonaws.com/0/206289/836fcabb-a31b-06bc-7d9e-e05242f087da.png)

`gyunyu.close()`のように呼び出さなくても`close()`が実行されています。

## 複数の例外をcatch
Java6までは下記のように書いていましたが、

```java
try {	
} catch (IllegalArgumentException e) {		
} catch (NullPointerException e) {
}
```

Java7からは下記のようにまとめて記述する事が出来る。

```java
try {
} catch (IllegalArgumentException | NullPointerException e) {
}
```

## switch文でStringの判定
switch文でStringを使用できるようになりました。
「1.4」までは`int`だけ、「5」から`enum`も判定に使用できるようになり、
「7」からStringでも判定できるようになりました。
以前からStringで判定できると思ってた・・・

```java
String s = "coffee";
switch (s) {
  case "ichigo":
    System.out.println("ICHIGO GYUNYU !!!");
    break;
  case "coffee":
    System.out.println("COFFEE GYUNYU !!!");
    break;
}
```
Githubのプライベートレポジトリからzipをダウンロードする方法


- 社内のエンジニアじゃない人にリリース版をzipで渡したいときに便利

```shell-session
$ curl -L -u "自分のGitHubのユーザ名" https://github.com/yourname/your-private-repository/archive/master.zip > master.zip
Enter host password for user '自分のGitHubのユーザ名':   # GitHubのパスワードを入力する
$ unzip master.zip
```
Python バウンドインナークラスを使ってみる

# はじめに

この記事のコードはPython3.6上で検証しています。

# 動機

Railsを使っていると、こういうコードを書くことがよくあります。

```ruby
class User < ApplicationRecord
  class NameInvalidError < StandardError; end
  class AgeInvalidError < StandardError; end

  ...
end
```

あるクラスに関連してしか使わないエラーを表すクラスを、関連先のクラスの中で定義しておいて

```ruby
class UsersController < ApplicationController
  rescue_from User::NameInvalidError do
    ...
  end
  ...
end
```

みたいな。

最近、個人的にPythonのTornadoというフレームワークを使ってWebアプリの開発を始めたのですが、同じような感じに出て来るコンテクストが限定されている例外クラスをその例外を使うクラスのなかで定義することができないか調べていると、バウンドインナークラスという仕組みがあることを知りました。

# バウンドインナークラス

```python
class BaseKlass():
    # こんなかんじでバウンドインナークラスを定義
    class InnerKlass():
        def __init__(self, value):
            self._value = value

        def value(self):
            return self._value

    def __init__(self):
        # Pythonらしく、`InnerKlass`だけだと名前解決できない
        self.inner = BaseKlass.InnerKlass('ハロー ハロー')

    def do(self):
        print(self.inner.value())

class InheritedKlass(BaseKlass):
    def __init__(self):
        # 継承したクラスもインナークラスを持っている
        self.inner1 = BaseKlass.InnerKlass('ぼくから世界へ 応答願います')
        self.inner2 = InheritedKlass.InnerKlass('ぼくらのコードは正しくつながっていますか')

    def do(self):
        print(self.inner1.value())
        print(self.inner2.value())

class MoreInheritedKlass(BaseKlass):
    # 継承もできる
    class InnerKlass(BaseKlass.InnerKlass):
        def __init__(self, value):
            self._value = value

        def value(self):
            return self._value + '───────'

    def __init__(self):
        self.inner1 = BaseKlass.InnerKlass('ぼくの世界は正しく回転している模様 ')
        self.inner2 = MoreInheritedKlass.InnerKlass('システムオールグリーン コミュニケーションは不全')

    def do(self):
        print(self.inner1.value())
        print(self.inner2.value())

if __name__ == '__main__':
    b = BaseKlass()
    b.do()

    i = InheritedKlass()
    i.do()

    mi = MoreInheritedKlass()
    mi.do()
```

この結果は、次のようになります。

```
ハロー ハロー
ぼくから世界へ 応答願います
ぼくらのコードは正しくつながっていますか
ぼくの世界は正しく回転している模様
システムオールグリーン コミュニケーションは不全───────
```

最後の場合のみ、バウンドインナークラスのメソッドがオーバーライドされて出力文字列の最後にダッシュがついています。

# 使い所

Rubyのようにオープンクラスがないので、階層化された名前空間を作るためにカジュアルに使うようには使えないでしょう。

ただ、冒頭にあげたようにあるクラスの中でしか使わないような例外クラスを定義したい場合などには使えるのではないかと思います。

# 疑問点

```python
class MoreInheritedKlass(BaseKlass):
    class InheritedInnerKlass(BaseKlass.InnerKlass):
        pass
```

はOKなのですが、

```python
class MoreInheritedKlass(BaseKlass):
    class InheritedInnerKlass(MoreInheritedKlass.InnerKlass):
        pass
```

だと `NameError: name 'MoreInheritedKlass' is not defined` と怒られてしまいます。
MoreInheritedKlassはBaseKlassを継承しているので、InnerKlassがいるのに？と思いましたが。

理由がわかる方がいたらぜひコメントで教えてください。
将棋のAPIがあったら対戦つくれそうかな(3)・。・逆だった。

内部も9×9のほうが簡単だったかな？。
そうでもないか。

その位置にある駒を毎回見ていくっていうのもどうなんだろう？。

とは思うけど。

先手・後手の設定をできるようにして、いるけれど、上が後手、下が先手(プレイヤー)で、局面投げてベストを受け取るまで。

サクッと・。・はいかなかった。

逆でした。
逆というか、左上原点で下方向に並んでいると思っていた。
違うボードと勘違いか。

将棋のボードなので右上原点にしたんでしょうね、忘れちゃったけど、たぶん。

駒名の変換はできているので位置の見かただけ。

駒台は、置いてあるものを変換してsfenに追記するだけでできるか。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/215245/0552035d-df3a-8bcb-5aaf-b6f4472826cc.png)

持ち駒を数えて・。・数えたことがあるはず。
簡易図(PNG)に持ち駒を表示・。・駒の今数を数えている。
ここを流用しよう。

普通は、こういう関数ありますとか・。・一覧あるよなぁ。そこらへんがラーメンですね。

というか、オブジェクト指向なんて何？・。・という作りか。そうでもないか。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/215245/909a42db-382f-6b5e-4859-9acfc525946f.png)

技術的に何もないな。
🐮(USI)用に変換しただけでした。
とりあえず・。・APIに送るデータはできた。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/215245/54adeb1b-01d0-33ba-0d0a-79a7f9c356d4.png)

真面目に先手・後手の設定を入れたいところ、、、だけど、、、盤面下(プレイヤー)が先手固定にしておこう。

"先手・後手のラジオボタンを設定してから、VS Startボタンを押して開始してください"・・・だろうな。

平手の初手、APIから何が返ってくるんだろう？。
ランダムになるんだろうか？。
それは分かりません。

ベストは同じになるかな？
選択肢が複数戻ってくるなら、ば、ベストだけを選ばなくていいか。

なるほど。

(3)は、ここまでにしておこう。

・APIに送ってみよう。
・Rxの道から、APIからの返信を受信して、駒を動かす。
・送受信の間は？、プログレスは必要？、駒は動かせないようにしておく？。

ぐらいを次の(4)で。

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

サーバーサイドとAPI・。・んーー、違うんだろうな。
まったく。

どっちも手が出ないようで、作ろうと思ったら作れそうだけど。

別の話。
Bash で並列に処理を実行して Ctrl-C でまとめて終了する

例えば 2 並列で無限ループでなにか処理させて、Ctrl+C で止められるようにする。
しかもシェルスクリプトではなく、コンソールにペタッと貼り付けて実行させたい。

## ダメなケース

```sh
for no in {1..2}; do
  (
    while sleep 1; do
      printf "%s: my name is %d\n" "$(date +%H:%M:%S)" "$no"
    done
  ) &
done
wait
```

このようなプロセスツリーになります。

```
bash,6979,6979
  ├─bash,7840,7840
  │   └─sleep,7848,7840 1
  └─bash,7841,7841
      └─sleep,7850,7841 1
```

フォアグラウンドなプロセスはシェルである `bash(6979)` の `wait` なので、Ctrl+C しても子の Bash には `SIGINT` が飛ばないので死なない。

## ダメなケース

サブシェルで囲んで `wait` がサブエシェルから実行されるようにします。

```sh
(
  for no in {1..2}; do
    (
      while sleep 1; do
        printf "%s: my name is %d\n" "$(date +%H:%M:%S)" "$no"
      done
    ) &
  done  
  wait
)
```

シェルから直接起動しているのは一番上のサブシェルなのでそれがプロセスグループリーダーになります。

```
bash,6979,6979
  └─bash,7963,7963
      ├─bash,7964,7963
      │   └─sleep,7969,7963 1
      └─bash,7965,7963
          └─sleep,7971,7963 1
```

サブシェルの `wait` がフォアグラウンドなので Ctrl+C でプロセスグループ `7963` に `SIGINT` が送られて全滅するかと思ったんですがしませんでした。Bash が `SIGINT` を無視するからですね。次のようにただの `ping` とかなら止まります。

```sh
(
  for no in {1..2}; do
    ping "192.168.2.$no" &
  done  
  wait
)
```

## ダメなケース

バックグラウンドプロセスの PID を保存して `trap` で `kill` する。

```sh
(
  pids=()
  trap 'kill ${pids[@]}' EXIT
  for no in {1..2}; do
    (
      while sleep 1; do
        printf "%s: my name is %d\n" "$(date +%H:%M:%S)" "$no"
      done
    ) &
    pids+=($!)
  done  
  wait
)
```

バックグラウンドプロセスの Bash だけ死んで、その Bash から起動している何かは死なずに孤児る。上の例だと `sleep` は死なない。

## ダメなケース

バックグラウンドプロセスはサブシェルと同じプロセスグループなので、プロセスグループを指定して全滅させる。

```sh
(
  trap "kill -- -$$" EXIT
  for no in {1..2}; do
    (
      while sleep 1; do
        printf "%s: my name is %d\n" "$(date +%H:%M:%S)" "$no"
      done
    ) &
  done  
  wait
)
```

`$$` のようなシェル変数はサブシェルでは初期化されない。この例では `$$` は親のシェルの PID なるため、うまくいかない。

下記のようにすればよく分かる。

```sh
echo "$$:$PPID"     # 6979:6978
( echo "$$:$PPID" ) # 6979:6978 ... サブシェルではなく親の PID となている
```

## 成功なケース

`$BASHPID` ならサブシェルの PID が得られるのでそれを使う。

```sh
echo "$$:$PPID:$BASHPID"     # 6979:6978:6979
( echo "$$:$PPID:$BASHPID" ) # 6979:6978:8219
```

```sh
(
  trap "kill -- -$BASHPID" EXIT
  for no in {1..2}; do
    (
      while sleep 1; do
        printf "%s: my name is %d\n" "$(date +%H:%M:%S)" "$no"
      done
    ) &
  done  
  wait
)
```

## 成功なケース

`$$` とか `$BASHPID` とか使わなくても `kill 0` で現在のプロセスグループにシグナルを送ることができる。

```sh
(
  trap "kill 0" EXIT
  for no in {1..2}; do
    (
      while sleep 1; do
        printf "%s: my name is %d\n" "$(date +%H:%M:%S)" "$no"
      done
    ) &
  done  
  wait
)
```

これが一番簡単だと思います。
色々なメーラーの癖

#様々なメーラーのMIMEヘッダやら区切りパートについて
現在、メール投稿によるブログの作成ができるシステムを開発中なわけですが、メーラーによって色々な癖があることが解ってきたのでまとめておこうと思います。

##メールデータの取得方法(生のテキスト)
1.WEB版のGmail宛へ送信
2.オプションで**メッセージのソースを表示**
3.**元のメールをダウンロード**でテキストデータとして保存

###利用したメーラー
| メーラー | SMTP | キャリア |
|:-:|:-:|:-:|
| Andoroid標準メーラー | docomo.ne.jp | docomo |
| iPhone版デコメーラー | ezweb.ne.jp | au |
| iPhone版Gmailアプリ | mail.gmail.com | au |
| WEB版Gmail | mail.gmail.com | PC |
| iPhone標準メーラー | st13p11im-asmtp003.me.com | au |
| Microsoft Outlook 16.0 | smtp.kagoya.net | PC |
| スマホ版WEB版Gmail | gmail.com | au |
**※注意：SMTPについてはちゃんとした情報ではなく、メールデータに載ってた物を抜粋しただけです！要するに多分これ的なサーバｗ**

#各種メーラーの癖(ここが本題)
1.Andoroid標準メーラー

    1.text/htmlパートのタグが全部大文字。
    2.バウンダリ(パート区切り文字)の先頭にハイフン(-)が4つ入る。
***
2.iPhone版デコメーラー

    1.画像がサムネイルになる。本体はデコメーラーのサーバに保存される。
    2.HTMLタグとHEADタグのみが大文字でそれ以外は小文字になる。
***
3.iPhone版Gmailアプリ

    1.宛先が同じ場合、Delivered-Toフィールドが削除される。
    2.MIMEヘッダの内容が薄い。(同じアドレス宛だからかもしれません)
    3.text/htmlパートのエンコードがquoted-printableである。
    4.Content-Dispositionが全てattachmentになる。
    5.本文中にファイルを挿入しても、添付ファイルとしてもContent-IDが付く。
    6.Dateフィールドの時差指定が日本時間になってない。(時差指定が+0000のまま)
***
4.WEB版Gmail

    1.X-Mailerフィールドが無い。(独自フィールドなので無くても問題ない)
    2.MIMEヘッダの内容が薄い。(同じアドレス宛だからかもしれません)
    3.ファイル毎に独自フィールドのX-Attachment-Idフィールドがある。
    4.inlineファイルにはContent-IDとX-Attachment-Idがある。
***
5.iPhone標準メーラー

    1.Content-Dispositionが全てinlineになる。
    2.text/htmlパートが無く、text/plainパートしかない。
    3.us-asciiコードを使っている場合がある。(多分、文末の空行のみ)
***
6.Microsoft Outlook 16.0(Outlook 2016)

    1.inlineだとContent-Dispositionフィールドが省略されてContent-IDフィールドのみある。
    2.attachmentだとContent-IDフィールドが無い。
    3.text/htmlパートのエンコードがquoted-printableである。
    4.inlineにはfilenameプロパティが無い。

とりあえず、自分がやりたいことで凄く邪魔くさいｗと思った癖のある部分をまとめてみました。まだ他にも色々とメーラーがあるのは知ってますがとりあえず調べれたのはこれだけ。基本的に携帯やスマホからの投稿を目的として作っているのでサンダーバードとかベッキーとかそんなのは調べませんｗ
オフラインリアルタイムどう書く F08 の実装例

問題：http://nabetani.sakura.ne.jp/hena/ordf07chairs/
実装リンク集：https://qiita.com/Nabetani/items/de5b9d3230603033ed74

で。

最初に書いたのは ruby。

```ruby
ORDER=[1,3,5,7,9,8,6,4,2]

def index( chairs, order )
  (0...9).select{ |x|
    chairs[x]=="-"
  }.min_by{ |x|
    s0 = chairs[(x+1)%9]=="-" ? -100 : 0
    s1 = chairs[(x-1)%9]=="-" ? -100 : 0
    [s0+s1+order[x]]
  }
end

def process( chairs, ch )
  case ch
  when /[a-z]/
    raise "hoge" unless chairs.count(ch.upcase)==1
    chairs.gsub( ch.upcase, "-" )
  when /[A-Z]/
    ix = index( chairs, ch<"N" ? ORDER : ORDER.map{ |x| -x } )
    raise "fuga" unless chairs[ix]=="-"
    chairs[0,ix]+ch+chairs[ix+1,9]
  end
end

def solve( src )
  chairs="-"*9
  src.chars.each do |ch|
    chairs = process( chairs, ch )
  end
  chairs
end

DATA.map{ |line|
  num, src, expected = line.split(/\s+/ )
  actual = solve( src )
  okay = actual == expected
  p [ ( okay ? "ok" : "**NG**" ), num, src, actual, expected ]
  okay
}.all?.tap{ |x| puts( x ? "ok" : "something wrong" ) }
__END__
0 NABETanI  I-E--T-B-
1 A A--------
2 Aa  ---------
48  WFNwBfbSAXCZzMDJUcKx  AM-JSUNDK
```

いつも通りテストケースの大半は省略。
どの椅子に座りたいのかを得点にして表現した。点が小さい椅子に座りたい。

空席かどうかも得点に入れても良かったんだけど、そこは select にした。

得点にして表現すること（評価関数を用意すること）も大事なんだけど、それ以上に大事なのは、剰余。剰余で表現すると条件分岐がなくなって楽になる。

で。

これを python に移植したらこうなった：

```python3:python3
ORDER0 = [1,3,5,7,9,8,6,4,2]
ORDER1 = [ -x for x in ORDER0 ]

def score( chairs, order, r ):
  s0 = ( -100 if chairs[(r+1)%9]=="-" else 0 )
  s1 = ( -100 if chairs[(r-1)%9]=="-" else 0 )
  return s0 + s1 + order[r]

def index(chairs, order):
  indices = [ r for r in range(9) if chairs[r]=="-" ]
  scores = [ score(chairs, order, r ) for r in indices ]
  return min(zip(scores,indices))[1]

def process( chairs, cmd ):
  if "a"<=cmd<="z":
    return chairs.replace( cmd.upper(), "-" )
  ix = index( chairs, ORDER0 if cmd<="M" else ORDER1 )
  return chairs[0:ix]+cmd+chairs[(ix+1):9]

def solve( src ):
  chairs = "-"*9
  for i in range(len(src)):
    chairs = process( chairs, src[i] )
  return chairs

def test( src, expected ):
  actual = solve(src)
  okay = actual==expected
  print( ", ".join( [("ok" if okay else "**NG**"), src, actual, expected ] ) )

test( "NABETanI", "I-E--T-B-" );
test( "A", "A--------" );
test( "Aa", "---------" );
test( "WFNwBfbSAXCZzMDJUcKx", "AM-JSUNDK" );
```

`min_by` がわからなかったので `zip` して `min` した。
`lambda` で長い処理を書くのはつらいので score を外に出した。
それぐらいかな。
gugenに応募してみた。

#概要
gugenに応募してみた。
raspberry piで、SDR作ってみた。

#gugenて何。
GUGENは日本最大級のオリジナルハードウェアコンテストです。

#gugenのページ
https://gugen.jp/entry2017/2017-052

#sdrて、何。
ソフトウェア無線（Software-defined radio）とは、電子回路（ハードウェア）に変更を加えることなく、制御ソフトウェアを変更することによって、無線通信方式を切り替えることが可能な無線通信、又はその技術。一般的には、広い周波数範囲において多くの変調方式が可能となるよう、ソフトウェアが、なるべく汎用性の高いプログラム可能なハードウェアを制御するものとして考えられている。-wiki-

#どこまで、作ったの。
アンテナは、市販の物。
最初のmixer-Oscは、市販のチューナーを利用。
次のmixer-Oscは、IC2個で自作。
A/D変換、D/A変換は、USBトングル利用。
スピーカー、アンプは、パソコン用を利用。
ソフトウェアは、python。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/18104/a26c5024-ccb6-84fb-4e73-c35be9d00356.png)

#誰が喜ぶの。
ラジオ少年。

#アルゴリズムは。

IQ変換と言って、複素数に分解して、Iの二乗とQの二乗の和の平方根を求めました。

#性能は。

耳がよい人なら、なんとか、聞き取れる程度。
https://www.youtube.com/watch?v=08myU6dbpJI


#今後の展開は。

アルゴリズムにhilbertを利用する。
本命は、tensorflowを採用する。

#ハードをもう少し説明して。
入力の山形放送918ｋｈｚに1373ｋｈｚをMIXすると中間周波数455ｋｈｚが得られます。
中間周波数を増幅して450ｋｈｚをMIXすると、5ｋｈｚが得られます。
これを、MIC入力につなぎます。pythonでリアルタイム信号処理してヘッドホンアウトしたものを
スピーカーアンプで増幅して、スピーカーから音として出力されます。



以上。
gitの 「 . 」 の意味

ぐぐっても検索に出にくかったので、メモで残す。

## gitの '.' について
例えば、git管理下から外したい時に
`git rm -r --cached` のコマンド叩くけど、ぐぐった時に
`git rm -r --cached .` をまずやるって記事見つけて、'.' の意味がわからなかった

## 意味
~~**サブディレクトリ内も含めた全てのファイル** を指すみたい。~~
**特定パスのディレクトリ** を意味する！

~~で、out/ 配下のファイルを管理下から外したい場合なんかは~~
~~`git rm -r --cached out/.` ~~
~~という書き方をすることで、git管理下から、out/配下を除外できる~~

.単体だと、カレントディレクトリ（現在のディレクトリ）になる。

で、例えば、カレントディレクトリ配下を消す時は、
`git rm -r --cached .` 
と、 `-r` オプションを組み合わせることで、子孫ディレクトリまで辿って全部消すことができる。

是便利也。

追記：@lo48576 さん　コメントありがとうございました！
そうだ IE11、切り捨てよう。

# はじめに
各ブラウザのECMAScript2015対応状況が思いの外進んでたと言う話。

## 発端
フロントサイドのフレームワークの勉強として、ReactやVueを触っているが、どちらも少し凝った事をしようとすると
- package.jsonがどうのこうの
- webpackが
- ecmascript2015が
とかの記述が多く、正直サーバサイドのエンジニア(javascriptに慣れ親しんだ者)にとってはしんどい。

## 必要性は分かってる
私だってプログラマーの端くれです。
これらの必要性は十分に理解出来ます。

でも仕事で使うわけではなくとりあえず触ってみたい者としては、あまり今までの感じとかけ離れてほしくない。
(と言うか理解がおいつかない…)

## トランスパイラは嫌だ
javascriptをコンパイルすると言う事に違和感が拭えない。
テキストエディタでちょこっとなおして、サーバにアップして確認。
それが出来ないのはちょっと…

## ecmascript2015は妥協する
これは仕方ない。
自分の理解とブラウザの対応が追いついていないのだから。
いずれ使うだろうし、頑張って理解するよ。

理解はするけどそれを自分でブラウザで動く様になおすのは面倒だなと思っていたら、現時点ではほぼ対応が完了している模様。
**IE11以外は…**

ブラウザ対応状況
http://kangax.github.io/compat-table/es6/

# 結論
どうせ公開する予定もないし、IE11で動かなくてもいいや。

### 実は
~~export文はどのブラウザも対応していないみたい。
けどいいや。一つにまとまってる方が全体は分かりやすいし。~~

~~export - JavaScript - MDN - Mozilla
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/export~~

(2017/11/22 追記)
どうやらFirefox以外のブラウザでは対応が進んでいるようです。

Can I use... Support tables for HTML5, CSS3, etc
https://caniuse.com/#feat=es6-module
Nifty Cloud mobile backendの配信端末登録APIを作った話


### ◆SDKに配信端末情報の登録機能が無かった

PUSH通知をアプリに実装しようと、Nifty Cloud mobile backend（以下、ncmb）を選択。

JSで開発していたので、Javascript SDKで配信端末情報の登録を行おうとしたら、SDKで出来るのは、配信端末情報の更新と削除のみ。

NCMB.Installation Class
http://mb.cloud.nifty.com/assets/sdk_doc/javascript/jsdoc/classes/NCMB.Installation.html#method_update

### ◆REST API用のシグネチャ生成でエラー連発

そこで、ncmbで用意されている配信端末登録APIを利用する事にした。

配信端末登録
http://mb.cloud.nifty.com/doc/current/rest/push/installationRegistration.html

しかし、ncmbで用意されているREST APIを利用するにはシグネチャ情報がいるのだが、これの生成がやっかいで、エラーを連発。

シグネチャの生成方法
http://mb.cloud.nifty.com/doc/current/rest/common/signature.html

### ◆ユーザーコミュニティに相談

そこで、ncmbのユーザーコミュニティで相談。

ユーザーコミュニティ
https://github.com/NIFTYCloud-mbaas/UserCommunity/issues/675

すると、すぐに回答がありました。


>署名を作る処理は意外と面倒なので、JavaScript SDKを使っているのであればRequestを用いると楽です。以下は私のコードですが参考にしてください。
>
>https://github.com/moongift/ncmb-cli/blob/aa0a25b634332bbe83b0468dac2aed75ed70ce3e/bin/ncmb-csv-import#L71

### <i class="fa fa-cube" style="font-size:1em;"></i>◆APIを自作して解決

という訳で、ncmbのSDKのソースを流用して、配信端末情報登録APIを作りました。

```javascript
const ncmb = new NCMB(config.appKey, config.clKey);

router.post('/api', (req, res, next) => {

  let body = {
    "applicationName" : "testApp",
    "deviceToken" : "token1234567890abc",
    "deviceType" : "ios",
    "sdkVersion" : "2.3.4",
    "timeZone" : "Asia/Tokyo",
    "appVersion" : "1.0"
  }

  ncmb.request({
    path : `/${ncmb.version}/installations`,
    method : "POST",
    data : body
  })
  .then((obj) => {
    res.header('Content-Type', 'application/json; charset=utf-8');
    res.send(obj);
    return;
  })
  .catch((err) => {
    res.header('Content-Type', 'application/json; charset=utf-8');
    res.send({"err" : err});
    return;
  })
});
`
[Confluence]サイドバー の ページツリー を 展開しておく 方法

公式の「Configure the sidebar links」にも記載されているが、読み取りにくいので。。。
[Confluence Support＞Configure the Sidebar](https://confluence.atlassian.com/doc/configure-the-sidebar-317194694.html)

#やり方
1. 設定したいスペースに遷移
2. 左下の「スペースツール」＞

```
\\{pagetree:root=@home|startDepth=2|expandCollapseAll=true}
```
いろいろ [オプション](https://confluence.atlassian.com/doc/page-tree-macro-163414255.html) はありますが、個人的には上記ぐらいのオプションで良いかと。
ちなみに、頭に改行を意味する`\\`を入れてます。
上の段にやや食い気味になって、クリックしにくかったので。

#注意事項
Confluence 6.1.4

#関連リンク
[[公式]ページツリーマクロについての説明＞Wiki markup example](https://confluence.atlassian.com/doc/page-tree-macro-163414255.html)
[[コミュニティ：解決済み質問]左っかわのツリーを展開したいんすけど、どうすりゃいい？（意訳）](https://community.atlassian.com/t5/Confluence-questions/How-do-i-auto-expand-a-tree-structure-on-the-left-hand-nav/qaq-p/92274)
VirtualBoxでメールを飛ばさない設定

どんなに気をつけていたとしても外部にメールを飛ばしてしまうことがあります。
そのため、VirtualBox から外部へリレーしないようにしておくのが無難です。
アプリケーション側はqueに入った状態になるので送信できた扱いになりますが
実際にはリレーされないのでメールが外部に飛ぶことはありません。

# postfixの設定ファイルを編集
```
vi /etc/postfix/main.cf
```
# リレーサーバーアドレスをループバックアドレスに変更
変更前

```
#relayhost = [49.212.16.72]:587
```
変更後

```
#relayhost = [49.212.16.72]:587
relayhost = [127.0.0.1]:587
```
#postfixの再起動
```
/etc/init.d/postfix restart
```
#【確認方法】適当なアドレスにメールを送ってみる

```
[root@dev log]# mail xxx@gmail.com
Subject: test
test
.
EOT
```
#ログを確認する
```
tail -f /var/log/maillog
```
Jun  6 13:49:45 dev postfix/smtp[2149]: 6279427ED1: to=<root@dev.dev>, relay=<font color="Red">127.0.0.1</font >[127.0.0.1]:587, conn_use=26, delay=0, delays=0/0/0/0, dsn=5.4.0, status=<font color="Red">bounced</font > (host 127.0.0.1[127.0.0.1] said: 554 5.4.0 Error: too many hops (in reply to end of DATA command))

Jun  6 13:49:45 dev postfix/qmgr[1757]: 6279427ED1: removed
Windows環境にVimをインストールする方法

## Vimの導入方法

[Vim公式のダウンロードページ](https://vim.sourceforge.io/download.php)にアクセスします。
導入先のOSに応じたダウンロードリンクをクリックします。
※現時点（2017年11月22日）での最近バージョンはVim8.0です。
今回は、「MS-Windows」なのでself-installing executableをクリックしてダウンロードします。
ダウンロードしてきたexeファイルを実行します。
Vimのインストールが完了するとデスクトップに「gvim」、「gvim Easy」、「gVim Read only」の3つのショートカットが作成されます
※インストール時のオプションをデフォルトから変更していない場合
インストールはこれで完了です。

## 環境変数の設定
ただVimをインストールしただけではコマンドプロンプトから起動することはできません。
それは、インストール時点ではVimの環境変数の設定がされていないからです。
![vim-not-recognized.png](https://qiita-image-store.s3.amazonaws.com/0/215694/daa0200d-154a-c171-2311-0058fba969c8.png)


Windows10の場合、「Windowsキー+ i」と押すことでWindowsの設定画面が開きます。
そこから「システム」→「バージョン情報」→「システム情報」→「システム情報の詳細設定」→「環境変数」の順でクリックすると、環境変数の設定画面が開きます。

ユーザー環境変数のPathを選択した状態で「編集」をクリックしてPathの設定を行います。
すでに入っている値に、;（セミコロン）で繋げて「vim.exe」ファイルが存在するディレクトリ（例：C:\Program Files (x86)\Vim\vim80）を追加してください。

追加後には、PCの再起動を行うことで環境変数の変更が反映されます。
これでコマンドプロンプトで`vim`と入力するとVimエディタが開くようになりました。
もし開かない場合は環境変数の設定が上手くいってないと思われるのでVimのインストールディレクトリおよび環境変数の値を見直して再度チャレンジしてください。

##  おまけ
Cortanaが賢い。
環境変数の設定の際にCortanaの検索ウィンドウに環境変数と入れるとダイレクトに環境変数の設定画面に行くことができます。

![cortana.png](https://qiita-image-store.s3.amazonaws.com/0/215694/63542225-06d9-1d07-88e1-cc0dd3044b94.png)

これで本記事は終了です。
Let's enjoy Vim!
【論文シリーズ】頑健性のあるボルツマンマシン

## 原文
[顔認識とノイズ除去のための頑健的なボルツマンマシン (Robust Boltzmann Machines for Recognition and Denoising)
Yichuan Tang (2012)](http://goo.gl/LmwgSl)



## 1. 要約／背景
* ボルツマンマシンで、欠損画像からも顔認識できるモデルを構築した。
    - 積算ゲートが特異な画像パターンも吸収する。
    - ノイズの統計的分布とパターン遮蔽物は、教師なし学習から導かれる
    - 認識のアウトプットは、モデルの事後分布に従う。

## 2. 骨子の理論
(1)エネルギー関数
ノイズ項 $\tilde{v}$ と二項分類項 $s$(可視変数が $h$グループと $g$ グループのどちらかと繋がる)を加えたモデルになる。

```math
\begin{align}
E_{RoBM}({\bf v}, {\bf \tilde{v}}, {\bf s}, {\bf h}, {\bf g}) &= \frac{1}{2}\sum_{i}\frac{\gamma^2_i}{\sigma^2_i}s_i(v_i - \tilde{v_i})^2 - \sum_{i}d_is_i - \sum_{k}e_kg_k \\
&- \sum_{i,k}U_{ik}s_ig_k + \frac{1}{2}\sum_{i}\frac{(v_i - b_i)^2}{\sigma^2_i} - \sum_{j}c_ih_i \\
&- \sum_{ij}W_{ij}v_ih_j + \frac{1}{2}\sum_{i}\frac{(\tilde{v}_i - \tilde{b}_i)^2}{\tilde{\sigma}^2_i}
\end{align}
```

![151207224117_4.JPG](https://qiita-image-store.s3.amazonaws.com/0/127228/5d5b034f-94f3-bafa-9edb-049ba8904d4c.jpeg)

画像データにおけるノイズが入った状態(v~)は次のようなイメージである。

![151207224117_2.JPG](https://qiita-image-store.s3.amazonaws.com/0/127228/8f4f75d6-fa8b-e0d9-168b-d97ec30027f8.jpeg)


ノイズ変数の事後分布は、直積に近似的に分解される。

```math
p(\tilde{v}_i|{\bf h},{\bf g}) = \prod_i\big\{\pi_i \mathcal{N}(\tilde{v}_i|\tilde{b}_i;\tilde{\sigma}^2_i) + (1-\pi_i)\mathcal{N}(\tilde{v}_i|\mu^{new}_i;\frac{\sigma^2_i\tilde{\sigma}^2_i}{\tilde{\sigma}^2_i + \sigma^2_i})\big\}
```

(3)サンプリング
隠し系のサンプリング

```math
p({\bf g}, {\bf h}| {\bf v}, {\bf s}, {\bf \tilde{v}}) = p({\bf g}, {\bf h}| {\bf v}, {\bf s}) = p({\bf h}| {\bf v})p({\bf g}|{\bf s})
```


可視系のサンプリング

```math
p({\bf v}, {\bf s}| {\bf g}, {\bf h}, {\bf \tilde{v}}) = \prod_ip(v_i, s_i| {\bf g}, {\bf h}, {\bf \tilde{v}}) = \prod_ip(v_i| s_i, {\bf g}, {\bf h}, {\bf \tilde{v}})p(s_i| {\bf g}, {\bf h}, {\bf \tilde{v}})
```
いずれも、条件項にノイズ変数が入っている。


## 3. モデル適用例
Tronto Face Databaseに登録されている画像に対して、60000枚で訓練したのち、2000枚でテストした。
画像にランダムノイズを入れたものと部分欠損(block occlusion)したパターンを加え、その除去率を計測した。
ベンチマークの手法に対して、RoBMモデルの除去パフォーマンスは良好だった。

![151207224117_7.JPG](https://qiita-image-store.s3.amazonaws.com/0/127228/0841669b-873f-e6f6-6409-f2a3884bd34e.jpeg)
システム開発業務自体の会計処理まとめ


会計回りのシステム開発とかだと簿記知識が必要になるけど、自分の開発業務が会社の財務会計にどう反映されているのかという意味で、システム開発自体の会計処理についてまとめてみる。

他にも色々仕訳のケースはありそうだけど、オーソドックスなものは多分こんな感じじゃないかと。


# でてくる仕訳項目
- ソフトウェア仮勘定
- ソフトウェア
- 役務収益
- 役務原価


# 販売目的 or 自社利用目的でソフトウェアを開発している場合（資産計上可能なケース）

将来の利益獲得または費用削減が確実であると判断できるソフトウェアの開発の場合は、そのソフトウェアを資産扱いとする。
その場合、開発に関わる費用（人件費、光熱費、サーバやPC等の機器など）は完成するまでは全てソフトウェア仮勘定として計上する。

| 借方                       | 貸方                |
|:---------------------------|:--------------------|
| ソフトウェア仮勘定(500万)  | 人件費(300万)       |
|                            | 水道・光熱費(50万)  |
|                            | 機器(150万)         |

そして開発が完了したら、ソフトウェア仮勘定をソフトウェアとして資産に振替える。

| 借方                 | 貸方                      |
|:---------------------|:--------------------------|
| ソフトウェア(500万)  | ソフトウェア仮勘定(500万) |


資産となったソフトウェアは、会計年度毎に減価償却費を計上し減価償却を行う。減価償却の期間は５年とかが多い(=年100万ずつ費用を計上する)

（1年目）

| 借方                    | 貸方                  |
|:------------------------|:----------------------|
| ソフトウェア償却(100万) | ソフトウェア(100万)   |

=> この結果、ソフトウェアの資産価値は 500万 - 100万で 400万になる。

## 何がどうなの？

資産計上できる開発の場合、開発に掛かるコストをローンを組むように後払い＋均一化することができる。通常費用が先行して発生し収益は後からついてくるのでそんな意味でも会社にとってありがたい。


# 販売目的 or 自社利用目的でソフトウェアを開発している場合（資産計上不可能なケース）

例えば、小規模な機能改善やバグフィックス、リファクタ等「保守・運用」と言われる様な開発案件は「将来の利益獲得または費用削減」ができると判断できないため、資産計上扱いにできない。その為発生する人件費などの開発に掛かる費用は全て費用として計上する。

| 借方               | 貸方               |
|:-------------------|:-------------------|
| 人件費(300万)      | 現金など(500万)    |
| 水道・光熱費(50万) |                    |
| 機器(150万)        |                    |

## 何がどうなの？

要はその開発案件が資産計上できる内容を含むかどうかで、ローンにできるのか、短期的な費用がかさむのかが変わる。収益獲得or費用削減に繋がる開発にすることはそんな意味でも大切。


# 受託開発をしている場合

請負工事と同じ様に処理をする。処理上工事進行基準と工事完成基準の２つがあるが、検収タイミングで売上を計上する（＝工事完成基準）会社が多いのではないかと思う。人件費等は売上原価になる。但し、決算期をまたぐ仕掛り開発がある場合は仕掛品として計上しておかなければならないっぽい。

（検収タイミング）

| 借方                       | 貸方                |
|:---------------------------|:--------------------|
| 売掛金等           | 売上               |
| 売上原価           | 人件費             |
|                    | 水道・光熱費       |
|                    | 機器               |


（決算整理）

| 借方               | 貸方               |
|:-------------------|:-------------------|
| 仕掛品             | 人件費             |
|                    | 水道・光熱費       |
|                    | 機器               |


（決算期をまたいだ検収の場合）

| 借方               | 貸方               |
|:-------------------|:-------------------|
| 売掛金等           | 売上               |
| 売上原価           | 仕掛品             |
|                    | (+当期発生費用)    | 



# 役務形態で開発をしている場合

費用は事前計上する場合は仕掛品で一度計上した後、収益を計上するタイミングで役務原価に振替える。収益は役務収益で計上する。


| 借方               | 貸方               |
|:-------------------|:-------------------|
| 仕掛品             | 人件費等           |


（サービス提供後）

| 借方               | 貸方               |
|:-------------------|:-------------------|
| 売掛金等           | 役務収益           |
| 役務原価           | 仕掛品             |
Kotlinで文字列を数値、日付文字列を日付(java.util.Date)、日付を文字列(String)に変換する

Kotlinで文字列を数値に変更する方法です。また日付文字列をDateに変換、Dateを文字列に変換します。

# 文字列から数値へ変換する（StringからIntへの変換）

Kotlinの標準ライブラリに文字列から数値へ変換するための拡張関数が用意されていてtoInt、toByte、toBooleanなどが使えます。

```kotlin
val str = "43"
println(str.toInt())
```

他にも次のような変換用の関数があります。

|  String型変換関数  |
|:--|
|fun String.toBoolean(): Boolean   |
|fun String.toByte(): Byte   |
|fun String.toDouble(): Double   |
|fun String.toFloat(): Float|
|fun String.toInt(): Int|
|fun String.toLong(): Long|
|fun String.toShort(): Short|

文字列を数値に変換できなかった場合は、NumberFormatExceptionが発生します。

# 日付を文字列に変換する（DateをStringに変換）

```kotlin:GetNowDate.kt
val df = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
val date = Date()
println(df.format(date))
```

フォーマット文字列は固定文字列としましたのでExceptionは発生しません。そのためここではtry-catchは不要です。

# 日付文字列を日付型に変換する（StringをDateに変換）

Stringから数値へ変換するように、StringからDateへ変換する拡張関数toDateを用意します。

```kotlin:DateUtil.kt
import java.text.ParseException
import java.lang.IllegalArgumentException
import java.text.SimpleDateFormat
import java.util.Date

fun String.toDate(pattern: String = "yyyy/MM/dd HH:mm:ss"): Date? {
    val sdFormat = try {
        SimpleDateFormat(pattern)
    } catch (e: IllegalArgumentException) {
        null
    }
    val date = sdFormat?.let {
        try {
            it.parse(this)
        } catch (e: ParseException){
        	null
        }
    }
    return date
}
```

Javaではtry-catchでParseExceptionを処理しなければなりませんでしたが、Kotlinでは例外処理は必須ではないので書いても書かなくてもOKです。
しかしここでは、日付の変換フォーマットと、日付に変換したい文字列のどちらもユーザ入力の可能性を想定しているので、try-catchを行っています。
例外が発生した場合はcatchでnullを返すようにしています。

拡張関数toDateは次のように利用します。

```text
>>> val strDate = "2017/10/24 12:12:12"
>>> println(strDate.toDate())
Tue Oct 24 12:12:12 JST 2017
```
WordPressで突然「下書きをプレビューする権限がありません」と表示されるとき どうしたかメモ

突然、WordPressのトップページだけ、「下書きをプレビューする権限がありません」と表示された＞＜

#確認したこと・やったこと

- ブラウザのCookieを消してみる
- ちゃんと200番で落ちてきているか（chromeのデヴェロッパーツールのNetWork。304のキャッシュじゃないか）。
- 「設定」>「一般」メニューでWordPress アドレス(URL)とサイトアドレス(URL)が違っていないか確認
- フロントページ（トップページ）が固定ページになっていたら、その固定ページの編集画面に行って、更新ボタンを押してみる

###その時の原因の推測
トップページは管理画面の固定ページのところで編集できるので、
編集中にこけて、固定ページのステータスが下書きになってしまっていた
OR
プラグインがいっぱい入っているんで、どれかがアップデートかかった時に何か起きたか
EclipseでJDKのバージョンが合っているのにエラーが出たりコンパイラが正常に動作しない場合

##EclipseでJDKのバーションが合っているのにエラーが出たりコンパイラが正常に動作しない場合の対処方法
###手順
1. Window->Preferences->Java->Compilerを開く
2. JDK ComplianceのCompiler compliance levelを一旦、他のバージョンに変更
3. Apply and Closeを押す
4. 確認画面が出るのでYesを押し、処理が終わるまで少し待つ
5. 1の画面からCompiler compliance levelを目的のバージョンに戻す
6. 3,4の手順を行う

表示上では設定は間違えてないのにJDKが正常に動作していない時などは、この操作で治るかもしれないです。
GTX1080Ti搭載のWindows10パソコンにUbuntu16やらCUDAやらインストールする流れ（３）

#はじめに
買ってきたWindowsパソコン（GTX1080Ti搭載）に諸々設定する流れ。

ubuntuインストールするまではこちら。
https://qiita.com/masataka46/items/9548b70cc71248cc1456
その後、CUDA、cuDNNを入れるまではこちら。
https://qiita.com/masataka46/items/0ef2223d22f841b8bfb8#_reference-e76b9ba29c8104716dd1

今回はpyenvを入れてpython3を使えるようにする。

スペック：
デフォルトのOS:Windows10 64ビット
インストール後：Ubuntu16.04 LTS
CPU:Corei7 7700K
GPU:GTX1080Ti
SSD:240GB
HDD:2TB
マザーボード:ASUS H170-pro

CUDA-8.0
cuDNN-6
など

#pyenv のインストール
こちらのサイト（１）
https://qiita.com/Kodaira_/items/feadfef9add468e3a85b
に従って進める

まず git をインストールする。

```
sudo apt-get install git
```

次に pyenv をインストールする。

```
sudo git clone https://github.com/yyuu/pyenv.git ~/pyenv
```

次に pyenv の PATH を設定する。`.bashrc`に以下を書き込む。

```
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
```

設定を反映させる。

```
source ~/.bashrc
```

#python3系のインストール
いきなり

```
pyenv install 3.6.3
```

とすると権限がどうのこうの言うので、

```
chmod -R 777 pyenv
```

などで権限を変更。再度試みると

```
pyenv install 3.6.3
.....
.....
zipimport.ZipImportError: can't decompress data; zlib not available
.....
```

などとなるので

```
sudo apt-get install zlib1g-dev
```

で`zlib1g-dev`なるものをインストール。再度実行。

```
pyenv install 3.6.3
.....
.....
Installing Python-3.6.3...
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?
.....
.....
```

などとなるので、このサイト（２）
https://qiita.com/banaoh/items/00aea13fe045fab7e8ba
を参考に`libssl-dev`なるものをインストール。

```
sudo apt-get install libssl-dev
```

再度実行すると、`WARNING`がいっぱい出たが、インストールは完了した。しかし

```
pyenv global 3.6.3
```

などとしても切り替わらない。そこでこのサイト（３）
https://qiita.com/utgwkk/items/bf282ca95f64ef7dd594
を参考に`WARNING`に表示された諸々をインストールした。

```
$ sudo apt-get install libbz2-dev libreadline-dev libsqlite3-dev
```

再度インストールしたところ、`WARNING`は出ずに完了。それでも切り替わらない時はこのサイト（４）
https://qiita.com/ta_ta_ta_miya/items/e24394c6b0022405a126
を参考にするといい。
オフラインリアルタイムどう書くF08の問題


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

問題は「のんびり座りたい strikes back」という名前で、詳細は
http://nabetani.sakura.ne.jp/hena/ordf07chairs/
です。

出題者の気分としては、問題を読み始めてから解けるまで30分あればなんとかなると思ってますが、ひとそれぞれで。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。

似たような問題をもっと解きたいという方は、
https://nabetani.hatenadiary.com/entry/yhpg_list
に過去問リンク集がありますので、そちらをご覧になると良いと思います。
mysql インストール(mac)


インストール

```
$ brew update
$ brew install mysql
```

mysql 起動
（停止は　$ mysql.server stop)

```
$ mysql.server start
Starting MySQL
. SUCCESS! 
```

コンソールに接続

```
$ mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.20 Homebrew

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

パスワード設定

```
$ mysql_secure_installation
```

パスワードログイン

```
$ mysql -uroot -p
```

https://qiita.com/hkusu/items/cda3e8461e7a46ecf25d
railsアプリをPostgreSqlに接続するまで

railsアプリを作成する際にpostgreを使用したので、その際のメモです。

#railsアプリ作成
```
$ rails new app-name -d=postgresql
```

#postgreの設定

##postgreにdatabaseの作成(本当は必要なかった?)
あとでコマンドを叩くのでする必要なかったです。

```
$ createdb database-name
```

##userの作成手順
userを新たに作成し、権限を付与します。必要だったのはほぼここだけです。

###postgre起動
postgreを起動します

```
$ psql -d database-name
```

###user作成

```
# create user user-name;
```

###パスワードの設定
```
# \password password;
```

###userの確認
```
# \du
```

```
                                        List of roles
     Role name      |                         Attributes                         | Member of
--------------------+------------------------------------------------------------+-----------
 user-name          |                                                            | {}
```

##権限の付与
```
# ALTER ROLE user-name WITH CREATEDB;
ALTER ROLE
```

##権限の確認
```
                                        List of roles
     Role name      |                         Attributes                         | Member of
--------------------+------------------------------------------------------------+-----------
 user-name          | Create DB                                                  | {}
```

##databaseの作成
```
$ bundle exec rails db:create
Database 'database-name' already exists
```

#まとめ
最低限の内容しかないですが、一通り書きました。
参考にしていただけたらと思います。

#参考
- http://next49.hatenadiary.jp/entry/20141105/p2
- https://www.postgresql.jp/document/9.4/html/manage-ag-createdb.html
- https://qiita.com/mm36/items/1801573a478cb2865242
フレンズ画像を生成させてみたい-前景抽出 GrabCut

[Wikiクローラで収集した画像](https://qiita.com/knok/items/a50a6f1fddb715a8eea2)から、キャラクター部分のみを抽出することを考えてみます。

OpenCVが持つ[GrabCut](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html)アルゴリズムを使って処理をしてみました。

# GrabCut

[PythonチュートリアルGrabCutのページ](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html)が既に十分詳しいですが、行っていることは一種のクラスタリングです。

まず明確に背景である部分と前景がすべて含まれている領域がわかっていることを前提とします。後者の領域は矩形で示します。

OpenCVの実装では、GC_INIT_WITH_RECTモードでgrabCutを呼び出す際は指定した領域すべてに前景、それ以外に背景のラベルを与えます。これが初期値です。

混合ガウシアンモデル(Gaussian Mixture Model, GMM)を用いて、前景と背景の画素値分布を学習します。混合ガウシアンモデルは任意の連続関数を複数の正規混合分布で近似する統計的モデリング手法です。

前景、背景それぞれにラベルされたピクセルの色情報をGMMに与え、訓練します。これにより、ピクセルの色情報を与えると前景である確率、背景である確率を出力する予測モデルが構築されます。

これらの予測モデルを用いて、グラフを構築します。グラフはすべてのピクセルがノードとなります。それ以外2つの特殊なノードsource, sinkを用意し、すべての前景ピクセルはsourceに、背景ピクセルはsinkにつなげます。
source/sinkと画素ノードをつなぐエッジの重みは先のモデルから得られる前景らしさ、背景らしさの確率に基づいた値をとります。
さらに各画素の上下左右に隣接するピクセル同士にもエッジをもたせます。エッジの重みは画素の色のノルムとしているようです。

このグラフを元に、sourceに属する画素群とsinkに属する画素群の2つに分割します。分割の基準は、切断されたエッジの重みの総和です。これが最小となる範囲で分割を行います。

できあがった前景・背景ラベル情報を元に、GMMモデル構築から分割までの処理を引数に指定した回数だけ行い、それを最終結果とします。

OpenCVでは、GMMのコンポーネント数が5にハードコーディングされています。ソースコード内部では13xコンポーネント数分のdouble配列をGMMモデル格納領域として用いるので、前景・背景それぞれ用に(1, 65)のnumpy配列を用意し与えます。

# 適用例

チュートリアルのコードを参考にしつつ、適用してみましょう。

```py3
import cv2
import numpy as np

# wiki画像 ホッキョクオオカミ
fname = 'fixed/cool/5/20151225174718cRVL4Dkz.jpg'
img = cv2.imread(fname)
rect = (210, 50, 230, 400) # キャラ全体をカバーする領域 (始点x, y, 幅、高さ)

def img_clip(img): # 画像全体からキャラクターを含む領域だけをクリッピング
    h, w, c = img.shape
    x0 = int(w * 0.45) # 右半分以上は情報表示部分なのでカット
    y0 = int(h * 0.76) # 下1/4も同様にカット
    clip = img[0:y0, 0:x0, :]
    return clip
cimg = img_clip(img)
mask = np.zeros(cimg.shape[:2], np.uint8) # マスク用領域
bgModel = np.zeros((1, 65), np.float64) # 背景GMMモデル
fgModel = np.zeros((1, 65), np.float64) # 前景GMMモデル
cv2.grabCut(cimg, mask, rect, bgModel, fgModel, 5, cv2.GC_INIT_WITH_RECT) # イテレーション回数5
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype(np.uint8) # maskの値が1の部分のみ残して0クリア
out = cimg * mask2[:, :, np.newaxis] # カラーチャンネルの分だけbroadcastしつつ掛け算、結果として1の領域のみ残す

cv2.imshow('output', out)
cv2.waitKey()
```

## 実行結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31714/04179e62-b897-2e5d-14aa-81256a8ab776.png)

思ったよりは悪くない結果ですが、目の部分もくり抜かれてしまっています。今回対象にした画像はレアリティ★5のキャラクターで、背景がホログラム風のパターンをしているため、目のハイライトと傾向が似ているのが原因と考えられます。

これについては事前に前景ラベルを陽に指定することで対応できます。その方法については改めて記事にします。

# リファレンス

* [使っている人いるのかな？OpenCV3.0から入ったラべリング処理について - Qiita](https://qiita.com/wakaba130/items/9d921b8b3eb812e4f197)
* [ラベリング処理アルゴリズム　画像処理ソリューション](http://imagingsolution.blog107.fc2.com/blog-entry-193.html)
* [Furukawa Laboratory 混合ガウスモデル（GMM: Gaussian Mixture Model）](http://www.brain.kyutech.ac.jp/~furukawa/data/gmm.html)