OmniAICreator/Qiita-1.07M huggingface dataset:
terraform importの使い方メモ

#terraform importの使い方メモ

##背景
terraformではv0.7.0以降で実装された`import`コマンドを使用して既存インフラをterraform管理下に置くことができます。といっても`tfstate`へのインポートのみです。しかも`v0.9.2`時点では一括インポートができないため、リソースIDを指定してインポートする必要があります。さらにその後`terraform plan`で差分がなくなるまでtfファイルを作り込む面倒な作業が待っています。そのような事情もあって現時点では[dtan4/terraforming](https://github.com/dtan4/terraforming)を使用する人が多いと思われますが、やはり対応リソースの広さに惹かれて本家の機能を使ってみました。

##本題
###事前にモジュール構造を決める
とりあえず手で環境を作って[Hashicorpのbest practice](https://github.com/hashicorp/best-practices)に従ったモジュール構造でコード化しようと試みました。作った環境は上記のコードとだいたい同じで、パブリックのサブネットとプライベートなサブネットがある単純なVPCです。（詳細は割愛）

###インポート
何はともあれ[公式のリファレンス](https://www.terraform.io/docs/import/usage.html)に従ってインポートしてみます。vpc-idはマネジメントコンソールから拾ってきます。リソースの多い場合はSDKなどでIDを引っこ抜いてくるスクリプトを作ったほうが良いと思います。

```
$ terraform import aws_vpc.vpc vpc-********
```

次にvpcのtfファイルを作成し、planを実行しました。しかし既存リソースは定義なしと見なされ再作成の対象となってしまいます。

```
$terraform plan

- aws_vpc.vpc

+ module.network.vpc.aws_vpc.vpc

```

原因は一見してわかるようにモジュール構造が異なるためです。そこでモジュール指定でインポートしてみると、今度はリソース名を解決できないと怒られます。

```
$ terraform import module.network.vpc.aws_vpc.vpc vpc-********
Error importing: failed to parse resource address 'module.network.vpc.aws_vpc.vpc': Unexpected value for InstanceType field: "vpc"
```

###モジュールの指定方法
インポートの際はplanの表示と違ってvpcモジュール側も`module.vpc`と指定する必要があったのでした。`apply`等と同じ仕様ですね。

```
$ terraform import module.network.module.vpc.aws_vpc.vpc vpc-********
```

この状態で`terraform plan`を実行するとめでたく差分なしとなりvpcは破壊されなくて済むのでした。terraformの管理下におく場合はとりあえずインポートしてからtfファイルを作り始めるというよりモジュール構造を決めてからインポートした方が効率的と思います。

###インポートできないリソース
ルートテーブルなどに紐づく関連付けやセキュリティグループのルールは個別のインポートができない仕様です。ルートテーブルに複数の関連付けなどがある場合自動的にリソース名の末尾に数字が付いた名前で別々のリソース定義としてインポートされてきます。

ここで気になるのが、例えばルートテーブルに対する関連付けを動的に生成するような管理をしたい場合です。例えば下記のようなコードで`private`ルートテーブルに対する関連付けを一括して管理したいとします。

```
resource "aws_route_table_association" "private" {
  count          = "${length(var.private_subnet_ids)}"
  subnet_id      = "${element(var.private_subnet_ids, count.index)}"
  route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
}
```

しかし`import`は上位のルートテーブル単位でしかできません。

```
terraform import module.network.module.route_table.aws_route_table.private rtb-*******
```

このコマンドの結果は`aws_route_table_association.private`、`aws_route_table_association.private-1`などどと別々の定義として`tfstate`に書き出されます。こうなると事後でstateに合わせるためにはtfファイルに関連付けの数だけリソース定義を書かないといけなくなりそうです。`state`と差分がなければコードなんて何でもいいだろという思想も一理ありますが、やはりここは保守性や拡張性なども考えたいところです。

###逆にtfstateをコードに合わせる
推奨はしませんが`tfstate`を手で編集するか、terraformをカスタマイズしてpull requestを出してしまうかですが、余程腕に自信のあるエンジニアでない限り前者の方が手っ取り早いでしょう。`aws_route_table_association.private-1`を`aws_route_table_association.private.1`
などどコードに合わせて書き換えてしまいましょう。（自己責任）

`tfstate`の書き換えは下記の記事を参考にさせて頂きました
[Terraforming未対応の既存リソースも自力でtfstateを書いてTerraform管理下に入れる](http://qiita.com/minamijoyo/items/e0f69bfa853bef60977e)

##結論
まだまだ未完成の機能なので単にインポートするだけで綺麗にコード化して管理できるとはいかないようです。`v1.0`が待たれます。
Rantly(property based testing tool)でテストデータ生成 - choose

Rantly#choose で複数のデータからランダムに値を選択します

## <i class='fa fa-question-circle'></i> 関連記事
[tbpgr の rantly 関連記事](http://qiita.com/search?utf8=%E2%9C%93&q=user%3Atbpgr%20tag%3Arantly)

## <i class='fa fa-flask'></i> サンプル
```ruby
Rantly(5){choose integer(5), string}
# => [-2, 5, "Jgc`sH", "AC}!~z", "y}Di53"]
Rantly(5){choose integer(5), string}
# => [1, "c(mHbo", 4, "6%KHBN", "f_]|tA"]
Rantly(5){choose 1, 'a', ('c'..'f')}
# => ["a", 1, "c".."f", 1, 1]
Rantly(5){choose 1, 'a', ('c'..'f')}
# => [1, "c".."f", "c".."f", "c".."f", "c".."f"]
```

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [abargnesi/rantly](https://github.com/abargnesi/rantly)
オープンソースのアンチウイルスソフト ClamAV の設定ファイル暴発防止戦略

ClamAV の設定ファイル(clamd.conf, freshclam.conf)は導入後にユーザーに設定してもらう前に暴発しないように
EXAMPLE 命令が有効な状態で配布してある。
これをコメントアウトすることで利用可能になる。

* clamd.conf

```
##
## Example config file for the Clam AV daemon
## Please read the clamd.conf(5) manual before editing this file.
##


# Comment or remove the line below.
Example
# 略
```

* clamd を実行

```sh
$ clamd

ERROR: Please edit the example config file /path/to/clamd.conf.
```

* clamd.conf を編集して Example 命令を無効化する

```
##
## Example config file for the Clam AV daemon
## Please read the clamd.conf(5) manual before editing this file.
##


# Comment or remove the line below.
# Example
# 略
```

* clamd を実行

```sh
$ clamd
# 正常に実行される
```

## <i class='fa fa-code'></i> 実処理
実処理はここにあります。

* [optparser.c#L888-L893](https://github.com/vrtadmin/clamav-devel/blob/7a85da5c9ad54809218a7c797828e0f5abe26b0f/shared/optparser.c#L888-L893)

## <i class='fa fa-graduation-cap'></i> 雑感
どういうアプローチを取るのが一般的なのかよくわからない。

## <i class='fa fa-book'></i> 関連資料
* [ClamAV Official](http://www.clamav.net/)
* [AmazonLinuxでclamavを使う - インフラ関係のメモ書き](http://rikuga.me/tag/clamav/)
macOS で Headless Chrome を試す

# Headless Chrome とは？

Headless Chrome とは、Google Chrome の ヘッドレスモードのことを指します。  
ヘッドレスモードでは、実際には画面描画を行わずにWebページを読み込む等の動作を行うことができます。これの何が嬉しいのかというと思うかもしれませんが、ヘッドレスモードを用いることでCLIからWebブラウジング操作をすることができます。つまり、スクレイピングができるのです。  

## なぜ Headless Chrome なのか？

スクレイピングと言えば、まず Nightmare.js とか Phantom.js が思い浮かびますよね。では、なぜそれらのツールを使わず Headless Chrome を使うのか。  
まずこれらは、実際に使われているブラウザではないため、特有の問題が発生する場合があるようです。また、例えば Nightmare.js は Electron を用いて実装されていますが、それ故に実際の画面やウィンドウマネージャーを持たない環境では起動できない場合があるようです。  
さらに先日、 Phantom.js 唯一のメンテナーが Headless Chrome の登場を理由に辞任を表明しました[^1]。

## macOS で使うのは少し面倒

そんな期待の Headless Chrome ですが、Linux 上からは便利なコマンドツールが揃っているようですが、macOSから使うにはひと工夫必要なようです。ここからは実際に macOS で Headless Chrome を使う方法を紹介します。

# Google Chrome Canary をインストールする

Chrome のヘッドレスモードは、Chrome 59 から利用できる機能です。2017年4月19日現在、Google Chrome の安定最新版はバージョン57系なのでヘッドレスモードは利用できません。利用するためには、開発版である Google Chrome Canary をインストールする必要があります。

Google Chrome Canary は [Google Chrome Canary ダウンロードページ](https://www.google.co.jp/chrome/browser/canary.html) から、または Homebrew cask を利用した以下のコマンドでインストールすることができます。

```
$ brew install Caskroom/versions/google-chrome-canary
```

## ヘッドレスモードで起動する

Chrome をヘッドレスモードで起動するには、コマンドライン上からオプション付きで Chrome を実行する必要があります。おそらく、`Google Chrome Canary.app` は `/Applications` ディレクトリ内にインストールされているはずなので、その中に含まれる実行ファイルを以下のように呼び出します。

```
$ /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --headless --remote-debugging-port=9222 --disable-gpu https://chromium.org
```

これで、 https://chromium.org にヘッドレスモードでアクセスしに行っているはずです。動作を確認するため http://localhost:9222 にアクセスしてみると、リモートデバッギングツールの画面が表示されるはずです。表示されているリンクを踏むと、デバッギングツール内で詳細な内容が確認できます。

# スクリプトからの操作は次回

だいぶ長くなったので、スクリプトからの操作は分割して別で投稿します。

追記: スクリプトからの操作について書きました。以下からどうぞ。
[macOS で node.js から Headless Chrome を操作してスクレイピング](http://qiita.com/gorohash/items/d6429bf0783a32555738)

# 参考

* [Chrome Platform Status](https://www.chromestatus.com/features/5678767817097216)
* [How to install and use Headless Chrome on OSX](https://objectpartners.com/2017/04/13/how-to-install-and-use-headless-chrome-on-osx/)

[^1]: https://groups.google.com/forum/m/#!topic/phantomjs/9aI5d-LDuNE
nfc raspberrypi felica servo: turn on/off light of a room 

nfc raspberrypi felica servo: turn on/off light of a room

自分のsuicaの場合だけ, サーボを回す. 

```turn_servo.py
import nfc
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
servo_pin = 3
GPIO.setup(servo_pin, GPIO.OUT)
servo = GPIO.PWM(servo_pin, 50)
my_id = '01010501b00ac30b'

def connected (tag):
    return
    #time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')
servo.start(0)
status = 'opened'

while True:
    print('waiting...')
    tag = clf.connect(rdwr={'on-connect':connected})
    felica_id = str(tag.idm).encode("hex")
    if (my_id == felica_id):
        print('matched!!')
        #servo.start(0)
        if (status == 'opened'):
            #open the door
            servo.ChangeDutyCycle(2.0)
            status = 'closed'
        elif(status == 'closed'):
            #close the door
            servo.ChangeDutyCycle(5.0)
            status = 'opened'
        #servo.stop()
    else:
        print('invalid id!!')

    print(status)
    print('scaned')
    time.sleep(0.2)

servo.stop()
GPIO.cleanup()
```
サーボで部屋の電気をon/off. 
本当はドア鍵の開閉がやりたかったけど, 鍵が思いのほか固かったので断念. 
しかもガムテ実装. 
まあいっか. 


![IMG_3579.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/882de38a-1c45-7fa1-e445-37719a3c0e9c.jpeg)


![IMG_3578.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/06e5cee1-c1f1-d082-f4d4-305d28c0c6f3.jpeg)

https://youtu.be/x625sLmCasE


# 補足

ホントは
http://kousaku-kousaku.blogspot.jp/2008/06/arduino.html
http://qiita.com/kedtn/items/7174f5112d99f12ce0e7
http://kondo-robot.com/product-category/servomotor/krs
http://radenzaiku.blog.shinobi.jp/%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E5%85%A8%E8%88%AC/futaba%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%B5%E3%83%BC%E3%83%9C%E3%81%AE%E8%A7%92%E5%BA%A6%E5%8F%96%E5%BE%97
のように, サーボの角度をとったり, 精度上げたりもやろうかと思ったけど, 面倒くさくなったのでまたいつか. 
KRSのサーボだと角度取得もできる...らしい?
msys2+nanoでOSクリップボードのコピペ


Windows7/msys2+mintty+bash前提。

## microを使いたかった
[Micro \- Home](https://micro-editor.github.io/)

nanoがよかったのでmicroも使いたかった。なぜなら**システムのクリップボードにコピペできる**らしいから。神か。

[いま熱い最新スクリーンエディタmicro ことはじめ \- Qiita](http://qiita.com/tadsan/items/f0747f09ea5ce863f2ec#rlogin-windows)

Chocolateyでインストールしようとしたらなんかエラー吐かれたので、とりあえずバイナリ落として~/binに置いた。

んで起動してみたら、`no suitable screen available`とかエラー吐かれた。

なんかCygwinかそれ系では動かないらしい。（[no suitable screen available\. Conemu Windows 10 · Issue \#201 · zyedidia/micro](https://github.com/zyedidia/micro/issues/201)）

げひー。

## nanoでOSクリップボードのコピペをしたい
萎えたが、諦めてnanoでコピペすることを考える。

Vimもそうだが、おおかたのターミナルエミュレータ上で動作するテキストエディタでは、いわゆる「クリップボード」がOS標準のソレとは独立しており、相互にコピペできない。

とはいえVimだと`+clipboard`でビルドされてると直接コピペめいたことができたりもする。（[vimエディタからクリップボードを利用する。 — 名無しのvim使い](http://nanasi.jp/articles/howto/editing/clipboard.html#id4)）

nanoにはこういったオプションはないようだ。

ただし、nanoはターミナルエミュレータ、この場合はmintty上で動作しているわけで、**minttyの機能でコピペ**はできるのではないか。

### minttyでペースト（成功）
minttyでは、デフォルトではShift+InsertでOSクリップボードからのペーストができる。これは、nano上でも問題なく動作した。

### minttyでコピー（失敗）
minttyでは、デフォルトでは文字列をマウスで選択することでコピーができる。

が、**nanoではマウスによる文字列選択ができない。**マウスクリックでカーソル移動はできるが、ドラッグで選択はできないのだ。

キーボードで文字列選択はできるが、当然これではコピーされない。

これはmintty前提の話だが、他のターミナルエミュレータでも難しいように思われる。

### /dev/clipboardでコピー（成功）
仕方ないので、別の手を考える。

nanoの外にテキストを出す方法は、**バッファをファイルに書き込む**しかない。

そこで、**神は我々に/dev/clipboardを与えられた。**

かなり無理矢理だが、以下の方法で「現在のバッファの指定のテキスト」を/dev/clipboardに書き込むことが可能。

1. 現在のバッファでテキストのコピーないしカットをする。
2. ctrl+rで新規バッファを作成し、meta(opt)+>(<)で切り替え。
3. ctrl+uでアンカット（貼り付け）
4. ctrl+oでバッファを保存。ファイル名を/dev/clipboardにする。（上書き保存）

正味やってらんないので、そこまでするくらいなら大人しくVimを使ったほうがいいと思う。
APIサービスをCloudEndpointsでGKE上に構築してPostmanで動作確認する

#概要
APIを公開したいとき、API仕様（ドキュメント）やモニタリング、認証といったものが必要になる。
Cloud Endpointsを使うとこれらのことを自分で０から実装する必要ことなくAPIを公開することができる。
以前のCloud EndpointsはAppEngine Standard Environment上で動くフレームワークでJavaやPythonだけサポートされてたが、今は違う。
今はPHP,Goなど他の言語でも利用可能、AppEngineだけでなく、コンテナでも利用可能になった。

Cloud Endpointsは分散API管理システムで、API を作成、共有、維持、保護するための機能を提供する。
OpenAPI仕様とgRPCサービスで使用可能。

Cloud Endpointsのアーキテクチャは下図のとおりであり、Extensible Service ProxyとService Management and Control APIから成る。

![endpoints-architecture.png](https://qiita-image-store.s3.amazonaws.com/0/95399/bace5038-96ff-1347-0364-7fcf77e1d92e.png)
引用元：https://cloud.google.com/endpoints/docs/about-cloud-endpoints?hl=ja

サンプルコードを利用して、GKE上にデプロイしたAPIを提供するコンテナに対して、Cloud Endpointsで外部にAPI公開を行う。Cloud Endpointsの動作確認をクイックスタートではcurlで行っていたが、今回はPostmanで行う。PostmanはWeb APIのテストクライアントでChrome Appが提供されている。

```
git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/endpoints/getting-started
```

#Endpointsの設定ファイル作成
swaggerで公開するAPIに必要な情報を記載する。

```endpoints/getting-started/src/main/appengine/openapi.yaml
・・・
host: "echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog"　←この部分のプロジェクト名を変更
・・・
```

#Cloud EndpointsにAPI設定をデプロイする

```
$ gcloud service-management deploy openapi.yaml
```

#コンテナをGKEにデプロイ
```
kubectl create -f container-engine.yaml
```

```
$ kubectl get service
NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
esp-echo     xxxxx   yyyyy   80:32524/TCP   15m
```
ここで出力されるEXTERNAL-IPは、Postmanで指定するのでメモしておく。

# API Keyの取得
API ManagerでAPI Keyを作成する。

# PostmanでAPIの動作確認
PostでAPIサービスのURLとパラメータ(keyにAPIキーの値を指定）を指定して、JSON形式のメッセージを記入。

<img width="936" alt="Screen Shot 2017-04-18 at 13.08.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/401ded27-1ffb-1c37-d2c7-cc2efa339e36.png">

上記のように記入した後、Sendを押すと以下のようにレスポンスが表示される。

<img width="943" alt="Screen Shot 2017-04-18 at 13.08.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/48712db3-debd-334f-5c90-eede5be5b9b8.png">

エコーするサービスなので、入力したメッセージがレスポンスとして返ってくることを確認。
Redshiftを使っみて

# 何
- Redshiftを使ってみて感想など

## 感想列挙
- sortキー,distキー,列圧縮の事前考慮が必要。後からalter tableで変えられるものは少ない。
- テーブルへのデータの入れ方によっては、未ソート領域が増えていく。空の状態へのCOPYやselect->insertが基本？
- 未ソート領域やdelete行を整理するためのVACCUM処理は小まめにやっておいた方が良い。まとめてやろうとすると、処理に必要な時間が予想できない。
- 単一テーブルへの集計処理はとても早い。テーブルを結合するような場合は、distキーの種類や位置の評価が必要。
- 大量データ処理に使うためにあるため、データ量は多くなる傾向があるが、後で変えられることが少ない。事前によく考えること。
- 大量データを集約する場合、月次テーブルとして日々当月を差し替えながら作成し、月次テーブルをunionしたものをviewとして定義すると管理しやすい。要らない月はdrop tableで消せる。
- トランザクション内で、drop table cascadeでviewごと消しつつテーブルのrenameやcreate viewを行うことで、アトミックに状態を変える
- 重要1 アトミック洗い替え https://www.slideshare.net/mobile/mineroaoki/at-aws-summit-tokyo-2014
- 重要2 注文書と名簿の比喩 https://www.slideshare.net/mobile/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-amazon-redshift
マップ上の同じピンを連続でタップした際に無反応だった時の対処法

MKMapViewの標準calloutの代わりに、独自Viewを使った際の挙動でちょっと詰まったのでメモします。

## 事象
マップ上の同じピンを２回連続でタップしても独自Viewが呼び出せない。


## 内容
MKMapviewのannotation(ピン)をタップした時にcallout(吹き出し)を使わずに独自のビューを表示する場合、calloutを表示しないよう`canCallout`に`false`を設定して、MKMapViewDelegateのdidSelectでViewの呼び出しを行うかと思います。

```swift:calloutを呼び出さないようにする
    func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
        for view in views {
            view.canShowCallout = false
        }
    }
```

```swift:ピンをタップして独自Viewを呼び出す処理(今回はViewControllerを表示してます)
    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView){
        let modalViewController = ViewController()
        modalViewController.delegate = self                    
        self.present(modalViewController, animated: false, completion: nil)
    }
```

modalViewControllerから呼び出し元(MKMapViewが表示されているViewController)に戻り、再度同じピンをタップしてもmodalViewControllerは開かれませんでした(didSelectも呼ばれていない)。

### 対処法

`canShowCallout`が`false`でもピンをタップした時にcalloutが開かれたような状態になっているようなので、同じピンへのdisSelectが効かなかったように思われました。
ですので、ピンの選択を解除する処理をdidSelect内に入れたところ、独自View表示と同時にピンの選択(calloutの表示)も解除されるため、同じピンへの２回連続タップも効くようになりました。

```swift:didSelectにピンの選択解除処理を入れる
    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView){
        let modalViewController = ViewController()
        modalViewController.delegate = self                    
        self.present(modalViewController, animated: false, completion: nil)

        // ピンの選択を解除
        for annotaion in mapView.selectedAnnotations {
            mapView.deselectAnnotation(annotaion, animated: false)
        }
    }
```

ちなみに　`setSelected` でも良さそうでしたが、こちらは効果がありませんでした。
画像の認識 〜 Yolo 

# Yolo を試してみました
以前、子供のために、Raspberry Pi Zero+Pi Camera を使ったプラレールを制作しました。
![image](https://qiita-image-store.s3.amazonaws.com/0/172071/3136908c-12a5-0e59-5a20-eda16720ed10.png)

先頭車両に穴をあけてカメラを取り付け、Raspbian にインストールした MJPG Streamer で映像をストリーミング、モーターは WebSocket でコントロール、そしてライト機能を追加して、スマホや PC のブラウザで遊びます。[^1]
映像を見ながらカメラ付きプラレールを操作するだけでも楽しいのですが、これに Yolo 画像認識を組み合わせたら、例えば、信号が赤なら止まる。電車が近くにあったら速度調整、駅に着いたら自動停止といったことも可能なのではないか？

という考えが頭に浮かび、Yolo が実際にどんなものなのか、触って確かめてみることにしました。

[^1]: 配線図やソースコードなど、いずれ公開しようと思います。

# Yolo, Darknet　とは？
Yoloは、"You only look once" の略で、リアルタイム画像認識を行うアルゴリズム(およびその実装)です[^2]。Yolo は Darknet というフレームワークを使用して実装しています。
Darknet は C で書かれた機械学習フレームワークです。位置づけとしては、Tensorflow や Chainer のようなものになります。FCN というネットワークを使用していますが、これは darknet 以外の機械学習フレームワークでも実現可能ということで、すでに有志の方々が、Yolo の [Tensorflow版](https://github.com/gliese581gg/YOLO_tensorflow) や [Chainer版](https://github.com/leetenki/YOLOv2) を実装されています。
今回はおためしなので、Darknet を使用します。
 
[^2]: 論文 https://arxiv.org/abs/1612.08242


# インストール
自分の環境は、すでに CUDA と OpenCV がインストールされているので、必要なものだけインストールしました。

````
$ cd git
$ git clone https://github.com/pjreddie/darknet.git
$ cd darknet
````
ここで、Makefile を編集、GPU と OpenCV を有効にします。

````
$ diff Makefile Makefile.org 
1c1
< GPU=1
---
> GPU=0
3c3
< OPENCV=1
---
> OPENCV=0
````

そして make

````
$ make
````

これだけです。

# 実際に動かしてみる
## 静止画
この写真は、邪魔しに来た我が家の猫(♀)です。猫も、猫の下敷きになっているマウスもきちんと検出しています。

````
$ ./darknet detector test cfg/coco.data cfg/yolo.cfg yolo.weights '/home/kmori2/ピクチャ/img_6643.jpg' 
````

![スクリーンショット_2017-04-18_21-05-56.png](https://qiita-image-store.s3.amazonaws.com/0/172071/b3806868-d89f-ae82-88fc-9a923d451b16.png)


GPU メモリ使用量を示すため、nvidia-smi の画面も貼り付けます。[^3]
darknet が GPU メモリを 1.3GB 使用しています。
最低でも 4GB の GPU メモリを搭載したボードでないと、darknet を使用するのはつらいかもしれません。

[^3]: これまで、GTX1050(2GB) を使用していましたが、先日、GTX1080ti(11GB)に換装しました。[こちら](http://kakaku.com/item/K0000956668/)の製品です。

## 動画
以前、子供と一緒にリモコンプラレールで遊んだ時に録画した映像を、Yolo にかけました。
上記静止画と同様、通常のモデル(Tiny ではない)を使用しています。
なお、この動画は 4 倍速です。動画を最後まで識別させるために、実際には 6 分以上かかりました。

````
$ ./darknet detector demo cfg/coco.data cfg/yolo.cfg yolo.weights ~/ビデオ/test0416-01.mp4
````

※画像をクリックすると youtube で再生されます。
[![Alt text](https://img.youtube.com/vi/BsFuXIljYJ4/0.jpg)](https://www.youtube.com/watch?v=BsFuXIljYJ4)
予想していたことですが、プラレールの運行中に視界に入るものについて、レールや駅など、列車に関わるものは全く認識していません。おおよそ Bed 、Laptop、Keyboard の3つとして検出してます。
乗り物の運行に関するものは特に学習していないようなので、これは当たり前ですね。

しかし、レゴの警官ミニフィグやソフビのウルトラマンは、しっかりと人(Person) として認識しています。ちょっと感動しました。（＾＾；

Yolo は検出したオブジェクトのリージョンまで検出するので、例えば「レール上に人(人形)が横たわっているので停止する」といった動作であれば簡単に実現できそうです。
まずはプラレールについて学習させ、モデルを作成しなければなりませんが、今後、楽しみです。
golangのお勉強2 


------------------------------------------------------------------------------------------------
	WEB APIの実装まわりを行き当たりばったりに調べる
------------------------------------------------------------------------------------------------

# helpやdocumentなど

* ドキュメント - The Go Programming Language
	* http://golang-jp.org/doc/


	かなり充実している公式ドキュメント
 
	* ピックアップ
		* ライブラリ
		* 言語仕様
		* ツール（godoc,gofmt...）

# IntelliJでの開発環境

IntelliJ IDEA で Go の開発環境を構築 on Mac - Qiita
http://qiita.com/ynqa/items/2fcc65e3b85f47f0c1ae




------------------------------------------------------------------------------------------------
	すでに奥深さに挫折感。。
------------------------------------------------------------------------------------------------

* godocについて

godoc（go doc）コマンド についてのまとめ - taknb2nchのメモ
http://d.hatena.ne.jp/taknb2nch/20131107/1383842703

便利だー。挙動も早い。
実装をさっと確認。
ドキュメントをサーバーを起動してブラウザ確認。
絞り込んでのドキュメント表示。

```bash
cd $GOPATH
godoc -http=:6060
```

godoc - GoDoc
https://godoc.org/golang.org/x/tools/cmd/godoc

```bash
godoc fmt                # documentation for package fmt
godoc fmt Printf         # documentation for fmt.Printf
godoc cmd/go             # force documentation for the go command
godoc -src fmt           # fmt package interface in Go source form
godoc -src fmt Printf    # implementation of fmt.Printf
```

# パッケージごとにメモ

## httpパッケージ

------------------------------------------------------------------------------------------------
	Apex+Lambda(golang)でAPIを使おうと思ったら最初にエンカウントした強敵 net/http
------------------------------------------------------------------------------------------------

`Handle`、`HandleFunc`、`Handler`、`HandlerFunc`についてまとめ - Qiita
http://qiita.com/udzura/items/39e6b927d6d17f76df06

Go 言語の http パッケージにある Handle とか Handler とか HandleFunc とか HandlerFunc とかよくわからないままとりあえずイディオムとして使ってたのでちゃんと理解したメモ - Qiita
http://qiita.com/nirasan/items/2160be0a1d1c7ccb5e65

大体わかったような気がしたが、最後の文章がわからない。

> 内部で func(ResponseWriter, *Request) から http.HandlerFunc へのキャストが行われています。

キャストの書き方、、どうやらクロージャーを使った変換のことっぽい？？

インタフェースの実装パターン #golang - Qiita
http://qiita.com/tenntenn/items/eac962a49c56b2b15ee8

> さらに，Person型のポインタを引数にとるようなfunc(p *Person) string型の関数をStringerFunc型にキャスト可能なfunc() string型に変換するような関数を考えてみます．引数を取らずに，特定の変数(この場合だとp)にアクセスするにはクロージャを用いるとよいでしょう．

# 概念や単語のニュアンス

Handler
	受け渡しする役割の人
Handle
	受け渡し操作（そのオブジェクトの１単位）
Mux
	マルチプレクサ、２信号を１信号にして出力
	ざっくりとはルーター的なもの（？）

# apex

## vendoring

Golang1.5で試験追加になったvendoringの使い方 - Qiita
http://qiita.com/shinofara/items/7dbc486138e6949c7a54


Lambda x Apexで、Goで書いたラムダ関数を楽に動かす - きょこみのーと
http://kyokomi.hatenablog.com/entry/2016/11/03/145147
RubyonRails5と4のバージョンを共存させる。

前回書いた[MacOSX Sierra でRubyonRailsの開発環境を構築する](http://qiita.com/etsracas/items/53f1230e13cf5f9c40ba)の記事ではバージョン5の環境を構築しましたが、Rails4のアプリも作りたい時があります。
そんなときに両方のバージョンを共存させる方法があります。

## rails4用のディレクトリを作成
rails5での環境が出来上がっている前提です。

```
$ mkdir ~/webapp4
```

## ruby 2.2.7をインストール
rbenvで別バージョンのrubyを入れることでそれぞれlocalでgemが管理できるという仕組みです。

```
$ rbenv install 2.2.7
$ rbenv versions
  system
  2.2.7
* 2.3.4 (set by /Users/ryo/.rbenv/version)
$ cd webapp4
$ rbenv local 2.2.7
$ ruby -v
ruby 2.2.7p470 (2017-03-28 revision 58194) [x86_64-darwin16]
```

## rails4をインストール
上記で作ったディレクトリ内にrails4をインストールすれば、そのディレクトリ配下はrails4の環境になります。

 ```
 $ gem install rails --version "4.2.7" --no-rdoc --no-ri
 $ rails -v
Expected string default value for '--rc'; got false (boolean)
Rails 4.2.7
 ```
 
 何かエラーのようなものが出るので調べると、thorのバージョンを下げる必要があるようです。
 
 ```
 $ gem list
 thor (0.19.4)
 $ gem install thor --version="0.19.1"
 $ gem uninstall thor --version="0.19.4"
 $ rails -v
 Rails 4.2.7
 ```
 
 無事このディレクトリ内のRailsは4.2.7になりました。
iTunesConnectにアップしたアプリが消えたときの解決方法

# 動作環境
* Xcode8.3.1

# 問題
Xcodeにてアプリをアーカイブして、iTunes ConnectへアップロードしたときにXcode側ではSuccessの表示になったのに、iTunes Connectでは表示がされないという事象がありました。
それを解決する方法を記したいと思います。

## Xcode側の表示

一見成功したように見えるのです　。

<img width="586" alt="20170418_1492500802.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/31587/b155e75a-23f8-a7da-0918-028367b8aba8.jpeg">


## iTunes Connect側の表示

<img width="1280" alt="20170414_1492170186.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/31587/1d361e41-bbc0-1b11-05e5-e55c69a2bebe.jpeg">

Xcodeでビルドをアップすると＋ボタンが表示されビルドバージョンでどのビルドを選択出来るようになります。
しかしこの問題では＋ボタンが表示されず、Xcodeでアップしたはずのアプリビルドの選択ができない状態になっています。

# 原因

調べると以下の二点を突破していないとこのような事象があるそうです

*  契約書の更新があった場合、iTunes Connectにて承諾をし、送られたメールを認証する
    * 今回請負で受けた仕事でして、AppleIDは共有して運用してました。そのためメールが送られてくることが抜け漏れていました。
*  Apple Watchのアイコン画像にアルファチャンネルが含まれていた

# 解決方法

## 契約書更新

メールを確認して承認をします。

## Apple Watchのアイコン画像にアルファチャンネルが含まれていた

Apple Watchのアイコン画像にアルファチャンネルが含まれていると、iTunes Connect側でアプリが反映されないようです。

アップロードしてしばらくするとiTunesConnectから以下の様なメールが来ていました。

>Dear developer,
>
>We have discovered one or more issues with your recent delivery for "[APPNAME]". To process your delivery, the following issues must be >corrected:
>
>Invalid Icon - The watch application '[APPNAME].app/Watch/watchkitapp.app' >contains an icon file >'[APPNAME].app/Watch/watchkitapp.app/AppIcon40x40@2x.png' with an alpha >channel. Icons should not have an alpha channel.
>
> ...以下略
>Once these issues have been corrected, you can then redeliver the >corrected binary.
>
>Regards,
>
>The App Store team

*具体的なアプリ名を[APPNAME]に置換しています*

アルファチャンネルを含めないようにアイコン画像を作成し直します。

今ある画像をプレビューアプリで開きます。

ファイル > 書き出す　メニューからアルファチャンネルのチェックを外して保存します。

<img width="719" alt="20170418_1492518093.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/31587/210911da-83c1-efba-c002-a54106d259de.jpeg">

この画像をアイコンに差し替えて、もう一度アーカイブし、iTunes Connectにアップロードします。

これでうまくいくはずです。

# 参考

* [iTunesConnectへアプリのアップロードでバイナリデータが消える。](https://ja.stackoverflow.com/questions/16889/itunesconnect%E3%81%B8%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%83%90%E3%82%A4%E3%83%8A%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8C%E6%B6%88%E3%81%88%E3%82%8B)
* [iTunesConnectにアップロードしたアプリが出てこない](https://teratail.com/questions/46630)
* [[iOS] iTunes Connect の申請でPNGファイルにアルファチャンネルが含まれていて申請に使えないときの対処](http://blog.be-style.jpn.com/article/105597923.html)
nanowalletに学ぶ、JavaScriptだけで暗号通貨のNEMアカウントを生成する方法

nanowallet とはNEM用に開発されたウォレットで、すべてJavaScriptで記述されています。ローカルでブラウザを開くだけで起動し、ノードへの接続は必要ですが同期など時間のかかる処理は必要ありません。このJavaScriptで記述されたウォレットが暗号通貨の勉強には最適ですので、今回はこのnanowalletを参考にしてアカウントを生成する方法を学んでみたいと思います。

[nanowalletの公式ダウンロードはこちら](https://www.nem.io/install.html)

GET THE NANO WALLET をクリックしてzipを解凍。start.htmlをダブルクリックで起動します。（インストール不要、ブラウザ必須）。慣れてきたら起動する前にzipファイルをアポスティーユ公証にかけて改ざんされていないかを確認するクセをつてもいいでしょう。github にソースコードがありますが、まだ私の方で動作確認できていません。
なお、[mijin.io](http://mijin.io/nanowallet/start.html) にも動作環境が提供されていますが、改ざんされていない保証はありません。

解凍したソースコードのうち、NEM開発者お手製のjsソースが main.js になります。AngularJSを利用しているようですね。開発には便利なのですが、解析するには多少骨が折れました。後は外部ライブラリとしてvendorsフォルダに格納されています。

さて、本題です。nanowalletでアカウントを作成するには２つ方法を使用しているようです。

- 全くランダムに生成する
- ログイン中のアカウントをマスターキーとして新たなアカウントを生成する

今回は1つ目の全くランダムに生成する方法を説明します。
依存するライブラリは以下のとおり。

```html:library
    <script src="vendors/cryptoJS/core-min.js"></script>
    <script src="vendors/cryptoJS/x64-core-min.js"></script>
    <script src="vendors/cryptoJS/ripemd160-min.js"></script>
    <script src="vendors/cryptoJS/sha3-min.js"></script>
```

暗号鍵を作成します。これはjsには便利なcrypto.getRandomValuesというコマンドがついています。

```
var rawBytes = new Uint8Array(32);
var hexPriv = ua2hex(crypto.getRandomValues(rawBytes));
```

32個の配列を作成し、16進数で表記します。これだけです。
次に公開鍵を作成します。

```
var account = new KeyPair(hexPriv);
var strPub = account.publicKey.toString();
```

このKeyPairが暗号通貨によってそれぞれ処理が変わってくるかと思います。
Ed25519と呼ばれる暗号化アルゴリズムを使用します。このあたりも参考になるかもしれません。
[【NEM／XEM】秘密鍵から公開鍵を作成する(Ed25519)](https://tadajam.katari.be/385GshHZ)

最後に、公開鍵をアドレス化します。

```
var address = toAddress(account.publicKey.toString(), 104);
```
104というのはネットワークIDでNEM のMainnet がそれにあたります。
これでアカウントに必要な、秘密鍵、公開鍵、アドレスが出来上がりました。


まあ、なーんてうすっぺらい説明なんでしょうｗ
ただのWeb技術屋なので勘弁してください。
でも、秘密鍵がただの乱数という発見がありましたね。これは注目すべきことです。
PHPセッション、ApacheセッションなどWeb技術には様々な乱数で生成された文字列が活躍します。
暗号通貨技術を利用すれば、これらの**セッションIDにアドレスという名のお財布機能が付与できる**ということです。
サイトに訪問したユーザにチップをあげる、または逆に通行料を徴収する。
チップの代わりに属性情報を持ったトークンをやりとりする。まさに広告ビジネスに使えそうですね。
大量のアクセスをさばく場合は注意が必要です。ただし、NEMの場合はmijinがありますね！あれ、何かつながりました？

では最後に動くものをアップしておきます。
[demo](http://nemtest.s3-website-ap-northeast-1.amazonaws.com/account_generate.html)

QRコードもここに張っておきますね
実際にはXEMという通貨を入れないと、アカウントは使い物になりません。
まずは感謝の気持ちをXEMに込めて、ぜひ周りのみなさんでアカウントと少額のXEMをプレゼントしあってみてください。
![image](https://qiita-image-store.s3.amazonaws.com/0/29187/74b1f1a6-2463-94af-568a-064ab9adabaf.png)

次はマスターキーから、アカウントを生成する方法を説明したいと思います。
それでは！

----
以下のNEMアドレスは、全てNEM上でエンジニアが活動できるための資金に使用します。
これから私が書く記事に共感していただけましたら、ご寄附いただけると助かります。
NEM ADDRESS: NBZNQL-2JDWTG-UAW237-PXV4SS-XSPORY-43GUSW-GSB7
GAEについて

# はじめに
単にGAEチュートリアルをそメモとしてに書いてます。
本家を見てください。

# コードの開発方法
1. 左上から「開発」を開く
2. ソースコードを開く

# app.yaml
``` app.yaml
runtime: php55
api_version: 1

handlers:
- url: /.*
  script: helloworld.php
```
基本hedlers以下のみの編集。

# cloud shell
1. ディレクトリの設定　$ディレクトリ名称=src/<プロジェクト名>
2. git clone でコピーする　git clone https://github.com/<git名>.git $TUTORIALDIR
3. ディレクトリの場所へ移動　cd $ディレクトリ名称
4. 元のgitファイルを壊さないために自分専用のブランチへ吐き出す。　git checkout チェックアウトしたいブランチ名

#デプロイ
1. 開いているディレクトリをテスト用に公開する　
　cloud shell にて入力　dev_appserver.py --php_executable_path=/usr/bin/php-cgi $PWD
2. cloud shellのちょっと上にある、ブラウザ左下の「↑」的なボタンを押す
3. 「ボード上でプレビュー8080」を選択する
4. チェックし終わったらctrl+C
5. 公開する　gcloud app deploy app.yaml --project <プロジェクト名>
6. 表示されるサイトにアクセス
nfc raspberrypi tag id matching

```id_matching.py
import nfc
import time
my_id = '01010501b00ac30b'

def connected (tag):
    time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')
touched = 0

while True:
    print('waiting...')
    tag = clf.connect(rdwr={'on-connect':connected})
    felica_id = str(tag.idm).encode("hex")
    if (my_id == felica_id):
        print('matched!!')
    else:
        print('invalid id!!')
        
    print('scaned')
```

で, 

指定したfelica(=my_id)だと, 

```
waiting...
matched!!
scaned
waiting...
```

違うfelicaだと, 

```
waiting...
invalid id!!
scaned
waiting...
```

となる.
mac - rails - AWS RDS Oracle

OracleをRailsでつないだのでメモ

## 環境
- macOS Sierra 10.12.2
- ruby 2.4.1
- rails 5.0.2
- activerecord-oracle_enhanced-adapter 1.7.10
- ruby-oci8 2.2.3

AWSにOracle入れたけどAWSのSDKは使ってない

## 下準備
### SQL DEVELOPER入れた
[SQLDeveloper](http://www.oracle.com/technetwork/jp/developer-tools/sql-developer/downloads/index.html)
- GUIのOracleクライアント
- railsとoracleを繋ぐだけなら入れる必要はなし

### SQL*Plus入れた
#### ダウンロードと解凍
[SQLPlus](http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html)
- mac用のbasic,sqlplus,sdkをダウンロード
- 適当なパスに解凍(ここでは$HOME/lib/instantclient_12_1)

```bash
$ cd ~/lib
$ mkdir instantclient_12_1
$ unzip instantclient-basic-macos.x64-12.1.0.2.0.zip 
$ unzip instantclient-sqlplus-macos.x64-12.1.0.2.0.zip 
$ unzip instantclient-sdk-macos.x64-12.1.0.2.0.zip
```

#### シンボリックリンクを貼っておく

```bash
$ cd ~/lib/instantclient_12_1
$ ln -s libclntsh.dylib.12.1 libclntsh.dylib
$ ln -s libocci.dylib.12.1 libocci.dylib
```

#### 環境変数設定

```bash:.bash_profile
export PATH=$HOME/lib/instantclient_12_1:$PATH
export OCI_DIR=$HOME/lib/instantclient_12_1
export TNS_ADMIN=$HOME/lib/oracle/network/admin
export NLS_LANG=Japanese_Japan.UTF8
```

#### tnsnames.ora
- ローカル・ネーミング・パラメータ構成ファイル (tnsnames.ora)
- tnsnames.oraをTNS_ADMINに設定したパスに作成
- **SERVICE_NAMEにはRDSの「DB名」を入れる**

```text:tnsnames.ora
net_service_name =
(DESCRIPTION=
  (ADDRESS=(PROTOCOL=tcp)
    (HOST=servername)
    (PORT=1521))
  (CONNECT_DATA=(SERVICE_NAME=ORCL))
)
```

#### sqlplusで接続確認
- パスは通ったけどコマンドを叩いたらエラー

```bash
$ which sqlplus
/Users/myname/lib/instantclient_12_1/sqlplus
$ sqlplus username/password@net_service_name
ERROR:
ORA-21561: OID generation failed
```

- hostnameをhostsに書いたらつながった

```bash
$ sudo sh -c "echo '127.0.0.1 `hostname`' >> /etc/hosts"
$ sqlplus username/password@net_service_name
SQL*Plus: Release 12.1.0.2.0 Production on Fri Mar 24 18:51:34 2017
...
Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production

SQL>
```

## Railsの設定
### Gemfile

```rb:Gemfile
gem rails 5.0
gem activerecord-oracle_enhanced-adapter
gem ruby-oci8 
```

`bundle install`

### database.yml
tnsnames.oraで設定したネットサービス名をdatabaseに設定

```yaml:database.yml
development:
  adapter: oracle_enhanced
  database: net_service_name
  username: username
  password: password  
```

### 接続確認

```rb:console
[1] pry(main)> ActiveRecord::Base.connection.current_database
=> ORCL
```
nfc raspberrypi return true? tag?

# true
```why_true.py
import nfc
import time

def connected (tag):
    print('connected!!')
    time.sleep(1)
    return 1

clf = nfc.ContactlessFrontend('usb')

while True:
    print('waiting...')
    result = clf.connect(rdwr={'on-connect':connected})
    print(result)
    print('scaned')

```

とやると, なぜか

```
waiting...
connected!!
True
scaned
waiting...
connected!!
True
scaned
waiting...
```

のようにtrueがでる. 

# tag
一方, returnに何も入れずに

```why_tag.py
import nfc
import time

def connected (tag):
    print('connected!!')
    time.sleep(1)
    return

clf = nfc.ContactlessFrontend('usb')

while True:
    print('waiting...')
    result = clf.connect(rdwr={'on-connect':connected})
    print(result)
    print('scaned')

```

とすると, 

```
waiting...
connected!!
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
scaned
waiting...
connected!!
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
scaned
waiting...
```

のようにtagがreturnされる. 
まぁこれは理解できる...か. 
でもreturn 1 でtrueになるのはやっぱ謎.
Raspberry Pi 3 のオンボードWi-Fiチップを使ってキャプチャ

Raspberry Pi 3 でWi-Fiパケットキャプチャをしてみました。

nexmonを使うとオンボードのWi-Fiチップを使ってキャプチャが出来ます。

# nexmon とは
* nexmonはBroadcomのWi-Fiチップのファームウェアにモニタモードの機能を付加するためのパッチ作成のフレームワークです。
* 最初はNexus5向けに開発されましたが、現在はRaspberry Pi 3 と Raspberry Pi ZERO Wに搭載のBCM43438でも利用できます。
* https://github.com/seemoo-lab/nexmon

# インストール
* nexmon 導入済みのKali Linux のイメージがあるのでそれを使いました。
* https://build.nethunter.com/nexmon-pi-builds/ からイメージをダウンロードしました。
* 自前でイメージをビルドしたい人は　https://github.com/offensive-security/kali-arm-build-scripts を使ってください。

* イメージをSDカードに書き込んで起動します。
 * Kali Linuxのデフォルトパスワードは 　
  * user : root
  * password : toor


* キャプチャしたパケットをWi-Fiのフレーム単位で表示をしたいので tsharkをapt-getでインストールする。

```
#apt-get instal tshark
```

# 操作例
* モニタモードを有効にする。　(radio tap header無しの場合は1、有りの場合は2をしているする。)

```
# nexutil -m1
```

* channel を設定する。

```
# iw dev wlan0 set channel 6
```

tshakでフレームをダンプする。

```
# tshark -i wlan0
```

宛先がブロードキャストのパケットを表示しないようにする場合

```
# tshark -i wlan0  -Y "wlan.da != ff:ff:ff:ff:ff:ff"
```

特定のAPとSTA間のeapolフレームを表示する。

```
# tshark -i wlan0   -Y "eapol && (wlan.da == APのMAC ||wlan.da == STAのMAC)" -V
```

Actionフレームを表示する。

```
# tshark -i wlan0   -Y "(wlan.fc.type == 0)&&(wlan.fc.type_subtype == 0x0d)" -V
```


airodump-ngでBSSの情報を見る。

```
# airodump-ng wlan0
```

kali linuxはその他にも下記のツールがインストール済みです。

```
airbase-ng              aireplay-ng             airolib-ng
aircrack-ng             airmon-ng               airserv-ng
airdecap-ng             airodump-ng             airtun-ng
airdecloak-ng           airodump-ng-oui-update
```

# Wi-Fiが調子悪くなった時
* Wi-Fiドライバをリロードしましょう

```
# modprobe -r brcmfmac
# modprobe brcmfmac
```
dockerでRoRを扱って、TZInfo::DataSourceNotFound: No source of timezone data could be found.

dockerのubuntu:16.04を使っていて、Ruby on Rails(Readmine)をビルドしている時に以下のエラーが発生した。

```
TZInfo::DataSourceNotFound: No source of timezone data could be found.
```

https://hub.docker.com/r/74th/redmine-all-in-one/builds/b4x27upgt4bm5lpgg6cbgde/

どうやら、今のUbuntuイメージには`/usr/share/zoneinfo`がないのが原因らしい。

Dockerfileに以下を追加する。

```
RUN apt install tzdata
```

参考 https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2229
Unity WebGL ブラウザの大きさに合わせる

#Unity側だけの知識ではハマる！
ブラウザの大きさに応じて画面をリサイズしていくような処理は、
Unity側で出来ないことはないけど手軽ではないという結論に至った。
htmlやjavascript、cssの知識を活用して今回はこの問題を解決する。

##１.Unity側の作業
Unity側の作業はロゴを消すぐらい。

File>Build Settings>Player Settings
Resolution and Presentation
WebGL TemplateをDefault→Minimalへ変更

<img width="275" alt="スクリーンショット 2017-04-18 20.03.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/14560/49e49ecd-eee2-5bc9-1a98-d8e25f681b95.png">



念の為下記も設定しておくといいかも。

- File>Build Settings>Player Settings
- Resolution and Presentation
- Default Screen Width {Canvas Scaler Refernce resolution xの値}
- Default Screen Height {Canvas Scaler Refernce resolution yの値}

※ここの値は書き出されたindex.htmlのcanvasのwidthとheightに反映されるだけなので、不要っちゃ不要。

##２.windowsResize.jsの作成（js久しぶりすぎて、ほとんど忘れてた。。）

```js
var container;
var canvas;
var timer = 0;

//初期化
function init() {
    canvas = document.getElementById('canvas');
    container = document.createElement('div');
    container.style.width = window.innerWidth + 'px';
    container.style.height = window.innerHeight + 'px';
    container.style.overflow = 'hidden';
    container.appendChild(canvas);
    document.body.appendChild(container);
    document.body.style.margin = '0px'
}

//サイズ変更処理
function resize() {
    container.style.width = window.innerWidth + 'px';
    container.style.height = window.innerHeight + 'px';
    canvas.width = window.innerWidth * window.devicePixelRatio;
    canvas.height = window.innerHeight * window.devicePixelRatio;
}

window.onload = function () {
    init();
    resize();
};

//ブラウザの大きさが変わった時に行う処理
(function () {
    var timer = 0;
    window.onresize = function () {
        if (timer > 0) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            resize();
        }, 200);
    };
}());
```

##３.windowsResize.jsの配置
書き出したindex.htmlと同階層にwindowsResize.jsを置く。
<img width="459" alt="スクリーンショット 2017-04-18 20.24.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/14560/bf7b37c1-716e-b9e4-e20a-0d331efe9c65.png">



##４.書き出し後のindex.htmlの修正
・index.htmlに1行追加

```html
<script type="text/javascript" src="windowResize.js"></script>
```

※head内だったらどこでもOK。タグの間に書くとか斜め上のことはやらないでください。

##５.最後に
後はUnity側のUI配置を画面サイズが変わっても崩れないように配置すればOK（これが一番大変そう）
MacにVagrant + VirtualBox + CentOSでWEB開発環境を構築しておいた　その1



### はじめに


Vagrantを初めて使ったので、使えるようになるまでの手順の記録。

### 使ったもの

|ソフトウェア|バージョン|
|---|---|
|OSX|10.12.3|
|VirtualBox|5.1|
|Vagrant|1.9.3|
|CentOS|7.0|

---

## VirtualBoxのインストール

https://www.virtualbox.org/
ここからダウンロード。この時の最新版は5.1。
ウィザードに従ってぽちぽちとインストール。


<img width="882" alt="スクリーンショット 2017-04-17 11.28.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/151247/b2b50b69-be2a-9faf-447c-3daf6d39807d.png">

---


## Vagrantのインストール
https://www.vagrantup.com/downloads.html
ここからMaxOS用のものをダウンロード。

インストールが完了したら、ターミナルを起動して確認しておきます。
バージョンは1.9.3でした。

```
$ vagrant --version 
Vagrant 1.9.3
```  

---





### BOXのインストール

http://www.vagrantbox.es/
上記の一覧から、今回使用するCentOSを探し出しURLをコピー。

`vagrant box add`コマンドでBOXのダウンロードとインストールを行います。


> vagrant box add (名前) (BOXのURL)


実際はこんな感じ。
```
$ vagrant box add CentOS70 https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.1.0/centos-7.0-x86_64.box
/---中略---/
==> box: Successfully added box 'CentOS70' (v0) for 'virtualbox'!
```
ネットワークの状態にもよりますが、それなりの時間がかかると思います。コーヒーでも飲みながらのんびり待つべし待つべし。  



インストールが完了したら、触りやすいところに作業ディレクトリを作成して、`init`コマンドでCentOS70を初期化。
これからはこのディレクトリからCentOSを起動できるようになります。

```
$ mkdir -p ~/Vagrant/CentOS70
$ cd Vagrant/CentOS70/

$ ~/V/CentOS70> vagrant init CentOS70
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

$ ~/V/CentOS70> ls
Vagrantfile
```

今開いている作業ディレクトリにVagrantfileが作成されます。
出力にら「`vagrant up`コマンドでもう環境出てくるぜ！」…って書いてあるので、そうしてみましょう。

```
$ ~/V/CentOS70> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'CentOS70'...
==> default: Matching MAC address for NAT networking...

/---中略---/

    default: /vagrant => /Users/hogehoge/Vagrant/CentOS70

```

長ったらしく起動処理が続きます。
きちんと動いているかを`vagrant status`コマンドで確認。

```
$ vagrant status
Current machine states:
default                   running (virtualbox)

/---略---/
```

ここまでで無事、ゲストOSが使えるようになりました。
とりあえず使ってみたいのえま、`vagrant ssh`でゲストのコマンドラインに接続。
このあたりも初めから設定されているのがVagrantの良いところですね。

```
$ vagrant ssh
Last login: Mon Apr 17 11:24:57 2017 from 10.0.2.2
Welcome to your Vagrant-built virtual machine.
[vagrant@localhost ~]$
```


これでVagrant上でCentOSを使える状態になりました。
サーバ環境の構築はまた次に。
Visual Studio Code を使って、PowerShell を書きはじめるときにしたこと

## インストール
* PowerShell の拡張機能をインストール

##  書いてみる
1. メニューから新規ファイルを作成
2. ファイル名``` helloworld.ps1```  として保存
ステータスバーが下記のようになる
![vscode.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/14354b3c-3932-16b3-aaa8-2b2a6e517d5c.png)

3. 下記のコードを記述
```ps1
Write-Host 'Hello world'
```
入力補完も効く
![vscodeac.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/a96fba6a-3fba-114f-333e-6dc0b7094802.png)
4. Ctrl + Shift + D でデバッグウィンドウを起動
![vscodedebug.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/ff2df71e-fe02-aa17-a4f2-0e2f9f185ca2.png)
虫のアイコンからも起動可能
5. 上部の▶クリックでデバッグが開始される
6. 隣のアイコンクリックでコンソールが開く
![vscoderun.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/0b695ecf-0378-eca5-1a25-3b70e190b8b1.png)

## 日本語を表示してみる
![vscodebake.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/bb6aa0a7-99e7-c11a-d292-b4234e76df18.png)
文字化け。。

```chcp``` コマンドでコンソールのエンコードを確認
![vscodechcp2.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/02ec23f2-818b-0abe-a724-2cf4832ced97.png)

932です。

ファイルのエンコードが UTF-8 なので、一旦コンソールを UTF-8 にしてみる
![vscode65001.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/61cda745-3f26-91bf-fb38-8d601d2a2a79.png)

なんでやねん

わからん。。

こちらのページが自分と同じ状況だったので、
参考にさせていただく。
http://thinkami.hatenablog.com/entry/2016/07/08/065709

UTF-8 BOM の設定をする
「エンコード付きで保存」から「UTF-8 with BOM」を選択する

![vscode65001OK.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/5b625890-bd93-4456-909d-308493d9446e.png)

![vscode932OK.PNG](https://qiita-image-store.s3.amazonaws.com/0/14443/8e01f2a7-3700-6297-ce85-e4bb376a2b17.png)
両方とも表示されている

Powershell は UTF-8 の BOM 付きじゃないと文字化けするみたい
 参考
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10137216220
nfc raspberrypi read tag on-release, on-connect

# on-release

```read_tag_release.py
import nfc
import time

def released (tag):
    print(tag)
    print('released!!')
    time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')

while True:
    print('waiting...')
    result = clf.connect(rdwr={'on-release':released})
    print('----------------------')
    print(result)
    print('scaned')
```

をやると, 
felicaを離した時に, 

```
waiting...
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
released!!
```

とでる. 

"scaned"が出ないけど, felicaをつけて離してつけて離して...を繰り返すと

```
waiting...
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
released!!
waiting...
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
released!!
waiting...
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
released!!
waiting...
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
released!!
```

となるので, while trueは効いてる模様. 
ふむ...


# on-connect, on-release

```connect_release.py
import nfc
import time

def connected (tag):
    print('connected!!')
    time.sleep(1)
            
def released (tag):
    print('released!!')
    time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')

rdwr_options={
    'on-connect':connected,
    'on-release':released,
}

while True:
    print('waiting...')
    #clf.connect(rdwr={'on-connect':connected, 'on-release':released})
    clf.connect(rdwr=rdwr_options)
    print('scaned')

```

のようにon-connectとon-releaseを両方使用してみたが, 
つけて離してつけて離して...を繰り返しても

```
waiting...
connected!!
scaned
waiting...
connected!!
scaned
waiting...
connected!!
```

となるだけで, on-releaseが効かず....

rdwr_optionsを使用せずに, 

```connect_release.py
import nfc
import time

def connected (tag):
    print('connected!!')
    time.sleep(1)
            
def released (tag):
    print('released!!')
    time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')

while True:
    print('waiting...')
    clf.connect(rdwr={'on-connect':connected, 'on-release':released})
    print('scaned')

```

とやっても結果は同じ. 
ふむ....
Webページはどのように表示されるのか？

#はじめに
ChromeやSafariなどのWebブラウザのアドレス欄に「www.google.co.jp」と入力するとGoogleのWebページが表示されますが、裏で何が起こっているのか、Webの仕組みについて勉強の導入として、ここで簡単にまとめさせていただきました。
プログラミングを初めたばかりで、HTMLやCSS,Javascript,Rubyと言った個別言語に注力していて、全体像を理解できていない、という方に是非読んでいただけたらと思います。

#Webページはどのように表示されるのか？
ChromeやSafariなどのWebブラウザのアドレス欄にURLを入力すると、そのURLを頼りに、WebブラウザからWebサーバに「Webページのデータを取得する」リクエストを送り、Webサーバがそのリクエストをもとにファイルや画像などをWebブラウザに返すことでWebページが表示されます。
ChromeやSafariなどのWebブラウザは一般にクライアントと呼ばれ、ファイルや画像などWebページのデータを保存している場所は一般にサーバと呼ばれます。
![Webの仕組み①.jpg](https://qiita-image-store.s3.amazonaws.com/0/101754/cf633f63-1270-bf96-7aba-0b239afc2996.jpeg)

#クライアントからサーバまで行くまで
クライアントがリクエストを送り、サーバがそのリクエストに対し、レスポンスを返すことでWebページが表示されることがわかりました。
ここからはリクエストとレスポンスの内容を「クライアントからサーバに行くまで」と「サーバからクライアントに返ってくるまで」に分けてもう少し詳しく見ていきます。

クライアントからサーバ行くまでにはどのようなステップがあるのでしょうか。
全体像を理解していただくために下記の図をご覧ください。
![Webの仕組み②.jpg](https://qiita-image-store.s3.amazonaws.com/0/101754/ec32ffe1-9e9a-70ee-ab4f-12b3a99553de.jpeg)

1. ドメイン（www.google.co.jp）を入力するとDNSサーバでサーバ側で処理可能なIPアドレス（74.125.235.120）に変換
2. リクエストをサーバがわかるように形式（[HTTPメッセージ](http://qiita.com/Sekky0905/items/dff3d0da059d6f5bfabf)）で作成
3. IPアドレスをもとに相手がどこにいるかルータを経由して、リクエスト（HTTPメッセージ）を配送していく
4. サーバにリクエスト（HTTPメッセージ）を送信

まず、Webブラウザの検索窓に入力されたURLは、DNSサーバにて、ドメインのIPアドレスを調べてもらい、サーバ側に目的のファイルを返してもらえるようHTTPメッセージを作成します。作成し終えると、IPアドレスを元に目的のサーバへとルータを経由しながらHTTPメッセージを配送していきます。ここまでが、クライアントからサーバまで行くまででした。

#サーバからクライアントに返ってくるまで
次にサーバにリクエストが到達してから、どのようにして、クライアントにレスポンスが返ってくるのか説明していきます。
![Webの仕組み③.jpg](https://qiita-image-store.s3.amazonaws.com/0/101754/da613241-71fd-054c-49c8-3ed2f196b709.jpeg)

1. サーバにリクエスト（HTTPメッセージ）が到達するとサーバのソフトウェアがそのリクエストを解析し、実行
2. リクエストに応じて、プログラムを実行し、HTMLなどを生成　※動的コンテンツを想定
3. クライアントにわかるようにHTTPメッセージを作成
4. IPアドレスをもとに相手がどこにいるかルータを経由して、配送していく
5. クライアントにHTTPメッセージを送信
6. クライアントがHTTPメッセージを解析して、Webページを表示

クライアントからのHTTPメッセージがサーバに到達するとまずApacheなどサーバのソフトウェアがそのHTTPメッセージの内容を解析します。そして、そのリクエストをもとに、Rubyなどのプログラムが実行し、HTMLなどを生成します。生成後、再びHTTPメッセージを作成し、IPアドレスをもとに目的のクライアントへとルータを経由しながらHTTPメッセージを配送していきます。クライアントに到達すると、WebブラウザにてHTTPメッセージが処理され、Webページが表示されます。

#参考
もっと詳しい仕組みについて知りたい方はぜひ以下の書籍を手に取ってみてください。
- 上野　宣（2013/5/25）『HTTPの教科書 』翔泳社
Fedora 25 で Git のマージツールに P4Merge を使う

Fedora 25 の Git でマージツールに [P4Merge](https://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools) を使う場合はひと工夫必要です、という話。

# P4Merge をインストール

Perforce の公式サイトから P4Merge をダウンロードします。
https://www.perforce.com/downloads/helix

わかりづらいですが、P4Merge は *HELIX P4V: VISUAL CLIENT* に含まれています。
Visual Client をダウンロードしましょう。

![Screenshot from 2017-04-18 19-41-24.png](https://qiita-image-store.s3.amazonaws.com/0/48002/35af339b-e632-1c01-f51d-09b3eca64c92.png)


ダウンロードしたら、tarball なので適当なところに展開します。

```shell-session
$ cd /opt
$ sudo tar xf ~/Downloads/p4v.tgz
```

# PATH の設定

展開先の `bin/` ディレクトリを `~/.bash_profile` を編集するなどして `PATH` に追加しておきます。

```bash:~/.bash_profile
PATH=$PATH:/opt/p4v-2017.1.1491634/bin
export PATH
```
# .gitconfig の設定

`git mergetool` 時に P4Merge を使うように `~/.gitconfig` を設定します。

```~/.gitconfig
[merge]
  tool = p4merge
[mergetool]
  keepBackup = false
[mergetool "p4merge"]
  path = /opt/p4v-2017.1.1491634/bin/p4merge
  keepTemporaries = false
  trustExitCode = false
```

# p4merge の起動スクリプトを配置

ここがひと工夫の部分。
Fedora 25 の Git はなぜか P4Merge サポートが入ってません。
（P4Merge がプロプライエタリ・ソフトウェアだからだろうか）
デフォルトだと以下のようなエラーメッセージが出てしまいます。

```shell-session
$ git mergetool
git config option merge.tool set to unknown tool: p4merge
Resetting to default...
```

Git のソースリポジトリから P4Merge 用のスクリプトを自分でとってくる必要があります。

```shell-session
$ cd /usr/libexec/git-core/mergetools
$ sudo wget https://github.com/git/git/raw/v2.9.3/mergetools/p4merge
```

# 確認

適当なリポジトリで `git mergetool` して P4Merge が立ち上がったらOK。

以上です。
nfc raspberrypi read tag

ref:
[1] http://tfukui2012.blog.fc2.com/blog-entry-22.html
[2] http://nfcpy.readthedocs.io/en/latest/modules/clf.html

nfc tagを読む
16進法らしいのでそのencodeだけ気をつける. 

```read_tag.py
import nfc
import time

def connected (tag):
    print(tag)
    print(tag.type)
    print( tag.idm )
    print( str(tag.idm) )
    print( str(tag.idm).encode("hex") )
    print( tag.pmm )
    print( str(tag.pmm) )
    print( str(tag.pmm).encode("hex") )
    print( tag.sys )
    print( str(tag.sys) )
    print( str(tag.sys).encode("hex") )
    time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')

while True:
    print('waiting...')
    result = clf.connect(rdwr={'on-connect':connected})
    print('----------------------')
    print(result)
    print( str(result.idm).encode("hex"))
    print( str(result.pmm).encode("hex"))
    print( str(result.sys).encode("hex"))
    print('scaned')

```

とやると, 
仮に,
ID =01010501b00ac30b
PMM=03014b024f4993ff
SYS=1234
の場合(ref[2]の情報を利用)

```
waiting...
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
Type3Tag
|?
|?
01010501b00ac30b
1CEF???
1CEF???
03014b024f4993ff
3
3
33
----------------------
Type3Tag ID=01010501b00ac30b PMM=03014b024f4993ff SYS=1234
01010501b00ac30b
03014b024f4993ff
33
scaned
waiting...
```
のような感じで出る.
vagrant1.9.3でHomestead起動時にエラーになる

OS：Windows10 64bit

vagrantを1.9.3にアップデート後、
いつものようにhomesteadを起動しようとすると、

```
homestead up
```

```
in `initialize': The requested address is not valid in its context. - connect(2) for "0.0.0.0" port 8000 (Errno::EADDRNOTAVAIL)
```

エラーが:cry:

https://aota.blog/homestead-vagarant-up-is-not-working-on-windows-machine/

こちらの記事を参考に、homestead.rbを修正。

```
config.vm.network "forwarded_port", guest: guest, host: host, auto_correct: true
↓
config.vm.network "forwarded_port", guest: guest, host: host, host_ip: "127.0.0.1", auto_correct: true
```

無事起動！

そのうちvagrant、もしくはhomesteadが修正されそうですが一応メモ。
callbackに登録されているメソッド一覧を確認する方法

### よくある問題
モデルのコードが多い場合やconcernをいっぱい使っていると、callbackの処理を追っかけるのも一苦労。
だからと言って、after_ や before_ のようなキーワードで検索したりすのもの面倒。

そんなお困りのあなたに！

### 解決策
rails consoleで確認できます。

例えば、Entryモデルの after_save に登録されている callback 一覧を確認したい場合

```
$ bundle exec rails console

>> Entry._save_callbacks.select { |cb| cb.kind.eql? :after }.map { |cb| puts cb.filter }

update_search_text
update_activity
```

update_search_text と update_activity というメソッドが after_save のときに呼び出されていることがわかります。

同じような感じで before_save のものを確認したい場合は、モデル名の後とselectの中のフレーズを少し変更すればOK

```
Entry._save_callbacks.select { |cb| cb.kind.eql? :before }.map { |cb| puts cb.filter }
```

さらに after_update を確認したいなら

```
Entry._update_callbacks.select { |cb| cb.kind.eql? :after }.map { |cb| puts cb.filter }
```

こんな感じで簡単に調べることができます。


詳細はこちらでチェック！
[Active Record Callbacks](http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#module-ActiveRecord::Callbacks-label-Debugging+callbacks)