OmniAICreator/Qiita-1.07M huggingface dataset:
爆速ナンバーリンクソルバー（3）〜 MiniSat in JavaScript with Emscripten

（この記事は、連載記事です。[ソルバー自体](http://jkr2255.github.io/js_puzzle_solvers/numberlink.html) [その1](http://qiita.com/jkr_2255/items/bb7cb2eee35e285a17a2) [その2](http://qiita.com/jkr_2255/items/0980d8e2e410d92338e8)）

さて、前回にナンバーリンクのSAT化を行いましたので、あとは実行環境を用意するだけです。ただ、JavaScriptという環境で実用に耐えるだけのSATソルバーがあるのかと思って調べてみたところ…ありました[^1]。

# SATソルバーの世界
まず、何も考えずに原始的な解き方をしてみようとすれば、変数すべてにtrue/falseの取りうるパターンを入れていく、ということになります。これでは変数 $n$ 個の場合に $O(2^n)$ だけの時間がかかってしまいます。そして、SAT問題はNP完全であって、現状では多項式時間で片付くアルゴリズムはありません（もし発見されれば、それがP=NPの証明となります）。

高速に処理しようとすれば、（こういう探索問題全般に共通する手法ですが）可能性のないパターンをどんどん切り捨てる「枝刈り」が必要となってきます。詳しくは別項で触れる予定ですが、90年代後半から枝刈りの手法が進化してきたことでSATソルバーはどんどん高速化し、応用範囲が広がって行きました。

そして、SATが進化する理由のもう1つとして、競技コンテストがある、ということがあります。毎年SATソルバーの性能を競い合う競技会があって、一線の研究者たちがソルバーを持ち込んでしのぎを削っています。しかも、競技に出場するソルバーは**オープンソース**なので、翌年の参加者は去年のソルバーから進化させて作る、というのがごく当たり前に行われており、それぞれの有利なところを取り入れて年々進化しています[^2]。

# MiniSat
そんなSATソルバーの世界の中で有名なソルバーとして、[MiniSat](http://minisat.se/)があります。最初に知った時には上記のような事情を知らなかったので、「オープンソースだしMiniだし、どの程度のものを解けるのかな」とあまり期待していなかったのですが、調べてみれば第一線級の優秀なプログラムだと判明してびっくりした次第です。

そして、プログラム自体はC++で書かれており、単体のプログラムとして使う以外に他のプログラムに組み込むこともできます。さらには、他言語へのバインディングも用意されています（もっとも、入出力はテキストで行うので、プログラムとして呼び出すことでも容易に制御できますが）。

# Emscripten
とはいえ、クライアントサイドのJavaScriptからC++へのバインディングなど不可能です。そんなわけで、最初からJavaScriptで書かれたソルバーを探していたのですが、なかなか高性能なものが見つかりません。そして、実用的な速度で動くソルバーを見つけたと思ったら、なんと「MiniSatをJavaScriptへコンパイルしたもの」でした（[GitHub](https://github.com/jgalenson/research.js/tree/master/minisat)）。

LLVMといって、コンパイラ型言語にも仮想マシンを仕込んで、プラットフォーム抽象化や高度な最適化を行うシステムがありますが、そのLLVMからJavaScriptへとコンパイルを行えるようにしたものが[Emscripten](http://kripken.github.io/emscripten-site/)です。つまりC/C++など、LLVMにできる言語であればおよそ何でもJavaScript化できてしまいます。

ただし、コンパイルされてできあがるJavaScriptはふつうのJavaScriptではなく、LLVMをそのままエミュレーション実行するかのような、低水準なコードとなります。一部だけ取り出して使うことはほぼ不可能で、まるごとJavaScriptから呼び出して使うことになります。

[^1]: というより、じつは因果関係が逆で、もともとは別な言語で進めていたことだったのですが、調べているうちにJavaScript上で実用性能を叩きだすソルバーを発見したので、使いやすさなどを考えてプロジェクト対象をそっちに切り替えた次第です。

[^2]: ある年のこと、去年優秀だった4つのソルバーを適当につないだだけで出してきた人がいたのですが、それが案外に優秀な結果を見せて大騒ぎ、なんてこともあったそうです。
Elixirでプロセス20万くらい作ってみた

# Elixirでプロセス20万位作ってみた

Elixirの下のErlang VMは軽量プロセスという仕組みを使って、並列プログラミングをサポートしている。ErlangのプロセスはOSのプロセスとは異なり、VM内でプロセスを切り替えている。

erlangやElixirではプロセスの使用を勧められる。

実際、どのくらいのプロセスが生成出来るか調べてみた。

## process limitの引き上げ

20万プロセスまで生成出来た。それ以上はデフォルトのprocess limit に引っかかって起動出来なかった。```erl +P 1000000``` でprocess limit をあげられるそうだが、~~erlang r18からそのオプションは無効化されたそうで、何を指定すれば、process limitの上限をあげられるかわからなかった。~~

追記: erlang r18で+P オプションは無効化されてないそうです。

追記：hayabusa333さんが、process_limitの上げ方を調べてくれた。 http://d.hatena.ne.jp/hayabusa333/20151104/elixir_erlang

```
export ELIXIR_ERL_OPTIONS="+P 1000000"
iex --sname bar@localhost --cookie foo -S mix run -e "ManyProcessFactory.main"
```

このように、```ELIXIR_ERL_OPTIONS```を使えばprocess_limitを増やせるようだ。
メモリが少ないので、あまり多くのプロセスを立ち上げると、erlのvmがcrashした。
awsで多めのメモリで試してみる。

## ex_topを使ってerlang VMの様子を見る

ex_topというツールを使えば exlixirでtopみたいなものを見ることが出来る。

https://github.com/utkarshkukreti/ex_top

## 実行結果

![](https://i.gyazo.com/b55bf082f4a4fd730301f7943b529016.png) 

20万プロセスを生成し、CPUも上手く分配して使えられているようだ。

## 使用したソースコード

https://gist.github.com/shibacow/86c6eba46d12b9f0d395
pecoのインストール


bash等のシェルを便利に拡張してくださるようです。
思った以上に便利そうなので、簡単にインストール方法をまとめておきたいと思います。

# 概要
ここです
https://github.com/peco/peco

標準出力をインクリメンタルサーチできます。
Demo画像見てもらえればなんとなく動きが想像できるのではないかと思います。

# インストール
以下より最新のバイナリを取得しましょう。
(2015/11/06時点では0.3.5が最新でした)
https://github.com/peco/peco/releases/

```shell-session:setup peco
cd /usr/local/src/
sudo wget https://github.com/peco/peco/releases/download/v0.3.5/peco_linux_amd64.tar.gz
sudo tar -C /usr/local/ -xzf peco_linux_amd64.tar.gz 
```

```shell-session:.bashrc
PATH=$PATH:/usr/local/peco_linux_amd64
```

goをインストールしソースからインストールも可能ですが、直接バイナリを取得してもOKです。

# 動作確認

```shell-session:ls
ls | peco
```

使い勝手よいので、ぜひお試しを。
fish で rbenv の初期処理を実行する方法


rbenvは0.4.0からfishに対応しています。homebrew で入れている場合は下記を実行してみてください。

```
brew upgrade rbenv
```

あとは `~/.config/fish/config.fish` に

```
rbenv init - | source
```

を追加すれば動きます。

なお、oh-my-fishを使っている場合は、

```
omf install rbenv
```

で、上のコマンドが勝手にセットアップしてくれます。
【IntelliJ】GitHubからプロジェクトを取得する

ずっとEclipse派だったけど、世間を見渡せば見渡すほどみんなIntelliJなので、ヒヨってIntelliJを導入。
既存のPlay2プロジェクトをIntelliJで使えるようにするために、結構ハマったのでメモ。
手探りでやっつけたので、もっとスタンダードな方法があるのかも。ないのかも。

[環境]
- Windows8.1
- IntelliJ IDEA 14.1.5(日本語化済み)
- PlayFramework2.4
***
0.GitとGitHubの設定は済ませておくこと

1.GitHubからプロジェクトの取得
![SnapCrab_Welcome to IntelliJ IDEA_2015-11-3_20-52-14_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/64360/4fe49df4-5af5-4387-ad78-8d3bf45f45fb.png)
![SnapCrab_Enter Master Password_2015-11-3_20-52-31_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/64360/6e887a4a-cc2b-512b-5106-aef4e9e82401.png)
![SnapCrab_Clone Repository_2015-11-3_20-53-1_No-00aaa.png](https://qiita-image-store.s3.amazonaws.com/0/64360/c8ecb07c-1734-c474-34bc-3d02ab6bc1a3.png)

2.SBTプロジェクトしてプロジェクトを構成する(?)
IntelliJのメニューから、
　ファイル -> New -> Project from Existing Sources
から、取り込んだプロジェクトをSBTプロジェクトとしてImport
![SnapCrab_Import Project_2015-11-3_21-4-29_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/64360/3ff61f5b-4ad0-c088-c5dc-727e1e14b4c0.png)

そのまま終了。

とりあえずこれでいけた！！！

Scala開発はIntelliJの方が捗るらしいので、頑張って使い方を覚えていきます。
CentOSにanyenvでRubyをインストールする


# 環境
CentOS 6.6

# 事前準備

まずは`Git`と`gcc`をインストール

```cmd
$ sudo yum install -y gcc git
```

# anyenvのインストール

作者の解説記事とリポジトリのREADMEを読みながらインストールします
[anyenvという**env系の簡易マネージャを作った](http://blog.riywo.com/2013/06/22/155804/)
[riywo/anyenv](https://github.com/riywo/anyenv)

```
$ git clone https://github.com/riywo/anyenv ~/.anyenv

$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> .bashrc
$ echo 'eval "$(anyenv init -)"' >> .bashrc
$ exec $SHELL -l
```

インストールが完了したらanyenvコマンドを確認してみましょう

```
$ anyenv install -l
Available **envs:
  Renv
  crenv
  denv
  erlenv
  exenv
  goenv
  hsenv
  jenv
  luaenv
  ndenv
  nenv
  nodenv
  phpenv
  plenv
  pyenv
  rbenv
  sbtenv
  scalaenv
```

`rbenv`がありますね。では、`rbenv`をインストールします。

# rbenv

## rbenvをインストール

```
$ anyenv install rbenv
$ exec $SHELL -l
```

## Rubyインストールの事前準備

Rubyのビルドに必要なライブラリをyumでインストールしておきます。

```
$ sudo yum install -y openssl-devel readline-devel zlib-devel
```

## Rubyインストール

今回はRuby2.2.3をインストールします

```
$ rbenv install 2.2.3
Downloading ruby-2.2.3.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/df795f2f99860745a416092a4004b016ccf77e8b82dec956b120f18bdc71edce
Installing ruby-2.2.3...
Installed ruby-2.2.3 to /home/yourname/.anyenv/envs/rbenv/versions/2.2.3
$ rubyenv versions
2.2.3
```

Ruby2.2.3をインストールできました。
複数バージョンをインストールするなら `rbenv install x.x.x` で適宜インストール出来ます

## バージョンを指定
### システム全体で使用するバージョンを指定する
```
$ rbenv global 2.2.3
```

### 特定のディレクトリでだけ使用するバージョンを指定する

```
$ rbenv local 2.2.3
```

## 確認

```
$ ruby -v
uby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
```
homebrewでopensslを入れたら、bundle installでeventmachineのエラーが発生

# 環境
- MacOSX EL Capitan
- Ruby2.1.7

# 現象
Macの`bundle install`で `eventmachine`のインストールに失敗した

```
$ bundle install
.
.
.
Installing eventmachine 1.0.5 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /Users/tkmiya34/.anyenv/envs/rbenv/versions/2.1.7/bin/ruby extconf.rb
checking for rb_trap_immediate in ruby.h,rubysig.h... no
checking for rb_thread_blocking_region()... yes
checking for ruby/thread.h... yes
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for inotify_init() in sys/inotify.h... no
checking for __NR_inotify_init in sys/syscall.h... no
checking for writev() in sys/uio.h... yes
checking for rb_thread_fd_select()... yes
checking for rb_wait_for_single_fd()... yes
checking for rb_enable_interrupt()... no
checking for rb_time_new()... yes
checking for sys/event.h... yes
checking for sys/queue.h... yes
checking for clock_gettime()... no
checking for gethrtime()... no
creating Makefile

make "DESTDIR=" clean

make "DESTDIR="
compiling binder.cpp
In file included from binder.cpp:20:
./project.h:116:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
         ^
1 error generated.
make: *** [binder.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/tkmiya34/work/startup-technology/yaqs/yaqs-development/vendor/bundle/ruby/2.1.0/gems/eventmachine-1.0.5 for inspection.
Results logged to /Users/tkmiya34/work/startup-technology/yaqs/yaqs-development/vendor/bundle/ruby/2.1.0/extensions/x86_64-darwin-15/2.1.0-static/eventmachine-1.0.5/gem_make.out
An error occurred while installing eventmachine (1.0.5), and Bundler cannot
continue.
Make sure that `gem install eventmachine -v '1.0.5'` succeeds before bundling.
```

# 解決方法
エラーメッセージ見たら`openssl`に問題がありそう。
`openssl`はhomebrewでインストールしています。

調べてたら`eventmachine`の[GitHub Issue](https://github.com/eventmachine/eventmachine/issues/588)に載っていました

```
$ brew link openssl --force
Linking /usr/local/Cellar/openssl/1.0.2d_1... 1548 symlinks created
```

もう一度 `bundle install`したらインストール成功しました
GitHubの初期設定〜GitHubにSSH接続するまでの設定手順〜

## はじめに
GitHubで開発するための初期設定である、GitHubにSSH接続するまでの設定手順について書いています。 

毎度、新しい環境にGitHubの設定をする度に調べている自分がいたので自分向けの備忘録として書いております。あしからず。誰かのお役に少しでもなれましたら


## 前提
```
・GitHubのアカウントは登録済
・クライアントPCはMacを前提としています
```

### 公開鍵と秘密鍵の作成

GitHubにssh接続するためには公開鍵をGitHubに登録する必要があります
クライアントPC（Mac）に公開鍵と秘密鍵を作成します

鍵を作るためディレクトリへ移動します

```
$ cd ~/.ssh/
```

下記のコマンドを叩いて、鍵を生成します
※ 3回くらい確認を求められますが、enterでOKです 

```
$ ssh-keygen -t rsa
```

鍵を確認します
id_rsa（秘密鍵）と id_rsa.pub（公開鍵）のファイルが作られていればOKです
id_rsa.pub がGitHubへ登録する公開鍵となります

```
$ ls -l
```

### クライアント側（Mac）へのSSHキーの設定

今後、GitHubの接続先を複数管理したりする時に楽なのでクライアント側にSSHの設定を書いておきます。

```
$ vim ~/.ssh/config
```

```lang:~/.ssh/config
Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  User git
```

### 公開鍵をGitHubに登録

GitHubにログインし下記ページへ移動します
https://github.com/settings/ssh

画面右上 「Add SSH Key」 をクリックします

![スクリーンショット（2015-11-03 19.18.20）.png](https://qiita-image-store.s3.amazonaws.com/0/38342/36c6a622-9b1c-b00e-f0cf-dd933a435f17.png)

"title" の項目に公開鍵の名前（任意の名前でOK）と、"key" の項目に先ほど作成した公開鍵の内容を貼付けます。
内容を確認し、"Add key" をクリックします

```lang:クリップボードにコピー（mac）
$ pbcopy < ~/.ssh/id_rsa.pub
```

```lang:クリップボードにコピー（windows）
$ clip < ~/.ssh/id_rsa.pub
```

![スクリーンショット（2015-11-03 19.22.40）.png](https://qiita-image-store.s3.amazonaws.com/0/38342/bfdbf409-2237-4d04-75fb-4707ba17144e.png)

## 接続のテスト

```
$ ssh -T git@github.com
```

下記のような表示がされていれば成功です

```
Hi {account-name}! You've successfully authenticated, but GitHub does not provide shell access.
```

以上で完了です。お疲れさまでした :kissing_heart: :ghost:
gitでローカルとリモートで異なるリポジトリ名を使う


余りこんなことする人いないだろうけど．ちょっとそういう必要に迫られたので.どうすればいいんだろうと思ったが．githubでローカルと異なる名前のリポジトリを作成しておいて以下のようにするだけだった．考えてみれば当たり前．

git remote add origin https\://github.com/githubユーザ名/リモートリポジトリ名.git
docker-composeを使ってnode.js開発環境を整える

# docker-composeを使ってnode.js開発環境を整える

Docker Language Stackの[golang](https://hub.docker.com/_/golang/)などを見るとcontainerの中でbuildやmakeする使い方が書かれている。

```shell-session
$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.3 go build -v
$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.3 make
```

これをdocker-composeを使ったらもう少し楽にできるような気がしたので、nodeの開発環境をdocker-composeを使ってみたらどうなるか?の試み。composeの使い方としては亜流な気もするが(汗。コードは[node-dev-container](https://github.com/fnishio/node-dev-container)参照。

## Dockerfile

必要なツールのインストールされた docker image を作っておく。
 `$ docker build -t node-dev .`

```shell:Dockerfile
FROM node:latest

# install tools
RUN npm install -g gulp \
&& npm install -g coffee-script \
&& npm cache clear
```

## docker-compose
開発に必要なコマンド(node/npm/gulp)や初期インストール用のコマンド(express-install/gulp-install) をserviceとして定義する。

```yaml:docker-compose.yml
default: &default
  image: node-dev
  volumes:
    - $PWD:/usr/src/app
  working_dir: /usr/src/app

node:
  <<: *default
  entrypoint: ['node']
  ports:
    - "3000:3000"

npm:
  <<: *default
  entrypoint: ['npm']

gulp:
  <<: *default
  entrypoint: ['gulp']

init:
  <<: *default
  command: npm init

express-install:
  <<: *default
  command: npm install express --save

gulp-install:
  <<: *default
  command: npm install gulp gulp-coffee --save-dev
```

例えば、expressで開発するなら

```shell-session
$ docker-compose run --rm init   # package.jsonを作る
$ docker-compose run --rm express-install  # express.js インストール
(app.jsを実装して)
$ docker-compose run --service-ports node app.js # node 実行
```

## まとめ
docker-composeのone-offコマンドを使ってcontainer内の開発環境をうまく使えないかと試してみたが、dockerコマンドから使うのに比べてさほど「楽」にはならなかった。workflowに必要なコマンドやvolumeのマウント、portのマッピングをdocker-compose.ymlにまとめておける点に多少メリットはある気もする。

あと container内で gulp の watch が何故かうまく動かない…
複数GitHubアカウントに対応したSSH認証キー設定(Mac用)

# はじめに

GitHubのアカウントを複数持っている場合、(例えばプライベートと仕事用など)
リポジトリ毎に使用するアカウントを指定したい事があると思います。
それ、SSHの設定をすれば簡単にできちゃうんです。

# SSH認証キー作成

```shell-session
ssh-keygen -C "yourmail@example.com" -f ~/.ssh/github-your-github-name
```
上述の*your-github-name*の部分はGitHubアカウントの名前が入ります。

パスフレーズは入力した方がセキュアです。
ただしパスフレーズを設定した場合後述の問題が発生する場合があります。

これを利用したいGitHubアカウント分用意します。

# GitHubへ公開鍵を登録

1. https://github.com/settings/ssh を開いて**Add SSH Key**ボタンを押します
2. **Title**に*github-your-github-name*を入力します。
3. **Key**に*~/.ssh/github-your-github-name.pub*の内容を入力します。

```shell-session
pbcopy < ~/.ssh/github-your-github-name.pub
```
で~/.ssh/github-your-github-name.pubの内容をクリップボードにコピーできます(Mac限定)
4. 入力が終わったら**Add Key**を押して完了です。
5. これを利用したいGitHubアカウント分繰り返します。

# .ssh/configの設定

```
Host github-your-github-name
	User git
	HostName github.com
	IdentityFile ~/.ssh/github-your-github-name
	TCPKeepAlive yes
	IdentitiesOnly yes
```
上記をGitHubアカウント分~/.ssh/configに追記します。

# アクセステスト

無事設定が終わったらアクセステストをしてみましょう。

```shell-session
ssh github-your-github-name -v
```

うまくいけば、

```
(中略)
Hi your-github-name! You've successfully authenticated, but GitHub does not provide shell access.
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
Connection to github.com closed.
Transferred: sent 3448, received 2008 bytes, in 0.8 seconds
Bytes per second: sent 4232.6, received 2464.9
debug1: Exit status 1
```

と表示されるはずです。

# gitリポジトリのclone

```shell-session
git clone git@github-your-github-name:NameOrTeam/Repository.git
```
*your-github-name*にはそのリポジトリにアクセスしたいGitHubアカウントが入ります。
*NameOrTeam/Repository.git*にはGitHubのリポジトリ名が入ります


# 既存のリポジトリをアカウント毎のSSH接続に切り替える

```shell-session
cd YourRepos
git remote show origin
```

としたとき

```
* remote origin
  Fetch URL: https://github.com/NameOrTeam/Repository.git
  Push  URL: https://github.com/NameOrTeam/Repository.git
```

や

```
* remote origin
  Fetch URL: git@github.com:NameOrTeam/Repository.git
  Push  URL: git@github.com:NameOrTeam/Repository.git
```

と表示されている場合アカウント毎の設定になっていません。

```shell-session
git remote set-url origin git@github-your-github-name:NameOrTeam/Repository.git
```

とすることで指定のアカウントに切り替えが可能です。
正しく設定されれば、```git remote show origin```したとき

```
* remote origin
  Fetch URL: git@github-your-github-name:NameOrTeam/Repository.git
  Push  URL: git@github-your-github-name:NameOrTeam/Repository.git
```

と表示されるはずです。

# ログイン直後にSourceTree等でリポジトリにアクセスできない場合

SSH認証キーにパスフレーズが設定されている場合、
SourceTree等を使ってFetchしたときにサーバに接続できない場合があります。

```shell-session
ssh-add github-your-github-name
```

を試してみてください。
Raspberry Piと.NETでAzure IoT Hubを使うときの制限

Azure IoT Hubが面白そうだったので試してみてたんだけど、Raspberry Piから使うには色々と制限が多くて自分がやりたいことがまだできる状況じゃなかった。せっかく調べたので調べた範囲でその制限をまとめておく。

とは言えIoT HubもIoT Hub用のSDKもまだプレビュー版なのでできないことが多いのは当たり前で、今後その制限もなくなっていくと思う。

IoT HubとSDKについては以下を参照。

[Azure IoT Hub | Microsoft Azure](https://azure.microsoft.com/ja-jp/services/iot-hub/)
[Azure/azure-iot-sdks](https://github.com/Azure/azure-iot-sdks)

# 前提条件
上にも書いた通り網羅的に調べたわけではなく自分がやりたいことに関係する部分だけしか調べていないので、この記事での条件を挙げておく。

+ 2015年11月3日時点での状況
+ Raspberry Pi上の.NETのプログラムからIoT Hubを使うときの制限

IoT HubのSDKは.NET向け以外にもC、Java、Node.js向けのものが用意されているけど、今回は.NET向けだけが対象で他については分からない。

それとデバイスもRaspberry Piに限定してる。最初にIoT Hubのチュートリアル（[Azure IoT Hub の使用 | Microsoft Azure](https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-csharp-csharp-getstarted/)）をWindows + C#で試した時は問題なく動いた。

# 制限
## Raspbianでは.NETはサポートされていない
SDKが対応するハードウェア、プラットフォーム、言語の組み合わせが下に書いてある。

[azure-iot-sdks/tested_configurations.md at master · Azure/azure-iot-sdks](https://github.com/Azure/azure-iot-sdks/blob/master/doc/tested_configurations.md)

これを見るとRaspberry PiとC#の組み合わせはRaspberry Pi 2 + Windows IoTしか対応していない。言い換えると、.NET向けSDKはWindows（デスクトップ）とWindows IoTにしかまだ対応してないので、それをインストールできるRaspberry Pi 2との組み合わせしか対応していない。なので、Raspberry Piの他のモデル（A+など）やRaspbianで.NET用のSDKを使いたくても使えないのが今の状況。

ただ、Monoサポートの計画はあるみたいなので、今後Raspbianでも使えるようになるかもしれない。

[C# SDK with AMQP Transport under Mono fails to run · Issue #64 · Azure/azure-iot-sdks](https://github.com/Azure/azure-iot-sdks/issues/64)

Issueのページから機能の投票ページへのリンクがあるので、対応してほしい人はぜひ投票してください。

## Windows IoT + C\#ではAMQPプロトコルに対応していない
**[2016/05/03 追記]
[Microsoft Azure Devices Client 1.0.6](https://www.nuget.org/packages/Microsoft.Azure.Devices.Client/)でAMQPに対応した（Windows IoT(10.0.14295.1000) on Raspberry Pi 3で動作確認済み）。
正確にはもう少し前のバージョンでAMQPをサポートするようになっていたけれど、実行すると例外が発生していた。
1.0.6で問題が解決して使えるようになった。**


上に載せた[リンク](https://github.com/Azure/azure-iot-sdks/blob/master/doc/tested_configurations.md)の表を見ると、Windows IoT + C#ではHTTPSだけサポートしていると書いてある。

IoT HubではAMQPとHTTP（HTTPSって書いてないけどどっちもHTTPだからだと思う、たぶん）をサポートしているけど、可能な限りAMQPを使うように勧めている。

[IoT Hub の開発者ガイド トピック - 通信プロトコルの選択 | Microsoft Azure](https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-devguide/#amqpvshttp)

AMQPの利点の1つは、サーバープッシュに対応してるのでIoT Hubからデバイスへのメッセージがすぐに届くところ。

例えば、あるデバイスにつながっている人感センサーが反応したときに別のデバイスにつながっているライトを点灯させたいとする。AMQPを使うとセンサーが反応したときにIoT Hub経由で別のデバイスにメッセージをタイムラグなしで送ることができるので、センサーが反応したときにすぐにライトを点灯させることができる。対してHTTPでは多くても25分に1回（IoT Hubのガイドライン準拠）しかIoT Hubに届いているメッセージを確認できないので、応答するまでにタイムラグが発生して使い物にならない。

そういうわけでAMQPが使えないのは結構大きい制限。

ただこれもまだ実装されていないだけでサポートする計画はあるみたいだ。

[UWP apps only HTTP support ? · Issue #79 · Azure/azure-iot-sdks](https://github.com/Azure/azure-iot-sdks/issues/79)

それと、リンク先に書いてあるようにHTTPにもメリットはあるので、AMQPとHTTP（と他のプロトコル）が選べる状況になるのが一番いい。

# 最後に
最初に書いた通り現時点での状況なので、今後何か進展があったら追記する予定。
表記 > 2進数 > 最後にbをつける > 111b

16進数の表記が`0x`で始めればいいというのは覚えているが、2進数はソースコメントでどう表記するか忘れた。

参考
https://www.uquest.co.jp/embedded/learning/lecture01.html
> 2進数：最後に「b」をつける
GoでXMLをパースする

必要に迫られたのでサンプルを書いてみます。
[はてなブックマークのテクノロジーカテゴリの人気エントリーのRSS](http://b.hatena.ne.jp/hotentry/it.rss)をパースしてみましょう。

標準の`encoding/xml`を使います。

```go:xml_parse.go
package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

type XML struct {
	Bookmarks []struct {
		Title string `xml:"title"`
		Link  string `xml:"link"`
		Date  string `xml:"date"`
		Count int    `xml:"bookmarkcount"`
	} `xml:"item"`
}

func main() {
	data := httpGet("http://b.hatena.ne.jp/hotentry/it.rss")

	result := XML{}
	err := xml.Unmarshal([]byte(data), &result)
	if err != nil {
		fmt.Printf("error: %v", err)
		return
	}

	for _, bookmark := range result.Bookmarks {
		datetime, _ := time.Parse(time.RFC3339, bookmark.Date)

		fmt.Printf("%v\n", datetime.Format("2006/01/02 15:04:05"))
		fmt.Printf("%s - %duser\n", bookmark.Title, bookmark.Count)
		fmt.Printf("%v\n", bookmark.Link)
		fmt.Println()
	}
}

func httpGet(url string) string {
	response, _ := http.Get(url)
	body, _ := ioutil.ReadAll(response.Body)
	defer response.Body.Close()
	return string(body)
}
```

それでは、実行してみましょう

```bash
$ go run xml_parse.go

2015/11/03 17:05:18
Microsoft、「OneDrive」の無料容量縮小ヘ　“容量無制限”は終了 - ITmedia ニュース - 38user
http://www.itmedia.co.jp/news/articles/1511/03/news033.html

2015/11/03 14:06:00
Microsoft、｢OneDrive｣のプラン内容の変更を発表 ｰ 無制限廃止や無料容量の縮小（15GB⇒5GB）など | 気になる、記になる… - 28user
http://taisy0.com/2015/11/03/60454.html

2015/11/03 12:13:58
一眼レフカメラVSスマホのカメラ！あなたはどっち派？ - YUチャンネルブログ - 45user
http://yuchanel.hatenablog.com/entry/2015/11/03/%E4%B8%80%E7%9C%BC%E3%83%AC%E3%83%95%E3%82%AB%E3%83%A1%E3%83%A9VS%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%AE%E3%82%AB%E3%83%A1%E3%83%A9%EF%BC%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AF%E3%81%A9%E3%81%A3%E3%81%A1

・
・
・
```

`encoding/json`を使ってJSONをパースする場合とほとんど違いがありませんね。
tmuxのwindowを分割してコマンドを同時実行するシェルスクリプトを作った

[tmuxで複数サーバの同時オペレーション | NaviPlus Engineers' Blog](http://tech.naviplus.co.jp/2014/01/09/tmux%E3%81%A7%E8%A4%87%E6%95%B0%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E5%90%8C%E6%99%82%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/)にtmuxのウィンドウを分割して、複数サーバに同時にログインして同じ作業をするスクリプトがある。

以下のコマンド

```
$ tmux_ssh reco-app0{1,2} reco-db0{1,2}
```

を実行すると、ウィンドウが4分割されて、それぞれ、reco-app01, reco-app01, reco-db01, reco-db02にログインして、synchronize-panes onされて、すべてのペインに同じキーが送られるようになる。

これと同じようなことをssh以外でもやりたいのでコマンドを作った。

* [tmsanrinsha/tmux_multi](https://github.com/tmsanrinsha/tmux_multi)

例えば、

```
$ tmux_multi ssh {} \; reco-app0{1,2} reco-db0{1,2}
```

と打つと、{}部分が、後ろの引数に置き換わって、tmux_sshと同じような作用をする。ただし、確認してから実行したいのでEnterは自分で打つことにした。実行までしたいときは^M（Ctrl+V Ctrl+M）を打つ。

```
$ tmux_multi ssh {}^Mhostname^M \; reco-app0{1,2} reco-db0{1,2}
```

このように打つと、サーバに入った後、hostnameが実行される。

引数をファイルから読み込むことも可能で、

```sh:hostlist
# reco-app00
reco-app01
reco-db01
reco-db02
```

のようなファイルを用意すると、#から始まる行は無視して、コマンドが実行される。指定は以下の様な感じ。

```
$ tmux_multi scp file {}: \; -f hostlist
```

ファイルは複数指定可能だが、引数と混ぜることは出来ない。

ファイルにコマンドを羅列してもよい。

```:commandlist
ssh reco-app01^Mhostname^M
ssh reco-app02^Mhostname^M
```

```
$ tmux_multi {} \; -f commandlist
```

synchronize-panesのon/offを簡単に行うためにキーバインドを設定しておくといいと思う。

```:.tmux.conf
bind-key S set-window-option synchronize-panes
```

on, offを書かないとトグルになる。

sync中かをステータスラインに設定することもできる。

```:.tmux.conf
set -g status-left '#{?pane_synchronized,#[bg=red],}[#S]'
```

もっと複雑なことをやりたい場合は、[tmuxinator](https://github.com/tmuxinator/tmuxinator)を使えばいいのかもしれない。
How to infer MAP estimate of HMM with OpenGM


OpenGMのpythonインターフェイスを使ってHMMでラベル系列の事後確率最大推定．

```py:準備
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

import opengm
```

データは以下のもの．時系列データの整数化・平滑化を試す．

```py:データ
d = '17.2 19.7 21.6 21.3 22.1 20.5 16.3 18.4 21.0 16.1 17.5 18.5 18.4 18.3 16.0 21.2 18.8 24.3 23.3 20.5 16.9 22.4 20.1 24.5 24.2 22.7 19.6 23.6 23.3 24.6 25.0 24.3 22.2 22.7 19.5 20.5 17.3 17.2 22.0 20.9 21.5 22.3 24.0 22.4 20.2 15.7 20.4 16.3 17.7 14.3 18.4 16.6 13.9 15.2 14.8 15.0 11.5 13.4 13.5 17.0 15.0 17.5 12.3 11.8 14.5 12.4 12.9 15.8 13.8 11.4 6.5 5.9 7.2 5.6 4.6 7.5 8.9 6.6 3.9 5.7 7.3 6.1 6.8 3.1 2.6 7.9 5.2 2.0 4.0 3.4 5.7 8.1 4.7 5.4 5.9 3.6 2.9 5.7 2.1 1.6 2.3 2.4 1.2 4.2 4.2 2.4 5.6 2.5 3.0 6.1 4.9 7.1 5.0 7.2 5.2 5.1 10.4 8.3 6.9 6.8 7.8 4.2 8.0 3.2 7.9 5.9 9.5 6.4 9.2 11.7 11.6 15.5 16.7'
d = np.array([ float(c) for c in d.split()])
```

ではHMMモデルの構築と推論の実行．

```py:実行!
nNodes = d.shape[0] # ノード数．
nLabels = 20 # 離散クラスの数．20
variableSpace = np.ones(nNodes)*nLabels # 各ノードのラベル数．ここでは全部同じ
gm = opengm.gm(variableSpace)

# unary
for i in range(nNodes):
    u = np.array([ abs(d[i] - j) for j in range(nLabels) ]) # データ項．ラベルとの差の絶対値
    f = gm.addFunction(u)
    gm.addFactor(f, i)

# pairwise
p = 10 # 隣接するノードのクラスが異なった場合のコスト．（同じなら0）
pairwise = np.array((np.ma.ones((nLabels,nLabels)) - np.eye(nLabels)) * p) # ペアワイズ項．同じラベルなら0，異なるならp
f_pw = gm.addFunction(pairwise)
for i in range(nNodes-1):
    gm.addFactor(f_pw, [i, i+1]) # ノードを連結するエッジの設定．HMMなので1次元．

inf = opengm.inference.DynamicProgramming(gm=gm) # 推論アルゴリズム：1次元なのでDPで十分
inf.infer() # 推論実行
res = inf.arg() # 結果を回収

# プロット．
plt.plot(d, label="data")
plt.plot(res, label="result")
plt.legend()
```

![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/44835/3e062178-db89-a4fb-7484-6a721de44b41.png)
コードの種類と作成ルール

#コードの種類
コードには次の種類が存在する。

- Specification(以下Specコード):仕様中心
- Maintenance(以下Maintコード):保守中心
- Perfomance(以下Perfコード):性能中心
- Enviroment(以下Envコード):環境中心
- Legacy(以下Legaコード):既存中心

コードを作成する時に作りたい内容をそのまま記述して終わりであれば、Developerの悩みは半分になるだろう。しかし実際には色々な理由でコードが変わる。

## Specコード:仕様中心
要求される仕様通り変換されたコードを意味する。

```java:spec.java
// Spec: valAとvarBが一致しない

// Bad: specの表現と一致しない。
if (valA == varB) {
  // 一致する場合の処理
} else {
  // 一致しない場合の処理
}

// Good: specの表現と一致する。
if (valA != varB) {
  // 一致しない場合の処理
} else {
  // 一致する場合の処理
}
```

## Maintコード:保守中心
処理内容の変更が発生する場合、簡単に改修できるようにするコードを意味する。

```java:maint.java
// Maint: typeの値が「a」→「b」に変わった。

// Bad: 似てる値では分かり難い。ミスする可能性が高い。
if (type == "a") {
 // process
}
if (type == "a" && kind == "a") {
 // process
}

// Good: 同じ値でも各意味が分かりやすい。
public static final String TYPE_INIT = “a”; 
public static final String KIND_MESSAGE = “a”; 

if (type == TYPE_INIT) {
 // process
}
if (type == TYPE_INIT && kind == KIND_MESSAGE) {
 // process
}
```

## Perfコード:性能中心
処理内容は変わらないが、性能問題(速さ、容量)の理由で適用するコードを意味する。

```java:maint.java
// Perf: メモリ不足による性能が落ちている。メモリ増設はできない場合

// Bad
String s = "a";
for(int index = 0; index < 100000000; index++){
    s += "b";
}


// Good
StringBuilder sb = new StringBuilder("a");
for(int index = 0; index < 100000000; index++){
    sb.append("b");
}
String s = sb.toString();
```


## Envコード:環境中心
言語の文法又はライブラリVersion内容の差による固有のコードを意味する。

## Legaコード:既存中心
既存コード(機能、作成ルール)を理解してできる限り影響を与えないようにするコードを意味する。

#コード作成ルール
[Underscore.js] 配列を指定した個数の配列に分割する


rubyでいう`Enumerable#each_slice`のようなことをunderscore.jsでやりたかったんですが、ドンピシャ一発取りできる関数って用意されてないみたい・・。というわけで、メモっておきます。

以下の例は [1, 2, 3, 4, 5, 6, 7] を [[1, 2, 3],[4, 5, 6],[7]] に変換する例です。

```javascript:例
var arr = [1, 2, 3, 4, 5, 6, 7];
var slice = 3;
return _.values(_.groupBy(arr, function(v, i) { return Math.floor(i / slice) }));
```
iMovieを使ってiPhoneアプリの紹介ビデオをつくる

# はじめに

iPhoneアプリの紹介ビデオをiMovieを使って作成する方法を紹介します。Simulatorではなく、実機の画面をキャプチャします。

# 画面タッチを可視化する

まず、画面タッチをわかりやすく可視化するために、アプリのコードに少々手を加えます。今回はCOSTouchVisualizerを使いました。

conopsys/COSTouchVisualizer
https://github.com/conopsys/COSTouchVisualizer

説明どおり実装すれば割と少ない変更で画面操作を可視化できるようになります。色・透過率などは自由にカスタマイズ可能です。

# 画面をキャプチャする

QuickTime Playerを使います。

- iPhoneをケーブルでMacに接続
- QuickTime Player: 「ファイル > 新規ムービー」を選択
- 「カメラ」から、接続されたiPhone名を選択
- 「マイク」から、接続されたiPhone名を選択
- 品質を選択

![スクリーンショット 2015-11-04 22.12.16.png](https://qiita-image-store.s3.amazonaws.com/0/55814/6a4ebd97-bc1a-d259-a8e0-f9b930b01418.png)

これで、iPhoneの画面がMac上に表示されるようになります。あとは、赤丸をクリックして録画開始すればOK。「ファイル > 保存...」を選択して、movファイルを保存できます。

# iMovieへの取り込み

キャプチャしたmovファイルをiMovieに取り込みます。あとは、背景・タイトルを自由に設定すればOK。ただ、iMovieのタイトル作成機能はかなり使いづらいので、別ソフトで背景＋タイトル（解像度:1920x1080）を作成しておいて、iMovie上で背景として挿入して、キャプチャしたビデオと合成するのがおすすめです。

この際、背景・タイトル画像を下側に、キャプチャしたビデオを上側に配置します。こうすると、ポートレート表示をキャプチャしたビデオの左右には背景が合成されて表示されるようになります。

![スクリーンショット 2015-11-03 0.55.27.png](https://qiita-image-store.s3.amazonaws.com/0/55814/b6e8ae0e-03d5-f7c9-0d7f-ae2632b1f684.png)

ちなみに背景・タイトル作成には、私は以下のアプリを使っています。

Sketch 3
https://www.sketchapp.com/

編集が終わったら、iMovieの「ファイル > 共有 > ファイル...」を選択。解像度、品質、圧縮のオプションを選択して保存すれば、MP4ファイルができあがります。

あとはこのMP4ファイルをYouTubeなどにアップすればOK。

こんな感じのビデオを作ることができます。
https://www.youtube.com/watch?v=C4BcRF9jP04
RailsでMaterial Design Liteを使う

# Material Design Lite (MDL)
Googleの提供しているデザインフレームワーク
[Material Design Lite](http://www.getmdl.io/index.html)  
マテリアルデザインのサイトを作れます
![MDL Templates](http://www.getmdl.io/assets/templates/blog.jpg)


# 前提条件
参考環境
Rails 4.2.4
Ruby 2.2.1
MDL 1.0.6

# 導入
1. [Download](http://www.getmdl.io/started/index.html#download)ページからjsとcssの一式を入手
2. Railsの`app/assets/javascripts/`に`material.js`ファイルを、`app/assets/stylesheets/`に`material.css`ファイルをコピー

# 使い方
[components](http://www.getmdl.io/components/index.html)ページに書いてある通りにパーツを使う

# turbolinksを使わない
RailsのturbolinksはMDLと相性が悪い。turbolinksが有効だと、最初のページ読み込み時は正常に動作するけど、ページ遷移とかすると途端にMDLが動作しなくなってしまう。

## 対応策:turbolinksをオフにする
turbolinksがオンのまま使う方法もありそうだけど、すぐに動かしたいときなどは以下の方法がオススメ。
`lang:app/assets/javascripts/application.js`にturbo linksを使用するように設定されているので、その行を削除する。


**変更前**

```lang:app/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require turbo links
//= require_tree .
```

**変更後**

```lang:app/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require_tree .
```

以上でMDLがRailsで動きました。おしまい。


# 参考URL
http://qiita.com/imatomi/items/2a59f74a88b8e7545c7b
a++ & ++aの違い = 前置インクリメントと後置インクリメントに違い



```
Which choice is the output value of the following code:
var a = 0
let b = ++a
let c = a++
print("\(a)  \(b)  \(c)") //211
```

```

注釈

If the operator appears before the variable, it increments the variable before returning its value.

もしオペレータが変数の前に表示される場合は、オペレーターが値を戻す前に、その変数をインクリメント(加算)します。

If the operator appears after the variable, it increments the variable after returning its value.

もしオペレータが変数の後に表示される場合は、オペレーターが値を戻した後、その変数をインクリメント(加算)します。
```

##インクリメントとは

インクリメント = 変数の値を「1」増やす処理の事を表す。
この時、前置と後置の明確な違いは、「処理(計算)順序」が変わる事にある。
前置の場合はほかの演算よりも先に変数の値を1増加させる処理を行う。
++a => aを１つ増やしてから、その結果を式の値として返す
後置の場合はほかの演算よりも後に変数の値を1増加させる処理を行う。
a++ => aの値を返した後に、aを一つ増やす。

コードで表すと下記のようになる。

```
var a = 0
let b = ++a
let c = a++
print("\(a)  \(b)  \(c)")


//インクリメントを使用しないで、記述する場合

var a = 0

//let b = ++a
//aの値を一つ増やしてから、その結果を式の値として返す。
a = a + 1
let b = a 

//let c = a++
//aの値を返した後に、aの値を一つ増やす。
let c = a
a = a + 1

print("\(a) \(b) \(c)")

```

##練習
```
インクリメントを使わずに、一つ一つの計算結果を理解しておく。

var a = 5

//let b = ++a + 5

a = a + 1 
let b = a + 5

//let c = a++ + 5
let c = a + 5
a = a + 1

print("\(a) \(b) \(c)")
```

##答え

```
// 7 11 11
```

参照
https://programmer-engine.work/archives/16831
http://ai-future.hatenablog.jp/entry/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E6%9C%AA%E7%B5%8C%E9%A8%93%E3%81%8D%E3%81%A4%E3%81%84
確率的クワイン

# はじめに

[クワイン(Quine)](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AF%E3%82%A4%E3%83%B3_%28%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%29)とは、自身のソースコードと同じ文字列を出力するコードのこと。ちゃんとやると面倒なので、確率的にクワインになるスクリプトを書いてみた。

# スクリプト

```rb:quine.rb
52.times{print"\"().245[\]acdehimnprst{}"[rand(24)]}
```

要するに自分のスクリプトに含まれる文字種全てを、ランダムに自分のスクリプトの長さだけ出力するスクリプト。文字は24種、スクリプトの長さは52文字なので、1/(24**52)の確率でクワインになります(投げやり)。

# 90億の神の御名

アーサー・C・クラークの短編で「[90億の神の御名](https://ja.wikipedia.org/wiki/90%E5%84%84%E3%81%AE%E7%A5%9E%E3%81%AE%E5%BE%A1%E5%90%8D)」というのがある。チベットの僧侶が神のあらゆる可能な御名をつらねたリストを編纂しているが、人間の手では時間がかかりすぎるというので、コンピュータの力を借りたいという。コンピュータを使えば実時間で「可能な神の名」を列挙することができるのだが、リストが完成すると世界は・・・という話。

ちなみに上記の確率的クワイン、手元の環境で/dev/nullに10万回出力するのに4.41秒かかったので、自分自身が出力され、見事クワインになる時間の期待値は2.6e67秒、えーと、8.3e59年くらい？ 宇宙の年齢が138e8年とからしいので、とりあえずこの宇宙でどんなに頑張って並列処理しても、上記スクリプトがクワインになることはなさそうですね(投げやり)。
OpenCVで肌色領域を認識させてみた

# やりたいこと
前回の記事では、AndroidのアプリケーションにOpenCV3.0を導入して、カメラ映像をグレースケールに変換する簡単な例を記述しました。

http://qiita.com/yokobonbon/items/0804d0418bf7dd612b66

今回やる内容は、前回の記事の続きと考えて下さい。

カメラ映像の中から肌色部分を抽出して、四角で囲むといった処理を行います。実行した結果は以下のようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/85182/523fa564-bc6e-f008-a4e5-a8a456d617f4.png)

# SkinDetector
このクラスでは以下のような流れで処理がされています
1. RGBからHSVに変換 (HSVなどの方が映像が輝度の影響を受けにくいそうです）
2. ノイズがのりやすいので、平滑化します
3. 肌色のしきい値内のあたり領域を取り出します
4. 領域の中で一番大きい領域を返します

```java
public class SkinDetector {
    private static SkinDetector sInstance;

    private static Scalar sLowerb;

    private static Scalar sUpperrb;

    private SkinDetector() {
        sLowerb = new Scalar(0, 58, 88);
        sUpperrb = new Scalar(25,173,229);
    }

    public static SkinDetector getInstance() {
        if (sInstance != null) {
            return null;
        }
        sInstance = new SkinDetector();
        return sInstance;
    }

    public static MatOfPoint getMaxSkinArea(Mat rgba) {
        if (rgba == null) {
            throw new IllegalArgumentException("parameter must not be null");
        }

        Mat hsv = new Mat();
        Imgproc.cvtColor(rgba, hsv, Imgproc.COLOR_RGB2HSV);
        Imgproc.medianBlur(hsv, hsv, 3);

        Core.inRange(hsv, sLowerb, sUpperrb, hsv);

        ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Mat hierarchy = new Mat(hsv.cols(), hsv.rows(), CvType.CV_32SC1);
        Imgproc.findContours(hsv, contours, hierarchy, Imgproc.RETR_LIST,
                Imgproc.CHAIN_APPROX_NONE);

        if (contours == null) {
            return null;
        }

        double maxArea = 0.0f;
        int maxIdx = 0;
        for (int i = 0; i < contours.size(); i++) {
            double tmpArea = Imgproc.contourArea(contours.get(i));
            if (maxArea < tmpArea) {
                maxArea = tmpArea;
                maxIdx = i;
            }
        }

        return contours.get(maxIdx);
    }
}
```

# 肌色領域を四角で描画する
onCameraFrameは前回の記事で説明させて頂いた通り、毎フレーム事に呼び出されます。

ここで先ほど作成した、SkinDetectorから肌色領域を取得し、その領域を四角の枠で元映像い付加して出力します。

SkinDetectorで取得される領域から四角の範囲を取得するには、Imgproc.boundingRectを用いることでRectが取得できます。

あとは、Imgproc.rectangleで四角を描画することが可能です。Imgprocにはこれ以外にも円とか、三角とかも記述できる関数が用意されています。

```java
    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        Mat rgba = inputFrame.rgba();
        MatOfPoint maxArea = SkinDetector.getInstance().getMaxSkinArea(rgba);
        if (maxArea != null) {
            Rect rectOfArea = Imgproc.boundingRect(maxArea);
            Imgproc.rectangle(rgba, rectOfArea.tl(), rectOfArea.br(), RECT_COLOR, 3);
        }
        return rgba;
    }

```

# 最後に

OpenCVには簡単に画像認識や画像処理ができる関数郡が用意されており、とても便利です。またNativeのコードを記述しなくてもJavaだけでも簡単な処理であればパフォーマンスが出せることが確認できました。
AWS+SVN環境構築メモ

初めてAWSに触り、SVNの環境を構築してみました。
その際のつまりポイントや参考にしたサイトなどをまとめています。
※このあたりの技術には疎い為、誤表記があるかもしれませんが悪しからず

途中、svn+ssh:// でやろうとしていたところ、
TortoiseSVNの設定でつまり、
「ややこしいからWebDavでやったほうが良い」とのアドバイスをいただき、
Apacheを使って、ポート：80 でやってみました。
ラクでした！
※AWSのセキュリティグループに設定追加するのをお忘れなく


## 参考にさせて頂いたサイト ##

[AWSの設定方法](http://usedoor.jp/howto/web/aws/ec2-make-instance/)
[SSHの設定方法](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/putty.html)
[Apacheの設定方法]
(http://promamo.com/?p=2924)
[SVNの設定方法[1]](http://www.mori-soft.com/2008-08-15-01-36-37/2008-12-07-09-39-26/119-ec2-subversionredmine-25)
[SVNの設定方法[2]](http://bokuibi.blogspot.jp/2011/12/subversion.html)
[Linuxコマンド一覧 - vi](http://www.k4.dion.ne.jp/~mms/unix/linux_com/vi.html)

ありがとうございます..！！
上記で一通り作成できました。
以下、メモ項です。
　
## リポジトリの場所 ##
/var/svn/hogehoge_project

## SVNの情報を見る ##
$ svn info file:///var/svn/hogehoge_project/

## Apache設定ファイル ##
/var/apache2/conf/httpd.conf
に↓追記

```conf:httpd
Include "/var/apache2/conf/extra/httpd-svn.conf"
```

## アカウント設定（チェックアウトはできるようになる） ##
$ cd /var/apache2/conf
$ sudo htpasswd -m ./.htpasswd.svn [ユーザー名]
この次に[パス]を入力してね★的な文言が出るので入力します。

## Apache再起動 ##
$ apachectl restart

## httpd-svn.confに追記する内容 ##

```conf:httpd-svn
<Location /svn>
    DAV svn
    # enable view for repositories parent directories
    #SVNPath "/var/svn/hogehoge_project"
    SVNParentpath "/var/svn/hogehoge_project"
    SVNListParentPath On
 
    # read/write accesses force Basic auth
    AuthType Basic
    AuthName "Subversion repository"
    AuthUserFile /var/apache2/conf/.htpasswd.svn
    Require valid-user
</Location>
```


## チェックアウト時のエラー ##
コマンド: リビジョン HEAD の http://[パブリックIP]/svn をチェックアウト, 再帰的, 外部を含む
エラー: Unable to connect to a repository at URL 'http://[パブリックIP]/svn'
エラー: Unexpected server error 500 'Internal Server Error' on '/svn'
完了:

→ リポジトリのパスを修正　ルートをsvnにして解消！
　

## コミット時のエラー ##
コマンド: コミット
エラー: コミットに失敗しました (詳しい理由は以下のとおりです):
エラー: Can't open file '/var/svn/hogehoge_project/db/txn-current-lock': Permission
エラー:  denied
完了:

→ chown -R apache:apache /var/svn で解消！
　

## チェックアウトの場所 ##
http://[パブリックIP]/svn/hogehoge_project
　

## 設定完了 ##
やっとできました！楽しいうれしい！！
個人的にはコマンドラインを使用するのが久しぶりで（しかも知識が浅く）
少し苦労しました。
これでUnityの共同作業が捗りそうです。

ちなみにSVN管理しているUnityのファイルは、
Assets, ProjectSettingsのみで、ひとまずアタリをつけて進めています。
※Library, Tempは無視リストに追加しました

機会を見つけてGitも導入したいです。
PHPエラー出力レベルを php.iniに設定する

# 内容
PHPのエラーレベルについて、実行時設定をphp.iniに設定する。

# OS
```shell-session
$ cat /etc/redhat-release
```
CentOS release 6.6

# php.iniでの設定

```shell-session
$ php --version
PHP 5.5.25

$ sudo vim /etc/php.ini

  error_reporting = E_ALL
  display_errors = On

$ sudo service httpd restart
```

デフォルトの設定は以下だった。
`error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT`

**E_DEPRECATED**
PHP 5.3.0 以降。
将来のバージョンで動作しなくなるコードについての警告を受け取る。

**E_STRICT**
PHP 5.4.0以降。
E_ALLに含まれる

ドキュメント
http://php.net/manual/ja/errorfunc.configuration.php

エラーレベルを設定する上で、以下のビット演算子のドキュメントは参考になる
http://php.net/manual/ja/language.operators.bitwise.php
Xcode 7 でビルドしたアプリを iOS 7 シミュレータで動かす


Xcode 7 の iOS シミュレータでは iOS7 以前の iOS を動作させることができません (iOS 8.1 以降のみ)。

実機で動かすのがもちろん確実ですが、その分端末を用意する必要があります。とりあえず、ざっくり iOS7 で動作確認したいというときにはシミュレータで確認できると楽です。

Xcode は異なるバージョンを共存させることができるので、iOS7 での動作確認するときには Xcode 6 でビルドする方法もあります。しかしこの方法だと Xcode 6 では iOS9 に対応できず、iOS9 SDK 向けのコードでビルドに失敗したりします。

ということで、Xcode 7 でビルドしたアプリを iOS7 上のシミュレータにインストールできればいいわけです。

# 用意するもの

* Xcode 6
* Xcode 7
* ターミナルアプリ

# 手順

1.  Xcode 7 でアプリをビルドする。Xcode 7 を使うのはここだけ

2.  Xcode 6 を立ち上げて、シミュレータを起動する

3.  シミュレータで利用したいデバイスに切り替える (例えば、iOS 7.1 iPhone 5s）。
    この手順は飛ばしてもいいんですが、#5 でアプリをシミュレータにインストールが楽になります。
       
4.  `xcode-select`コマンドで Xcode 6 に切り替える

    ```sh
    $ sudo xcode-select -s /Applications/Xcode6.app/
    ```
    ここでは `/Applications/Xcode6.app/` としていますが、Xcode 6 のパスを指定します。
    `xcode-select` コマンドは通常 `sudo` で実行する必要があると思います。El Capitan では未確認。

5.  `simctl` コマンドを使って #1 でビルドしたアプリをインストーリします。

    ```sh
    $ xcrun simctl install booted ${APP_PATH}
    ```
    ここで `${APP_PATH}` は #1 でビルドしたアプリのパスです。この探し方については後述。
    `booted` は現在起動中のシミュレータを指定するオプションです。`booted` の代わりにシミュレータにインストール済みのデバイスを UUID で指定することもできます。
    
6.  インストールしたアプリをシミュレータ上で起動します。


シミュレータで動作確認した後は xcode-select コマンドを再度実行して Xcode 7 に戻しておくことを忘れずに……。

```sh
$ sudo xcode-select -s /Applications/Xcode.app/
```


## ビルドしたアプリがどこにあるのかを調べる方法

特にビルド場所について設定していなければ、Window メニューから Projects ウィンドウから確認できます。

1.  Xcode (Xcode 6 でも Xcode 7 でもどちらでも大丈夫) の Window メニューから Projects ウィンドウを開きます。
    ![Screen_Shot_2015-11-03_at_21_15_57.png](https://qiita-image-store.s3.amazonaws.com/0/17936/f94871fb-57d2-df4f-0803-a34bac6010a8.png "Screen_Shot_2015-11-03_at_21_15_57.png")
    

2.  プロジェクトリストからターゲットのプロジェクトを選択します。
    ![Screen_Shot_2015-11-03_at_21_16_07.png](https://qiita-image-store.s3.amazonaws.com/0/17936/6f459577-9a49-c3f2-5727-220ae11e3d15.png "Screen_Shot_2015-11-03_at_21_16_07.png")

    Derived Data の矢印をクリックすると、該当箇所を Finder で開くことができます。

4.  Build → Products → ターゲット (例えば、Debug-iphonesimulator) とたどります。
    ![Screen Shot 2015-11-03 at 21.18.51.png](https://qiita-image-store.s3.amazonaws.com/0/17936/ff50b500-bb2d-a512-78f3-15b1f01549f7.png "Screen Shot 2015-11-03 at 21.18.51.png")
swiftの演算子に関して


##Comparison operators 比較演算子

swift演算子に関して記述していきます。

```
Equal to (a == b)
Not equal to (a != b)
Greater than (a > b)
Less than (a < b)
Greater than or equal to (a >= b)
Less than or equal to (a <= b)
```

##Ternary Conditional Operator 三項条件演算子

(question ? answer1 : answer2) = 条件式 ? 式1 : 式2 式の評価がtrueなら式１、falseなら式2を返す。

```
gender == 0 ? print("male") : print("female")
```

```
The example above will evaluate the expression gender == 0. If true, it prints "male". Otherwise, it prints "female".

上記の例では、gender == 0を評価し、trueならmaleを、falseならfemaleを出力する。
```

```
Guess the value stored in the "rowHeight" variable value of the following code:
let height = 40 
let isCheck = true 
let rowHeight = height + (isCheck ? 50 : 20) // ??
```

##Range operators 範囲演算子

```
Range Operators

Swift offers two range operators, which are shortcuts for expressing a range of values.

The closed range operator (a...b) defines a range running from a to b, and includes the values a and b. The value of a must not be greater than that of b.
1...3 //1, 2, 3

The half-open range operator (a..<b) defines a range that runs from a to b, but does not include b. It is said to be half-open because it contains its first value, but not its final value. As with the closed range operator, the value of a must not be greater than that of b.
1..<3 //1, 2
```

##Logical operators 論理演算子

```
Logical Operators

Logical operators modify or combine the Boolean logic values true and false. Swift supports the three standard logical operators found in C-based languages:

Logical NOT operator (!a): Inverts a Boolean value so that true becomes false and false becomes true.

Logical AND operator (a && b): Creates logical expressions in which both values must be true for the overall expression to be true.

Logical OR operator (a || b): An infixed operator made from two adjacent pipe characters. It creates logical expressions in which only one of the two values has to be true for the overall expression to be true.
```

##Optional type or value　オプショナル型

```
オプショナル型は「その値が宣言した型(Int)か値がない状態を示すnilを保持していること」を表している。

Optionals are used in situations in which a value may be absent. 
An optional says:
-There is a value, and it equals x
or
-There isn't a value at all
var myCode: Int? = 404

An optional Int is written as Int?, not Int. The question mark indicates that the value contained within is optional, meaning that it might contain some Int value, or it might contain no value at all. 
```

参照　https://programmer-engine.work/archives/16831
duplicate symbol _OBJC_IVAR_$_HOGEHOGECLASS.value〜というビルドエラーが出た場合


ネット上で検索すると、よく

```
#import hegehegeclass.h
```

とするところを

```
#import hogehogeclass.m
```

としていた間違いが多いのだけれど、今回の場合は違った。

原因を調べたところ、hogehogeclass.mとhogehogeclass.hを他projectから持ってくるときの追加方法が悪かったらしく、

```
設定の「TARGET」-「Build Phases」-「Compile Sources」に同じクラス名が二つ入っていた
```

必要のない片方を消すことで、問題なくビルドができるようになった。
WEBページからメーラーを宛先、件名、本文を設定して起動する方法

```html:mailto

<a href="mailto:abcd@mailaddr.com?subject=[送信タイトル]&body=-------本文------- %0D%0A 本文内容">メーラー起動</a>

```
メーラーを起動した場合の本文の表示内容

```text:メーラー本文

-------本文-------
 本文内容

```


* mailto: にメールアドレスを設定
* subject= に件名
* body= に本文

を設定

本文を設定する際に改行を使いたい場合は「%0D%0A」を入れると可能

その他

```html:mailto

<a href="mailto:abcd@mailaddr.com?subject=[送信タイトル]&body=-------本文------- %0D%0A 本文内容&bcc=TEST@test.com,test2@test.com&cc=test@test.com">メーラー起動</a>

```

* cc= でccの宛先メールアドレス
* bcc= でbccの宛先メールアドレス

が可能
ccやbccで複数アドレスを設定したい場合は「,」で区切って設定できます。
anyenvをHomebrewでインストールできるようにしてみた

## 使い方

```
$ brew tap mumoshu/anyenv
$ brew install anyenv --HEAD
```

## ソースコード

https://github.com/mumoshu/homebrew-anyenv

## つくった経緯

普段Macで開発してるのですが、ミドルウェア類はDocker上、アプリは場合によってMacやVagrantで作成した仮想マシン上、コマンドラインツール、IDEその他はMac上で動かしてます。Mac上で動かすアプリ以外のものは基本的に全てHomebrew + [homebrew-file](https://github.com/rcmdnk/homebrew-file)で入れてます。

そろそろanyenvを使い始めようかな…と思ったところbrew installできなかったので、簡単に作れるものなら作ってみよう…ということで作ってみました。

## つくり方

(1) GitHub上の `mumoshu/homebrew-<formula名>` というレポジトリに、(2) 以下の様な内容の `homebrew-<formula名>.rb` を置くだけ。

```rb
class Anyenv < Formula
  desc "anyenv - all in one for **env" if respond_to? :desc
  homepage "https://github.com/riywo/anyenv"
  head "https://github.com/riywo/anyenv.git"
  version "5693de4"

  def install
    inreplace "libexec/anyenv", %Q|ANYENV_ROOT="${HOME}/.anyenv"|, %Q|ANYENV_ROOT="#{prefix}"|
    prefix.install Dir["*"]
  end

  def caveats; <<-EOS.undent
    Add the following to the ~/.bashrc or ~/.zshrc file:
      echo 'eval "$(anyenv init -)"' >> ~/.your_profile
    EOS
  end

  test do
    shell_output("eval \"$(#{bin}/anyenv init -)\" && anyenv version")
  end
end
```

mumoshu/homebrew-anyenvというGitHub上のGitレポジトリに置くと、`brew tap mumoshu/anyenv` で取り込めるようになります。brew tapの引数に渡すtapの名前のほうでは、Gitレポジトリ名にある `homebrew-` というプレフィックスが省略されることに注意。

Formula書き方は、[Homebrewのドキュメント「Formula Cookbook」](https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/Formula-Cookbook.md#formula-cookbook)のとおりです。

Formulaの説明文を指定する `desc` メソッドは、古いHomebrewだとNoMethodErrorになってしまうようなので注意。上のコード例では `if respond_to? :desc` で、呼べるときだけ説明文を指定するようにして雑に対処してます。実際、Travis CI上のMac OS X環境に入っているHomebrewだとNoMethodErrorになったので、やっておいて損はないかと思ってます。
どのくらいの点推定値になる時、どのくらいの信頼区間になるんですか？

イベント割合に関して。
どのくらいの点推定値になる時、どのくらいの信頼区間になるんですか？という質問は意外と多い。
その時に使えるのが、下記。

```
CI<-function(y,z,alpha){
for(i in 10:y){
ans1 <- binom.test(round(i*z*0.01,0)-1, i, conf.level = alpha*0.01)
ans2 <- binom.test(round(i*z*0.01,0),   i, conf.level = alpha*0.01)
ans3 <- binom.test(round(i*z*0.01,0)+1, i, conf.level = alpha*0.01)

print(c(i,round(i*z*0.01,0)-1, (round(i*z*0.01,0)-1)/i ,ans1$conf.int[1:2]))
print(c(i,round(i*z*0.01,0)  ,  round(i*z*0.01,0)   /i ,ans2$conf.int[1:2]))
print(c(i,round(i*z*0.01,0)+1, (round(i*z*0.01,0)+1)/i ,ans3$conf.int[1:2]))

}
}
```

引数としては
yは標本の大きさをどのくらいまで考えるか。
zは考えたい点推定値（整数値で指定）→56％なら0.56ではなく、56と入力
alphaは信頼区間を何％で指定するか。（整数値で指定）多くの場合は95%かな。

いろいろ考えるのが面倒だったので、とりあえず周辺のプラマイ１くらいのものを全部出力して、あとから、必要部分をサーチしていく形で。
ちなみに標本の大きさ一桁は実験として少なすぎなので出力しないことにしています。（実は１桁だとエラーが出るｋ・・・）

ということで標本の大きさを15、点推定値75％、95%信頼区間と考えると、


```
> CI(15,75,95)
```
| 標本の大きさ|イベント|点推定値|信頼区間の下限|信頼区間の上限|
|:-----------|:------------:|:------------:|:------------:|------------:|
|10.0000000|  7.0000000|  0.7000000|  0.3475471 | 0.9332605|
|10.0000000|  8.0000000  |0.8000000  |0.4439045|  0.9747893|
|10.0000000|  9.0000000  |0.9000000  |0.5549839|  0.9974714|
|11.0000000 | 7.0000000  |0.6363636  |0.3079047|  0.8907366|
|11.0000000 | 8.0000000  |0.7272727  |0.3902574|  0.9397823|
|11.0000000 | 9.0000000  |0.8181818  |0.4822441|  0.9771688|
|12.0000000 | 8.0000000  |0.6666667  |0.3488755|  0.9007539|
|12.0000000 | 9.0000000  |0.7500000  |0.4281415|  0.9451394|
|12.0000000 |10.0000000  |0.8333333  |0.5158623|  0.9791375|
|13.0000000 | 9.0000000  |0.6923077  |0.3857383|  0.9090796|
|13.0000000 |10.0000000  |0.7692308  |0.4618685|  0.9496189|
|13.0000000 |11.0000000  |0.8461538  |0.5455289|  0.9807933|
|14.0000000 | 9.0000000  |0.6428571  |0.3513801|  0.8724016|
|14.0000000 |10.0000000  |0.7142857  |0.4189647|  0.9161107|
|14.0000000 |11.0000000  |0.7857143  |0.4920243|  0.9534207|
|15.0000000 |10.0000000  |0.6666667  |0.3838037|  0.8817589|
|15.0000000 |11.0000000  |0.7333333  |0.4489968|  0.9221285|
|15.0000000 |12.0000000 | 0.8000000  |0.5191089|  0.9566880|


こんな感じになりました。

出力部分はちょっと例としてよくないな・・・。

改良必要。
coding79 > うまく機能したコーディング(+プラクティス)リスト 

2015年7月中旬からの4カ月ほどで下記のようなコーディングを行った。

- C++ Builderプロジェクト
- 組込みCプロジェクト
- Unity 小プログラム (いくつかはgithubに公開済)
- RPi2 小プログラム
- VisualStudio 小プログラム

上記のコーディングトータル : (おそらく)1100時間程度
上記以外、勉強のための写経コーディング : 100時間程度

これらコーディングをしていく中で自分としてはうまく機能したと思えるコーディング（＋プラクティス)について記載する。

すでに本に記載されている事項が多いかもしれない。

他に良い方法があるかもしれないが、「現在」自分がいいと思う事項を掲載している。今後「あれは間違いだった」というのは当然起こりうる。

書いている事項の間の矛盾もあるかもしれない。

各記事は限定公開にして、こちらのリンクとして掲載する。「これは間違いだった」という時に公開を取り下げる可能性はある。

この記事を書く理由は、「何がどううまくいったか」の整理。

<hr>
下記、順番には意味はない。
ある程度まとまった記事から以下のリストに追加する。

- [#if 0でなく if(false) { にする](http://qiita.com/7of9/private/8d97523070ac4dde5b7a)
- [TODOリストを作成し、編集しながら作業する](http://qiita.com/7of9/private/91f9eb8e2868c38521ac)
- [C++実装できるものはC実装でなくC++実装とする](http://qiita.com/7of9/private/25826c430af4e79a2c65)
- [Off-by-one error 対策 > idx_st1 を使う](http://qiita.com/7of9/private/067d8a5a633e0976d6fe)
- [覚えている数値を使う > 3.141592 / 2.7182 / 0.5772 ...](http://qiita.com/7of9/private/5ad5a16d8b8ba46496d6)
- [ポインタを書替える > #if 1 char szbuf[100]; dstPtr = &szbuf[0];](http://qiita.com/7of9/private/009081a0d6705c52e03b)
- [寿司屋のカウンターのように整理する](http://qiita.com/7of9/private/89c1395fe124db1f316c)
- [ソースリーディングを意識した実装をする](http://qiita.com/7of9/private/35f42bba099e8b847241)
- [情報を追いすぎない](http://qiita.com/7of9/private/911386931224abca0eb3)
- [座標を意識する](http://qiita.com/7of9/private/2f61482572fae58f10ad)
- [テスト関数内の関数呼び出しが明確になるようにする > someFunc(valTest);](http://qiita.com/7of9/private/63d201916ba0a38fc885)
- [探し物は後でする / 思いつきはTODOリストに追加](http://qiita.com/7of9/private/dfb72c17034d99527def)
- [過去の方法にとらわれない](http://qiita.com/7of9/private/7a92cf4ae02aa3c7a538)
- [ソースリーディングに時間がかかるコードはリファクタリングする](http://qiita.com/7of9/private/709580602bc82cd46cd2)
- [違和感の解消を行う](http://qiita.com/7of9/private/bf623f8bf3318a89c3d7)
- [スコープの広い変数は具体的な名前に (typeIndex) / 引数の名前は省略形に (typeIdx)](http://qiita.com/7of9/private/bb63cb49fa8616daed54)
- [IDEのエラー機能を使う](http://qiita.com/7of9/private/bb0f493a65f7e7a3928a)
- [最初は構造化をしすぎない > 動くコード作った上で、TDDをしながら、リファクタリングする](http://qiita.com/7of9/private/b68d4ac62c8de59b5b1a)
- [UIとロジックを分離する](http://qiita.com/7of9/private/eb6c49d742966a051aa6)
- [まずは具体的な名前にする > 後から簡単な名前にするのは簡単](http://qiita.com/7of9/private/a23a0dd5f682bcc1349e)
- [適材適所のツールを使う / ただし、最新のツールを追いすぎない](http://qiita.com/7of9/private/d791c2fb4f35c787609f)
- [メインとなるものは何かわかるようにしておく](http://qiita.com/7of9/private/e7b9cb643d8ff2edce08)

(以下、追記 2018/02以降)

- [関数のコール場所をコメントで記載する (賛否両論)](https://qiita.com/7of9/private/678f7826bb30d78b5f09)
Selenium でスクレイピング [Python]

PythonにてSeleniumを用い、スクレイピングを行う。

# 0. 環境
MacOSX10.11.1

### CentOSの場合
Xvfb その他諸々が必要
参考: [CentOS6.4 + Selenium の環境作成](http://qiita.com/u_s_k/items/1ee410f87d8651b5a4df)

# 1. [pipでSeleniumをインストール](http://selenium-python.readthedocs.org/installation.html#downloading-python-bindings-for-selenium)
```bash

$ sudo pip install selenium
```

### CentOSの場合

別途、ライブラリのインストールが必要。

```bash

$ sudo pip install pyvirtualdisplay
```
http://stackoverflow.com/questions/26070834/how-to-fix-selenium-webdriverexception-the-browser-appears-to-have-exited-befor


# 2. 実行
## 2.1. Seleniumをインポート

```py
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# pyvirtualdisplayを用いる場合
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1024, 768))
display.start()
```

## 2.2. ブラウザ(FireFox)を開く
```py

driver = webdriver.Firefox()
```
後からLinux（CentOS）でスクリプトを回す際に、
FireFoxの方が便利（楽）なのでFireFoxを使う。

## 2.3. URLを開く
```py
url = "http://google.com"
driver.get(url)
```

## 2.4. ブラウザを閉じる
```py
driver.close()

# pyvirtualdisplayを用いる場合
display.stop()
```