OmniAICreator/Qiita-1.07M huggingface dataset:
[Unity] カメラに写っているかで処理を分岐する


基本的にはUnityの機能をそのまま使うのでいいかなと思います。
→詳しくはこちらを参照ください（[カメラに写っている間のみ処理を行う](http://tsubakit1.hateblo.jp/entry/20131007/1381156232)）

## 使えるメソッド

- OnBecameVisible
- OnBecameInvisible

これらは、可視／不可視状態になった際に呼ばれるMonoBehaviourのコールバックです。

ただ、シーンエディタ上のカメラで撮影された場合にも呼ばれるとのことで、デバッグ環境では若干使いづらいかもしれません。

その場合に使えるのが

- OnWillRenderObject

です。
これは、撮影されるカメラごとに一度呼ばれるコールバックで、`Camera.current` で、現在撮影中のカメラの情報にアクセスすることができます。
ここで、`SceneCamera` を除外することで、上記の問題であるシーンエディタ上でのデバッグも問題なく行える、というわけです。


さて、以上がUnity上のサイクルによる処理ですが、自前で計算をしてふんわり処理を行いたい場合は、以下のようにマトリクスをうまく使ってやることで処理が可能です。

## 概要

普通に、プロジェクション変換まで座標を持っていって計算する方法です。
要はクリッピング領域内外の判定をCPUで行う、ということですね。

### 行列計算

```csharp
Matrix4x4 V = _camera.worldToCameraMatrix;
Matrix4x4 P = _camera.projectionMatrix;
Matrix4x4 VP = P * V;
```

こんな感じで各種マトリクスを取得することができます。
それを先に `VP` 行列として計算しておきます。
これに、自身の `transform.position` をかけてあげればプロジェクション空間に座標が変換されます。

### デバイス正規化座標系への変換

続いて、計算されたベクトルから `w` 除算を経て、デバイス正規化座標系へ変換します。
これにより、すべての `x, y, z` 座標は `-1.0 ～ 1.0` の範囲に正規化されます。
（逆にこの値に収まっていない場合は、計算中の点が視錐台の外にあることを示しています）

```csharp
var p = transform.position;
Vector4 pos = VP * new Vector4(p.x, p.y, p.z, 1.0f);

if (pos.w == 0)
{
    IsInView = true;
    return;
}

float x = pos.x / pos.w;
float y = pos.y / pos.w;
float z = pos.z / pos.w;
```

あとは、計算された `x, y, z` それぞれの値を比較し、`-1.0 ≦ x(y, z) ≦ 1.0` の範囲かを調査して、範囲外だった場合は表示されていない、ということにすれば目的達成です。

ただ、これはあくまでカメラの視錐台内に入っているか、を計算しているに過ぎないので、仮に前面になにか大きなオブジェクトがあって視界を覆っていても、計算上は「見えている」ことになる点に注意が必要です。
（ただそれは、Unityのコールバックも同様です）

```csharp
if (x < -1.0f)
{
    IsInView = false;
    return;
}
if (x > 1.0f)
{
    IsInView = false;
    return;
}

if (y < -1.0f)
{
    IsInView = false;
    return;
}
if (y > 1.0f)
{
    IsInView = false;
    return;
}

if (z < -1.0f)
{
    IsInView = false;
    return;
}

if (z > 1.0f)
{
    IsInView = false;
    return;
}

IsInView = true;
```

あとは、この `IsInView` の変化を監視して、`true` だったらカメラに映っている、`false` だったら映っていないとして処理を分岐してあげればOKです。
Mac OSX でのスクリーンショット（プリントスクリーン/画面キャプチャー）方法

# Mac OSXでのスクリーンショット（プリントスクリーン/画面キャプチャー）方法
## はじめに
MacOSXでの画面キャプチャー（スクリーンショット）方法
いつも忘れるので自分用備忘メモ

画面全体
`Command(⌘) + Shift + 3` キーを押す

一部分（範囲指定）
`Command(⌘) + Shift + 4` キーを押す
マウスポインタが十字に変わるのでドラッグして範囲を指定する

ウィンドウ指定
`Command(⌘) + Shift + 4` キーを押す
マウスポインタが十字に変わるで、`Space` キーを押す　
マウスポインタがカメラアイコンに変わったら
取りたいウィンドウの上でクリック（キャンセルは`esc`）


これでデスクトップにpngファイルができる。

## 参考
https://support.apple.com/en-us/HT201361
https://support.apple.com/ja-jp/HT201361
EdgesHelperでマンガ風表現


helperをあえて残しておくことで、マンガ風の表現ができるようになる

デモ：https://mo49.github.io/qiita/20160908/edge.html

```javascript
genEdge(obj) {
  const edges = new THREE.EdgesHelper(obj, 0x000000);
  this.scene.add(edges);
}
```

> 参考
[【three.jsのヘルパー解説集】 ⑦EdgeHelperの使い方](http://qiita.com/sawa-zen/items/24f68c74362f63fe1d39)
[three.jsのエッジ描画と現状の問題点](http://flabo.io/code/20141217/01-draw-3d-with-threejs-2/)
vimperatorで突然履歴のサジェスチョンが効かなくなった場合に試すこと

Firefoxを使い続ける理由第1位(俺調べ)であるところのvimperatorですが、なぜか突然open,tabopen時にhistoryからのサジェスチョンが効かなくなってしまいました。まったく原因はわからないですが、そんな時に効く対処療法です。

## .vimperatorrcに追記する内容

```.vimperatorrc
nnoremap t :set<Space>cpt=lh<CR>:tabopen<Space>
nnoremap o :set<Space>cpt=lh<CR>:open<Space>
```

## 関係するヘルプ
<img width="640" alt="Screen Shot 2016-09-27 at 14.01.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/1101e86a-a1f6-4046-4ca4-a0e103379b1f.png">



cptにhを追加してやるのがミソ。デフォルトはslなので、lの機能が突如効かなくなってしまったと思われます。
hで履歴をサジェストするように強制指定。ついでにsはいらないので削除。bやhは遅くなるらしいですが背に腹は変えられんところです。

完全に対処療法ですが参考になれば。
Ubuntuで古いバージョンのKernelイメージを削除する方法

/bootの容量が100%になってしまうと、apt-get等のコマンドに失敗する、そうなる前の対策。

# 定期的に古いカーネルがあるか確認
## 確認方法
現在実行中のカーネルを確認

```shell-session
$ uname -r
3.13.0-76-generic
```

インストール済みカーネルイメージの確認

```shell-session
$ dpkg --get-selections | grep image
genisoimage                                     install
libcupsimage2:amd64                             install
libxcb-image0:amd64                             install
linux-image-3.13.0-24-generic                   install
linux-image-3.13.0-68-generic                   install
linux-image-3.13.0-70-generic                   install
linux-image-3.13.0-71-generic                   install
linux-image-3.13.0-73-generic                   install
linux-image-3.13.0-74-generic                   install
linux-image-3.13.0-76-generic                   install
linux-image-3.13.0-77-generic                   install
linux-image-3.13.0-79-generic                   install
linux-image-extra-3.13.0-24-generic             install
linux-image-extra-3.13.0-68-generic             install
linux-image-extra-3.13.0-70-generic             install
linux-image-extra-3.13.0-71-generic             install
linux-image-extra-3.13.0-73-generic             install
linux-image-extra-3.13.0-74-generic             install
linux-image-extra-3.13.0-76-generic             install
linux-image-extra-3.13.0-77-generic             install
linux-image-extra-3.13.0-79-generic             install
linux-image-extra-3.13.0-83-generic             install
linux-image-extra-3.13.0-96-generic             install
linux-image-generic                             install
```

## 古いカーネルを削除
単品削除

```shell-session
$ sudo apt-get remove linux-image-3.13.0-24-generic
```

複数同時削除

```shell-session
$ sudo apt-get remove linux-image-3.13.0-{24,68,70}-generic
```

## 実際にディスク上から削除

```shell-session
$ sudo apt-get autoremove
$ sudo update-grub
```

## どうしても消えない場合
/bootの容量を強制的にあける(rmで古いkernel関係のファイルを削除)
/bootの容量が空いてきたら、以下を実行して再起動。

```shell-session
$ sudo apt-get -f install
$ sudo apt-get autoremove
```

※本当はやりたくありませんが。。。
以上
Perlでバーコード(Code128)をpng出力＆HTML画像埋め込みする方法

# Barcode::Code128を使ったバーコード出力
## 関連ライブラリをインストール
GD関連
```shell-session
$ sudo apt-get install libgd-dev
$ cpanm GD
```
本体のライブラリをインストール
```shell-session
$ cpanm Barcode::Code128
```
## テストコード
```pl
use Barcode::Code128;

my $code = new Barcode::Code128;

open(PNG, ">code128.png");
binmode(PNG);
print PNG $code->png("12345A");
close(PNG);
```

[Barcode::Code128の使い方](http://search.cpan.org/~wrw/Barcode-Code128-2.01/lib/Barcode/Code128.pm)

# バーコード画像をHTML埋め込み出力
出力したバーコード画像をBase64にデコードして、HTMLに埋め込む。
```shell-session
$ cpanm MIME::Base64
```

## テストコード
```pl
use Barcode::Code128;
use MIME::Base64;

my $code = new Barcode::Code128;

# output html
my $img = $code->png("AIUEO");
my $img_base64 = encode_base64($img, '');

print '<img src="data:image/png;base64,' . $img_base64 . '">';
```

## 出力結果
```html
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOQAAAA3AgMAAABhkw6fAAAADFBMVEXMzMz/AAAAAAD////ghtjGAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAHRJREFUSInt1cEJwCAMBdCQSXrsmOI4/5IRulcOTb8doEUPSml+DmrggYiiYDTyG3kEA48w93ALBAc3sKz1WeDynrBhhgbOlClTpkw5Ta74HT4lM6/ZFSoVpf+wqmyUolI6IcUqiQGJZbudLCufmo7chMxzLgWrZR49PA+KAAAAAElFTkSuQmCC">
```

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOQAAAA3AgMAAABhkw6fAAAADFBMVEXMzMz/AAAAAAD////ghtjGAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAHRJREFUSInt1cEJwCAMBdCQSXrsmOI4/5IRulcOTb8doEUPSml+DmrggYiiYDTyG3kEA48w93ALBAc3sKz1WeDynrBhhgbOlClTpkw5Ta74HT4lM6/ZFSoVpf+wqmyUolI6IcUqiQGJZbudLCufmo7chMxzLgWrZR49PA+KAAAAAElFTkSuQmCC">
Integrating with setuptools / python setup.py test / pytest-runner

[pytestお勉強](http://qiita.com/mkisono/items/4771111002287dd42de7)の続き。公式ドキュメントや[逆引きpytest](http://qiita.com/FGtatsuro/items/0efebb9b58374d16c5f0)を参考に試しています。

pytestを、以下のコマンドで実行できるようにします。やり方は[ここ](http://docs.pytest.org/en/latest/goodpractices.html#integrating-with-setuptools-python-setup-py-test-pytest-runner)に書いてある通りです。

```bash
python setup.py test
```

setup.pyファイルに設定を追加します。coverageのプラグインも入れています。

```setup.py
setup_requires = [
    'pytest-runner',
    ]

tests_require = [
    'pytest-cov',
    'pytest',
    ]

setup( # 一部を抜粋
      setup_requires=setup_requires,
      tests_require=tests_require,
      )
```

setup.cfgファイルに設定を追加します。coverageやテストにかかった時間を表示するオプションを設定しています。

```setup.cfg
[aliases]
test=pytest

[tool:pytest]
addopts = --verbose --durations=0 --cov=app --cov-report=html
testpaths = tests
python_files = *.py
```

参考
* [pytest-runner](https://pypi.python.org/pypi/pytest-runner)
【メモ】chromeで印刷の改ページ位置が直らない時の対応

【メモ】
paddingやmarginが影響している場合があるので、
page-breakやposition、floatを見直してもダメな時は
余白を疑う。

※bootstrapだとrowのネガティブマージンが影響しているので、print.cssで殺しておく。
Ubuntu16.04にOpenCVSharpをインストールした

Ubuntu16.04.2でOpenCVSharpをビルドしようとしたらエラー出たのでメモ。

とりあえずチュートリアルを参考に
[Tutorial for Ubuntu 14.04](https://github.com/shimat/opencvsharp/wiki/Tutorial-for-Ubuntu-14.04)


```bash
#
sudo apt-get install mono-complete

#
sudo apt-get install cmake libgtk2.0-dev libv4l-dev libavcodec-dev libavformat-dev libswscale-dev
cd
wget http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.10/opencv-2.4.10.zip
unzip opencv-2.4.10.zip
cd opencv-2.4.10
cmake .
make -j 4
sudo make install

#
cd
git clone https://github.com/shimat/opencvsharp.git
cd opencvsharp/src
cmake .
make -j 4　#ここでエラー
sudo make install
```

```text:エラー内容
In file included from /home/test/opencvsharp/src/OpenCvSharpExtern/calib3d.h:4:0,
                 from /home/test/opencvsharp/src/OpenCvSharpExtern/calib3d.cpp:1:
/home/test/opencvsharp/src/OpenCvSharpExtern/include_opencv.h:13:39: fatal error: opencv2/calib3d/calib3d_c.h: そのようなファイルやディレクトリはありません
compilation terminated.
```

ヘッダーファイルが無いらしいけどopencvsharp/lib/opencv/include配下にはファイルがあったので、こけてるmakefileを確認すると、

```text:opencvsharp/src/OpenCvSharpExtern/CMakeFiles/OpenCvSharpExtern.dir/flags.make
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.5

# compile CXX with /usr/bin/c++
CXX_FLAGS = -fPIC

CXX_DEFINES = -DOpenCvSharpExtern_EXPORTS

CXX_INCLUDES =
```

となっていたので以下のように修正。

```text
CXX_INCLUDES = -I/home/test/opencvsharp/lib/opencv/include
```

make -j 4を再度実行するとビルドが通りインストールも成功したっぽい。
「DO NOT EDIT!」とか書いてあったけど良かったんだろうか。
Quantum Chemistry - Harmonic Oscillator Model

関連 http://qiita.com/7of9/items/d3a1799928734375f34f

CG分野で使われるSpherical Harmonics。自分の数値シミュレーション計算に用いたいと思い調べると、量子化学の講義にたどり着く。

短く分かりやすそうな159本のビデオを少しずつ消化中。

Quantum Chemistry - Harmonic Oscillator Model
https://www.youtube.com/watch?v=Thy9YXnAY2s&index=42&list=PLm8ZSArAXicL3jKr_0nHHs5TwfhdkMFhh

- 原子がどのように振動するか
- 図
  - Atom1とAtom2がcovariant bondというものでリンクしている
  - covariant bond
  - http://ejje.weblio.jp/content/covariant
- 紫
  - V(r): potential energy (bonding)
  - あらゆるV(r)に対するモデルを欲しい
  - rは0から無限大の値を取る
- 黄色
  - High Energyになると
  - bondが乖離(かいり)する
  - それは、rが無限大の時にVの値が0となることを意味する
- 水色
  - 凝集された状態 (solid や liquid)
  - resits compressionが起きる 
  - それは、rが非常に小さい時にVの値が無限大になることを意味する
- オンレジ
  - 黄色と水色の中間はどうか
  - Gas状態の時
  - 有限のサイズの分子
  - どこかのサイズにおいてLocal Minimumがある
     - V()のr微分=0というオレンジの右上の式
     - V()のrの2回微分>0というオレンジ右下の式
- 左下の図
  - rが「ある長さ(r_0?)」の時に平衡状態になる   
- 白色の式
  - Forceの定義
  - V()のr微分のマイナス
- 右上の図
  - 左側の式をもとに図示した
  - ピンクのV(r)の線
     - rが小さい時に値が非常に大きく
     - rが増加するごとに値が減少していく
     - r0 (r nought)において平衡状態になりV(r)は最小となる
          - nought: https://en.wikipedia.org/wiki/0_(number)
     - r0の点でエネルギーは`-D_e`となる
        - D_e: dissociation energy
     - rがさらに増加するとV(r)が増えていき
     - 最終的に0になる (dissociateする)
- ピンク
   - V(r)は複雑な式となる
- 水色
   - ピンクを近似したもの
   - V2(r)
   - 二次多項式での表現
   - パラボラ表現に別の項を追加したもの
- 緑の式
   - V2(r)の式
   - (r - r0)の二乗の式: パラボラ
   - kは白色の式で与えられる
      - r=r0の時のV()の2回微分
- オレンジと紫
   - 緑の式でr-r0をxと置いた
   - さらにV2()にD_eを足した
- 黄色
   - 緑の式と紫の式から得られる
   - Harmonic Oscillatorの式になっている
[ruby]ruby2.4のEnumerable#sum

### Enumerable#sum

ruby `2.4`で入るらしい`Enumerable#sum`ですが、最初見たときは「あぁ、そういうのも追加されるのか」というぐらいだったのですが、

https://moneyforward.com/engineers_blog/2016/08/04/ruby-core-201607/

で、

> 特定の場合(浮動小数点数の配列とか)には誤差が累積しないアルゴリズムが採用されています

と紹介されていたので、「お？」と思って試してみました。

まず普通に足し算

```sh
% ruby -ve 'p ([0.1] * 10).inject(:+)'
ruby 2.4.0preview2 (2016-09-09 trunk 56129) [x86_64-darwin15]
0.9999999999999999
```

浮動小数点での誤差が正しく（？）でてますね。


次に`sum`で足し算

```sh
% ruby -ve 'p ([0.1] * 10).sum'
ruby 2.4.0preview2 (2016-09-09 trunk 56129) [x86_64-darwin15]
1.0
```

おお！　・・・と思ったら、

http://qiita.com/jnchito/items/9f9d45581816f121af07

によると、

```sh
% ruby -ve 'p ([0.1] * 3).sum'
ruby 2.4.0preview2 (2016-09-09 trunk 56129) [x86_64-darwin15]
0.30000000000000004
```

というケースもあるんですね。
csvのセル内に潜む改行問題


csvのセル内に改行があるとExcelで開けないという闇がある．
ってかそもそも扱いづらくなる．

## 正規表現使ってテキスト処理？

めんどいよね

## Rubyでサクッとスクリプト書いて加工しよう！

`class CSV`つかえばよか

```ruby
require 'csv'

FILEPATH = ARGV[0]

exit 0 if FILEPATH.nil?

# 一回全部読む
arr = CSV.read(FILEPATH)

# 改行をホワイトスペースに変換
arr.each do |a|
	# /\R/はかなり力強い解法 /(\r\n|\r)/がもっと正確
   a.each { |r| r.gsub!(/\R/, " ") unless r.nil? }
end

# 書き換えするお
CSV.open(FILEPATH, "w") do |csv|
   i = 1
   length = arr.length
   arr.each do |a|
      csv << a
      puts "#{i}/#{length}"
      i += 1
   end
end
```

これでなんとかなる．
FOSRestBundleを使った場合の複数ファイルアップロード

Symfony2でFOSRestBundleを使ったAPIサーバに、
複数ファイルをアップロードする処理を実装したときに、
ハマったのでメモを残します。

環境

* Symfony2.8
* FOSRestBundle2.1

# 1. 前提

今回のケースはParamFetcherを利用して、
送信されたファイルを取得するケースです。

ParamFetcherを利用する場合以下の設定がapp/config/config.ymlに必要です。

```config.yml
fos_rest:
    param_fetcher_listener: true
```

# 2. Controllerの実装

Controllerは以下のように実装します。

```HogeController.php
    /**
     * アップロード
     *
     * @Rest\Post("", name="hoge_video_upload")
     * @Rest\FileParam(name="files", map=true)
     */
    public function uploadAction(ParamFetcher $paramFetcher)
    {
        $files = $paramFetcher->get('files');

        $uploadManager = $this->get('hoge.upload_manager');
        $entities = $uploadManager->tryUpload($files);

        return $entities;
    }
```

FileParamに `map=true` オプションをつけるのがポイントで、
これを記載しないと複数のファイルをコントローラで受け取ることができません。

もともとFileParamで複数ファイルを取得できないバグがあったようですが、
つい最近（2016/08）、Ver2.1で修正されたようです。
それまでは複数ファイルの取得は、`$request->files->get('image-data')` で取得するしかなかったようです。

# 3. 参考

https://github.com/FriendsOfSymfony/FOSRestBundle/pull/1474
https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1535
CentOS > MPICH > MPICH2よりもMPICHの方が新しい

```txt:動作環境
CentOS 6.8 
```

yumからMPICHをインストールしようとして調べていて、以下を見つけた。


http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12146331047

> となるので、mpich-autoloadというパッケージは存在するが、mpich2-autoloadというパッケージは存在しないとわかります。2012年にmpich2 はmpichと改名したので、2015年現在ではmpich2よりもmpichの方が新しいということです。

2016年9月現在、mpich2をインストールするのでなく、mpichをyumでインストールするということらしい。


CentOS6.8で調べたら以下となった。

```
> yum list available | grep mpich
...
mpich.i686                                  3.1-5.el6                    base   
mpich.x86_64                                3.1-5.el6                    base   
mpich-autoload.x86_64                       3.1-5.el6                    base   
mpich-devel.i686                            3.1-5.el6                    base   
mpich-devel.x86_64                          3.1-5.el6                    base   
mpich-doc.noarch                            3.1-5.el6                    base   
mpich2.i686                                 1.2.1-2.3.el6                base   
mpich2.x86_64                               1.2.1-2.3.el6                base   
mpich2-devel.i686                           1.2.1-2.3.el6                base   
mpich2-devel.x86_64                         1.2.1-2.3.el6                base   
mpich2-doc.noarch                           1.2.1-2.3.el6                base   
...
```
InvalidOperationException: The operation is not possible when moved past all properties (Next returned false)

[自分のブログの記事](http://enpel.hatenablog.com/entry/2016/09/27/120439)

というわけで表題のエラーの話

今回はEditorGUI.PropertyFieldでVector3型を表示しようとしてできなかったので対応した話。

```
// ここで表題のエラーが出る
EditorGUI.PropertyField(rect, action.FindPropertyRelative("targetPosition"));
```

action.FindPropertyRelative("targetPosition")はVector3型が格納されている
action.FindPropertyRelative("targetPosition").vector3value等を見ると正常に取れている事がわかる

EditorGUI.PropertyField(rect, action.FindPropertyRelative("targetPosition"));
を使いたいけど表題のエラーが出てうまくいかない場合は以下のように直す事で解決ができる。

```
action.FindPropertyRelative("targetPosition").vector3Value = EditorGUI.Vector3Field(rect, "hoge", action.FindPropertyRelative("targetPosition").vector3Value);
```

しかし厳密な解決じゃないというか
例えば

```
var properties = new string[] { "hoge", "fuga", "targetPosition" };
foreach (var p in properties)
{
    EditorGUI.PropertyField(rect, action.FindPropertyRelative(p));
}
```
のようにしたい場合にこまるかもしれない。
1つ2つの例外ならいいかもしれないけどそうもいかないとおもう。

そこについては解決したらまたなんか描きます


### 追記

```

var properties = new string[]{"hoge", "fuga", "targetPosition"};

foreach (var p in properties)
{
    var property = action.FindPropertyRelative(p);
    switch(property.propertyType)
    {
        case SerializedPropertyType.Vector3:
            property.vector3Value = EditorGUI.Vector3Field(rect, property.displayName, property.vector3Value);
            break;
        default:
            EditorGUI.PropertyField(rect, property);
            break;
    }
}
```

これで良さそう
carthageのxcodebuildのversionを指定する

普通にDEVELOPER_DIRを指定すればOKだった

```
$ DEVELOPER_DIR=/Applications/Xcode7.app carthage update SVProgressHUD --platform ios
```

## 背景

Xcode7のアプリとXcode8のアプリをそれぞれメンテする必要があったので、Xcode7を残しつつXcode8を入れてた

するとcarhtage使うときに、デフォルトだとxcodebuildがXcode8のやつを使うようになってて、Xcode7アプリのcarthageビルドができず困っていた

上記のようにDEVELOPER_DIRを指定して、Xcode7(swift2.2)でcarthageビルドすれば無事ビルドできた
WRF > Link > smpar, dmparでの速度 @ Smiling Lifeさん

WRF(Weather Research and Forecasting Model)関連。


以下においてsmparとdmparなどでの処理速度の調査がされている。
http://blog.livedoor.jp/rootan2007/archives/51519663.html

> 以上の環境において4種類のWRF計算を対象に、OpenMPとMPIの配合具合を変化させながら調査してみました。

...

> - ネスティングしている計算でのみSM(OpenMP)による速度向上がある。
> - 使用メモリ容量が小さいときほど、SM並列数が大きくするとよい。

> という2つのことがわかります。

> まず、興味深いことはネスティングをしないと共有メモリの効果が全く出ない、むしろ速度低下につながるということです。

OpenMP, MPICHなどを使って自分の環境でどういう組合せが早いか確認したほうがよさそうだ。
在 iOS 專案 Mock 心得文和意料之外的收穫

最近開始做新的專案，每一次開新專案總是會有一些新的期許和跨出幾步。

前一個專案因為和同事達成共識，所以開始寫部分的單元測試，
這次就開始思考要怎麼 mock 一些相依（耦合）的物件。

那 mock 是什麼呢？
簡單的來說，他是測試替身（test double）的其中一種。
為了可以讓 "目標物件"（SUT, Software Under Test） 可以被獨立測試，就必須隔離與 "相依外部物件"（DOC, Depended-on Component） 的互動

## 對象

這次要 mock 的對象是網路存取層，
以目前的專業來說，網路存取的部分也就是使用 Alamofire 的那一層。

## 過去的做法

過去的做法我覺得比較不好，當時我們是用了一個叫做 "[OHHTTPStubs](https://github.com/AliSoftware/OHHTTPStubs)" 的這個 library ，他是透過直接介入網路存取層，來達成攔截及回傳指定 response 的效果。

不過這個工具還算不錯，有讓我們達成測試串接 web API 時處理回應的部分。

### 哪裡不好？

總覺得哪裡怪怪的，是不是

「沒有辦法達成抽換 mock ，才會用這個方式攔截網路相關的 requests ？」

於是這也是我這次決定要嘗試，連網路存取這個部分，都能夠由自己抽換掉的嘗試。

## 目標

- 不透過第三方套件，就能達成這件事
- 合理的配合物件的可測，而進行重構

## 技術疊之一 → `Protocol`

在這一段時間，大概是這個月初（2016/9），
開始比較熟悉的搭配 Swift 的 protocol 來開發。
（也就是一般人說得針對介面來開發）

類別的行為也能夠開始定義的比較明確、
要替換不同行為的物件，只要有配合指定的 protocol ，
就可以很輕易的抽換掉而不用改太多的東西。

當時心裡就有開始有感覺：
> 這應該就是可以用在測試時，抽換相依物件的技巧

所以我覺得能夠 **熟悉** 怎麼利用 protocol 來開發，是一件很重要的事情。

## 意外的收穫 → Mock 和職責分離的關係

這幾天在寫測試的時候，有會發現有些東西抽不掉。
以我這次碰到的情形來說，就是包裝 Alamofire 的那一層。

即使在設計接口（protocol）和實作的時候會思考職責分離這件事，
不過還是會有意料之外的事情會發生。

原本在設計 protocol 的時候，雖然是有發現怪怪的地方，
但是因為動的起來，就先沒有想太多。
結果在寫測試的時候就發現抽不掉了（囧），
於是就動手來重構。

### 碰到的問題

（這一段沒有看實際的 code 可能會看不懂，會盡可能地寫清楚）

再審視過相關的 protocols 的時候，
就開始發現像是 network client （Alamofire 的包裝類別），
就不能是設定 API 路徑(route)的成員變數。

這樣導致要測試發送 request 和處理 response 的 service classes 的時候，
因為在設計上， service class 有相依 route ，
要 mock 網路存取時，就必須要先 mock route ，才有辦法 mock network client 。

當下就是想「唉呀！」，怪怪的感覺又浮出來了，
不能這樣寫呀， network client 照理來說也不能被包在 route 裡面，
於是就針對這個地方再做重新調整。

### 重構後的結果

在過程中經歷過一次刪除一個多餘 protocol ，調整上一小節的提到職責不正確的地方。
終於達成自由 mock 網路回應的目標了。

而針對職責明確而重構這件事，也是在要達成 mock 這個目標意外的收穫。

## 心得和需要注意的地方

### Protocol 中要抽換的物件的寫法

因為要可以抽換他，就必須要讓使用 protocol 的 class 或是 struct 可以替換，
所以定義時 getter 和 setter 都要加上。

``` swift
protocol MYProtocol {
var something: Any  { get set }
}
```

### 隨時注意職責分離

必須無時無刻的思考每一個 protocol 或是 class 應該或是不應該做什麼事情，不恰當的相依可能會導致

- 模糊了這個 protocol 或是 class 的真正用途
- 在測試時，要抽換 mock 時，會導致抽不了或是多做工

### Server Side 的部分

這個部分的注意點就比較跟測試沒關係，
內容上其實也和前一個專案的心得相同。

Web API 必須要：

- 制定好成功與失敗的回應
- 必須要處理好錯誤結果的回應

第一個，制定好回應的規範，可以讓介接的 client 端知道丟什麼會發生什麼事，
並針對會發生的事情： 
1. 實作對應的 UI 回饋
2. 撰寫針對同一支 API 不同回應的測試，確認都有完整的根據約定處理到

第二個就是要處理錯誤結果：
1. 丟了非約定的內容，必須要有對應的錯誤訊息回傳；不能直接跳 exception 就回吐 HTTP 500 ，讓 client 端無法適當的反應在畫面上。
2. 當有約定的錯誤結果時，必須要遵守。而不會不同的字串 request ，而有時沒處理到或沒接到錯誤。

## 下一步

應該就是 UI 相關的測試了吧！

UI 本身又 UI 類別（UIViewController, UIView 等等）的測試，以及 UI automation 的測試，
主要會先從 UI 類別先著手，
這些都再找機會來嘗試唄！
Padrinoで複数のアプリケーションをマウントしている時に別のアプリケーションのviewを使う

Padrino 0.13.2でのお話です。Padrinoは複数のアプリケーションをマウントして用いることができます。

```ruby:#{Padrino.root}/config/apps.rb
# Mounts sub applications.
Padrino.mount('MyApp::SubApp0', :app_file => Padrino.root('subapp0/app.rb')).to('/subapp0')
Padrino.mount('MyApp::SubApp1', :app_file => Padrino.root('subapp1/app.rb')).to('/subapp1')

# Mounts the core application for this project
Padrino.mount('MyApp::App', :app_file => Padrino.root('app/app.rb')).to('/')
```

この時、夫々のアプリケーションのviewやlayoutは別々の名前空間に存在しますが、例えばadmin用途と一般ユーザ用途でよく似たviewを使いたいことがあります。その場合は、renderにオプション引数でviewとlayoutのパスを指定します。

```ruby:#{Padrino.root}/subapp0/controllers/something.rb
get :index do
  ...
  render "something/index", views: MyApp::App.view_path(""), layout: MyApp::SubApp0.layout_path(:application)
end
```

これでメインのアプリケーションの something/index.haml を、SubApp0のレイアウトを用いて描画することができます。ヘッダやフッタはSubAppの用途によって違うこともあるので、レイアウトも別途指定できるのは便利だと思います。
TensorFlowによる将棋ソフトの開発日誌（ゆっけさんの場合） #1

目次 [TensorFlow将棋ソフト開発日誌 目次](http://qiita.com/YusukeSuzuki@github/items/30bcaf7b14f015493121)

TensorFlow将棋ソフトを作ることにした

経緯
==========

プライベートでTensorFlowを使ったニューラルネットワークを遊んでいるがアプリケーションが思いつかない。ネタに走り過ぎず学習データの調達が容易で他人と価値が共有できるようなものが良い。もともと自分は画像認識をお仕事としてやってきたが画像認識系は個人でやるにはデータセット調達の負担が大きい。規定のタスクのベンチマーク用のデータセットはあるがすでに解かれているタスクをやったって面白くない。

将棋はすでに解かれている（解く試みが多くなされている）タスクではあるものの他者と競技できるという点で面白い。将棋文化自体は個人的に良い印象はなかったがタスクとして楽しそうなのでやってみることにする。なお将棋のルールはよくわかっていない。

アプローチ
===============

Alpha Goに近いアプローチになると思う。入力盤面に対する出力次手について勝敗を基準にロスを与えていく。既存の棋譜を使用するのであれば各手順の盤面について勝敗が紐付いているため各盤面を独立に学習することができる。AI同士の対局から学習する場合は終了してからその対局の各盤面について勝敗を基準に学習する。

既存の棋譜による学習を事前学習的に先に行い以降はAI同士の学習を重視していく。

学習を加速させるために指し手モデルと勝敗予測モデルのふたつを作る。AI同士の学習において（つまり各盤面の勝敗が未決定の学習において）、合理的な手を指していないと学習する対局自体が価値の低いものになってしまう。

対局の1手および全体については以下のような形になる。

- 指し手モデルが次手を出力する
- 勝敗予測モデルが勝敗を予測する
- 勝敗予測モデルの合否によるロスで指し手モデルは学習し、合格が出るまで学習した後に実際に駒を進める
- 対局が終了した段階で勝敗予測モデルが対戦結果による学習を行う

勝敗予測モデルが成長することで指し手モデルは合理的な手をより早く学習し、指し手モデルが成長することで勝敗予測モデルは盤面からの勝敗可能性をより真実に近い形で学習する。これはGANに近いアプローチになっていると思う。

ここまでRNN、LSTMの話題を出していないが将棋とは本質的にはそういうものである。時系列データとして扱うのは対局者の個性というファクターを導入するときであろうと思うが今のところそれは考えていない。

ここまでいろいろ書いたがちゃけば大した自信はない。

モデルの検討
==============================

入力ベクトル、出力ベクトルの設計が一番影響が大きいと見込んでいる。入力ベクトルについてシンプルな形式から学習できるはずのインプリシットな情報をエクスプリシットに与えるかどうかが大きい。つまり例えば盤面から次に可能な手は陰に与えられているわけだが、これを学習で獲得するか入力ベクトルとして与えてしまうかというようなことだ。前者の場合は学習の収束に時間がかかりかつモデルを大きくしなければならない。後者の場合は入力ベクトルが大きくなるため一層ごとの学習コストが大きくなる。自分は入力ベクトルについては後者のアプローチをとる。

出力ベクトルについても似たような話がある。理想的には合法な次手のみが出力される線形のきれいな（つまり学習しやすい）関数の重みとして得られるのが良い。合法な手の中のうちロスが小さいものを学習させていきたい。しかしこれは今のところ自分には思いつかないので非合法な次手の出力も許し合法な手により小さなロスをつけて学習させるアプローチを取る。合法・非合法を学習しなければならないので学習コストがかかるがしかたがない。

中間層についてはまだあまり考えていない。とりあえずは5層くらい重ねたいが勾配消失との戦い、財布との戦いになりそうな感じ。

当面の課題
==============================

- 棋譜データを一括でダウンロードできるサービスを探すこと。
- 勝敗判定などの補助ライブラリにpython-shogiを利用するが盤面の左右反転・180度回転（画像認識におけるデータオーグメンテーション）機能がなかったり、入力ベクトル化するのに使いにくかったりするのでなんとかする。
- 電王戦はめんどくさそうなので興味がないのだがAI将棋のネットワーク対戦ランク付けサービスがあると良いのだがまだ見つけてない。

目標
==============================

年内中に「まあ将棋にはなっている」「〜級程度には見える」というところまで到達したい。
Photoshopで3DのOBJファイルからMTLファイルを作成する方法

パブリックドメインで公開されている3Dモデル「[Spot](http://www.cs.cmu.edu/~kmcrane/Projects/ModelRepository/)」を、とあるJavaScriptライブラリから読み込もうとすると、OBJファイルとテクスチャ画像の他にMTLファイルが必要になりました。しかしSpotのZIPファイルの中にはMTLファイルが含まれておらず。。試行錯誤の末、Photoshopで無事作成できたので備忘録として残しておきます。
※3Dは初心者なため、もっと手軽に作成できる方法がありましたら教えてください :sweat_smile: 

![spot](https://qiita-image-store.s3.amazonaws.com/0/55103/213ce17c-23b7-8609-af00-aaeaaff84320.png)

▲Spot

# 1. PhotoshopからOBJファイルを読み込む

Photoshopを起動して、SpotのOBJファイルをドラッグ&ドロップで読み込みます。

![PhotoshopからOBJファイルを読み込む](https://qiita-image-store.s3.amazonaws.com/0/55103/fa2cfd32-2c88-3175-1dfd-a0d89e6f6817.png)

# 2. MTLファイルの作成

レイヤーパネルのOBJファイルのレイヤー（レイヤー1）を右クリックして、「3Dレイヤーを書き出し」を選択します。

![3Dレイヤーを書き出しを選択](https://qiita-image-store.s3.amazonaws.com/0/55103/2907e847-a0e4-0cdc-bb50-4d8faa355b80.png)

すると書き出す形式の設定ウィンドウが表示されるので、「3Dファイル形式」を[Wavefront|OBJ]に設定し「OK」ボタンをクリックして書き出します。

![プロパティを書き出し](https://qiita-image-store.s3.amazonaws.com/0/55103/ba57f447-fe75-a8be-cf5c-97b119db5470.png)

OBJファイルとMTLファイルが書き出されました。

![スクリーンショット 2016-09-27 11.06.04.png](https://qiita-image-store.s3.amazonaws.com/0/55103/02e961a4-f9f3-40f4-7778-39d6c446101a.png)

# 3. MTLファイルを編集

MTLファイルをテキストエディターで開き、テクスチャ画像のファイル名部分を編集します。これでMTLファイルの作成が完了です。

編集前

```
newmtl __PS_3D_Default
Ka 0.000000 0.000000 0.000000
Kd 0.803922 0.803922 0.803922
Ks 0.200000 0.200000 0.200000
Ns 6.062867
d 1.000000
Tr 0.000000
map_Kd __PS_3D_Default - 初期テクスチャ.PNG 
```

編集後

```
newmtl __PS_3D_Default
Ka 0.000000 0.000000 0.000000
Kd 0.803922 0.803922 0.803922
Ks 0.200000 0.200000 0.200000
Ns 6.062867
d 1.000000
Tr 0.000000
map_Kd model.png 
```

# 最後に

いつも3D系の実験をするときは、ネット上にあるありがた3Dモデルを使わせていただくのですが、ちゃんと理解して自分でも作れるようにならないとなと感じました。

もっと勉強しないと
Chrome拡張Evernote Web Clipperによるエラーのフィルタリング

**環境**
- MAC OS X El Capitan
- Chrome バージョン 53.0.2785.116
- Evernote Web Clipper 6.9.2


Chrome拡張機能のEvernote Web Clipperを入れていると、
製作中のウェブサイトをデバイスモードで検証する時に、エラーが大量に表示されて鬱陶しい。
（この拡張を入れなければ良いのですが）

![sample1.png](https://qiita-image-store.s3.amazonaws.com/0/84446/e38c7754-c0f7-6a87-4e78-af4dba7046bf.png)

そんな時の対処法。

1. エラーのところで右クリック
![sample2.png](https://qiita-image-store.s3.amazonaws.com/0/84446/87a7402b-0ffe-f755-cf8f-4f70e98179f1.png)

2. Filterを選択して、Hide Messages from *** を選択すれば完了！


* * *

**参考**
[If chrome is the device mode, web clipper reblogged output js error on the console.](https://discussion.evernote.com/topic/80637-if-chrome-is-the-device-mode-web-clipper-reblogged-output-js-error-on-the-console/)
bashにgitのブランチ名を表示する

#結論

<b>1.以下のリンクからgit-prompt.shとgit-completion.bashをダウンロード</b>
https://github.com/git/git/tree/master/contrib/completion

<b>2.ダウンロードしたファイルを移動</b><code>
sudo mkdir -p /usr/local/git/contrib/complation/
sudo mv git-completion.bash /usr/local/git/contrib/complation/
sudo mv git-prompt.sh /usr/local/git/contrib/complation/
</code>

<b>3..bashrcに追加する</b><code>
source /usr/local/git/contrib/completion/git-prompt.sh
source /usr/local/git/contrib/completion/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '</code>

<b>4..bashrcを適用させて終了</b><code>
source ~/.bashrc
</code>

※動作環境
OS X 10.11.4

#参考文献
bashでgitのブランチ名を表示
http://qiita.com/tanishi/items/2adb71024d675bc43177
複数のGemfileを使う

# Bundlerで複数のGemfileを使う方法

通常、`bundle exec`でgemを利用する時にはGemfileに必要なgemを列挙して利用するが、まれに複数のGemfileに分けたい場合もある。

ここでは例として、既存のRailsプロジェクトのGemfileに加えて別のgemを追加で読み込みたい場合を考える。
既存のGemfileは編集せずにそのままにしておいて、追加で必要なgemは別のGemfileで指定する。

# 方法

GemfileはRubyの内部DSLなので、Gemfileの中からもう一方のGemfileをevalすればよい。

追加で必要なgemは、別のディレクトリ(additional)に配置したGemfileに記載する。
ファイル構成は以下のとおりとなる。

```
project/
  |- Gemfile     # 既存のgemfile
  |- 他のファイル
  |- ...
additional/
  |- Gemfile
```

additionalの中にあるGemfileを以下のように編集する。

```rb:additional/Gemfile
eval_gemfile File.join( File.dirname(__FILE__), "../project/Gemfile")

gem "additional_gem"   # 追加のgem
```

`eval_gemfile`メソッドは、中のファイルを読んでinstance_evalしているだけ。
参考 : http://www.rubydoc.info/github/carlhuda/bundler/Bundler/Dsl:eval_gemfile

以降、additionalの中で `bundle install` して、`bundle exec`で実行すれば両方のgemが使えるようになる。

# （追記） Gemfile.lockを使いたい場合は？

既存のプロジェクトがGemfile.lockを使ってバージョンを固定していたとする。
そのGemfile.lockに記載されたgemを使いたい場合、上記の方法ではうまくいかない。

上記の方法を利用するためには、Gemfile.lockからGemfileを構築するとできる。

```rb:gemfile_lock2gemfile.rb
require 'bundler'

lockfile = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))

puts "source 'https://rubygems.org'"
lockfile.specs.each do |s|
  puts "gem '#{s.name}', '#{s.version}'"
end
```

以下のスクリプトを既存のプロジェクトのGemfile,Gemfile.lockがあるディレクトリで実行する。
標準出力に、Gemfile.lockで指定されたバージョンに固定したGemfileができる。

このGemfileを上記の方法でevalすれば、既存のプロジェクトのgemを使うことができる。

## 参考情報

http://stackoverflow.com/questions/12237055/how-to-use-gems-not-in-a-gemfile-when-working-with-bundler
http://stackoverflow.com/questions/7962743/bundler-load-multiple-gemfiles
CentOS / Linux > ssh -Xが遅い > ssh -X -C で対応

```txt:動作環境
PC A
  Windows 10 pro
  VMware workstation
  CentOS 6.8 on VMWare
  Windows 8.1 pro on VMWare
PC B
  CentOS 6.8 (Xeon E5-2620v4)
```

関連  http://qiita.com/7of9/items/8e1a6cbec1105d157e32

CentOS on VMWare (PC A)からPC Bへのssh -Xが遅かった件について。

https://ubuntuforums.org/showthread.php?t=1855933
にてsshの-Cオプションというのを見つけた。

`ssh -X -C`で接続するようにしたらsublime textでのスクロールやコード入力が通常の速度になった。

これでコーディングに支障がでない速さになった。
Set-AzureVNetGatewayKey に引数として与える名前を調べる

たまにしか行わないので何度でも忘れる。

# 調べ方

`Get-AzureVNetSite` を実行する。

# 引数とのマッピング

`Get-AzureVNetSite` で得られる値のうち、`Name` が `-VNetName` に続ける値。 
同じく `GatewaySites` で得られる配列の要素が `-LocalNetworkSiteName` に続ける値。

# 蛇足

`-SharedKey` に続ける値は、言うまでもなく、その時の気分で。
爆速でリモートブランチにPushする

# したいこと
現在の作業中のローカルブランチを、同名のリモートブランチにPushしたい

そんなスクリプトを作ったので紹介させていただきます。

# シェル

```bash:bashrcに追記する
function gp(){
    current_branch_name=`git rev-parse --abbrev-ref HEAD`
    if [ "${current_branch_name}" != 'develop' ] && [ "${current_branch_name}" != 'master' ]; then
       	git push origin ${current_branch_name}
    else
        echo "このブランチは　${current_branch_name}　です"
    fi
}
```

# 使い方
コンソールで`gp`と叩くと`git push origin 現在のブランチ名`となります


```bash:コンソール
# some_branchブランチで作業中のとき
$ gp

Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (7/7), 9.31 KiB | 0 bytes/s, done.
Total 7 (delta 1), reused 0 (delta 0)
To https://s1160054@bitbucket.org/s1160054/workplace.git
   178accd..d626f83  some_branch -> some_branch
```

## develop, masterブランチにはPushしない

```bash:コンソール
# masterブランチの時
$ gp
=> このブランチは master です
```

```bash:コンソール
# developブランチの時
$ gp
=> このブランチは develop です
```
Docker Ingress Overlay Networkでコンテナ間通信を行う

docker1.12 から導入された
IngressOverlayNetwork使って、コンテナ間通信をしたかったのですが、
嵌ったので、メモ。

# Version

使用したVersionは以下。

```shell
docker version
```

```shell
Client:
 Version:      1.12.1
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   23cf638
 Built:
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.1
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   23cf638
 Built:
 OS/Arch:      linux/amd64
```

# やりたい構成

1ホスト内に以下のような構成でServiceを作成。
apache(nginx) -- tomcat(spring) -- mysql

Serviceを作成したコマンドは以下

```shell
docker service create -p 80:80 --replicas 1 --name apache apache_image
docker service create -p 8009:8009 -p 8080:8080 --replicas 1 --name tomcat tomcat_image
docker service create -p 3306:3306 --replicas 1 --name mysql mysql_image
```

# コンテナ間通信できない問題

apacheコンテナ→tomcatコンテナ
tomcatコンテナ→mysqlコンテナへの通信ができない。

以下、色々確認したコマンド
ホスト側

```shell
1.ss -natp | grep 8080
 → LISTEN     0      128         :::8080 # 各portは待ち受けされている
2.curl 192.169.56.100:8080 -w '%{http_code}\n' -o /dev/null  -s
 → 200 # ホストからは通信できてる
```
コンテナ側

```shell
docker exec -ti apache.1.8vfwjrtun0gbthomghmzt4e67 # コンテナに入る
3. curl 192.169.56.100:8080 -w '%{http_code}\n' -o /dev/null  -s
 → curl: (7) Failed connect to 192.169.56.100:8080; Connection timed out # コンテナからは通信できない
```

# コンテナ間通信できない原因：icc

ホスト側で

```shell
tcpdump -i docker_gwbridge
```
を実行してpacketを確認したところ、コンテナからの通信パケットも届いてることを確認

じゃあ、設定かな？というとこで、

```
docker network inspect docker_gwbridge
→
[
    {
        "Name": "docker_gwbridge",
　　　　　...
        "Options": {
            "com.docker.network.bridge.enable_icc": "false", # ★こいつか！
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.name": "docker_gwbridge"
        },

```

# docker_gwbridge作り直して解決

docker_gwbridgeを作り直して、
その際に"com.docker.network.bridge.enable_icc"="true"を追加。
そうすると、apacheコンテナからtomcatコンテナに通信ができた。

が、作り直すのも多少手間取った。
docker_gwbridgeにはgateway_ingress-sboxというコンテナが割り当てられており、削除できない。
別のbridge作って、別のingress作って、リンクさせて。。。
っていう方法が良くわからなかったので、dockerを入れ直した。
(ingressはswarm initしたら作成される)
swarm initする前に、docker_gwbridgeを削除し、以下のコマンドで作成。

```
docker network create -o "com.docker.network.bridge.enable_icc"="true" -o "com.docker.network.bridge.enable_ip_masquerade"="true" -o "com.docker.network.bridge.name"="docker_gwbridge" docker_gwbridge
```

その後、swarm initすると無事、再作成したdocker_gwbridgeがingressとリンクして、
コンテナ間通信できるようになった。

きっともっと良いやり方があるな。。。
ひとまず、やりたいことはできるようになった。
Ruby on Rails(bundle exec rake test => error)


template0のencodingを変更することで解決

    mike@rbci:~$ psql -U postgres 
    psql (9.0.3) 
    Type "help" for help. 
    postgres=# update pg_database set datallowconn = TRUE where datname = 'template0'; 
    UPDATE 1 
    postgres=# \c template0 
    You are now connected to database "template0". 
    template0=# update pg_database set datistemplate = FALSE where datname = 'template1'; 
    UPDATE 1 
    template0=# drop database template1; 
    DROP DATABASE 
    template0=# create database template1 with template = template0 encoding = 'UTF8'; 
    CREATE DATABASE 
    template0=# update pg_database set datistemplate = TRUE where datname = 'template1'; 
    UPDATE 1 
    template0=# \c template1 
    You are now connected to database "template1". 
    template1=# update pg_database set datallowconn = FALSE where datname = 'template0'; 
    UPDATE 1
GitHub のユーザー名を既に取得されているものに変える方法

ｸﾞｸﾞﾙとすでにいくつか出てくるネタですがやってみました。意外と簡単。僕の場合は以下のようにして変更しました。

| 変更前 | 変更後 |
|---|---|
| `delphinus35` | `delphinus` |

`35` は昔なんとなく付けたものなので特に理由もなかったのですが、GitHub の [Name Squatting Policy][]（ユーザー名不法占拠ポリシー？）を読むと以下のようにありました。

[Name Squatting Policy]: https://help.github.com/articles/name-squatting-policy/

> （抄訳）GitHub のユーザー名は早いもん勝ち、かつ、活溌に使ってる人のものです。使いもしない人がユーザー名を占有するのは許されません。余り使われていないアカウントは GitHub スタッフの裁量によって名前を変更されたり、削除されたりします。でも、活動状況が全て公開されてるわけではないことにも注意してね。

お金で売買しちゃダメよ、とかも書いてありますがそこは省略。

# 実際に変えてみる

使いたいユーザー名のプロフィールページ（[https://github.com/delphinus](https://github.com/delphinus)）を見ると、activity が**全くなし**、どう見ても取っただけの放置アカウントでした。もっとも、上にも書いてありますとおり、activity は非公開にも出来ますから確実ではないですけどね。

というわけで、support@github.com 宛てに、以下のようにメールしました。

> Hi,
>
> My name is delphinus. I have a GitHub account `delphinus35`  https://github.com/delphinus35, but I want to use the account `delphinus` that is the same as my handle name.
>
> I see the profile page https://github.com/delphinus, and I found the account `delphinus` is inactive. Can you release this account for me to use this?
>
> Thanks.

送ってから 10 時間ほどで以下のようなメールが到着。

> （抄訳）ついてるね！（You're in luck!）「Name Squatting Policy」に照らし合わせてみても、`delphinus` は不活溌アカウント（inactive account）と認められそうです。
>
> `delphinus` は既に解放したので、自由に使ってね。

_いつも思うけど、海外サービスのサポートアカウントってなんでこんなにカジュアルなんだろう。_

というのは置いておいて、この時点で [https://github.com/delphinus](https://github.com/delphinus) は 404。アカウントは誰でも取得できる状態になっているので、[アカウント設定ページ][]の **Change username** をクリックして変更しました。

[アカウント設定ページ]: https://github.com/settings/admin

# 変えるとどうなるの？

この時点で元のプロフィールページ（[https://github.com/delphinus35](https://github.com/delphinus35)）は 404 になるのですが、レポジトリーへの push は変わらずに出来ます。どういう仕組みなの？ と思ってｸﾞｸﾞﾙと [What happens when I change my username?][whw]（ユーザー名を変えるとどうなるの？）に以下のような記述がありました。

[whw]: https://help.github.com/articles/what-happens-when-i-change-my-username/

> （抄訳）ユーザー名を変えると GitHub はレポジトリーへの参照を自動的にリダイレクトします。又、Web 上の**リポジトリーへの**リンクについても以前と同じように動作します。（訳注：プロフィールページ https://github.com/ユーザー名 は 404 になります）
>
> 古いリポジトリーへの push も問題なく動きますが、速やかに新しいユーザー名を使った URL に変えることをオススメします。なぜなら、**元のユーザー名を他人が取得した場合、その人はあなたと同じ名前のリポジトリーを作ることが出来、以後の参照は全てそちらを向くことになるからです。**

とまあ、結構融通の利く実装になっているようです。太字にした部分には注意が必要ですが、鍵が違うので push や pull は出来なくなるんじゃないですかね。多分。

とはいえ念のため、以下のようにして、URL を変えておきましょう。

```sh
$ git remote -v
origin  git@github.com:delphinus35/dotfiles (fetch)
origin  git@github.com:delphinus35/dotfiles (push)

$ git remote set-url origin git@github.com:delphinus/dotfiles
```

# まとめ

**ユーザー名が決して早いもん勝ちではない**ことは Web サービスとしては珍しいですね。GitHub はターゲットが開発者であることと、個人の認証は登録した鍵によることから、ユーザー名に固執する必要はない、という判断なのでしょう。

ついでにこれを機に、Qiita のユーザー名も `delphinus` に変えておきました（こっちは単に未取得なだけだった）。他の SNS も GitHub 位カジュアルにユーザー名変えれたらいいのにな〜。
素数ジェネレータ(python)

素数を取得する処理が時々欲しくなるのでライブラリ化。
アルゴリズムは[ここ](http://ami-gs.hatenablog.com/entry/2014/02/09/204205)のを参考にさせて頂きました。

指定最大値に応じたリストを作るため、大きい値を指定すると動かない。(マシンのメモリ搭載量による)
うちのPC環境(メモリ8GB)では10,000,000指定までは動き、100,000,000指定だと固まりました。。

(2016/9/27修正)
[エラトステネスのふるい](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9)の論理により、指定最大値の平方根を超える値については、素数判定のリストを更新する必要がないことが分かったので、処理見直し。

```py3:prime.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time


def primes(max_number):
    """
    指定値未満の素数を取得するジェネレータ
    :param max_number: 最大値
    :return: 素数ジェネレータ
    """
    if max_number <= 2:
        raise StopIteration
    yield 2
    is_prime = [1] * max_number
    square_root_of_max = max_number ** 0.5
    for number in range(3, max_number, 2):
        if is_prime[number] is 0:
            continue
        yield number
        if number <= square_root_of_max:
            for multiple in range(number * 2, max_number, number):
                is_prime[multiple] = 0


if __name__ == '__main__':
    while True:
        input_number = int(input("指定値未満の素数を列挙します。指定値:"))

        start_time = time.time()
        for prime in primes(input_number):
            print(prime)
        elapsed_time = time.time() - start_time
        print("elapsed time:{0}".format(elapsed_time) + "[sec]")
```

おまけ:
自分で実装した素数取得処理。
実行速度が参考にしたサイトのものより遅かったので不採用。

```py3:prime_old.py
def primes(max_num):
    if max_num <= 2:
        raise StopIteration
    yield 2
    non_primes = set(range(2 * 2, max_num, 2))
    for num in range(3, max_num, 2):
        if num in non_primes:
            continue
        yield num
        non_primes.update(range(num * 2, max_num, num))
    else:
        raise StopIteration
```

参考:
http://ami-gs.hatenablog.com/entry/2014/02/09/204205
https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9
さくらのレンタルサーバーライトでRubyを使ってJSONライブラリを利用する方法

# はじめに

「require "json"」として使おうと思ったらエラーで使えなかったので、使えるようにした手順を以下に記します。

# ソースコードのダウンロード

以下のURLよりソースコードのZipファイルを入手します。

https://github.com/qdaemon/m5

# ソースコードの配置

さくらのレンタルサーバーのホームディレクトリに「lib」フォルダを作ります。
Zipファイルを解凍し、以下のフォルダの中身を前述のサーバーに作った「lib」フォルダにアップロードします。

m5-master/3rdParty/lib/ruby/1.8/

ちなみに、アップロードするファイルとフォルダは以下のとおり。

- json.rb（スクリプト）
- json（フォルダ）

# テストコードの作成

以下のコードを作成してアップロードし、実行権限を付与してブラウザでアクセスします。

```ruby:json_sample.cgi
#!/usr/local/bin/ruby

$LOAD_PATH << "/home/[ユーザー名]/lib"

require "json"

print <<EOF
Content-Type: text/html

Sucsess
EOF
```

![スクリーンショット 2016-09-27 8.22.13.png](https://qiita-image-store.s3.amazonaws.com/0/114240/1e53c486-e2a2-8e29-9c62-95bf426910f9.png)


動いた！！
link > Paraview > 2GBで500^3個を扱える

Unityで100万個の粒子から構成される物体のViewerを作ろうかと考えていたが、他のツールも気になった。

DDSCATなどではParaviewやMayavi2などといったツールを使っているようだ。

Paraviewでの粒子数は
https://www.sharcnet.ca/help/index.php/Visualization_of_2D_and_3D_datasets_with_ParaView
> On a typical desktop with 2 GB memory you can work interactively with datasets up to ~500^3. Some of our visualization workstations have 48GB memory and will let you visualize datasets up to ~2000^3 (single variable in single precision)...

2GBで1.25億個扱えそうとのこと。こちらの方がずっと良い。

ParaviewはWindows, MacOS X, Linuxに対応したオープンソースソフト。Qtなどを使っていてCentOSでのインストールにひっかかる例などが見られる。Windowsではインストールが簡単ですぐに使えそう。

実際にParaviewで閲覧した例。
http://ddscat.wikidot.com/targets

ParaviewはVTKという形式で読込むため、元ファイルからの変換ツールがある。
https://nanohub.org/resources/ddaconvert
Blenderの形状からの変換という記載もある。

「学習」以外の目的でUnityでViewerを作る意味が薄れた。何か利点はないだろうか。
個々の粒子を単独で扱えれば衝突による「変形」やGravityの影響などを見るというのができそうだが、1024個単位のMeshでの扱いではそれも中途半端だ。
ParaviewにはないAndroidでの動作というのが一つあるが、RAMの少ないAndroid上での使用の利点があまり考えられない。

Android上の場合、博物館でスマホにて情報表示するツールというのはできそうだ。特定のQRコードを読込んだ後にWiFi経由で形状データを読込み、その3D形状をスマホ上で表示する。しかしながら自分が使いたいツールとは違う。
技術英語 > These experiments provide [virtually] no evidence.

@ Code Complete (No. 13209 / 36077)

> These experiments provide <font color=red>virtually</font> no evidence.

http://ejje.weblio.jp/content/virtually
> ほとんど

http://ell.stackexchange.com/questions/48053/difference-between-virtually-and-almost
> Virtually means "almost (in respect to degree or strength)" or "almost completely".
[学習記録]Rails TouTorial 2日目


第6章...終了
	だんだんハードになってきました、、、
	
正規表現やテストの想定の意味も説明してくれていて、ほんといい教材だと思います。
これらをマスターしたら質の良いプログラムが書けるような気がします。


<hr>

TECH CAMPのマスターコースの相談会というものに行ってきました。
相談会というよりはただ質問するだけでした。

聞きたかった点は大きく２点

・カリキュラムの内容

こちらのツッコミが甘く、全体の内容はHPでわかる内容しか説明してくれませんでした。
集中コースと夜間コースはカリキュラム変更で実施内容に差がなくったそうです。
（以前はグループワークがあったのがなくなった）
オンラインテキストでもくもくと学習を進める方式です。
学習に成果物（ポートフォリオ）はオリジナルを作るのではなく、課題をまとめるだけのようです。


・就職支援状況

１期の方（２名）は社内プログラマに就職されたようです。
よくよく話を聞いていると、就職支援力には自信がないそうで、企業からバックマージンが見込めない方には審査がゆるい就職支援がないコース(受講料20万円UP）を勧めているようです。







サービス業として気をつけた方がいいと思った点

・会議室の隣が事務所

待っている間景気のいい話が聞こえてきました。
若い会社なので、イケイケはいいのですがお客さんがいる可能性があるところの壁一枚向こうなので、常に意識をするかレイアウトを見直した方がいいかも。

あと、事務所へのショートカットに会議室がなっているらしく、出勤してきた講師が会議室に飛び込んできました（笑）


・会議室に内側から鍵をかけること

上記の通り抜け対策だと思いますが、説明者とマンツーマンになるのでお客さんが女性、講師が男性の場合、なにかあったら疑われると思います。

他にもセールスの面やヒアリングの仕方などは、販売者目線（笑）で気になりました。
EditTextのthemeを設定したらhandle部分に謎の下線が出てきたときの対処法

こんにちは。
今回は、下の画像のような状況に陥ってしまった場合の対処法をまとめます。

![貼り付けた画像_H28_09_27_2_21.png](https://qiita-image-store.s3.amazonaws.com/0/42282/f5f79402-7167-34bf-81c9-3cf6e49a1584.png)

## 状況

さて、AndroidのEditTextは独自のTheme設定を適用することができます。
具体的にはこの記事（ http://qiita.com/konifar/items/47d467e3574c9228fdc8 ）がすごくよくまとまってるので見てもらえればと思うのですが、これをやろうと思ったときに上の画像のような状況が発生しました。

具体的なレイアウトやstyleは以下のようになっています。

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/EditTextTheme" />

</RelativeLayout>
```

```styles.xml
<resources>

    <style name="EditTextTheme" parent="Widget.AppCompat.EditText">
        <item name="colorControlActivated">#ffa600</item>
    </style>

</resources>
```

いらないところは省きました。
やってることはとても単純です。EditTextに対して、`android:theme="@style/EditTextTheme"`として、styles.xmlで定義した独自のスタイルを設定しているだけです。

これだけで、なぜかhandle部分に謎の下線が生まれました。謎だ……
どうでもいいですが、あの持ち手text selection handleって言うんですね。これを調べてて唯一「へぇ」って思えた出来事でした。

# 調査してみた結果

最初はずっと、`colorControlActivated`を設定したせいで発生したものかと思っていたのですが、どうやら色々と調べてみるとそうでもないらしいことが分かりました。
ちなみにGoogleで結構調べていたのですが、それらしいものは一つしか見つかりませんでした。
http://stackoverflow.com/questions/37588019/edittext-with-custom-theme-shows-underline-under-selection-handle

発生件数が少ないんですかね…同じような状況になった人募集中です。
とにかく、原因が全然わからなかったし、EditTextのソースを読む気にもなれなかったので、自分で色々と試行錯誤して見た結果、次のことが分かりました。

- API 23の端末で再現
    - API 22以下の端末では再現しなかった（handle部分に下線が表示されなかった）
- styleに `parent="Widget.AppCompat.EditText"` や `parent="android:Widget.EditText"` と書いている
    - これは、親styleをEditTextのものに設定している一般的な書き方です（ググったら大半はこれでやってます）

上記の2点を満たしたときに、謎の下線が出てきてしまう、という状況が発生しました。
なるほど。アプリ全体のThemeを定義する際などは、parentに`Theme.AppCompat.Light`とか書きますもんね。どうりで発生する件数が少ないわけです。

# 解決策

styleのparent指定を外しましょう。

```styles.xml
<resources>

    <style name="EditTextTheme">
        <item name="colorControlActivated">#ffa600</item>
    </style>

</resources>
```

これだけです。

![device-2016-09-27-024401.png](https://qiita-image-store.s3.amazonaws.com/0/42282/3c960767-6261-70b8-1a96-3b6bab0527c4.png)

やったー！！下線が消えたぞ！！！
見つけたときは、本当に偶然にparentを消してみただけだったのですが、まさか上手くいくとは思わず何度も外したり戻したりを繰り返してました笑

# 終わりに（考察）

よく分からないですが、たぶん、API 23のバグです（雑）
根本原因はいまだに分かっていません。詳しい方はコメント等で補足頂けると幸いです。
ASUS Chromebook C300MAに、Croutonを使わずにArch Linuxをインストール

やった。これだ。

俺がやりたかったのはこれなんだ！

喜びのあまり、叫びそうです。

ASUS Chromebook C300MAに、Croutonを使わずにArch Linuxをインストールすることができました。

ChromeOSの何倍も快適です。日本語入力も問題ありませんので、この記事もArch Linux on Chromebookで書いています。


# 経緯

今までCroutonを使ってUbuntuを使っていましたが、Chroot環境であるが故に

- Dockerがインストールできない
- Ubuntuのバージョンアップができない
- 一部、ハードウェア制御に制約がある

などの不満がありました。

その結果、最近はChromebookは同居人に渡し、自分は中古PCにArch Linuxを入れて常用するようになっていました。

Arch LinuxのWikiを見ていると、ChromebookやChromeOSについて詳しく書かれており、ひょっとしたらあのC300MAにもインストールできるのではないかと思ってきました。

で、Arch LinuxのWikiの通りにやったらできたので、その報告です。

同じことをしたい物好きな方の参考になれば幸いです。

# 必要なもの

- C300MA本体
- USBメモリ2本
- 安定的なWifi環境

# 手順

ざっくりと、下記の手順になります。

- Arch LinuxのLive USBを作っておく
- Chromebookのデベロッパーモードを有効化する
- Write-Protect-Screwを外す
- [Jolnlewis氏のスクリプト](https://johnlewis.ie/custom-chromebook-firmware/rom-download/)を実行し、seabiosをインストールする
- Legacy BootでArch LinuxのLive USBにBoot
- もう一本のUSBメモリにArch Linuxをインストールする

# LiveUSB作成

[Wiki](https://wiki.archlinuxjp.org/index.php/USB_%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2)を参考に、Arch LinuxのLive USBを作成します。基本的にISOファイルを`dd`で書き込めばOK

# デベロッパーモードを有効化

そこら中に情報があるので割愛

# Write-Protect-Screw を外す

[この記事](http://chromesoku.com/rw-filesystem-on-chromebook/)に至極分かりやすく書いてあるので、それに従います。

# seabiosをインストール

[Jolnlewis氏のスクリプト](https://johnlewis.ie/custom-chromebook-firmware/rom-download/)を実行します。

```bash
cd
rm -f flash_chromebook_rom.sh
curl -O https://johnlewis.ie/flash_chromebook_rom.sh
sudo -E bash flash_chromebook_rom.sh
```
（このサイト落ちたらどうしよう・・・Git化してくれないかな）

途中で、「RW_LEGACY の変更と、 BOOT_STUB の復活、どっちがしたい？」と聞かれるので、RW_LEGACYの方、と答えておきましょう。後はメッセージに従っていればOKです。

これで、　Seabiosが有効化されているので、Legacy BootができるようCroshを開いて下記コマンドを入力しましょう。

```sudo crossystem dev_boot_usb=1 dev_boot_legacy=1```

# Arch LinuxのLive USBでBoot

一回シャットダウンして、最初に作成したLive USBを差し込み、電源を入れます。
おなじみの白い画面になったら、Ctrl+Lを押します。Legacy BootのLですね。

すると、Arch LinuxのLive USBの画面が出てくるはずです。私はここで感動しました。

ちなみに、神機と名高いAcer C720はデベロッパーモードにしただけで、Legacy Bootができます。Seabiosが入っているから、らしいです。

# Arch Linuxをインストールする

後は、もう一方のUSBメモリに通常通りArch Linuxをインストールするだけです。USBメモリにしているのは、ChromeOSも残しておきたいため、また内蔵MMCディスクだと容量が足りないためです。

自分の場合はシンプルなシングルパーティション構成にしました。デュアルブートはChromebookの場合必要ないので、それで良いでしょう。Swap領域もメモリ4GB積んでいるので必要ありません。


あとは、必要なパッケージを入れて、やりたい放題です。

起動の度にCtrl+Lしなければならないのが玉に傷ですが、まあ今までもCtrl+Dしていたので良いでしょう。

Xサーバーを起動してからも、いろいろやらないといけないことは多いのですが、いったんここでこの記事は終了にします。

# 追記

音が出ない。

HDMIケーブル経由でしか出ない。
OpenCVとPythonでHigh Dynamic Range Image (HDR)を作ってみる（Mertens, Robertson, Debevec）

# はじめに
　スマホやデジカメで、夕暮れ、夜景、逆光、外光が差し込む暗い室内など、コントラストが強い環境で撮影すると、明るい部分が白くつぶれてしまったり、逆に、暗い部分が黒くつぶれてしまったりして、がっかりした経験はありませんか？
　これは、明るい部分や暗い部分の階調が足りなくなってしまうためにおこる現象です。
　今回は、明るい画像と暗い画像をいいとこどりで合成して、High Dynamic Range Imageを作ってみます。

# 環境
+ OpenCV: 3.1.0
+ Python: 3.5.2

これから環境構築をこちらを参考にしてください。
[OpenCV 3とPython 3の環境構築](http://qiita.com/olympic2020/items/d5d475a446ec9c73261e)

# 処理前の画像
![サムネイル.png](https://qiita-image-store.s3.amazonaws.com/0/107056/a36df5fd-c082-1a8e-d0ea-98b4a7300dfa.png)

露出を２段階づつ変えて撮影したJPEG画像が３枚。
綺麗に合成させるためには、カメラを固定して、絞りを同じにし、露光時間だけを変化させて、連続撮影するとよいです。


# HDR処理後
OpenCVで処理した画像。

+ **Mertens**
![fusion_mertens.jpg](https://qiita-image-store.s3.amazonaws.com/0/107056/46e8d1b9-125e-0827-5262-d9d48f43ac8c.jpeg)
    　  
+ **Debevec**
![ldr_debvec.jpg](https://qiita-image-store.s3.amazonaws.com/0/107056/cc874646-30a2-71fb-87a7-47ea1bd62abe.jpeg)
    　  
+ **Robertson**
![ldr_robertson.jpg](https://qiita-image-store.s3.amazonaws.com/0/107056/3401653c-6029-837a-f6f6-12eeb9caf723.jpeg)



# プログラム

```hdr.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np

# ３枚の画像ファイルを読み込む
img_fn = ["img1.jpg", "img2.jpg", "img3.jpg"]
img_list = [cv2.imread(fn) for fn in img_fn]

# ３枚の画像に対して露出時間をセット
exposure_times = np.array([0.2, 0.05, 0.0125], dtype=np.float32)

# Debevec法によるHDR合成
merge_debvec = cv2.createMergeDebevec()
hdr_debvec = merge_debvec.process(img_list, times=exposure_times.copy())
tonemap1 = cv2.createTonemapDurand(gamma=2.2)
res_debvec = tonemap1.process(hdr_debvec.copy())

# Robertson法によるHDR合成
merge_robertson = cv2.createMergeRobertson()
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy())
tonemap2 = cv2.createTonemapDurand(gamma=2.2)
res_robertson = tonemap2.process(hdr_robertson.copy())

# Mertens法によるHDR合成
merge_mertens = cv2.createMergeMertens()
res_mertens = merge_mertens.process(img_list)

# 8ビットデータに変換
res_debvec_8bit = np.clip(res_debvec*255, 0, 255).astype('uint8')
res_robertson_8bit = np.clip(res_robertson*255, 0, 255).astype('uint8')
res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8')

# 画像をファイルに保存
cv2.imwrite("ldr_debvec.jpg", res_debvec_8bit)
cv2.imwrite("ldr_robertson.jpg", res_robertson_8bit)
cv2.imwrite("fusion_mertens.jpg", res_mertens_8bit)
```

写真の枚数が３枚、露出が-2, 0, +2の場合、次のようになります。
`img_fn = ["img1.jpg", "img2.jpg", "img3.jpg"]`
`exposure_times = np.array([0.2, 0.05, 0.0125], dtype=np.float32)`

写真の枚数が５枚、露出が-2, -1, 0, +1, +2だったら、この部分を次のように変更します。
`img_fn = ["img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg"]`
`exposure_times = np.array([0.2, 0.1, 0.05, 0.025, 0.0125], dtype=np.float32)`


# おわりに
　今回、パラーメータ調整を一切しなかったMartens法で、迫力のある画像を合成することができました。他のサンプル画像〔[1](https://en.wikipedia.org/wiki/High-dynamic-range_imaging)〕でもいろいろと試しましたが、３つの中では、Martens法が見た目に優れていました。
　HDR関連の機能として、OpenCVにはトーンマップ調整用関数（Drago, Durand, Reinhard, Mantiuk）や、キャリブレーション用関数（Debevec, Robertson）なども用意されています。
　OpenCVを使えば、自動でかなりよい合成ができることが分かったので、何かの際には活用したいと思います。