OmniAICreator/Qiita-1.07M huggingface dataset:
org.jsoup.HttpStatusExceptionをorg.slf4j.Logger#error(String, Throwable)の第二引数に渡してロギング(実装にはlogbackを利用)したら、URLとステータスコードが記録されなかった件

# 発生した現象
`org.jsoup.HttpStatusException`(これは内部でURLとステータスコードを持っている)を`org.slf4j.Logger#error(String, Throwable)`の第二引数に渡してロギング(実装にはlogbackを利用)したら、URLとステータスコードが記録されなかった。

# バージョン
- jsoup: 1.7.2
- slf4j-api: 1.6.5
- logback-core: 1.0.6
- logback-classic: 1.0.6

# やりたいこと
`org.jsoup.HttpStatusException`をロギングしたときにURLとステータスコードを記録したい(ですよね？？)。

# 現象の再現コード
## `HttpStatusExceptionTest.java`

````java
package org.jsoup;

import java.io.IOException;
import java.net.URL;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpStatusExceptionTest {

	@Test
	public void test() throws IOException {
		try {
			Jsoup.parse(new URL("http://google.co.jp/notfound"), 30000);
		} catch (HttpStatusException e) {
			Logger log = LoggerFactory.getLogger(HttpStatusExceptionTest.class);
			log.error("", e);
		}
	}

}
````

## `logback.xml`
存在しない。

## ログ出力
````
20:01:23.835 [main] ERROR org.jsoup.HttpStatusExceptionTest - 
org.jsoup.HttpStatusException: HTTP error fetching URL
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:537) ~[classes/:na]
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:534) ~[classes/:na]
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:493) ~[classes/:na]
	at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:205) ~[classes/:na]
	at org.jsoup.helper.HttpConnection.get(HttpConnection.java:194) ~[classes/:na]
	at org.jsoup.Jsoup.parse(Jsoup.java:183) ~[classes/:na]
	...
````

# 解決案(いずれかを行えば良い)
- `HttpStatusException#toString`がURLとステータスコードを出しているので、`log.error(e.toString(), e);`とする。
その時のログは以下の通り。

````
20:09:00.798 [main] ERROR org.jsoup.HttpStatusExceptionTest - org.jsoup.HttpStatusException: HTTP error fetching URL. Status=404, URL=http://www.google.co.jp/notfound
org.jsoup.HttpStatusException: HTTP error fetching URL
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:537) ~[classes/:na]
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:534) ~[classes/:na]
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:493) ~[classes/:na]
	at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:205) ~[classes/:na]
	at org.jsoup.helper.HttpConnection.get(HttpConnection.java:194) ~[classes/:na]
	at org.jsoup.Jsoup.parse(Jsoup.java:183) ~[classes/:na]
	...
````
- 他のロギングライブラリを使う(slf4j-simple 1.7.12だと`log.error("", e)`でURLとステータスコードが出力された)。

# ポエム
- Java的に言うと`HttpStatusException#getMessage`が詳細メッセージ(この場合だとURLとステータスコード)を返すように実装するのが筋がよい気がするがどうなんでしょう。
- `log.error("hogehoge", e)`って結構使うので、もし使ってるライブラリのどれかが例外の詳細メッセージを`toString`で返していたらと思うと、logbackをプロダクションで使うのちょっと怖いです……
- logbackのソース追ってたんですけど、`filterAndLog_0_Or3Plus`っていうメソッド名が怖かったので諦めました。ごめんなさい…
JRuby は実行時最適化によって 50倍以上速くなり、CRuby を華麗に抜き去る場合がある。

先日、
[JRuby は JIT によって 10倍ぐらい速くなる場合がある。](http://qiita.com/Nabetani/items/628809ba045892752fb9)
という記事を書いたんだけど、測りなおしたらそんなもんじゃなかったことがわかった。

まずはグラフ。対数目盛に注意。
わけのわからないところに横線があるが、一本2倍になっている。

![Kobito.lsPRQu.png](https://qiita-image-store.s3.amazonaws.com/0/6854/e2d863c7-7094-20eb-2b14-03d15626f7d8.png "Kobito.lsPRQu.png")

今回は、【「とある無駄な計算」10回セット】を200回行った。
「とある無駄な計算」は、前回と同じ。
前回は「とある無駄な計算」を20回だったので、計算の規模は百倍になる。
前回は平均をとったが、今回は平均はとっていない。

という辺りが前回との違い。

グラフを見ると、あまり出入りのない CRuby に対し、JRuby は出入りが多い。
グラフが凸凹しているのは、測定しているのが生の時間だから、他のプロセスがCPUを専有していたのかもしれないんだけど、JRuby と CRuby の傾向の違いは読み取れると言っていいと思う。

横軸の回数は、【10回セット】の回数なので、前回のグラフの右端は、今回のグラフでは左端の方にある。

今回は横軸が 70 の辺りで JRuby が CRuby を抜き去っているんだけど、前回のグラフになおすと700 の辺りになるので全然我慢が足りなかったといえる。
ちなみに。
10回セットに変更したのは、時間が短くなりすぎて測れないという弊害を避けるため。

グラフを見ての通り。
最初はJRuby が10倍以上遅かったんだけど、70回目ぐらいにCRuby を抜き去り、最終的には CRuby の倍ぐらい速いというところに落ち着いている。
JRuby は40倍以上速くなっている。
40倍以上と書いたが、10回セット同士で比べているので、1回ごとの速度比で見ると、50倍を超えていることは間違いない。

一方。CRuby はとくに動きはない。ところどころ遅くなっているが、鋭いピークもなければ速くなっているようなトレンドもない。

実行時最適化の結果を保存する方法があるといいと思うけど、あるのかなぁ（未調査）。



追記。
ソースコード載せ忘れてた。

```ruby
#encode:utf-8

(p RUBY_DESCRIPTION) rescue p "1.8.x or former"
require "benchmark"

def test
  a=->(b){->(c){->(d){->(e){ (->(f){f+1})[e] }[d] }[c] }[b] }
  r=a[a[a[a[a[a[a[a[a[a[a[a[a[a[
  a[a[a[a[a[a[a[a[a[a[a[a[a[a[
    1
  ]]]]]]]]]]]]]]]]]]]]]]]]]]]]
  n=400
  s=eval("#" "{"*n+"r"+"}"*n)
end

def run_bench
  200.times do |ix|
    tick = Benchmark.realtime{ 10.times{ test } }
    puts "%d,%.9f" % [ ix+1, tick ]
  end
end

run_bench
```

代わり映えしないけどこんな感じで。
SQL Server AlwaysOn 構築メモ（その４）


前編では可用性グループを作成し、実際にデータが同期されるところまで設定しました。
ここでは、ユーザーの追加や接続テストなどをしてみます。

##全体構成

* その１：[前提知識の整理と基礎環境構築編](http://qiita.com/zaburo/private/5ca86becda6023b90f7e)
* その２：[WSFC(Window Server Failover Clustering)構築編](http://qiita.com/zaburo/private/cb8f82ebbe553ccbb6fe)
* その３：[AlwaysOn構築編](http://qiita.com/zaburo/private/3468af8cd7d89b4c8bd5)
* その４：[接続確認編](http://qiita.com/zaburo/private/055542f1f1b36668b87f)
* その５：[テストしてみる](http://qiita.com/zaburo/private/b25794fa2b05bcf331e7)
* その６：[その他（可用性グループへのDB追加など）](http://qiita.com/zaburo/private/3c3d17051bb612828fda)

##本編での主な内容

* 接続ユーザーの追加（包含データベース設定）
* アクセスしてみる

##接続ユーザーの追加

可用性グループに追加されたDBにアクセスするユーザーは通常のユーザーではダメです。
SQL Serverでは、データベースのユーザーと、ログインが別の概念になっているため、データベース単位で同期されるAlwaysOnでは、通常のログイン機構がうまく機能しないためです。

そこで、データベースにユーザー情報を含ませる「包含データベース」を構成し、AlwaysOnでもうまく機能するユーザーを追加します。

>包含データベースを利用せずに、[全てのサーバに同じSIDのユーザーを作る方法](https://support.microsoft.com/ja-jp/kb/918992)もあるようですが、ここでは王道？の包含データベース設定を行ないます。

###包含データベースの設定

手順としては、

* SQL1,SQL2のSQL Server全体のプロパティにて、「包含データベース」を"true"にします。
* 次に包含データベースにするDBのプロパティにて「コンテインメントの種類」を"部分"に設定します。

という感じです。

####包含データベースを有効にする

Mangement Studioでデータベースの最上位を右クリックして、プロパティを開き、詳細設定を選択します。
そして「包含データベースの有効化」をTrueに変更します。この操作はSQL1,SQL2の両方で行って下さい。

![ao](http://www.bluecode.jp/qiita/ao049.png)

####コンテインメントの種類を部分にする

今度は、可用性グループに参加させたDBを選択し、右クリックしてプロパティを開きます。
そして、オプションの設定を選択し、「コンテインメントの種類」を部分にします。

![ao](http://www.bluecode.jp/qiita/ao050.png)

このステップでAlter Tableするエラーに何度か遭遇しました。同期中でロックされてるのか？など、いろいろ考えましたが、原因はテーブルのデザイン（エディタ）を開きっぱなしにしていることでした。実行済のクエリエディタが開いていてもダメなようです。

なお、デザインエディタ等を閉じてもだめな場合は、Management Studioの利用状況モニターから対象のDBを掴んでるプロセスが無いか確認んし、必要なら強制終了すればいいと思います。

![ao](http://www.bluecode.jp/qiita/ao051.png)

####ユーザーを作成する

なんとかコンテインメントの種別を部分に変更できたら、いろいよユーザーを追加します。
全体のログインではなく、各データベースのセキュリティ、ユーザーから、新しいユーザーを追加します。

![ao](http://www.bluecode.jp/qiita/ao052.png)

ユーザー名、パスワードを設定します。

![ao](http://www.bluecode.jp/qiita/ao053.png)

その後、メンバーシップにて、ユーザーに付与する権限を目的に応じて選択します。

![ao](http://www.bluecode.jp/qiita/ao054.png)

##アクセスしてみる

では、実際に作成したユーザー情報やリスナーでアクセスできるか試してみます。
なお、実運用では、DMZに設置されたWebサーバからアクセスするというなケースが多いと思いますが、わざわざWebサーバを立てるのもなんですので、ADにSQL Serverのクライアントツールをインストールして、接続実験をしてみます。

###クライアントツールのインストール

とりあえず、ここではコマンドラインツールであるsqlcmdを使ってみます。
sqlcmdはSQL Serverのインストールディスクの中から、基本ツールをインストールすると入ります。Feature Packなどからも個別にインストール可能なようです。

![ao](http://www.bluecode.jp/qiita/ao055.png)

インストールできたら、接続できるか確認してみます。
書式は、

```bash
sqlcmd -S hostname -U username -P password -d database
```

包含データベースへのアクセスの場合はDB名を指定します。

![ao](http://www.bluecode.jp/qiita/ao056.png)

> と表示されれば、ログイン成功です。何か操作を行ってみましょう。

ここまでで、AlwaysOnの基本構成は終わりました。フェールオーバーできるか等、確認したいところですが続きは[その５](http://qiita.com/zaburo/private/b25794fa2b05bcf331e7)で。
SQL Server AlwaysOn 構築メモ（その２）


前編ではADの構築と、各サーバのドメインへの参加までの手順を見ました。
本編ではWindows Server Failover Clustring(WSFC)の構築をやってみます。

##全体構成

* その１：[前提知識の整理と基礎環境構築編](http://qiita.com/zaburo/private/5ca86becda6023b90f7e)
* その２：[WSFC(Window Server Failover Clustering)構築編](http://qiita.com/zaburo/private/cb8f82ebbe553ccbb6fe)
* その３：[AlwaysOn構築編](http://qiita.com/zaburo/private/3468af8cd7d89b4c8bd5)
* その４：[接続確認編](http://qiita.com/zaburo/private/055542f1f1b36668b87f)
* その５：[テストしてみる](http://qiita.com/zaburo/private/b25794fa2b05bcf331e7)
* その６：[その他（可用性グループへのDB追加など）](http://qiita.com/zaburo/private/3c3d17051bb612828fda)

##本編での主な内容

* WSFCの構築

WSFCを構成し、SQL1,SQL2をノードに追加します。

##WSFCの構築

では、SQL1とSQL2においてWSFCの構築・構成を行ないます。SQL1,SQL2は素の状態のWindows Serverを想定しています。

>SQL ServerのインストールはWSFCの前でも後でも大丈夫です。

なお、以後の作業は、SQL1,SQL2においてドメインadministrator(bluecode¥administrator)でログインして行うものとします。

>初回のログイン時には、前回ログイン時のアカウントがキャッシュされているので注意して下さい。

###フェールオーバークラスタリングの追加

SQL1,SQL2にて、役割と機能の追加で、フェールオーバークラスタリングを追加します。

![ao](http://www.bluecode.jp/qiita/ao010.png)

また、この時、同じリストにある（一番上）「.NET Framework 3.5 Features」もインストールしておいてください（SQL Server インストール時の依存関係で引っかかるので）。

インストールが完了したら、SQL1（もしくはSQL2でも可）の管理ツールから「フェースオーバークラスターマネージャー」を開き、下段の方にある「構成の検証」をクリックします。

![ao](http://www.bluecode.jp/qiita/ao011.png)

ウィザードがスタートするので、「参照」をクリックし、自分自身(SQL1)を含めた検証対象のサーバを追加します。

![ao](http://www.bluecode.jp/qiita/ao012.png)

テストをするのが推奨なので、そのまま進みます。

![ao](http://www.bluecode.jp/qiita/ao013.png)

実施するテスト内容が表示されますので、次への進みます。

![ao](http://www.bluecode.jp/qiita/ao014.png)


テストが実行されます。数分かかります。

![ao](http://www.bluecode.jp/qiita/ao015.png)

テストが完了しました。
いくつかのワーニングがありますが、「テストは正常に完了しました」と出ていれば大丈夫です。

![ao](http://www.bluecode.jp/qiita/ao016.png)

デフォルトのまま次に進むと、そのままクラスターの作成ウイザードが開きます。

![ao](http://www.bluecode.jp/qiita/ao017.png)


クラスター名を指定します。特に何でもいいです。ここではTEST-CLUSTERとしました。

>私はDHCP構成でやっているのでIP聞かれませんが、IPアドレスを聞かれたら適切なIPを入力します。

![ao](http://www.bluecode.jp/qiita/ao018.png)


作成内容が表示されるので、次へ進みます。

![ao](http://www.bluecode.jp/qiita/ao019.png)

クラスターが作成されました。
いくつかのワーニングがありますが、「正常に完了しました」の文字があれば大丈夫です。

![ao](http://www.bluecode.jp/qiita/ao020.png)

ノードを選択し、各サーバがノードに追加されているか確認して下さい。

![ao](http://www.bluecode.jp/qiita/ao021.png)

>私はMacアドレスでDHCPのIPを固定していたので、実サーバのIPとクラスタのIPが重複し、少しハマりました。本番環境ではDHCPでサーバを立てることはないと思いますので、問題ないでしょう。

ここまでの手順でAlwaysOnのベースとなるWSFCの構成が完了しました。
今回はここまで。続きは[その３](http://qiita.com/zaburo/private/3468af8cd7d89b4c8bd5)で。
【Go】import 書き方まとめ

Go 初心者のため、勉強も兼ねて import の書き方についてまとめました。

## 相対パスでのインポート

```go
import "./model"
```

この方法による import はおすすめされていないようです。


## 絶対パスでのインポート

```go
import "shorturl/model"
```

絶対パスを指定してインポートします。


## 単一行での import

```go
import "fmt"
import "string"
```

一行に一つのパッケージを記入する書き方です。


## グループ化

```go
import (
    "fmt"
    "string"
)
```

一つの import ステートメントで複数のパッケージをインポートする書き方です。


## ドット操作

```go
import (
    . "fmt"
    "string"
)
```

通常、「`fmt.Println("hello world")`」と書くところをドットをつけてインポートすると「`Println("hello world")`」と書くことができます。
つまり、ドット付きインポートはパッケージの関数を呼び出す際に**パッケージ名を省略**して書くことができます。


## エイリアス操作

```go
import (
    f "fmt"
)
```

このような書き方でパッケージ名にエイリアスをつけることができます。
上の場合、「`fmt.Println("hello world")`」のかわりに「`f.Println("hello world")`」とエイリアスを用いて書くことができます。


## アンダースコア操作

```go
import (
    "database/sql"
    _ "github.com/ziutek/mymysql/godrv"
)
```

インポートしたパッケージの関数を直接は使わないけれど、依存関係によってインポートの必要がある時にinit関数だけを実行するとういことですかね…。
（完全には理解しきれていない…´・ω・`）

http://astaxie.gitbooks.io/build-web-application-with-golang/content/ja/02.3.html#import
> _操作はこのパッケージをインポートするだけでパッケージの中の関数を直接使うわけではなく、このパッケージの中にあるinit関数をコールします。


http://golang.jp/2010/01/1061
> インポート宣言は、インポート「する側」と「される側」の依存関係を宣言します。自分自身のパッケージをインポートすること、またはインポートしたパッケージ内でエクスポートされている識別子を一切参照しないことは誤った使い方です。インポートによる副作用(初期化)のためだけにパッケージをインポートするときは、パッケージ名としてブランク識別子を使ってください。


## 参考
http://golang.jp/2010/01/1061
http://astaxie.gitbooks.io/build-web-application-with-golang/content/ja/02.3.html#import
http://qiita.com/shiena/items/c1ac3192af3b00f413ac
PHPのissetで複数の変数を確認しました。

PHPに変数が含まれているか確認をするisset()という言語構造があります。それに変数を複数渡せるということを知りました。


# issetで変数を確認しました
`isset()`にカンマ区切りで変数を渡した例です。

```php:issetで複数の変数をチェック
$hoge = "hogee";
$piyo = "piyooo";

var_dump(isset($hoge));
bool(true) // 結果

var_dump(isset($hoge, $piyo));
bool(true) // 結果
```
複数の変数をチェックできましたʕ•ӫ̫͡•ʔ

次は定義していない変数を渡しました。

```php:issetで$hogeをチェック
$hoge = "hogee";

var_dump(isset($huga));
bool(false) //　結果

var_dump(isset($hoge, $huga));
bool(false) // 結果
```
`$huga`を定義していなかったので失敗しました。

これは便利。いままでissetで変数を一個ずつチェックしてました／(^o^)＼

# 参考
http://php.net/manual/ja/function.isset.php
sparse modeling スパースモデリング

# sparse modeling

$$ E(\boldsymbol x)  =  \parallel  y - Ax  \parallel  ^{2} + \lambda \sum_{i} |x| $$

$E:$ 最適化関数，
$\boldsymbol x:$ 知りたい情報， 
$y:$ 観測データ，
$A:$ 観測行列，
$\lambda:$ 正則化パラメータ

少ない情報から全体像を的確にあぶり出したり,
複雑な事がらをスパースにすることで本質を浮かび上がらせるモデル

***

$$ E(\boldsymbol x) $$ 左辺の$\boldsymbol x$が求めたい解
$$  \parallel  y - Ax  \parallel  ^{2} $$ 
右辺の $y$が数少ない観測データ.その解がこの項の $x$．ここで**解の候補を選ぶ**
しかし,少ない観測データだけでは答えが1つに決まらない.

そこで次の項の  
$$ \lambda \sum_{i} |x| $$ で**解の候補**を絞り，いろんな解の候補の中から,「まばらなもの」や「1番スカスカなもの」を選ぶ．

* **解の候補を選ぶ**
* **解を絞る**

それを繰り返しながら両方の条件(命令)をうまくバランスさせることが重要
# sparse
「すかすか」，「疎ら」という意味

***

sparse modelingを使い,
MRIの撮影時間を3分の1に短縮したり,
過去の津波到達範囲の判別につながる方法を開発.
さらにはブラックホールの正体にも迫ろうとしている.

ビッグデータから知りたい情報を探す必要がある.
知りたい情報はビッグデータに比べればスパースなはずだ.

脳が使っている情報処理を色んな観測機に使えばうまくいくのでは?という発想.


http://www.nhk.or.jp/zero/contents/dsp514.html
http://sparse-modeling.jp
http://mns.k.u-tokyo.ac.jp/index.php?%A5%B9%A5%D1%A1%BC%A5%B9%A5%E2%A5%C7%A5%EA%A5%F3%A5%B0

普段の生活の中でも本質を抽出することに使えると思う.

***
Please donate at [wish list](http://amzn.to/343JRQu) if you find this useful:thumbsup_tone1:
（再実施）ファイルパスを引数として受け取り、存在有無を判定するケース

#先日投稿したものについて

（個人メモ）引数でファイル名を指定し、有無をチェックするようなケース

http://qiita.com/rojiuratech/items/06c2441f87662f909bbe

実家に帰省中に寝ぼけながら書いたものとはいえ、うごくけど、酷いもの。

# 自然言語に置き換えると、いかにまずいかわかる
先日投稿したものは、意味は通じるが文法的には必要もないのに複雑で、誤解を生みやすいものである。
だって・・・。

## 反対の反対なのだ
<pre>
unless ARGV[0] == nil
</pre>

第一引数が存在しないが成り立たない　＝　存在する
・・・ってあんた・・・。

まあたしかに等式は成り立つ。だがそんな複雑で意味が通じにくい書き方をする必要があるか？！ないだろ！！

#条件分岐の入れ子も、避けた方が良い
スパゲッティーコードだなんだとか、昔から言われていたが
条件分岐を入れ子にすると、読みにくい上にメンテナンスが面倒。


# これらを踏まえて
unless って、条件式が偽のとき以下の処理をするので、
異常終了などを呼び出すときに使う。
（条件式が真であると仮定し、例外的な処理を呼び出すのに使う０

<pre>
# 第一引数が、入力するファイル名とする

#第一引数が存在しなかったら、判定対象外なので。警告を出して終了する。

unless ARGV[0]
 #そもそも、引数自体が存在しないケース
 puts "引数で、入力ファイルが与えられていません"
 exit(1)
end

#第一引数が存在する場合、第一引数のファイルの存在を確認する
if FileTest.exist?(ARGV[0])
 puts "第一引数のファイル #{ARGV[0]} は存在します"
else
 puts "第一引数のファイル #{ARGV[0]} は存在しません"
end
</pre>

少しは読みやすくなった（笑）。

# 実行結果


##実施環境
同一ディレクトリ内に、実行ファイルと判定対象ファイルが存在する。
<pre>
$ ls
argv2_2.rb	hoge.txt
</pre>

## 引数が与えられていない場合

unless 部分で偽になり、警告を発して強制終了になる。
<pre>
$ ruby argv2_2.rb 
引数で、入力ファイルが与えられていません
</pre>

## 引数で指定したファイル（のパス）が存在しない場合

ifの部分の判定式が偽になり、警告メッセージを発して正常終了する。

<pre>
$ ruby argv2_2.rb hoga.txt
第一引数のファイル hoga.txt は存在しません
</pre>

## 引数で指定したファイル（のパス）が存在する場合

ifの部分の判定式が真になり、メッセージを出力して終了する。

<pre>
$ ruby argv2_2.rb hoge.txt
第一引数のファイル hoge.txt は存在します
</pre>

# まとめ
ある結果を得るための人工物を作るときは、できるだけ簡単な構造で作ったほうがいいって学生時代に散々言われたろ！！
ブラウザのPOODLE脆弱性を調べるための簡単なサーバー

[POODLE脆弱性がSSL 3.0からTLS 1.0 / TLS 1.1に拡大 | ブログ | SSL・電子証明書ならGMOグローバルサイン](https://jp.globalsign.com/blog/2014/poodle_vulnerability_expands.html "POODLE脆弱性がSSL 3.0からTLS 1.0 / TLS 1.1に拡大 | ブログ | SSL・電子証明書ならGMOグローバルサイン")

昨年からPOODLE脆弱性っていうのが世の中を騒がせていますが、
SSLv3のサポートを切ったときの挙動やブラウザのTLS1.2の対応状況を調べて欲しいみたいなことは言われていませんか？

最新のブラウザの情報やメジャーなブラウザについては十分な情報が集まるかと思いますが、シェアの低いマイナーなブラウザについては情報を集めるよりも実際に動作確認したほうが早いかもしれません。

そんなケースがあったので今回のサーバーを書いてみました。

＊ server.key server.crtの作成方法は割愛します。

```
$ ls
server.key server.crt server.go
```

SSSL3.0をサポートした状態でサーバーを起動します。

```
$ go run server.go -port=4443 -minprotocol=ssl30 -maxprotocol=ssl30
```

サーバーを起動した後は適当にhostsファイルを編集してブラウザからアクセスしてください。

上の状態で立ち上げたサーバーだとSSL3.0しかサポートしてない状態ですのでブラウザは接続に失敗して真っ白なページかエラーページが表示されると思います。

最後に、簡単に手元で動作確認出来るので他のエンジニアに気を使わず検証出来て便利ですよね。
一度コンパイル出来てしまえば簡単にどこの環境でも動かせるこの辺りがGoの魅力ですね。

``` go
package main

import (
    "crypto/tls"
    "flag"
    "fmt"
    "log"
    "net/http"
    "time"
)

type BaseHandler struct{}

func (bh *BaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hey World!")
}

var keyfile, crtfile string
var port int
var minprtcl, maxprtcl string

func init() {
    flag.IntVar(&port, "port", 443, "listen port")
    flag.StringVar(&keyfile, "keyfile", "server.key", "ssl server.key")
    flag.StringVar(&crtfile, "crtfile", "server.crt", "ssl server.crt")
    flag.StringVar(&minprtcl, "minprotocol", "tls10", "minimum negotiation protocol: ssl30, tls10, tls11, tls12")
    flag.StringVar(&maxprtcl, "maxprotocol", "tls12", "maximum negotiation protocol: ssl30, tls10, tls11, tls12")

    flag.Parse()
}

func convertTlSNumber(protocol string) uint16 {
    var version uint16

    switch protocol {
    case "ssl30":
        version = tls.VersionSSL30
    case "tls10":
        version = tls.VersionTLS10
    case "tls11":
        version = tls.VersionTLS11
    case "tls12":
        version = tls.VersionTLS12
    default:
        log.Fatal("Unknown Protocol: ", protocol)
    }
    return version
}

func main() {
    mux := http.NewServeMux()

    bh := &BaseHandler{}
    mux.Handle("/hello", bh)

    addr := fmt.Sprintf(":%d", port)

    svr := http.Server{
        Addr:           addr,
        Handler:        mux,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
        TLSConfig: &tls.Config{
            // ClientAuth: tls.RequireAnyClientCert,
            MinVersion: convertTlSNumber(minprtcl),
            MaxVersion: convertTlSNumber(maxprtcl),
            // Info: MAXのバージョンが優先される => Cap
        },
    }
    log.Printf("Listening on " + svr.Addr)
    // err := svr.ListenAndServe()
    err := svr.ListenAndServeTLS(crtfile, keyfile)

    if err != nil {
        log.Fatal(err)
    }
}

```
unity > unityApp > udp echo server (delay付き) > Convert.ToInt16(string) / int.Parse()との違い / IPアドレス取得 / Thread.Sleep(msec)

```txt:実装
Unity 5.1.2-f on MacOS X 10.8.5
```

UDPポートでエコーバックするソフト。

![Scene_unity_-_150829-udpEcho_-_Android__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/74ef5363-c371-e1e5-70d4-d631314af58f.jpeg)

以下の機能を持つ。

- port 6000で受信した文字列をそのまま返信する
- 返信時は指定したdelay(msec)の待ちを発生させてから返信する
  - 通信回線の悪い状況の再現 [(参考)](http://qiita.com/7of9/items/96cfad56b0bd12ef1459)
- ソフト起動直後にポート6000にて通信ができるようになる

[github](https://github.com/yasokada/unity-150829-udpEcho)
[callgraph @ mindmup](https://atlas.mindmup.com/2015/08/c6a5c1d030600133cd3515f6b19af581/udp_echo_server_150829_/index.html)


このアプリ実装で以下の方法が整理できた

- textからintへの変換 > Convert.ToInt16(string);
  - int.Parse(string)もあるが、Conver.ToInt16(string)がいいとのこと [(参考)](http://devlights.hatenablog.com/entry/2015/03/24/152150)
  - Convert.ToInt16()を使うには`using System`
- IPアドレスの取得 > getMyIPAddress()にて実装
- Thread.Sleep(20)しないと androidではunity splash screenから進まない. Macでは問題なかった

(追記 2017/04/19)
https://www.youtube.com/watch?v=v-1k7b9L-Sw&list=PLUyYwyJA_WfQd5zeCU890TDFQAqboekyc#t=2.856409
の15:20あたりでも`int.Parse()`と`Convert.ToInt16()`が出てくる。
AzurePowershellで自動ログインできない場合の対処法


# 問題 
「Your Azure credentials have not been set up or have expired, please run Add-AzureAccount to set up your Azure creden
tials.」
Windowsを起動し直してAzureコマンドを利用する度に上記メッセージが表示される。

# 対処
インポートした設定ファイルが使われていない可能性あり。

```shell-session
> Get-AzureAccount
```
で登録されているアカウント一覧を見る。
IDにメールアドレスがあるものはおそらく最初にログインしたときのが記憶されている。
たぶん上から順番に見ていくのでそれを削除

```shell-session
> Remove-AzureAccount <アカウントID>
```
無事解決した。
Azure PowerShell で Reserved IPを設定


# ILPIP(Instance Level Public IP)
ILPIP : サービスではなく仮想マシンに直接グローバルIPを割り当てる。
問題点：仮想マシンを再起動する度には変更されてしまう。
ILPIPに後述の予約済みIPは利用できない
![](https://acomdpsstorage.blob.core.windows.net/dpsmedia-prod/azure.microsoft.com/en-us/documentation/articles/virtual-networks-instance-level-public-ip/20150810093839/figure1.png)

# 予約済みIP(Reserved IP)を使用する
予約済みIP :  Azureで利用できる固定のグローバルIP
仮想マシンインスタンスが存在するサービスに予約済みIP(=固定IP)を割り振る。

- 予約済みIPの取得

```shell-session
> New-AzureReservedIP -ReservedIPName "IPアドレスの名前" -Label "ラベル名" -Location "East Asia"
```

 - 確認

```shell-session
> Get-AzureReservedIP
```


 - サービスへ適用
サービスへ適用したところ以下のエラーが発生。

```shell-session
> Set-AzureReservedIPAssociation -ReservedIPName "予約済みIPの名前" -ServiceName "サービス名"
Set-AzureReservedIPAssociation : BadRequest: The region "予約IPの名前" specified for the reserved ip asiaeast is different than the region
 japaneast that hosted service japaneast belongs to, they need to belong to the same region.
```
予約済みのIPとサービスを同じリージョンにしないといけないらしい。
一旦、予約済みIPを削除。

```shell-session
> Remove-AzureReservedIP -ReservedIPName "予約IPの名前"
```
以下のダイアログが表示されたので「はい」を選択
![](http://i.imgur.com/irDTNik.png?1)

東アジアはおそらく香港。東日本で再作成。

```shell-session
> New-AzureReservedIP -ReservedIPName "予約済みIPの名前" -Label "ラベル名" -Location "Japan East"
> Set-AzureReservedIPAssociation -ReservedIPName "予約済みIPの名前" -ServiceName "サービス名" 

OperationDescription                        OperationId                                 OperationStatus                           
--------------------                        -----------                                 ---------------                           
Set-AzureReservedIPAssociation           xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx        Succeeded                                 
```

今度はエラーが発生しなかった。

`dig`コマンドで名前解決をしたところうまくいっているようだ。

ただし、

**サービス内の仮想マシンが全て停止**しているときは予約済みIPに対して**課金が発生する**($0.41/時 ~306円/月 2015/08/21時点)




# 参考
 - [Instance Level Public IP Overview](https://manage.windowsazure.com/@rtamuratelemaco.onmicrosoft.com#Workspaces/NetworkExtension/VirtualNetwork/roxenet_aec358a0-4d64-47da-8ccf-b099a593c90b/dashboard)
 - [Azure仮想マシンは「仮想ネットワークに配置」すべし](http://qiita.com/ksasakims/items/2f495c8ecdd38168039b)
 - **[IP アドレスの料金](http://azure.microsoft.com/ja-jp/pricing/details/ip-addresses/)**
 - [予約済み IP の概要](https://azure.microsoft.com/ja-jp/documentation/articles/virtual-networks-reserved-public-ip/)
IoTのためのHTML5モバイルアプリ - Part1: リソース

[konashi.js](http://konashi.ux-xu.com/kjs/)はWebViewを使いインターネットで公開しているHTML5アプリを読み込みます。iOSで開発しなくても[jsdo.it](http://jsdo.it/)上でHTML5/JavaScript/CSSのコードを書けば簡単に実行することができます。スマホのWebブラウザから利用できるHTML5モバイルアプリにすると、より汎用的なIoTクライアントが開発できそうです。

<!-- more -->

## HTML5ハイブリッドモバイルアプリ

HTML5ハイブリッドモバイルアプリ用のフレームワークには[Cordova](https://cordova.apache.org/)/[PhoneGap](http://phonegap.com/)や[Appcelerator](http://www.appcelerator.com/)などがあります。HTML5/Javascript/CSSを使って、スマホのネイティブアプリを開発することができます。作成したアプリはApp StoreやGoogle Playから配信します。

基本的にはCordova開発のUIコンポーネントですが、デスクトップブラウザのUIとしても使えます。

* [Ionic](http://ionicframework.com/)
* [OnsenUI](http://ja.onsen.io/)

## HTML5モバイルアプリ

スマホのWebブラウザからアクセスして使うWebアプリを開発するために使います。レスポンシブに対応しているので、モバイルファーストでデザインしてデスクトップブラウザからも利用できます。

[Framework7](http://www.idangero.us/framework7/)はiOSとAndroidのネイティブアプリに近いUIを開発できます。[Sencha Touch](https://www.sencha.com/products/touch/)はエンタープライズアプリの[ExtJS](https://www.sencha.com/products/extjs/)に慣れていれば使いやすいです。

* [Ratchet](http://goratchet.com/)
* [Sencha Touch](https://www.sencha.com/products/touch/)
* [Framework7](http://www.idangero.us/framework7/)
* [Titon](http://titon.io/en)

### HTML5のデバイス系API

W3Cで策定されているデバイス系APIを使うと、スマホに搭載されているセンサー類をHTML5/JavaScriptから制御することができます。特に[Geolocation API](http://www.w3.org/TR/geolocation-API/)や[Vibration API](http://www.w3.org/TR/vibration/)などは、簡単なフィジカル・コンピューティングのアプリ開発に向いていると思います。konashi.jsからも利用できます。

* [デバイスAPIはどこまで使える？最新事情を紹介](https://codeiq.jp/magazine/2014/12/20086/)に
* [【保存版】スマートフォンって実はセンサーの塊！](http://ics-web.jp/lab/archives/4095)
* [エンタープライズモバイルアプリの本命技術、「HTML5ハイブリッドアプリ」とは](http://codezine.jp/article/detail/8141)

### 課題

一番大きな課題はJavaScriptのコードがインターネットから見えてしまうので、連係したいWebサービスのAPIキーなどの情報を安全に保存できないということです。クラウド上でサーバーサイドを用意したり。BaaSを使って安全にセキュリティに関するデータを保存する必要があります。または[myThings](http://mythings.yahoo.co.jp/)のようなアプリを使って、OAuthのマッシュアップを代行してもらうのもよいと思います。
Eclipseのメモリを増やす

最近Eclipseが超重かったので、調べてメモリを増やした。

mac
アプリケーション > eclipse > eclipse 右クリックして【パッケージ内容を表示】 > Contents MacOS > eclipse.ini

XmsとXmxの数値を変更すればOK。

`-Xms512m
-Xmx1024m`
arduinoでethernet

オークションで手に入れたenc28j60をarduino unoにつないで見ました。
##写真
![MVC-007S.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/35ccf23d-0310-d0e5-8397-5da1ba2c8f7a.jpeg)
##回路図
![enc2.PNG](https://qiita-image-store.s3.amazonaws.com/0/18104/ceae6208-0889-8d9c-1ee9-b05f9482e5f9.png)
##ハイパーターミナル
![enc.PNG](https://qiita-image-store.s3.amazonaws.com/0/18104/7a7927d8-5aec-831e-51c2-9257bebfe681.png)
##サンプルコード
```
#include "EtherCard.h"

static byte mymac[] = {
	0x74,
	0x69,
	0x69,
	0x2D,
	0x30,
	0x31
};
byte Ethernet::buffer[700];
static uint32_t timer;
const char website[] PROGMEM = "tanista.dip.jp";
static void my_callback(byte status, word off, word len)
{
	Serial.println(">>>");
	Ethernet::buffer[off + 300] = 0;
	Serial.print((const char *) Ethernet::buffer + off);
	Serial.println("...");
}
void setup()
{
	Serial.begin(9600);
	Serial.println(F("\n[webClient]"));
	if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) Serial.println(F("Failed to access Ethernet controller"));
	if (!ether.dhcpSetup()) Serial.println(F("DHCP failed"));
	ether.printIp("IP: ", ether.myip);
	ether.printIp("GW: ", ether.gwip);
	ether.printIp("DNS: ", ether.dnsip);
	if (!ether.dnsLookup(website)) Serial.println("DNS failed");
	ether.printIp("SRV: ", ether.hisip);
}
void loop()
{
	ether.packetLoop(ether.packetReceive());
	if (millis() > timer)
	{
		timer = millis() + 50000;
		Serial.println();
		Serial.print("<<< REQ ");
		ether.browseUrl(PSTR("/"), "", website, my_callback);
	}
}

```
RubyMineのショートカットキーでコードジャンプの選択肢を表示する

Controllerのメソッド内のソースコードにカーソルがある状態で、Control + Option + 上キーで対応するTestやMVCのコードにジャンプする選択肢が表示される。

![スクリーンショット 2015-08-29 16.11.45.png](https://qiita-image-store.s3.amazonaws.com/0/16400/df42726d-b0e4-87de-906b-920e943870a1.png)

ちなみに、エディタdef indexの左の2行目と5行目のところにアイコンが出ているが、2行目をクリックするとControllerに対応するviewを全て候補に表示、5行目はそのメソッドのviewを候補として表示してくれる
ディスクトップ画面設定

#はじめに
ディスクトップの画面については

・Ubuntu（GNOME）
・Kubuntu（KDE）
・ Xubuntu（XFce）
・OpenGEU（Enlightenment DR17+GNOME）

があるみたい、

#インストール方法

インストール方法としては、コマンドでの方法で行ってみた
**【 Kubuntu（KDE）】**

```:command
$ sudo apt-get install kubuntu-desktop
日本語化　
$ sudo apt-get install language-pack-kde-ja
```

どうやら「language-pack-kde-ja-base」はいらない模様…

**【Ubuntu（GNOME）】**

```:command
$ sudo apt-get install ubuntu-desktop
```

**【Xubuntu（XFce）】**

```:command
$ sudo apt-get install xubuntu-desktop
```

途中でいいかダメか聞いてくる(Y/n)ので「Y（大文字）」を入力
（小文字の「y」はダメ、一回ここでハマった(^^ゞ）

#参考にしたサイト
[■第6回　デスクトップのカスタマイズ（1）：Ubuntu/Kubuntu/Xubuntuの切り替え/Ubuntu Tweak ：Ubuntu Weekly Recipe｜gihyo.jp … 技術評論社]
(http://gihyo.jp/admin/serial/01/ubuntu-recipe/0006)

[■UbuntuにKDEアプリの日本語化パッケージをインストール | Ubuntuアプリのいいところ](http://ubuntuapps.blog67.fc2.com/blog-entry-27.html)


#切り替えるには？。
ログアウトします。
アカウント名を選択をします。

ログイン名のちょっと右上にubuntuマークがある
（これがない場合はなんかインストールで失敗している）

クリックすると選べるので選ぶ
東京オリンピックのロゴの　原案の方を再現しようとしたらより簡単だった件

# 例のロゴ、原案があった？！
おでんやのり弁で再現されたり、ある意味おもちゃと化している例のロゴですが、
原案があったそうです

http://headlines.yahoo.co.jp/hl?a=20150828-00000089-nksports-spo.view-000

これも、比較的容易に再現できます。

# インスパイヤ元

東京五輪エンブレム for Ruby
http://qiita.com/Peranikov/items/5997cd4437e7aaa8ddab

kawasaki.rb の発表でオリンピックのアレがあったので、早速再現してみた。
cairoが必要です。

## まず先に、環境を整える

インストールに手間取りましたが・・・。
http://qiita.com/minos1st/items/723e1aa3f4e73ff339ae

# ソースコード

インスパイヤ元のに少し手を加えただけですが・・・。
<pre>

require 'cairo'

format = Cairo::FORMAT_ARGB32
width = height = 480

surface = Cairo::ImageSurface.new(format, width, height)
context = Cairo::Context.new(surface)

a = 160
#background
context.set_source_rgb(1, 1, 1) # white
context.rectangle(0, 0, width, height)
context.fill

#top left triangle
context.set_source_rgb(0.7, 0.57, 0.27) # yellow
context.triangle(0, 0, a, 0, 0, a )
context.fill

#top right triangle
context.set_source_rgb(0.7, 0.7, 0.7) # gray
context.triangle(2 * a , 0, 3 * a, 0, 3 * a , a )
context.fill

#centar black bar
context.set_source_rgb(0, 0, 0) # black
context.rectangle(a, 0, a, a * 3)
context.fill

#bottom right circle
context.set_source_rgb(0.9, 0, 0.08) # red
context.arc(2.5 * a, 2.5 * a, 0.5 * a, 0, 2 * Math::PI)
context.fill

surface.write_to_png("tol2.png")

</pre>

# 実行結果

![tol2.png](https://qiita-image-store.s3.amazonaws.com/0/60472/c02f0457-5647-1996-37a7-279f71756f62.png)



# 解説

原案の方がより単純な仕組みです
１：白い背景領域を用意する（当初のと変わらない）
２：領域上部に三角形のパーツを２つ、配置する（四角形から変更）
３：黒い長方形を配置する（当初のと変わらない）
４：領域右下に、赤い円形のパーツを配置する（位置が異なる）

なお、手元のフォルダ情報によると、
当初のほうのファイルサイズが9KBに対し、こっちは7KB。
（たしかに、形状がより単純だし）

ねっ。簡単でしょ！


# 蛇足
cairoのインストールのほうが、より大変だった。
ubuntu 起動時の画面の変更

色々ディクトトップをいじっていると、起動するときの画面が

一番最後のディスクトップをインストールした画面になる…
別にいいんだけど、起動画面のロゴを変更したいなと…

コマンドで

```text:command
$ sudo update-alternatives --config default.plymouth
```

これでどの画面に変更するかの選択が表示

変更した場合はこれで反映決定させる

```text:command
$ sudo update-initramfs -u -k all             
```

…う？コマンドは打ったけど帰ってこない…
なかなか帰ってこない( ^^) _旦~~
４・５分は待ったかなあ…帰ってきた

とりあえず再起動したらちゃんと反映されていたヽ(ﾟ▽ﾟ*)乂(*ﾟ▽ﾟ)ﾉ
ログインのデフォルトを変更したい


ファイル場所

```:command
$ sudo gedit /etc/lightdm/lightdm.conf.d/10-xubuntu.conf 
```

でパスワードを入力するとデフォルトの状態だとgeditが起動して

```:10-xubuntu.conf
[SeatDefaults]
greeter-session=unity-greeter
user-session=ubuntu
autologin-user=
```

となっているはずなので

```:lightdm.conf
[SeatDefaults]
greeter-session=unity-greeter
user-session=xubuntu
autologin-user=オートログインしたいユーザー名
```
に変更する
lessコマンド（よく使いそうなものだけ版）

#はじめ#
運用とかでログファイルを読むことが多いのですが
特に使うのがtailコマンドと lessコマンド

そのうちlessコマンドで、ファイル表示後の
よく使うコマンドのみの一覧
(全てのコマンドは他で検索してみてください)

#**lessコマンド一覧**#

　　|コマンド | 動作内容
---|--------|-------------------------
読込|r | 画面を再描画します。
読込|R | 画面を再描画します。(閲覧中に変更があった場合にその内容が反映されます。)
読込|F | ファイルの最終行を読み続けます。(「tail -f」コマンドと同様)
移動|SPACE | 1画面進めます。
移動|d | 半画面進めます。
移動|RETURN | 1行進めます。
移動|b | 1画面戻ります。
移動|u | 半画面戻ります。
移動|y | 1行戻ります。
移動|g, < | ファイルの先頭に移動します。
移動|G, > | ファイルの終端に移動します。
検索　|/パターン | 「パターン」マッチする前方検索を行います。
検索　|?パターン | 「パターン」マッチする後方検索を行います。
検索　|n | 前回の検索を繰り返します。
検索　|N | 前回の検索を逆方向へ繰り返します。
ヘルプ|h, H | ヘルプを表示します。
終了|q, Q, :q, :Q, ZZ | 終了します。
adbをMacのターミナルで使えるようにする

##前提条件
Android Studioが入っていること（Hello Worldが作れること）

#ToDo
##Android SDKの格納場所を確認する
Android Studioで
「File」＞「Other Settings」＞「Default Project Structure…」
ここに記載されています。
![スクリーンショット 2015-08-27 12.54.24.png](https://qiita-image-store.s3.amazonaws.com/0/84307/ab51a002-5d94-99e9-0ab1-18660df9b86b.png)


##bash_profileにAndroid SDKのパスを記入する
下記コマンドでbash_profileを開きます
`$vi ~/.bash_profile`
先ほど確認したAndroid SDKの場所を記入します
`export PATH=$PATH:/Users/furusin/Library/Android/sdk/platform-tools`

##bash_profileを再度読み込む
方法は２つあります。
１．ターミナルを再起動
２．コマンドで改めて読み込む

###コマンドで改めて読み込む場合
ターミナルで次のコマンドを打ち込みます。
`$source ~/.bash_profile`

#完了
以上で終了です。ターミナルでadbと打って「adb: command not found」とならなければ成功です。
turtleに三角関数を描いてもらった

Python2.7で動作させましたが，多分Python3でも大丈夫だと思います．

```python
import turtle as tur
import math

tur.shape('turtle')
tur.left(90)

A = 5
for k in range(360):
	tur.forward(1)
	tur.setheading(math.degrees(math.atan(A * math.cos(math.radians(k)))))
```
(追記 2015/8/29 19:41) 実行結果です．

![spam1.gif](https://qiita-image-store.s3.amazonaws.com/0/83161/d615cd20-5fda-f710-9f03-6d817af939bd.gif)
macにgem のcairoを入れようと思ったら　Homebrewでコケて実はgccでコンパイルすればOKだった件

kawasaki.rbで東京オリンピックのロゴの画像を作成してみたって話を聞いて、再現したくなった。がcairoのインストール部分で苦戦したので投稿

# brewが通らない？

<pre>
$ gem install cairo
</pre>
<pre>
Building native extensions.  This could take a while...

ERROR:  Error installing cairo:

ERROR: Failed to build gem native extension.



    /Users/ShinichiMinoshima/.rbenv/versions/2.1.5/bin/ruby -r ./siteconf20150829-9567-mgx3xj.rb extconf.rb

checking for GCC... yes

checking for Win32 OS... no

checking for cairo version (>= 1.2.0)... no

checking for brew... yes

installing 'cairo' native package... failed

failed to run 'brew install cairo'.

*** extconf.rb failed ***

Could not create Makefile due to some reason, probably lack of necessary

libraries and/or headers.  Check the mkmf.log file for more details.  You may

need configuration options.

Provided configuration options:

--with-opt-dir

 --without-opt-dir

--with-opt-include

--without-opt-include=${opt-dir}/include

--with-opt-lib

--without-opt-lib=${opt-dir}/lib

--with-make-prog

--without-make-prog

--srcdir=.

--curdir

--ruby=/Users/currentuser/.rbenv/versions/2.1.5/bin/ruby

--with-pkg-config

--without-pkg-config

--with-override-variables

--without-override-variables

extconf failed, exit code 1

</pre>
homebrew のところで
何か必要なものが足りなくて失敗したんだろうけど、下で提示されているコマンドは違うような気がする。

# 似たような事例

Mac OS X & Homebrewでcairoのインストール
http://teppeis.hatenablog.com/entry/20120103/1325598908

`$ brew install cairo`

で、失敗。gccでコンパイルしたらインストールに成功したケースです。

# gcc指定でインストール成功
<pre>
$  brew install cairo --use-gcc
</pre>

<pre>
$  brew install cairo --use-gcc

==> Installing dependencies for cairo: libpng, freetype, fontconfig, pixman, gettext, libffi, glib

==> Installing cairo dependency: libpng

==> Downloading https://homebrew.bintray.com/bottles/libpng-1.6.18.yosemite.bottle.tar.gz

######################################################################## 100.0%

==> Pouring libpng-1.6.18.yosemite.bottle.tar.gz

🍺  /usr/local/Cellar/libpng/1.6.18: 17 files, 1.2M

（中略）

==> Installing cairo

==> Downloading https://homebrew.bintray.com/bottles/cairo-1.14.2_1.yosemite.bottle.3.tar.gz

######################################################################## 100.0%

==> Pouring cairo-1.14.2_1.yosemite.bottle.3.tar.gz

🍺  /usr/local/Cellar/cairo/1.14.2_1: 111 files, 6.1M
</pre>

依存性ファイルがいっぱい。

# （追記）（重要）　sudo で インストール

<pre>
$ sudo gem install cairo
</pre>
<pre>
Building native extensions.  This could take a while...
Successfully installed cairo-1.14.1
Parsing documentation for cairo-1.14.1
Installing ri documentation for cairo-1.14.1
Done installing documentation for cairo after 2 seconds
1 gem installed
</pre>

# 教訓
そういえば、Rails環境を構築するのにmysql2とかを入れた時にも似たようなケースがあったかな？

トラブルシューティングでは、どのあたりでコケたかを把握し、その症状で絞り込む。と。
C#のenumでビット演算をする


普通にintにキャストしてもビット演算してもいいのですが、enumのままできる方法を調べた時のメモ。
確認した環境はmono4.0(C#6.0相当)

---

列挙定数を 2 の累乗 (1、2、4、8 ..,)と宣言するのに加え、FlagsAttribute属性を付与することでビットフィールドとして扱われ、ビット演算が可能となる。


[FlagsAttribute クラス](https://msdn.microsoft.com/ja-jp/library/system.flagsattribute(v=vs.110).aspx)


```cs
[Flags]
enum language
{
	CSharp = 1,
	Java   = 1 << 1,
	Ruby   = 1 << 2,
	Perl   = 1 << 3,
	Python = 1 << 4,
}
```


OR演算を使って複数ビットをもたせる。

```cs
language mySkill = language.CSharp | language.Perl;
Console.WriteLine((int)mySkill);	// => 9
Console.WriteLine(mySkill); 		// => CSharp, Perl
```

ちゃんとビット持っていることを確認。


特定ビットのON/OFFは、普通にビット演算すれば可能。

```cs
language mySkill = language.CSharp | language.Perl;

mySkill |= language.Java;		
Console.WriteLine(mySkill);		// => CSharp, Java, Perl

mySkill &= ~language.Perl;
Console.WriteLine(mySkill);		// => CSharp, Java
```

特定ビットがONであるかどうかはAND演算で可能ですが、HasFlagメソッドを使えばスッキリ。
[Enum.HasFlag メソッド](https://msdn.microsoft.com/ja-jp/library/system.enum.hasflag(v=vs.110).aspx)


```cs
if (mySkill.HasFlag(language.CSharp)) {
	Console.WriteLine ("I can write " + language.CSharp);
}
```

---
【2014/08/30追記】 
HasFlagメソッドは、値型(enum)を参照型(Enum)として扱うため、ボックス化のコストが発生するため、パフォーマンスを気にする場合はAND演算のほうがよいようです。

Temarin_PITAさんコメントありがとうございます。
ドットインストールのローカル開発環境構築でchef/centos-6.5を実行できない

# vagrant init chef/centos-6.5を実行できない

ドットインストールのローカル開発環境の構築 [MacOS X編]を進めていたところ、タイトルのところで詰まりました。

https://atlas.hashicorp.com/chef/boxes/centos-6.5
にアクセスすると404エラーとなり、ファイルが無くなったようです。
https://atlas.hashicorp.com/bento/
chefの代わりにこちらのURLでbentoのvagrant boxを入手できますが、残念ながらcentos6.5のBOXはありません。

そこで試しにbento/centos7.1をvagrant initしてみました。ですが、ドットインストールの後の行程でPHPやMySQLをインストールするためのシェルスクリプトが、centos7.1ではうまく動作しませんでした。やはりcentos6.5を入れるしかなさそうです。

「公式以外の野良boxを使うのは怖い」みたいなコメントを横目にしつつ、検索上位にでてきた
http://www.vagrantbox.es
の CentOS 6.5 x86_64 を入れます。
`vagrant box add centos6.5 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box`

Vagrantfileが作られないのが気になりましたが、`vagrant up`します。あとはドットインストールの指示に従いながらシェルスクリプトを実行したところ、無事にPHPやMySQLのインストールが完了しました。
※残念ながらRubyは動作していませんでした。

- php -v
- mysql --version
- python --version
- ~~ruby -v~~
- sudo service httpd status

以上です。
BluemixでWatson 〜Speech to Textを試して見る

Bluemixのサービスの中にWatsonに分類されているサービスがたくさんありますが、それぞのサービスがどのようなものなのか試してみようと思います。
なにやらそれぞれが難しそうなので、まずは簡単なところから

#Speech to Textとは
なんとなく名前を見ただけで機能が想像つきます。文字通り、マイクに向かって話しかけた言葉をテキストにしてくれます。今の所サポートしているのは、英語、日本語、スペイン語でした。英語、スペイン語の間に日本語が入っているのは凄いと思います。数で言えば中国語とかの方が人口が多そうなのに・・・
#サービスの追加
まずはサービスの追加。Watsonにカテゴライズされた中にあります。ここから自分のダッシュボードにサービスを追加します。最初の１０００分は無料なので、それまでは費用はかかりません。（そもそも自分はトライアル中だし、大丈夫なはず）
![スクリーンショット_2015-08-19_0_12_01.png](https://qiita-image-store.s3.amazonaws.com/0/89268/e069ac4d-8838-3336-e17f-b1105e0bd95b.png "スクリーンショット_2015-08-19_0_12_01.png")
そしてダッシュボードから、Speech to Textサービスの起動
起動後の画面はこんな感じです。![スクリーンショット_2015-08-19_0_12_49.png](https://qiita-image-store.s3.amazonaws.com/0/89268/480b754e-50b2-cbac-0661-cbb6a6a64314.png "スクリーンショット_2015-08-19_0_12_49.png")

![スクリーンショット_2015-08-19_0_13_00.png](https://qiita-image-store.s3.amazonaws.com/0/89268/5d14de45-0141-29c4-001a-ba7c23190655.png "スクリーンショット_2015-08-19_0_13_00.png")

このデモアプリケーションでは、Speechの入力は、この画面に向かってマイクから直接音声も入れられますし、あらかじめ録音されている音声ファイルをアップロードすることでも処理できるということです。

まずはやってみます。日本語から。
原稿とか準備しておけばよかったのですが、思いつきで話をしているので日本語としても間違っているのかもしれません。入力結果はこんな感じ。単純なスピーチ認識ではなく、バックエンドでWatsonが手伝っているだけに、生麦と言ったところで言っていないのに生卵まで画面に表示されていたような気もします。「青巻き紙」とか言ってみましたが、自分の方が噛んでしまいました。
![スクリーンショット_2015-08-19_0_19_12.png](https://qiita-image-store.s3.amazonaws.com/0/89268/510c0f8d-1b28-5b59-55e6-905963d7ffad.png "スクリーンショット_2015-08-19_0_19_12.png")
![スクリーンショット_2015-08-19_0_19_33.png](https://qiita-image-store.s3.amazonaws.com/0/89268/5a5e9e22-322c-1840-eac2-8f8fbfd4bca2.png "スクリーンショット_2015-08-19_0_19_33.png")


そして英語
自分が話しかけても全然ダメです。発音がなっていないみたいです。
手元にあったBoseのヘッドホンの説明をiPhoneから流して、それを入力にSpeech to Textで処理してみました。
どうですか？これならイケそうです。やっぱり英語得意みたいです。結構なスピードでしゃべっていましたがきちんと追いついてきています。
![スクリーンショット_2015-08-19_0_31_04.png](https://qiita-image-store.s3.amazonaws.com/0/89268/f8e2f628-b748-a694-4ab1-9f8d8d36c462.png "スクリーンショット_2015-08-19_0_31_04.png")

#まとめ
Speech to Text は、アプリケーションに組み込んで利用できるようになっていますが、今回利用したのは、サンプルとして提供されていたデモアプリケーションです。実際にAPIをアプリケーションに組み込んでみると、音声制御や、録音済みの音声からテキスト情報を起こすなどいろいろな用途に使えそうです。
BigDataとして音声ファイルとかを解析するときには、まず、この機能を使ってテキスト化してしまえば、解析がうまくできそうです。

今回は、PCの本体に内蔵されたマイクを利用しましたが、ちゃんとヘッドセットとかつければより認識率は高くなりそうです。サービスも単体で動きますので、Bluemix上で、まずは、どれくらいの精度で認識するか試してみてはいかがでしょうか。
Go言語 http POSTする際のContent-Type

http pkg を使って postする際、
リクエストヘッダの違いで、若干ハマったのでメモ。

## はじめに

`net/http` pkg の使い方に関しては、
こちらの記事が詳しいので、参考にさせていただきました。

[Go net/httpパッケージの概要とHTTPクライアント実装例](http://qiita.com/jpshadowapps/items/463b2623209479adcd88)

## コード例
### ■パラメータをURLエンコードする場合
要はContent-Type が、 `application/x-www-form-urlencoded` の場合です。

`net/url` pkg で定義されている `type Values` を使ってます。
https://golang.org/pkg/net/url/#example_Values

```go
package hoge

import (
    "net/http"
    "net/url"
    "strings"
)

func HttpPost(url, token, device string) error {
	values := url.Values{}
	values.Set("token", token)
	values.Add("device", device)

	req, err := http.NewRequest(
		"POST",
		url,
		strings.NewReader(values.Encode()),
	)
	if err != nil {
		return err
	}
	
	// Content-Type 設定
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	
	return err
}
```

### ■パラメータがjson形式の場合
Content-Type が、 `application/json` の場合。
`jsonStr` という変数名の未加工文字列リテラルで、
json形式のパラメータを記述しています。

```go
package hoge

import (
    "net/http"
    "net/url"
    "bytes"
)

func HttpPost(url, token, device string) error {
	jsonStr := `{"token":"` + token + `","device":"` + device + `"}`

	req, err := http.NewRequest(
		"POST",
		url,
		bytes.NewBuffer([]byte(jsonStr)),
	)
	if err != nil {
		return err
	}

	// Content-Type 設定
	req.Header.Set("Content-Type", "application/json")
	
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	
	return err
}
```

参考
http://stackoverflow.com/questions/24455147/go-lang-how-send-json-string-in-post-request
Java 8でJenkinsのJNLPエージェント(Win7)がうまく機能しない時の対応

## 環境

　OSは、JenkinsもJNLPエージェントも同じWindows7上で動いています。
ビルドの設定で、Subversionをポーリングする設定になっています。"\Jenkins"フォルダに"svn update"します。
　(あれ…そもそも、なんで、同じWindows7上で動いているのにわざわざJNLPエージェント使ってるんだっけ…??)

## 経緯

　Java 8 をu40からu60へアップデートしたら、Windows上でJNLPエージェント経由でSubversionをポーリングするところでずっと止まるようになってしまいました。

## 状況

　Jenkinsのコンソール上に、「ディレクトリがロックされている」とメッセージが出て、クリアーまではするけど、svn updateがうまく動作していないようで、作業ディレクトリが空のまま。
　結果として、Subversionのリビジョンが上がっているのか判断できずに処理待ちになります
本来なら作業コピーが作成されるはずのですが…


## 原因

　いつのアップデートで入ったのか分からいのですが、セキュリティの項目が１つ増え、そのセキュリティ項目にチェックを付けたらローカルドライブにSubversionの作業コピーを正常に作成してくれました。

![Jennkins.PNG](https://qiita-image-store.s3.amazonaws.com/0/64245/b88daa66-aa51-50dc-9c60-082f9a2b4fa5.png)

　正確にどんな設定なのか調べようとしたのですが、情報が見つけられなかったので、同じことで困っている人は、自己責任で設定してください。また、もし、情報があったら、教えてください。
　サンドボックスを有効するとJenkinsで設定した作業ディレクトリがサンドボックスになるのかと予想しています。
JavaScriptで配列から特定の要素を削除する方法

# はじめに

配列から特定の要素を削除するにはいくつか方法があります。
単純に先頭の要素を削除するにはshift()で実現できます：

```js
var ary = ['あ', 'い', 'う', 'え', 'お'];
console.log(ary.shift());  // => あ
console.log(ary);  // => ['い', 'う', 'え', 'お']
```

逆に最後の要素を削除するにはpop()で実現できます：

```js
var ary = ['あ', 'い', 'う', 'え', 'お'];
console.log(ary.pop());  // => お
console.log(ary);  // => ['あ', 'い', 'う', 'え']
```

また一部の要素を取り出すのはslice()で実現できます：

```js
var ary = ['あ', 'い', 'う', 'え', 'お'];
console.log(ary.slice(2, 4));  //  =>  ['う', 'え']
console.log(ary);  // => ['あ', 'い', 'う', 'え', 'お']
```

ここではsplice()を使って、もっと柔軟に好きな位置の要素を削除する方法をまとめてみます。
splice()の初歩的な使い方は次の通りです：

```js
var ary = ['あ', 'い', 'う', 'え', 'お'];
console.log(ary.splice(1, 2));  // =>  ['い', 'う']（1番目から2つ取り出す）
console.log(ary);  // => ['あ', 'え', 'お']（取り出された後の配列）
```

# 1次元配列

例えば次の配列から１、２、４番目の要素を削除するとします：

```js
['あ', 'い', 'う', 'え', 'お']
```

これは次のコードでできます：

```js
var ary = ['あ', 'い', 'う', 'え', 'お'];
var exe = [1, 2, 4];    //削除したい位置（先頭が0であることに注意）
for(var i=0; i<exe.length; i++){
  ary.splice(exe[i]-i, 1);    //exe[i]-i番目から1つだけ削除
}
```

この結果、配列aryは次のように加工されます：

```js
['あ', 'え']
```

ポイントは次の部分です：

```js
ary.splice(exe[i]-i, 1);
```

for文で1周する度に配列が短くなっていくので、**回った分だけ前に詰まります**。
それを考慮して、回った分だけ削除位置を前に詰めます。

# 2次元配列

配列が2次元になっても基本的には同じです。
2次元の場合は行を削除する場合と列を削除する場合があります。
行の方が簡単なので、まずは行から見ていきましょう。

## 行を削除

例えば次の配列から１、２、４行目を削除するとします：

```js
[
  ['あ', 'い', 'う', 'え', 'お'],
  ['か', 'き', 'く', 'け', 'こ'],
  ['さ', 'し', 'す', 'せ', 'そ'],
  ['た', 'ち', 'つ', 'て', 'と'],
  ['な', 'に', 'ぬ', 'ね', 'の'],
]
```

これは次のコードでできます：

```js
var ary = [
  ['あ', 'い', 'う', 'え', 'お'],
  ['か', 'き', 'く', 'け', 'こ'],
  ['さ', 'し', 'す', 'せ', 'そ'],
  ['た', 'ち', 'つ', 'て', 'と'],
  ['な', 'に', 'ぬ', 'ね', 'の'],
];
var exe = [1, 2, 4];    //削除したい位置（先頭が0であることに注意）
for(var i=0; i<exe.length; i++){
  ary.splice(exe[i]-i, 1);
}
```

この結果、配列aryは次のように加工されます：

```js
[
  ['あ', 'い', 'う', 'え', 'お'],
  ['た', 'ち', 'つ', 'て', 'と'],
]
```

つまり行の削除は1次元の場合と全く同じコードで実現できます。

## 列を削除

ほんのちょっとだけレベルが上がります。
例えば次の配列から１、２、４列目を削除するとします。

```js
[
  ['あ', 'い', 'う', 'え', 'お'],
  ['か', 'き', 'く', 'け', 'こ'],
  ['さ', 'し', 'す', 'せ', 'そ'],
  ['た', 'ち', 'つ', 'て', 'と'],
  ['な', 'に', 'ぬ', 'ね', 'の'],
]
```

これは次のコードでできます：

```js
var ary = [
  ['あ', 'い', 'う', 'え', 'お'],
  ['か', 'き', 'く', 'け', 'こ'],
  ['さ', 'し', 'す', 'せ', 'そ'],
  ['た', 'ち', 'つ', 'て', 'と'],
  ['な', 'に', 'ぬ', 'ね', 'の'],
];
var exe = [1, 2, 4];    //削除したい位置（先頭が0であることに注意）
for(var i=0; i<ary.length; i++){    //このfor文で行を回す
  for(var j=0; j<exe.length; j++){
    ary[i].splice(exe[j]-j, 1);
  }
}
```

この結果、配列aryは次のように加工されます：

```js
[
  ['あ', 'え'],
  ['か', 'け'],
  ['さ', 'せ'],
  ['た', 'て'],
  ['な', 'ね'],
]
```

ポイントはaryではなくary[i]に対してsplice()を実行することです。


# さいごに

もっとスマートな方法をご存知の方は、ぜひ教えて下さい。
[AngularJS] [Parse.com] シンプルなローディングバーライブラリを手軽に使う

# 環境等
* AngularJS:1.3.4
* Parse JS SDK:1.4.2
* Angular Loading Bar:0.8.0

# Angular Loading Bar
[Official] http://chieffancypants.github.io/angular-loading-bar/
[GitHub] https://github.com/chieffancypants/angular-loading-bar

![039a9112be49354aaf3e9aaa289e9494.gif](https://qiita-image-store.s3.amazonaws.com/0/40758/d127b22f-a729-46be-c480-9025ba26f2de.gif)

上のサンプル画像では、bodyの最上部のバーと左上のインジケータ（ぐるぐる）がAngular Loading Barで表示されています。
シンプルですね。
バーかインジケータのどちらかのみ使うことも簡単にできます（今回は割愛）。[[こちらを参考]](https://github.com/chieffancypants/angular-loading-bar#configuration)

Angularの `$http` のリクエストをフックして自動的にローディングバーを表示できるようですが、Parse.comを使用していると `$http` は使いません。

そこでAngular Loading Barが用意してくれているAPIを使います。と言ってもParse.comへのアクセス開始時にstart()、完了時にcomplete()を呼ぶだけです。簡単。では↓で使い方。


# 使い方

## インストール

```sh
$ npm install angular-loading-bar
# または
$ bower install angular-loading-bar
```
または

```html
<link rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/angular-loading-bar/0.8.0/loading-bar.min.css' type='text/css' media='all' />
 <script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/angular-loading-bar/0.8.0/loading-bar.min.js'></script>
```


APIを使いたいので[こちら](https://github.com/chieffancypants/angular-loading-bar#service-api-advanced-usage)にあるとおり`'cfp.loadingBar'` をDIします（APIを使わないときは `'angular-loading-bar'`）。

```js:index.js
    angular.module('myApp', ['cfp.loadingBar'])
```

## ローディングバーの表示（サンプルコードはTypeScriptです）

```ts:sample.ts

      var MyObject = Parse.Object.extend('MyObject');
      var query = new Parse.Query(MyObject);

      // ローディングバー スタート！
      // complete()を呼ぶまで自動的にじわじわ進んで行きます。
      // （100%の手前で止まります）
      cfpLoadingBar.start();

      // Parse SDKによる非同期処理
      // この例ではfind()
      query.find()
      .then((results: Parse.Object[]) => {
        // find成功時の処理（省略）

        // ローディングバー完了（バーが右端まで一気に進みます）
        cfpLoadingBar.complete();
      },
      (error: Parse.Error) => {
        // find失敗時の処理（省略）

        // 失敗時もローディングバー完了（バーが右端まで一気に進みます）
        cfpLoadingBar.complete();
      });

```

save()など他の処理でも使い方は同じ。
進捗度（パーセンテージ）などの指定をしたいときは公式を参考に。

# [おまけ] BootStrapのNavBarの下に表示する

![037d6b5a2aff6301889247342b6f8162.gif](https://qiita-image-store.s3.amazonaws.com/0/40758/e860124d-6ca5-8567-8c2d-227d7b1bf755.gif)

```css
.bar {
  /* navbarの高さ分下へ */
  margin-top: 50px;
}
```
cv::Matを遅く使う方法(img.at<uchar>(y,x) を使う全画素処理)

OpenCVの自作ライブラリが、無駄に遅いことに気づいた。
全画素処理で無駄に15%程度遅い書き方をしていた。

結論：
img.at\<uchar\>(y,x)はランダムアクセス用に使う。
全画像処理を行う場合には、各行の先頭のポインタを求め、行の中では、一次元配列として
処理するのが可読性がよく、しかも速い。

ここで実験している範囲では上記の結論になりますが、
別の記事に書いているように、
[画像処理で2重ループをなるべく書くな](http://qiita.com/nonbiri15/items/9d4296b3a79fad38bf76)
と主張します。


```cpp:pixelAccess.cpp
#include <opencv2/opencv.hpp>
/**
* @brief cetnter of gravity (img.at<uchar>(y,x) version)
* @param[in] img
* @param[out] meanX
* @param[out] meanY
* 画素の位置を求めるためには毎回、乗算が必要。
*/
void meanXY(const cv::Mat &img, double &meanX, double &meanY){
	double sumX = 0.0;
	double sumY = 0.0;
	double sum = 0.0;

	for (int y = 0; y < img.rows; y++){
		for (int x = 0; x < img.cols; x++){
			uchar pixel = img.at<uchar>(y, x);
			sumX += pixel * x;
			sumY += pixel * y;
			sum += pixel;
		}
	}
	meanX = sumX / sum;
	meanY = sumY / sum;

}

/**
* @brief cetnter of gravity (pointer version)
* @param[in] img
* @param[out] meanX
* @param[out] meanY
* 同じ行の中では、次の画素にアクセスするのに乗算は不要になる。
*/
void meanXY2(const cv::Mat &img, double &meanX, double &meanY){
	double sumX = 0.0;
	double sumY = 0.0;
	double sum = 0.0;

	for (int y = 0; y < img.rows; y++){
		const uchar *pLine = img.ptr<uchar>(y);
		for (int x = 0; x < img.cols; x++){
			uchar pixel = pLine[x];
			sumX += pixel * x;
			sumY += pixel * y;
			sum += pixel;
		}
	}
	meanX = sumX / sum;
	meanY = sumY / sum;

}

int main(int argc, char* argv[]){
	char name[] = "lena.jpg";
	cv::Mat img = cv::imread(name, 0);

	double f = 1000.0 / cv::getTickFrequency();
	int64 time = cv::getTickCount();

	double meanX;
	double meanY;
	for (int i = 0; i < 100; i++){
		meanXY(img, meanX, meanY);
	}
	
	int64 time2 = cv::getTickCount();

	double meanX2;
	double meanY2;
	for (int i = 0; i < 100; i++){
		meanXY2(img, meanX2, meanY2);
	}
	int64 time3 = cv::getTickCount();

	printf("meanX =%f\n", meanX);
	printf("meanY =%f\n", meanY);
	printf("meanX =%f\n", meanX2);
	printf("meanY =%f\n", meanY2);


	double percent = 100.0*(time3 - time2) / (time2 - time);

	printf("%f ms \n", (time2 - time)*f);
	printf("%f ms (%f %%)\n", (time3 - time2)*f, percent);
}
```

実行結果　(win32 release mode)
meanX =266.523905
meanY =247.455709
meanX =266.523905
meanY =247.455709
74.742080 ms 
63.385786 ms (84.806024 %)


付記：
　OpenCVのモジュールの中にある関数で、自分の関数を置き換えられないか、OpenCVのドキュメントを読んでみよう。
　OpenCVの関数の中でマルチコアの対策がされている関数を使えば、素直に高速化することができます。
　ポインタ演算をするよりは、OpenMPの利用で速くする方がいい。
Android AnnotationでNullPointerException

投稿していない日数をtwitterで通知しているのに、２００日以上ぶりの投稿・・・

先日久しぶりにAndroidを触った際、以前から触ってみたいと考えていた[AndroidAnnotation](http://androidannotations.org)を使って見ることに。

### Android Annotationとは
AndroidAnnotationの詳しい説明はggって欲しいですが、簡単にはAndroidのxmlのviewやitemとの連携をannotationで書け、コード記述量を減らせるライブラリです。

具体的には、

```
@EActivity(R.layout.test)
public class Test extends Activity {
	@ViewById(R.id.mySurfaceView)
	TestSurfaceView tsv;
	
	@Click(R.id.leftButton)
	protected void leftButtonClick(final View view) {
		// TODO
	}

```

のように書くことがで、viewやview itemの紐つけ、押した際の処理を定義できます。
これによって今までfindViewByIdやonClickListenerを複数定義してごちゃごちゃになっていたところを、annotation付きのメソッドで簡略に記述できます。

### 今回の発生した問題
今回はこれを利用してコード量を減らし、一部のviewはインスタンスを保持し、メソッドを呼び出せるようにしました。

```
@EActivity(R.layout.test)
public class Test extends Activity {
	@ViewById(R.id.mySurfaceView)
	TestSurfaceView tsv;
	
	protected void onCreate(BundlesavedInstanceState) {
　　　　super.onCreate(savedInstanceState);
　　　　// 試しにメソッド呼びだし
　　　　tsv.doSomething();
	}
}
```

しかし、これを実行するとNullPointerExceptionが発生します。今までonCreateでfindViewByIdを呼び出していたので、なぜNullなのか分からず、混乱しました。

そのため調べてみると、どうやらannotationをつけたviewは自動でインジェクションされるものの、onCreateの時点ではインジェクションされていないそうです・・・

### じゃあどうするのか？
onCreateでは挿入されませんが、インジェクションされた後に呼び出すことを指定できるannotationがあります。@AfterViewをつけるとそのメソッドはインジェクション後に呼び出されます。

つまり、以下のように書けば解決します。

```
@EActivity(R.layout.test)
public class Test extends Activity {
	@ViewById(R.id.mySurfaceView)
	TestSurfaceView tsv;
	
	protected void onCreate(BundlesavedInstanceState) {
　　　　super.onCreate(savedInstanceState);
	}

	@AfterViews
	void initialize(){
       // Wait for surfaceview ready
　　　　// 試しにメソッド呼びだし
　　　　tsv.doSomething();
	}
}
```

久しぶりにAndroidを触ることもあり、かなり苦戦しました・・・