OmniAICreator/Qiita-1.07M huggingface dataset:
[WPF] XAMLでの文字列のフォーマット指定とバインディング

WPFでのデータを使用した文字列の指定はViewModel側で文字列まで加工する必要があるかと思っていたけれども、実はXAML側で指定できたのでやりかたメモ

# 基本

以下のように `StringFormat` を使用します。

```xml:基本
<TextBlock Text="{Binding Value, StringFormat={}{0} 円}"/>
<TextBlock Text="{Binding Value, StringFormat=商品A {0} 円}"/>
```

バインディングするデータが最初に来る場合は、頭に `{}` を付ける必要があります。（属性値のBindingなどではなく文字として中括弧がつかいたいため）

# 書式指定
StringFormat内では書式指定ができます。（例：数字の0埋めなど）

```xml:3桁の０埋め
<TextBlock Text="{Binding Value, StringFormat=商品A {0:D3} 円}"/>
```

指定方法は以下などを参照してください

+ [複合書式指定](https://msdn.microsoft.com/ja-jp/library/txafckwd(v=vs.110).aspx)
+ [標準の数値書式指定文字列](https://msdn.microsoft.com/ja-jp/library/dwhawy9k(v=vs.110).aspx)
+ [カスタム数値書式指定文字列](https://msdn.microsoft.com/ja-jp/library/0c899ak8(v=vs.110).aspx)
+ [標準の日時書式指定文字列](https://msdn.microsoft.com/ja-jp/library/az4se3k1(v=vs.110).aspx)
+ [カスタム日時書式指定文字列](https://msdn.microsoft.com/ja-jp/library/8kb3ddd4(v=vs.110).aspx)
+ [標準の時間間隔書式指定文字列](https://msdn.microsoft.com/ja-jp/library/ee372286(v=vs.110).aspx)
+ [カスタム時間間隔書式指定文字列](https://msdn.microsoft.com/ja-jp/library/ee372287(v=vs.110).aspx)
+ [列挙型書式指定文字列](https://msdn.microsoft.com/ja-jp/library/c3s1ez6e(v=vs.110).aspx)

# マルチバインディング
一つの文字列に複数のデータをバインディングしたい場合は以下のようにします。
MultiBindingの指定でもデータが最初に来る場合は頭に `{}` をつける必要があります。

```xml
<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="First {0} : Second {1}">
            <Binding Path="FirstValue"/>
            <Binding Path="SecondValue"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>
```

string以外の型から文字列を取得したい場合はConverterを使いますが、
Converterも以下のようにして使用できます

```xml
<Binding Path="Value" Converter="{StaticResource SomethingConverter}"/>
```

[MultiBinding クラス (System.Windows.Data)](https://msdn.microsoft.com/ja-jp/library/system.windows.data.multibinding(v=vs.110).aspx)
[Binding クラス (System.Windows.Data)](https://msdn.microsoft.com/ja-jp/library/system.windows.data.binding(v=vs.110).aspx)

# 参考
[BindingBase.StringFormat プロパティ (System.Windows.Data)](https://msdn.microsoft.com/ja-jp/library/system.windows.data.bindingbase.stringformat(v=vs.110).aspx)
[.NET Framework における型の書式設定](https://msdn.microsoft.com/ja-jp/library/26etazsy(v=vs.110).aspx)

[Nine Works　WPFのStringFormatによるフォーマット指定](http://nineworks2.blog.fc2.com/blog-entry-10.html)
Amazon API GatewayをCross-Originで利用する設定、Cross-Originせずに利用する設定のまとめ

Amazon API Gatewayを利用し、AWS Lambda関数をAPIとして公開する事が出来ますが、公開したAPIをAjaxで利用する場合、Cross-Originでアクセスするケースが出てきます。
※ Cross-Originにしないでアクセスする事もできますが、そちらは後述します。

対応を行う際にいろいろ調べたので、まとめとして書いてみます。

# CORSでAPIを利用する
### API GatewayリソースのCORSを有効にする
API Gatewayの設定については開発者リファレンスに記載されています。
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html

一部引用します

>Lambda または HTTP の プロキシ統合の場合、OPTIONS レスポンスヘッダーを API Gateway から設定できます。ただし、プロキシ統合では統合レスポンスが使えないので、Access-Control-Allow-Origin ヘッダーを返すにはバックエンドに依存する必要があります。

私の解釈としては以下の通りです。
![image020.png](https://qiita-image-store.s3.amazonaws.com/0/169729/28c2f7c7-d23a-b1df-197e-20c4e3ae6758.png)


１．AjaxでAPI Gatewayを利用するHTMLコンテンツを取得します。
このドメインはAPI Gatewayとドメインが異なるため、APIを利用するとCross-Originになります。

２．preflightリクエストを送信します。
Cross-Originのアクセスになるため、preflightリクエストを送信しますが、preflightリクエストを送るか否かについてブラウザに依存するそうです。（ChromeとIE11で動作が異なる為、少しハマりました）
preflightはOPTIONSでリクエストされ、Mock エンドポイントがレスポンスします。

３．preflightリクエストが成功するとAPIを呼び出します。このレスポンスにもAccess-Control-Allow-Originヘッダーが必要になります。

開発者ガイドに記載されている
>Access-Control-Allow-Origin ヘッダーを返すにはバックエンドに依存する必要があります

というのはLambdaの処理（＝バックエンド）でレスポンスヘッダーを設定してくださいという解釈をしました。

具体的には以下の実装になります

```py3
def respond(err, res=None):
    return {
        'statusCode': '400' if err else '200',
        'body': err if err else json.dumps(res, cls=DecimalEncoder),
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin' : '*'
        },
    }

```

CORSで利用する場合の設定はこれでおしまいです。


# CORSを有効にしないでAPIを使う

Access-Control-Allow-Origin : * を設定したくない。また、*の代わりにドメイン指定するのも煩雑だという考えもあると思います。
その場合はCross-Originにならない場所からAPIを利用する事で、CORSを有効にする必要が無くなります。

こんなイメージです。

![image033.png](https://qiita-image-store.s3.amazonaws.com/0/169729/8b62e957-610b-f20c-290a-c680b51d451a.png)

設定方法としては「HTTP プロキシ統合」が参考になります。
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html

具体的にはLambda関数を公開しているAPIと同じAPIにHTTPプロキシのリソースを作成し、HTMLコンテンツをProxyします。
エンドポイントURLの場所がHTMLコンテンツの置き場です。

![HTTP_PROXY.png](https://qiita-image-store.s3.amazonaws.com/0/169729/4379c491-dedb-f71b-7647-7bc3e428a60a.png)
注意点としては、APIの直下にhtmlという子リソースを作り、その下にプロキシリソース{proxy+}を作成しています。{proxy+}はパターン一致でProxyするので「html」のリソースを1階層はさまないとreadやwriteのLambda関数に対するリクエストもHTTP Proxyに流れてしまうと考えたからです。

以上の設定を行う事で、Cross-Originにしないで利用できるようになりました。

## HTTP ProxyするとHTMLとJSはProxyされるがimageファイルが壊れる？
おまけですが、HTMLコンテンツをHTML Proxyで表示させた際にimageファイルが壊れてしまいました。
※HTTP Statusは200で返りますが、ブラウザで表示できない状態になります。

この事象は「バイナリサポート」を設定することで解消します。（API Gatewayのお作法のようですね）
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-payload-encodings.html

![API GW.png](https://qiita-image-store.s3.amazonaws.com/0/169729/6a4419d5-51c4-02b8-8d39-9d031b09b4c2.png)
ansibleのdry-run時のエラーでdry-runがストップすることを回避

例えば、以下のようなplaybookを作成して、ansibleに `--check` オプションを付与して実行すると

```
- name: add repo centos 6
  tags:
   - install-zabbix
  yum:
   name: http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch.rpm
   state: present

- name: install lastest zabbix centos 6
  tags:
   - install-zabbix
  yum: name=zabbix-agent state=latest
```

以下のようにdry-runでは実際にzabbixのリポジトリはインストールされないために、yumインストールの段階で
`No package matching 'zabbix-agent' found available, installed or updated`
というエラーが発生してdry-runがストップしてしまう。

```
TASK [zabbix : add repo centos 6] **********************************************
changed: [ad-ssl6] => {"changed": true, "changes": {"installed": ["/tmp/tmpRmWHYC/zabbix-release-2.4-1
.el6.noarch.rpm"]}, "results": []}

TASK [zabbix : install lastest zabbix centos 6] ********************************
fatal: [ad-ssl6]: FAILED! => {"changed": false, "failed": true, "msg": "No package matching 'zabbix-ag
ent' found available, installed or updated", "rc": 126, "results": ["No package matching 'zabbix-agent
' found available, installed or updated"]}
```

---


そこで、以下を参考にして、`when` と `ignore_errors` を用いてdry-runがストップしないようにする
http://docs.ansible.com/ansible/playbooks_checkmode.html


```
- name: add repo centos 6  (this task will be skipped in check mode)
  tags:
   - install-zabbix
  yum:
   name: http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch.rpm
   state: present
  when: not ansible_check_mode

- name: install lastest zabbix centos 6  (this task will be skipped in check mode)
  tags:
   - install-zabbix
  yum: name=zabbix-agent state=latest
  ignore_errors: "{{ ansible_check_mode }}"
```
zabbixのリポジトリインストールの部分で、
`when: not ansible_check_mode` でdry-runの判断をさせ、
dry-runの場合は実行せず、それ以外だと実行するように設定。

yumのインストール部分ではdry-run時は必ずエラーが出るため
`ignore_errors: "{{ ansible_check_mode }}"`
で、dry-run時に発生したエラーの場合は無視するように設定を行う。

---

そうすると、dry-run実行時以下のようにリポジトリのインストールはスキップされ、
yumインストール時のエラーは無視されるようになり、dry-runが滞りなく進むようになる。

```
TASK [zabbix : add repo centos 6] **********************************************
skipping: [ad-ssl6] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}

TASK [zabbix : install lastest zabbix centos 6] ********************************
fatal: [ad-ssl6]: FAILED! => {"changed": false, "failed": true, "msg": "No package matching 'zabbix-agent' found available, installed or updated", "rc": 126, "results": ["No package matching 'zabbix-agent' found available, installed or updated"]}
...ignoring
```
Squeelの書き方をRails5に対応させるメモ


私のプロジェクトのRailsアプリケーションがついに4.2系から5.0系に進化するときがやってまいりました。

その際、 **squeel** が結構幅を利かせており、直すのに結構四苦八苦してしまいました。

なのでこちらではその忘備録とともに、同じくsqueelにsqueal(悲鳴)をあげる方々の助けに少しでもなればという事で書いていきます。

# squeelについて
- [公式](https://github.com/activerecord-hackery/squeel)
- 実は私はsqueelは使った事がないので、よくわからないのですが、要は短く綺麗にActiveRecordへの指示を出せるGemだったようです。
- [さよならSqueel](http://qiita.com/jkr_2255/items/44f0e5a686390d0cb496)の記事にある通り、Rails5へのアップデートに伴い、ついにアップデートがされなくなってしまいました。

# squeel修正対応表
- では早速本題に向かいます。

## 今回メインで使うモデルについて
```ruby
class Corporation < ActiveRecord::Base
  belongs_to :ceo
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :corporation
  
  attr_accessor %i(name)
end
```

## order
### 複数のプロパティでソートをしている場合
- squeelの公式には書いていなかったのですが、複数orderを指定する場合にこんな書き方ができたようです

```ruby
User.joins(:corporation).order { [:name, :id] }
```

- これに関してはすでに簡単にAcriveRecordで書けるようになっているのでありがたかったです。

```ruby
User.joins(:corporation).order(:name, :id)
```

特に問題はなし

### 複数のプロパティ（親要素含む）でソートをしている場合

```ruby
User.joins(:corporation).order { [:name, corporation.name] }
```

- これはちょっと「ん？」となった。親要素ってどうやってソートするんだっけ？
- これが正解

```ruby
User.joins(:corporation).order(:name, Corporation.arel_table[:name])
```

- さらっと`arel_table`使ってますが、[Arelでクエリを書くのはやめた方が良い5つの理由（Rails 5.0以前の場合）](http://qiita.com/jnchito/items/630b9f038c87298b5756)の中盤に書かれてある通り、 ~~5.1以降はarel_tableをガンガン使ってもいい方向性になるかもなので、使い方を覚えておいて損はないでしょう。~~
- @jnchito さんからコメントいただきまして、arel_tableが今後ともまだプライベートAPIのままの可能性もあるということで、引き続き控えめにみておいた方がいいとのことでした。失礼いいたしました

- ちなみに今回は`belongs_to`している対象が元のモデル名と同じだったからいいものの、

```ruby
# user.rb
belongs_to :my_office, class_name: 'Corporation'
```

とかだった場合って迷いません？ですがこの場合はおとなしく

```ruby
User.joins(:my_office).order(:name, Corporation.arel_table[:name])
```

が正解。

### 複数のプロパティ（親の親要素含む）でソートをしている場合
- あまり考えたくないけどもこんなバージョンが来た場合

```ruby
User.joins(corporation: :ceo).order { [:name, corporation.ceo.name] }
```

何重すんねんって思ったけども、この場合はこう

```ruby
User.joins(corporation: :ceo).order(:name, Ceo.arel_table[:name])
```

いやはやarel_tableの仕組み覚えななぁ‥‥

### DESC,ASCが入っている場合

```ruby
User.order { [name, age.desc] }
```

- 中かっこを使ってまとめてあげると見やすい

```ruby
User.order(:name, { age: :desc })
```

## joins(主にleft_outer_join)
- 私のプロジェクトでは、squeelでjoinsを使っている場合は大概が`LEFT OUTER JOIN`のためだった

### 一つのテーブルに対してLEFT OUTER JOINしている場合
```ruby
User.joins { corporation.outer }
```

- squeelのあった頃は`LEFT OUTER JOIN`するのが面倒くさかったらしいです

- これに対しては、Rails5ですでにメソッドが追加されているのでこう書きます

```ruby
User.left_outer_joins(:corporation)
# もしくは
User.left_joins(:corporation)
```

どっちを使うかはお好みで。短いから普通は後者かな？

### 複数のテーブルに対してLEFT OUTER JOINしている場合
- 次はちょっとややこしい

```ruby
User.joins { corporation.outer.ceo.outer }
```

- つまりはUserに対して`Corporation`で`LEFT OUTER JOIN`した後に、またさらに`Ceo`を`LEFT OUTER JOIN`している
- これに対してはこう

```ruby
User.left_joins(corporation: :ceo)
```

- これがもしも

```ruby
User.joins { corporation.ceo.outer }
```

とかだった場合（`Corporaton`が`INNER JOIN`、`Ceo`が`LEFT OUTER JOIN`）

```ruby
User.left_joins(corporation: :ceo).where.not(Corporation.arel_table[:user_id].eq nil)
```

こんな感じで無理やりそれっぽくこじつけるか、諦めて一つ前のようにまとめて`LEFT OUTER JOIN`してしまうか、他の手立てを使うかを考えないといけない‥‥

# まとめ

- order関係は楽だけども、join周りが場合によってはしんどいかも
Node v8 をインストールしたら node-sass が動かない

2017年5月30日に [Node v8](https://nodejs.org/en/blog/release/v8.0.0/) がリリースされたのでさっそくインストールしたところ、思わぬ場所でつまづいたので自分用にメモ。

## 発生した問題

1. ndenv で Node v8.0.0 をインストールして、グローバルに設定した

```
% ndenv install v8.0.0
% ndenv global v8.0.0
```

2. 作業ディレクトリに移動して、それまで使っていた Node のバージョンをローカルに設定した

```
% cd /path/to/project
% ndenv local v6.9.5
```

3. なぜか webpack で css のビルドが落ちる (なぜか webpack-dev-server は問題なし)

```
% webpack 

Hash: c1bcf7764e985de80da9
Version: webpack 1.14.0
Time: 5778ms
                       Asset       Size  Chunks             Chunk Names
                   bundle.js     448 kB       0  [emitted]  bundle
                  bundle.css     368 kB       0  [emitted]  bundle
    + 813 hidden modules

ERROR in ENOENT: no such file or directory, scandir '/Users/[username]/path/to/project/node_modules/node-sass/vendor'
 @ ./app/assets/index.js 8:0-27
```

node-sass が動いていない模様。
webpack-dev-server は問題なく動いていて、webpack はテストのときだけバックグラウンドで動かしていたので、気付くまで小一時間かかりました。

## 解決策

node-sass が Node のバージョンに依存していることが問題らしいです。`rm -rf node_modules && yarn` でインストールし直して解決しました。
でもローカルは以前のバージョンのままなのに...。詳細はよく理解できておらず。
Ruby + Sinatra で GraphQL リクエストを受け取る

シンプルすぎる実装ですがここまで来るのにけっこう時間かかったのでメモがてらに。

# GraphQL
RESTに代わる問い合わせの仕様と理解しています。
こちらの記事がとてもわかりやすかったのでどうぞ↓
[GraphQL入門 - 使いたくなるGraphQL](http://qiita.com/bananaumai/items/3eb77a67102f53e8a1ad#graphql%E3%81%AE%E7%89%B9%E5%BE%B4)

# Hello, #{name}!
リクエストで名前を受け取って，JSONで `Hello, hirapi!` 文字列を返してみます。

使うのはこれ。
[rmosolgo/graphql-ruby: Ruby implementation of GraphQL](https://github.com/rmosolgo/graphql-ruby)

### 免責（言い訳）
「とりあえず動かす」が目的で，設計がGraphQL APIの仕様として適切かと言われるとそうでもないです。
仕様は上記記事とか公式[GraphQL Best Practices | GraphQL](http://graphql.org/learn/best-practices/)や[GitHub GraphQL API | GitHub Developer Guide](https://developer.github.com/early-access/graphql/)をご参照ください。

現実的にはidを受け取ってActiveRecordなりでレコード取得→結果をJSONで返す，という使い方になるかと思います。
そのとき返す形式もGraphQL::ObjectTypeとして定義できるみたいですが、そのあたりはこの記事では扱いません。

例外処理まわりもつけていません。適宜つけてください。

## Gemfile

```ruby:Gemfile
source 'http://rubygems.org'

ruby '2.4.0'

gem 'sinatra'
gem 'sinatra-contrib'
gem 'graphql'
```

## main.rb

```ruby:main.rb
require 'graphql'
require 'sinatra'
require 'sinatra/json'
require 'sinatra/reloader'

register Sinatra::Reloader

configure do
	QueryType = GraphQL::ObjectType.define do
		name 'query'
		field :hello do
			type types.String # このクエリはStringを返す（"Hello, hoge!"）
			argument :name, types.String # nameパラメータはStringで欲しい
			resolve -> (obj, args, ctx) do
				"Hello, #{args['name']}!" # DB等処理。クエリ内のパラメータは配列argsで受け取る
			end
		end
	end

	Schema = GraphQL::Schema.define do
	  query QueryType
	end
	
end

post '/' do
	req = JSON.parse(request.body.read)
	query = <<-EOS # よくない実装
	{
		hello(name: "#{req['name']}")
	}
	EOS
	Schema.execute(query).to_json

end
```

Ruby側でqueryを作ってますがリクエストが面倒くさくなるのが嫌だっただけです。
queryの通りのJSONをPOSTさせてそのまま `Schema.execute(query)` に渡すべきですねw


## 挙動
実行してサーバー起動させて（sinatra便利）

```
[vagrant@app app_dir]$ ruby main.rb
== Sinatra (v2.0.0) has taken the stage on 4567 for development with backup from Puma
Puma starting in single mode...
* Version 3.8.2 (ruby 2.4.0-p0), codename: Sassy Salamander
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:4567
Use Ctrl-C to stop

```

リクエスト

`curl -X POST -d '{"name": "hirapi"}' http://localhost:4567`

レスポンス

```
{"data":{"hello":"Hello, hirapi!"}}
```

おわり。
MySQLのCSV出力が権限によって出来ない場合の対処法

## はじめに :dolphin: 
[MySQLのSELECT文でcsvを出力する](http://qiita.com/catatsuy/items/9fdf4423d5f4885b9bf9)

を参考にCSVファイルを出力したのですが、環境によってはユーザ権限の問題等によりエラーが発生してしまいます。

「とりあえずCSV出力したいんじゃ :punch:  」という方への対処法を調査したのでこちらに記載いたします。

**こんなエラーが発生する**

```
ERROR 1 (HY000): Can't create/write to file '/tmp/fruits.csv' (Errcode: 13)
```

```
ERROR 1045 (28000): Access denied for user '{ユーザ名}'@'%' (using password: YES)
```

## 結論 :tada: 
以下でザクッと解決

**tsv**

```bash
mysql -h {host名} -u{user名} -p {DB名} -e "{SQL}" > {ファイルパス}
```
具体的には…

```bash
mysql -h database.com -uadmin_user -p my_database -e "select * from fruits;" > /tmp/fruits.tsv
```

**csv**

```bash
mysql -h {host名}  -u{user名} -p {DB名} -e "{SQL}" | sed -e 's/^/"/g' | sed -e 's/$/"/g' | sed -e 's/\t/","/g' > /tmp/fruits.csv
```

具体的には…

```bash
mysql -h database.com -uadmin_user -p my_database -e "select * from fruits;" | sed -e 's/^/"/g' | sed -e 's/$/"/g' | sed -e 's/\t/","/g' > /tmp/fruits.csv
```


## おわりに
原因として、MySQLログインユーザのファイル書き込み権限がなかったことなどが挙げられます。詳しく知りたい方は以下の記事が非常に参考になりますのでご覧ください。

[MySQL SQL結果をINTO OUTFILEを使用せずCSV取得](http://kenzo0107.hatenablog.com/entry/2016/03/14/161251)

[MySQLリモートDBの結果をローカルCSVファイルに出力する方法](http://shusatoo.net/db/mysql/mysql-remote-db-result-output-local-csvfile/)
regjumpが神ってるのでURLプロトコルで指定のレジストリキーを開けるようにする


## regeditのコマンドラインオプションでは指定のレジストリキーを開けない
- [regeditのコマンドラインオプション](http://www.corso-b.net/itaya/TIPS/TIPS15.html)

登録とか削除とかはできるが、目的のキーを一発で開くということができない

## regjumpとかいう神アプリ（×2）
ちょっと混乱したのだが、regjumpという名前のソフトウェアは2つある。

ひとつは、Microsoft謹製、RegJump。こちらは純然たるコマンドラインツールであり、GUIは用意されていない。

- [【レビュー】クリップボードにも対応。レジストリの指定パスへすばやくアクセスできる「RegJump」 - 窓の杜](http://forest.watch.impress.co.jp/docs/review/738946.html)

もうひとつは、fenrirの作者として有名なforia氏の手になる、regjump。こちらはコマンドラインオプションこそあれGUIツールであり、基本的に起動して入力フィールドにレジストリキーを入力する形で利用する。

- [B@r09u3 Style Op.2](http://hp.vector.co.jp/authors/VA026310/soft2.htm)

いずれも、引数としてレジストリキーを与えることで、レジストリエディタで指定のキーを即座に開くことができる。

今回の用途では前者で充分であるし、後者は今後のメンテが見込めないことから前者を利用するつもりだったのだが、なぜかプロトコルハンドラとして登録するとうまくいなかった。
よって、今回は後者を利用する。

## regjumpのコマンドラインオプション

```txt
/c			クリップボードに格納されているレジストリキーにジャンプ
/s="RegistryKey"	RegistryKeyにジャンプ
/t			ジャンプしたら終了
/h			非アクティブになったら終了
/v			バージョン情報
```

`/t`について、「ジャンプしたら終了」とあるが、`/s`と併用した場合、実際の挙動は「GUIを表示せず実行してそのまま終了」という感じになる。
（実はこの点、必ずコンソールが表示されるMicrosoft RegJumpより目立たずクールである）

例えば、コマンドプロンプト等で指定のレジストリキーを開くには、以下のようなコマンドを実行する。

```shell-session
<regjump.exeのフルパス> /t /s=<対象レジストリキー>
````

## URLプロトコルハンドラの登録
- 参考：[カスタム URL スキーム の 設定 と 利用 - galife](https://garafu.blogspot.jp/2014/02/url.html)

今回、スキーム名は`reg`とし、regjumpはC:\apps\RegJump\regjump.exeに配置するものとする。
キー`HKEY_CLASSES_ROOT\reg\shell\open\command`を作成し、規定のコマンドを`"C:\apps\regjump\regjump.exe" /t /s="%1"`とする。

エクスポートしたものが以下。

```reg_url_protocol.reg
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\reg\shell\open\command]
@="\"C:\\apps\\regjump\\regjump.exe\" /t /s=\"%1\""
```

例えば、「ファイル名を指定して実行」等で`reg://HKEY_CLASSES_ROOT\reg\shell\open\command`を実行すると、先程登録したキーを開くことができる。

ただ、どちらかと言えば、`regjump.exe /c`をランチャかなにかに登録しておいて、コピーしたキーを開けるようにしたほうが使える機会は多いと思う。
【ommail】CentOSでログイン通知【rsyslog】

CentOS にログインしたらメールで通知を受け取れるように設定します
Gメールは使わないで、社内メールサーバ等を利用するパターンです
　[【ssmtp】CentOSでログイン通知【rsyslog】](http://qiita.com/nobu-maple/items/34d052ddfe2fbab4e79c)　の ommail版です


もし、意図しないタイミングでメールが来たら。。ヤバイ状況です
が、メール通知を仕掛けておかないと気が付きもしないかも

ちょっと設定ファイルを書いて、数行の簡単なシェルを組むだけ
手間をかけずにログインメール通知を仕掛けてみます

ここに書いた手順は centos ですが、他Linuxでも似たようにできると思います
（未確認）


# ommail モジュールのインストール確認

rsyslog からメールを送るための ommail モジュールがインストールされてるか確認です
ファイルがあれば OK です

```bash
 ls -l /lib64/rsyslog/ommail.so
 -rwxr-xr-x. 1 root root 14800 12月 17 18:52 2014 /lib64/rsyslog/ommail.so

```

もし入ってなかったら rsyslog を落としてきてコンパイルとかかな？
この辺を参考に
http://www.rsyslog.com/doc/v8-stable/configuration/modules/ommail.html




# システムログ設定

OSがログインしたことをsyslog に残すので、syslogに記録されたタイミングでメール送信をできるように設定を追加です

## ommail 設定

```bash:/etc/rsyslog.d/ommail.conf
$ModLoad ommail

$ActionMailSMTPServer  192.168.25.25
$ActionMailFrom   メール送信元アドレス

$template login_subject,"Server01 Login(%fromhost%)"
$template login_body,"%fromhost%\r\nUser Login\r\n%msg%"

$ActionExecOnlyOnceEveryInterval  1

#------------------------------------------------------------
## Server Login
$ActionMailSubject login_subject
$ActionMailTo      メール送信先アドレス
if \
      ( $msg contains 'pam_unix(' ) \
  and ( $msg contains 'session opened' ) \
then :ommail:;login_body
```

ommail のモジュールを読み込んで

送信用メールサーバを設定（アドレスとか送信者とか）

login_bodyという変数？に ログイン元のfromhost と、syslogに記録されたメッセージを設定

もし（if） syslog に記録されたメッセージ（$msg）に 
　'pam_unix(' っていう文字列と
　'session opend' っていう文字列があったら
ommail モジュールを使って login_body の内容を送信

っていう設定になってます。
カンタンですね


もし、同じ内容のログが １ 秒以内に記録されても、１回だけしか送らないって設定も入れときました（ActionExecOnlyOnceEveryInterval ）
※ ツール系とかの処理でログイン通知が大量に来ることがあったので追加



# 設定反映

設定が終わったら、rsyslog に設定を読み込ませて反映させときます

```bash
$ sudo  service  rsyslog  reload
```

または

```bash
$ sudo  systemctl restart rsyslog
```



以上
動作確認等は前回の記事 [【ssmtp】CentOSでログイン通知【rsyslog】](http://qiita.com/nobu-maple/items/34d052ddfe2fbab4e79c) と同じなので割愛
GMail が使えないセキュアな社内サーバでもログイン通知を仕掛けられますよ
メール送信に認証が必要であれば、 sSMTP 版を参考に
MacBookで外付けカメラで動画を撮る

一瞬ハマったので記録。

#Quick Time Playerで新規ムービー収録を選択
<img width="317" alt="スクリーンショット 2017-05-31 17.14.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/5ee3a1bf-0c15-d143-dd35-6707026df38c.png">
#外部のカメラを選択する
<img width="367" alt="スクリーンショット 2017-05-31 17.14.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/13f69ce2-b646-61d2-36b8-647b7ac53bda.png">
#録画ボタンを選択する


#参考
http://fmol.be-ourselves.jp/?p=4954
マルチモーダルコーパスの使用例について

- まずコーパスってなに？

慣れない言葉なのでまずコーパスについて調べてみた。

>コーパスとは、日本語や英語などをはじめとした自然言語の文書を大量に集めたもののことである。
コーパスは、言語学や情報処理において自然言語処理の研究や機械学習の学習データとして利用される。単に文書を集めるだけではなく、品詞や統語構造などを付与してあるものは、特に「タグ付きコーパス」などと呼ばれる。また、英語と日本語の文同士を、互いに対訳の形で収集したものは対訳コーパスと呼ばれる。
weblio辞書より

自然言語の文書の集合体のことという解釈をした。
〇〇コーパスのようになれば〇〇というもののデータの集合体になるのかな？


- 次にマルチモーダルコーパスは？

マルチモーダル　ー　複数のことを考えること
マルチモーダルコーパスは対話の内容だけでなく画像処理的なデータ、例えば視線の動きやまばたきの数など色々な要素をデータとして集めたものであると解釈した。

- ではマルチモーダルコーパスで何ができるのか


本来は会話の内容でしか判断できなかったことが画像処理などの面からも考えることができ、より推定の精度が挙げられると考える。

実際の使用例として
子育ての支援ができるという記事を見つけた。
http://www.blog.crn.or.jp/report/02/119.html

子育てと言っても目的、ライフスタイルなど様々な人が行うわけで求める物がそれぞれ違う。
学術的に研究している人たちもそれぞれの感覚があり、なかなか話が噛み合わないそうだ。
その人達の共通言語としてマルチモーダルコーパスを使おうという話だった。
様々な行動シーンで発話・視線・ジェスチャ・感情・意図などの注釈を持たせるみたいです。
言語の発達・他者理解の発達・発達段階別の子どもへの接し方などの複数の観点で発達の要因を捉え、研究する基盤データベースとなっている。
研究者が研究し、実際に子育てをしている人たちが試し、フィードバックを行い、また研究が深まるというループになるそうです。

- コーパスどうやって作るの？
映画でマルチモーダルコーパスを作ろうという論文を見つけた。
山形大学の映画からのマルチモーダル対話コーパスの作成　というものです。

大規模な対話コーパスを作るのにはコストがかかり自由に利用できるマルチモーダル対話コーパスはなかなか存在しないようで、映画から作ろう。
しかし、なかなか難しいようです。映画は対話だけで成り立っていないので非対話の所から対話部分を抽出する必要がある。しかし、抽出の精度が低いようです。
ミュージカル映画などで歌の部分を対話として抽出してしまうようなこともあるようです。

-リンクデータコーパスを作るには？
http://bpmlod.github.io/report/nif-corpus/index.html
ここの記事が話に近いと思って
ファイル名。pathlibでは半角スペースあってもいいけど、subprocessで叩くときは半角スペースはエスケープすべし、とおもいきや、check_outputを使うとエスケープ不要

- csvを読み込みたい。
- ファイルによって文字コードはまちまち
- ファイル名に`␣`がある

ときのはなし

```
import pathlib
import subprocess as sp

path_file = pathlib.Path('hoge hoge.csv')

encoding = sp.getoutput('nkf -g ' + str(path_file))
df = pd.read_csv(path_file, encoding=encoding)
```
とかくと、subprocessの方でエラー

```
import pathlib
import subprocess as sp

path_file = pathlib.Path('hoge\ hoge.csv')

encoding = sp.getoutput('nkf -g ' + str(path_file))
df = pd.read_csv(path_file, encoding=encoding)
```
（`hoge`と`hoge`の間を`\␣`にした）
とかくと、pd.read_csvの方でエラー

怒った！！！！！

怒りのハードコーディングで解決（べつにそんなハードでもないけど）

```
import pathlib
import subprocess as sp

path_file = pathlib.Path('hoge hoge.csv')

encoding = sp.getoutput('nkf -g ' + str(path_file).replace(' ', '\ ')))
df = pd.read_csv(path_file, encoding=encoding)
```
ただ、`␣`を`\␣`に置換しただけ。


許せない…！
なんでシステムが自動で入れるフォルダ名に`␣`があるのだ。
私…全てのファイル名に紛れている␣を、生まれる前に消し去りたい。全ての宇宙、過去と未来の全てのファイル名に紛れている␣を、この手で。


---

追記（2017/06/01 17:50）
@shiracamus 氏のコメントを参考に、
`encoding = sp.check_output(['nkf',  '-g', str(path_file)])`
とすれば動きました。

ドキュメントを読んでも`getoutput`と`check_output`の違いは分からず…。
勉強が足りませんな。
【CakePHP2】レビューの評価平均順にhogeを表示する


# はじめに

環境はCakePHP2.5.6

hogeに対して複数のreviewを持つ可能性があるという構成
Hoge hasMany Review

reviewsテーブルはid,score,content（レビュー内容）,hoge_idという定義。

hogeをレビュー評価（平均）順にするには、どうしたらいいか……？

というものです。


#解決策

「DBに新カラム？やめといて」と言われてしまいました。
正直それが一番いけそうだと思ったのですが……。ぐぇぇ

「VirtualFieldで出来るんじゃない？」なんていう助言も頂いたのですが、どうにも分かりませんでした。

最終的に辿り着いたのは、

① SQL文で綺麗にソートしたものを取得する
② 'order'にidを文字列で渡して、その順番で表示してもらう

という方法です。

調べまくっていて他にやっている人を見かけなかったので、ここに報告させて頂きます。

SQL文を好きなだけ使える上に、好き放題paginateも使えるんじゃないかと思います。

CakePHPの新たな可能性を見た、という気持ちです。


##ソースコード

###Model

```php:Model/Hoge.php
public function getHogeSortScore() {
        $query = "
                SELECT
                                hoges.id,
                                hoges.name,
                                (sum(reviews.score))/count(review.id) as review_ave,
                                count(review.id) as review_count
                        FROM
                                hoges
                                        LEFT JOIN reviews
                                                ON (hoges.id = reviews.hoge_id)
                        group by hoges.id
                        order by review_ave desc, id;
        ";
        $data = $this->query($query);
        return $data
}
```


###Controller

```php:Controller/HogeController.php
public function index() {

        $score_sort_hoges = $this->Hoge->getHogeSortScore();

        $hoge_ids = array();
        foreach ($score_sort_hoges as $item) {
                // ただidだけの配列を作る
                $hoge_ids[] = $item['hoges']['id'];
        }
        // 配列に入ったものを,で区切った文字列に
        $str_hoge_ids = implode(',' , $hoge_ids);

        // 指定した順番に表示してもらうため
        $sort_order = 'FIELD(Hoge.id, ' . $str_hoge_ids . ')';

        $this->paginate = array(
                // 'conditions' => $conditions,
                'limit' => 10,
                'order' => $sort_order,
        );

        $options = array(
                'Hoge.del_flg' => 0,
        );
        $hoges = $this->paginate($options);
        $this->set(compact('hoges'));
}
```


# 修正

order byで、idも指定しておかないと
「1ページ目で出たものが2ページ目でも出てくる」なんていうヤバい表示になっていました。
SwiftでKotlinのletのようなもの

KotlinがGoogleさんに認められた(?)ので、Kotlinを勉強し直さないとと思い、記事を読んでいたら**let**という機能があると...
結構便利そうなのでSwiftでもできないかなーと

読んでた記事
↓↓↓↓↓↓↓
[JavaプログラマがKotlinで便利だと感じること](http://qiita.com/koher/items/cb91dbbff9b14575f498)

# Kotlinのlet

## 例
たとえば、数を足すだけのメソッド`foo`がありますよと
その`foo`を複数回使う計算とかでてきますよね...

```kotlin
(foo(1, 2) + 6) / foo(1, 2) // 3
```

こんな感じ
どっちの`foo`も引数が同じなので、返り値も同じですね
そうなると無駄ではw（`foo`がもっと重い処理になったら複数回も呼びたくないとw

## とりあえずの解決策

```kotlin
val f = foo(1, 2)
(f + 6) / f // 3
```

とりあえず、`foo`は1回しか呼ばなくてすみましたね
でも、2行になってしまったよ...（細かいですがw

## そこで**let**様

```kotlin
foo(1, 2).let { f -> (f + 6) / f }
```

1行だし、1回しか`foo`呼んでないしいい感じ
とりあえず、**let**の実装を...

```kotlin
inline fun <T, R> T.let(block: (T) -> R): R = block(this)
```

呼び出し元をClosureにいれるのか！ふむふむ

# Swiftでやっちゃおう
まず、名前がかぶるので`let`が使えない（みなさんご存知、変数宣言時の`let`がありますねw
なので、`lets`にしました（`let_swift`の略みたいな感じです

とりあえず、実装を！

```swift
// プロトコルを定義
protocol Lets {}

// プロトコルにメソッドを追加
extension Lets {
	func lets<R>(_ closure: (Self) -> R) -> R {
		return closure(self)
	}
}

// プロトコルを拡張したいクラスに
extension Int: Lets {}
```

プロトコルとして定義して、そのプロトコルでクラス（今回は`Int`）を拡張します
使い方は、この通り簡単です

```swift
foo(1, 2).lets({
	($0 + 6) / $0
}) // 3
```

## 改善できなかった点
Swiftに全ての元になるクラスがみつからなかったため、使うクラスに随時拡張していかなくてはならなそうでした....

### 追記
演算子を使用して...と、コメントでいただきましたので、みなさんのお役に立てればと！
`=>`演算子を使用しています

```swift
foo(1, 2) => {
	($0 + 6) / $0
}
```

詳細は[こちらのGitHub](https://github.com/koher/swiflet)にあります。

# まとめ
今回紹介したクラス拡張の仕方は、きっとどこかで役に立つと思うのでぜひぜひ覚えてください。
今回は`Int`クラスに拡張しましたが、他のクラスでもできますのでみなさんもお試しください:sunglasses:

# GitHub Gist
https://gist.github.com/hmhmsh/016582e6f9d88c9ec309035b1f9d9936

# 参考
[SwiftでKotlinのapplyっぽいものを使いたい](http://qiita.com/tsumuchan/items/e4913c9583d00d9bea7d)
（こちらで紹介されている`apply`も役に立つ、使いやすいので是非お試しください）
JavaでStreamって使ってる？

# Java 9 Stream 新機能
Java 9 でStreamに３つの機能が追加されますね。

・takeWhile　条件を満たす間のデータを対象とする
・dropWhile　条件を満たす間のデータを対象外とする
・ofNullable　nullを許容する

でも新機能以前に仕事で Stream を使ってる人（というかソース）を見ないなーと思います。
（仕事だとあんまり新しいものを使う機会がない）

新しい物にも触れていかないと置いて行かれちゃいますのでどんなものか軽く調べてみました。

# そもそも Stream ってどういうときに使うの？
多分こういう時に使うと思います。

・基本的に今までより少ない記述で書けるようになるので、ソースがスッキリする。
・色んなAPIの返却値が Stream になっていたりするので知らないとそもそも使えない。
・parallel()を使って並列処理を走らせたい。　(2017/06/01 追記)
・リストの中身を使って違うリストを作成する。（2017/06/02　追記）

# どうやって Stream を使うの？
例１：リストをループしてメソッドに渡す

```java
List<String> list = Arrays.asList("その１", "その２", "その３", "その４", "その５");
// Hogeクラスのfugaメソッドにリスト内の文字列を渡している
list.stream().forEach(Hoge::fuga);
```

例２：文字列リストから整数リストを作成

```java
List<String> sl= Arrays.asList("11", "12", "13", "14", "15");
List<Integer> il = sl.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());
```

例３："C:\temp"以下のcsvのパスを全部取得後、"A"で始まるファイルの件数だけ取得
※Files.findは対象のパス、探す深度、マッチング条件を渡して Stream を返します。

```java
Path target = Paths.get("C:\temp");
try(
    Stream<Path> paths = Files.find(target , Integer.MAX_VALUE, (p, a) -> p.getFileName().endsWith(".csv"));
){
    // 「A」で始まるCSVだけカウントしてみる
    long c = paths.filter(p -> p.getFileName().startsWith("A")).count();
}
```

ちょこちょこ出てくる「 -> 」っていのは「ラムダ式」ってやつですね。

streamAPIはだいたい引数が Consumer になっていてメソッド参照とかラムダ式を渡せるようになっています。

まぁ「 -> 」が出てきたら左側が引数、右側はメソッドの中身が書いてあると思えば良いのではないでしょうか。

メソッド参照は「Hoge::fuga」という風に書いてある奴ですね。
読むだけなら「Hoge.fuga(str)」の括弧部分が省略されてると思えばいいと思います。

# 比較してみる
Stream を使うことでどれくらいソースが縮むのか書いてみましょう。

■ Stream を使う場合

```java
paths.filter(p -> p.getFileName().startsWith("A"))
```

■ Stream を使わない場合

```java
/** フィルターの部分 */
private List<Path> filter(List<Path> paths) {
    List result = new ArrayList<>();
    for (Path p : paths) {
        if (isStartA(p)) {
            result.add(p);
        }
    }
    return result;
}
/** ラムダ式の部分 */
private boolean isStartA(Path p) {
    return p.getFileName().startsWith("A");
}
```
Stream とラムダ式を使うことでいかに記述が減るか分かりますね！

# まとめ
上記の結果を見ると Stream とかラムダ式をもっとバンバン使った方がいいじゃんって感じですが、
実際に仕事で使うとなると「for・while禁止」とかしないとソースが滅茶苦茶になってしまったりが悩みどころでしょうか
あとわかってない人には意味不明のソースになります。（これはわかってない人が悪い気もする）

せっかく便利にアップデートされていってるのだから人間のほうもアップデートしていきたいですね！
json4s, play-jsonでのOption#emptyの取扱い


## json4s
valueが`JNull`の場合はnullをvalueとする、`JNothing`の場合はfieldごと除去

```scala
scala> compact(render(("aaa" -> 123) ~ ("bbb" -> JNull)))
res: String = {"aaa":123,"bbb":null}
scala> compact(render(("aaa" -> 123) ~ ("bbb" -> JNothing)))
```


`Option`で値が存在しない場合は`JNothing`が選ばれ、fieldごと除去される

```scala
res: String = {"aaa":123}
scala> ("aaa" -> 123) ~ ("bbb" -> Option.empty[Int])
res: org.json4s.JsonAST.JObject = JObject(List((aaa,JInt(123)), (bbb,JNothing)))
scala> ("aaa" -> 123) ~ ("bbb" -> Option.empty[String])
res: org.json4s.JsonAST.JObject = JObject(List((aaa,JInt(123)), (bbb,JNothing)))
```
### 備考
NullがAnyRefの親クラスであるため、String等AnyRefの系列のときのみnullが使える

```scala
scala> ("aaa" -> 123) ~ ("bbb" -> Option.empty[String].orNull)
res: org.json4s.JsonAST.JObject = JObject(List((aaa,JInt(123)), (bbb,JString(null))))
scala> ("aaa" -> 123) ~ ("bbb" -> Some(1).orNull)
<console>:23: error: Cannot prove that Null <:< Int.
 ("aaa" -> 123) ~ ("bbb" -> Some(1).orNull)
 ^
```

## play-json
基本的にfieldごと除去するようなことはしない。

```scala
scala> Json.obj("aaa" -> 123, "bbb" -> JsNull)
res: play.api.libs.json.JsObject = {"aaa":123,"bbb":null}
scala> Json.obj("aaa" -> 123, "bbb" -> JsNull).toString()
res: String = {"aaa":123,"bbb":null}
scala> Json.stringify(Json.obj("aaa" -> 123, "bbb" -> JsNull))
res: String = {"aaa":123,"bbb":null}
scala> Json.stringify(Json.obj("aaa" -> 123, "bbb" -> Option.empty[Int]))
res: String = {"aaa":123,"bbb":null}
scala> Json.stringify(Json.obj("aaa" -> 123, "bbb" -> Option.empty[String]))
res: String = {"aaa":123,"bbb":null}
```

play.api.libs.json.JsPath#writeNullableを用いて記述されている場合はfieldごと除去

```scala
scala> (((__ \ 'aaa).write[Int] ~ (__ \ 'bbb).writeNullable[String])(identity[(Int, Option[String])] _)).writes((123, None))
res: play.api.libs.json.JsObject = {"aaa":123}
```
CentOS公式のDockerイメージにZabbix server 3.2をyumでインストールするとcreate.sql.gzが存在しない

AnsibleでDockerfileを使わずにDockerイメージを作成するデモ第2弾。
今回はZabbix serverで行き詰まったのでメモとして残します。

結論から言うと、yum.confに `tsflags=nodocs` をコメントアウトすることで解決しました。
tsflags=nodocsがあるとyumで/usr/share/doc関連がインストールされません。
Dockerイメージのサイズを減らすためのようです。

```/etc/yum.conf
[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release
override_install_langs=en_US.utf8
tsflags=nodocs # <-　こいつのせい！
```

↓

```/etc/yum.conf
[main]
...
#tsflags=nodocs
```
SublimeText3用のRobocodeビルドスクリプトを書いた

# はじめに

学校の授業で、Robocodeの実習が始まりました。
Robocodeのデフォルトのエディタはあまりにも使いづらいので、SublimeTextでコーディング、ビルドができるようにしました。

# コード

```json:robocode.sublime-build
{
	"selector": "source.java",
	"file_regex": "^(.*?):([0-9]*):?([0-9]*):? (.*)",
	"cmd": ["javac","-deprecation","-g","-source","1.6","-encoding","UTF-8","-classpath","\"C:\\Program Files\\Java\\jre1.8.0_91\\lib\\rt.jar;Z:\\robocode\\libs\\robocode.jar;Z:\\robocode\\robots\"","$file"],

	"windows":
	{
		"encoding": "utf-8",
	}
}
```

<font color="red"><b>※javac、robocodeのパスは適宜置き換えてください。</b></font>

# さいごに

特に解説等はありません。
本当はVSCodeを使いたいのですが、ソフトウエアのインストールが禁止されているので、SublimeTextのポータブル版を使っています。
これで、Robocodeの開発効率が少しでも上がるといいです。
SQLite3で躓いたところ

#躓いたところ

以下のようなフォームでチェックボックスにチェックを入れられたデータを消したかったわけです。

```index.html
<form action="{{ url_for('delete_data') }}" method="post" enctype="multipart/form-data">
  <ul>
    {% for entry in result %}
      <li>
        <input type="checkbox" name="action" value="{{ entry[0] }}">{{ entry[1] }}:{{ entry[2] }}
      </li>
    {% endfor %}
  </ul>
  <input type="submit" value="削除">
</form>
```

```index.py
if request.method == 'POST':
  data_ids= request.form['action']
```

こういう感じで受け取った、変数を渡したかったんですね。

```index.py
c.execute('''DELETE FROM message WHERE data_id=data_ids''')
```

これで何度も怒られる。

#結論

こう書けば良かった模様。変数で渡す場合はこうなるんですねぇ・・・。

```index.py
query = "DELETE FROM message WHERE data_id=?"
c.execute(query,(data_ids,))
```
どなたかご教示ください。好きじゃないPHPから意地悪されてますぅ(´;ェ;`)ｳｩ･･･　$talken='ef8b0ad3b04306414b3e0890f6bf'; が空白表示

$talken='ef8b0ad3b04306414b3e0890f6bf'; という代入をし、
これをechoしてもDBレコードに代入しても、空っぽ！

敬遠しているPHPなので、バグ潰しに苦労してます。

丸見えのパスワードをおためごかしな方法で改善しようとしている最中なのです。
解決法など、ご存じの方、宜しくお願いします。:sweat_smile:

<img width="253" alt="スクリーンショット 2017-05-31 16.08.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/5135/4310557d-1c16-fc44-4a84-e9f9a677561e.png">
Python で Ctrl-C をキャッチする

Python で Ctrl-C (SIGINT) をキャッチする方法について検索すると、`signal` モジュールを使用する方法がよくヒットするが、もっと簡単にできるよという TIPS です。

結論から言えば、`KeyboardInterrupt` 例外を捕まえれば OK です。

`KeyboardInterrupt` を使用した場合のコード：

```py
try:
    while True:  # なんらかの重い処理 (for だったり while だったり。。。)
        pass  # ここに、Ctrl-C で止めたい処理を書く
except KeyboardInterrupt:
    # Ctrl-C を捕まえた！
    # print('interrupted!')
    pass  # なにか特別な後片付けが必要ならここに書く
    # プログラムをこの時点で殺すなら sys.exit する
# あとは普通の処理を書けば良いが、Ctrl-C を握りつぶして処理続行は大変お行儀が悪いので注意
```

# 注意
厳密に言えば、`KeyboardInterrupt` はシェルから切り離されたバックグラウンドジョブの場合は SIGINT を捕まえてくれないらしいですが、通常のシチュエーションであればまず `KeyboardInterrupt` を使用して問題ないと思います。
(参考：https://stackoverflow.com/questions/40775054/capturing-sigint-using-keyboardinterrupt-exception-works-in-terminal-not-in-scr/40785230#40785230)
Docker for Mac: dockerd のデバッグログの見方

[Docker for Mac](https://docs.docker.com/docker-for-mac/) での dockerd のログの見方についてのメモです。Docker for Mac の 17.03.1-ce-mac12 で確認しています。公式に載っている方法ではないので今後使えなくなる可能性があります。自分はDocker レジストリとの間で問題があった際のトラブルシュートに使いました。

## ログレベルの設定

Dockerのアイコン -> Preferences -> Daemon -> Advanced で JSON 形式で設定を記述します。デバッグログの出力は下記のように `debug` を `true` に設定し Restart するだけです。

```
{
  "debug" : true
}
```

ログレベルを`debug`以外に設定したい場合は個別に`log-level`という値で設定します。その他の詳細な設定は公式ドキュメントの [Daemon CLI reference (dockerd)](https://docs.docker.com/engine/reference/commandline/dockerd/#options) をご覧ください。

<img src="https://qiita-image-store.s3.amazonaws.com/0/100377/16a1ae41-71c8-6fdc-5c3c-d58dd9f9d450.png" width="492">


## ログを見る

ログを見るには Docker for Mac の VM に入る必要があります。sshd が立ち上がっていないので、下記のように docker 経由で特権と nsenter を使ってホストにアクセスするのが簡単です。

```bash
$ docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
```

上記でホストのネームスペースのシェルにアクセスできます。dockerdのログは `/var/log/docker.log` に出力されています。

```bash
$ tail -f /var/log/docker.log
...
May 30 12:03:13 moby root: time="2017-05-30T12:03:13.597589319Z" level=debug msg="form data: {\"password\":\"*****\",\"serveraddress\":\"quay.io\",\"username\":\"tksm\"}"
May 30 12:03:13 moby root: time="2017-05-30T12:03:13.618582619Z" level=debug msg="hostDir: /etc/docker/certs.d/quay.io"
May 30 12:03:13 moby root: time="2017-05-30T12:03:13.621788419Z" level=debug msg="hostDir: /etc/docker/certs.d/quay.io"
May 30 12:03:13 moby root: time="2017-05-30T12:03:13.621826919Z" level=debug msg="attempting v2 login to registry endpoint https://quay.io/v2/"
May 30 12:03:15 moby root: time="2017-05-30T12:03:15.557921119Z" level=debug msg="Increasing token expiration to: 60 seconds"
```

### 補足: docker を使わない方法

dockerd 自体に問題がある場合、上記の方法でアクセスできないと場合もあると思われます。tty を screen でアタッチする方法でも VM のシェルにアクセスすることができます。screen のデフォルトでは `ctrl+a -> d` でデタッチできます。

```
$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
```
文書分類に影響している単語を確認する

# はじめに
機械学習を使ってみたけど、なんでこんな結果になったの？と思ったことはないでしょうか。手法によっては要因を読み解くことができます。本記事ではナイーブベイズを題材とし、文書分類における単語の「尤度」について紹介します。

<img width=500 src="https://qiita-image-store.s3.amazonaws.com/0/143285/746ce639-13fc-1513-17d9-1bd20909d673.png">

scikit-learnでの確認を**[githubに公開しています](https://github.com/kamujun/naive_bayse_anatomy/tree/master)**ので、合わせて御覧ください。

# ナイーブベイズにおける文書分類

## 文書分類とは
文書分類は予め与えられた訓練データ(文書)をもとに学習し、新たな文書を与えられたカテゴリに分類するタスクです。
文書を学習する際何を元に分類させるか、特徴を与える必要があります。今回は単語を特徴として与える手法について説明します。

## 文書の特徴としての尤度
文書の特徴に単語を扱う中でも、出現頻度とする手法があります。学習において、出現頻度は各カテゴリ・単語毎に尤度として表されます（厳密には異なりますが、確率のようなものと考えて下さい）。

<img width=500 src="https://qiita-image-store.s3.amazonaws.com/0/143285/f1014ca5-decf-8494-ff86-d596230df53f.png">

尤度がどのように分類に関わるのか、ナイーブベイズで用いられるベイズの定理を絡め、確認します。

## ベイズの定理
文書判別は文書が各カテゴリに属する確率によって求められます。確率が最も高いカテゴリを推定結果とするということです。確率はベイズの定理で算出され、その中で尤度が用いられています。

* ベイズの定理

```math
P(C|Fi) ＝ \frac{P(C)P(Fi|C)}{P(Fi)}\\
（C：カテゴリ、Fi：特徴集合 ≒ 単語の集合、つまり文書）
```

■各要素の説明
<dl>
<dt>$P(C|Fi)$</dt><dd>文書FiがカテゴリCに属する確率（事後確率）。</dd>
<dt>$P(C)$</dt><dd>カテゴリCが出現する確率(事前確率)。　
文書の内容を考慮せず、訓練データにおいて該当のカテゴリが出現した確率です。
    例：2000文書中ITカテゴリが1400文書あったなら、0.7
</dd>
<dt>$P(Fi|C)$</dt><dd>もしカテゴリCであるとした時、特徴集合Fiとして出現する確率です。(尤度)</dd>
<dt>$P(Fi)$</dt><dd>文書がFiとして出現する確率です。
    Cが関係していない通り、どのカテゴリの事後確率でも等しくなります。
　判別の場合はカテゴリ毎の事後確率を比較すればよいので、除外して計算されることが多いです。</dd>
</dl>

## 例題にて尤度計算の確認
以下条件時に、各カテゴリにおける各単語の尤度が学習結果から得られていたとします。

<img width=500 src="https://qiita-image-store.s3.amazonaws.com/0/143285/000ba1b1-6ea9-7b0e-86fe-3a1f41c1d8a4.png">


判別を行いたい文書の特徴集合が「林檎　発売　みかん」だった場合、各カテゴリの尤度P(Fi|C)は以下のように算出されます。P(Fi|C)は各尤度の積ですが、対数になっているので加算で求めることができます。

IT: $-0.3 + -0.3 + -0.8 = -1.4$
農業: $-0.4 + -0.4 + -0.3 = -1.1$

今回は尤度だけ見ると農業カテゴリと推定されることになります。
上記の通り、各単語の尤度が大きくなるほど事後確率も上がっている事が分かります。
例では「みかん」という単語の尤度に大きな差があり、判別に大きく影響していることが分かります。

事前確率にもよりますが、カテゴリ間で尤度の差が大きい単語ほどこの分類器では判別に影響すると言えます。


# 実データ確認
実データで尤度を確認してみます。映画レビューデータセットである「Movie Data Review」を用いて、ポジティブレビューとネガティブレビューを分類しました。学習後、尤度の差が大きかった単語上位10件は以下のようになりました。
「mulan」など固有名詞の他に、「worst」などの形容詞が表れています。

|単語|ネガティブ|ポジティブ|尤度差(絶対値)|
|:--:|:--:|:--:|:--:|
|mulan|-10.83863242|-9.33020901|1.50842341|
|truman|-10.42987203|-9.000858011|1.429014015|
|worst|-8.809010658|-10.1341868|1.325176141|
|shrek|-10.87230098|-9.598985497|1.273315479|
|seagal|-9.529290176|-10.78823673|1.258946555|
|godzilla|-9.264337631|-10.47190374|1.207566113|
|flynt|-10.81220934|-9.627421483|1.184787854|
|lebowski|-10.82237984|-9.664010458|1.158369383|
|waste|-9.193245829|-10.34277587|1.149530044|
|stupid|-8.96333841|-10.10326246|1.139924046|


## 考察・所感
人気な映画、俳優などの固有名詞が判別に影響しているのは妥当性があると感じます。また、肯定的・否定的な形容詞も判別に影響していることが分かりました。これらの単語が判別に影響している事は、納得出来るのではないかと思います。

# おわりに
単語の尤度を確認することで、どの単語が文書判別に影響しているか確認することが出来ました。いつでも理解できる内容ではないかもしれませんが、要因を確認することで求めている推定が行えているか確認することは大切だと感じました。

# 参考文献
ナイーブベイズの解説はこちらを参考させて頂きました。
→[ナイーブベイズを用いたテキスト分類](http://aidiary.hatenablog.com/entry/20100613/1276389337)
尤度と確率の違いについてはこちらが分かりやすかったです。
→[尤度とは何者なのか？](http://myenigma.hatenablog.com/entry/20120624/1340538748)
実装上出てきたスパースについてはこちらが分かりやすいです。
→[scipy.sparseの内部データ構造](http://hamukazu.com/2014/12/03/internal-data-structure-scipy-sparse/)
ターミナルでサクッとファイル監視して自動実行させるスクリプト

# 概要
ターミナル上でファイル更新をキャッチして、指定コマンドを実行してくれるスクリプト

## 参考
参考というかほぼこれの転載、プラス前後の手順
http://mizti.hatenablog.com/entry/2013/01/27/204343

# 前提
* シェルスクリプトが実行できる環境

# 手順

## １．シェルスクリプト作成

適当なディレクトリで

```
vi watch.sh
```

```watch.sh
#!/bin/sh
if [ $# -ne 2 ]; then
        echo "実行するには2個の引数が必要です。
        第一引数: 監視対象ファイル名
        第二引数: 監視対象ファイルが更新された際に実行されるコ>マンド
        例： ./autoexec.sh a.cpp 'g++ a.cpp && ./a.cpp'"
        exit 1
fi
echo "監視対象 $1"
echo "実行コマンド $2"
INTERVAL=1 #監視間隔, 秒で指定
last=`ls --full-time $1 | awk '{print $6"-"$7}'`
while true; do
        sleep $INTERVAL
        current=`ls --full-time $1 | awk '{print $6"-"$7}'`
        if [ $last != $current ] ; then
                echo ""
                echo "updated: $current"
                last=$current
                eval $2
        fi
done
```

シェルスクリプト実行用の権限付与(いらないかも？)

```
chmod u+x watch.sh
```

## ２．完成
実行してみる

```
./watch.sh test.php "php test.php"
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/61dea3c0-d776-4f47-d66b-3414a67f9953.png)

優秀すぎる、、、ありがとう、、、
http://mizti.hatenablog.com/entry/2013/01/27/204343
のかた、、、

継続的に使うというよりは、突然監視のニーズがあったときに便利 :raised_hands:
DBのインデックスと複合インデックス

#Q:インデックスとは?
データの並び順序のこと
初期状態では主キーに対してインデックスが割り当てられている。

#Q:インデックスをつける意味は?
データ件数が多いテーブルの検索を早くすることができる。

例えば下記の社員テーブルに対し、社員コードにインデックスを付けた場合

社員テーブル(インデックス:無し)

|社員コード|所属コード|社員名|
|:-:|:-:|:-:|
|1004|101|テスト太郎A|
|1002|102|テスト太郎B|
|1003|101|テスト太郎C|
|1001|101|テスト太郎D|
|1005|102|テスト太郎E|

社員テーブル(インデックス：社員コード)

|社員コード|所属コード|社員名|
|:-:|:-:|:-:|
|1001|101|テスト太郎D|
|1002|102|テスト太郎B|
|1003|101|テスト太郎C|
|1004|101|テスト太郎A|
|1005|102|テスト太郎E|

この並び順をDBが保持する。
※「並び順」を保持するのであり、この並び替えを行ったテーブルを保持するわけでない

そして、下記のようなSQLを実行したとき、

```sql
select * from 社員テーブル where 社員コード = 1003
```

・「社員テーブル(インデックス:無し)」のとき
データの並び順が決まっていないため、全件検索し該当レコードを探す
・「社員テーブル(インデックス：社員コード)」のとき
社員コード列が昇順に並んでいるので、社員コード列に対して二分探索のようなアルゴリズムでの検索を行い該当レコードを探す
	
インデックスは検索を効率よく行う仕組みのため、テーブルの件数が多いほどインデックスの有無による速度差は大きくなる。
逆に、テーブル件数が少ない場合はそこまで差は出ない。

#Q:じゃあ複合インデックスって?
複数の並び替え条件でインデックスを作ること。

例えば、所属コードと社員コードでインデックスを作った場合

社員テーブル(インデックス：所属コード,社員コード)

|社員コード|所属コード|社員名|
|:-:|:-:|:-:|
|1001|101|テスト太郎D|
|1003|101|テスト太郎C|
|1004|101|テスト太郎A|
|1002|102|テスト太郎B|
|1005|102|テスト太郎E|

このような並び順を保持する。

注意点として、複合インデックスは２つ目以降のインデックスのみで使用できない
上記のテーブルは所属で絞り込んだならば社員コードはソートされているが、社員コード単体で見た場合はソートされていない。そのため、社員コードのみを検索条件としたときは全件検索が実行される。

例えば下記のようなSQLを実行したとき、

```sql
select * from 社員テーブル where 社員コード = 1003 
/*インデックス：所属コード,社員コード*/
```
データの並び順が社員コード順になっていないので、全件検索し該当レコードを探す動きになる

#Q:主キーインデックスと普通のインデックスの違いは？
インデックスという視点では違いはない。主キーはDBが自動でインデックスをつけ削除不可である。したがって何もインデックスを作成しなくても主キーのインデックスは必ず生成される。

**※主キー順は非常に重要である。**
上記の社員テーブルにおいて社員コードのみで絞り込む要件しかない場合、
１．社員テーブル(主キー順：所属コード,社員コード)
２．社員テーブル(主キー順：社員コード,所属コード)

『１．』の主キーでは主キーインデックスが所属コード、社員コードの順となるため新しく社員コードのみのインデックスを作成する必要がある。
しかし『２．』の主キーなら主キーインデックスが社員順となるため新しくインデックスを作成する必要はない。
見た目の区分に合わせて主キーを作りたくなるが、実際のデータがどのように検索されるかで主キーを作らないと無駄なインデックスが増えてしまう。


#Q:インデックスは複数作れるの?
できる。このときは内部的に複数の並び順を持っている。
例えば上記の
・社員テーブル(インデックス：社員コード)
・社員テーブル(インデックス：所属コード,社員コード)
をそれぞれ保持することもできる

#Q:ならインデックスは使いそうなものを片っ端から作った方がいいのか？
むやみにインデックスを作ると下記の問題が起こる。そのためインデックスは必要最小限であることが望ましい。
・検索時に間違った(想定とは違う)インデックスが使用される確率が上がる
インデックスはオプティマイザが判定して使用する。
多数のインデックスがあると想定とは別のインデックスを使い結果的に速度低下につながることがある。
・登録時に低速になる。
データ登録を行えば当然並び順に影響を与えるためインデックスの再作成が行われる。大量のインデックスがあればすべてのインデックスを再作成するため登録に時間がかかるようになる。
特に大量のデータを一括登録するテーブルの場合はインデックスを張るのは慎重にすること。

#Q：特定のインデックスを強制的に使わせることはできないの？
SQLのヒント句を用いれば可能。ただし基本的にオプティマイザが最適なインデックスを使う。
下記のような時以外は使わないのが基本となる。
・テーブルのレコード件数の増減が激しく、統計情報から正しいインデックスを推察できない。
　例：登録レコード数が多く、１日の終わりにバッチ処理でテーブルの中身をクリアする場合など
・SQLの構造がおかしく正しいインデックスを使用できないが、不具合のリスク等を考えSQLの修正は行いたくない。
・統計情報の更新を行いたいが、DBを触ることが許されずSQLだけで何とかしなければならない。

#追記：インデックスを正しく使うにはテーブルの統計情報の定期的なリフレッシュが必要
インデックスが使われるかどうかはDBのオプティマイザが判断しており、
さらにオプティマイザがインデックスを使用するかどうかの判断材料としてテーブルの統計情報を使用する。

- オプティマイザ：SQLから実際のDBデータ取得処理を生成する機能。プログラムならコンパイルが近い。
- 統計情報：テーブルにどんなデータがどれぐらい入っているかの情報のこと

この統計情報は一定のタイミングで更新されるが、統計情報の自動更新を切っていたり(更新はそれなりに重いため)、インデックス追加直後などは更新されていない。
よって統計情報を更新しないと実際のデータの状態と統計情報の状態にずれが発生し、その結果SQL実行時に正しいインデックスが使用されないことがある。
Docker for Mac で遅いファイルマウントを何とかする

## 前提
+ docker-compose を使用していること。   
※composeを使用していなくてもdockerコマンドでsyncできます・・・  
+ 開発環境のみで実施。  

## 何ができる？
ファイル同期ができる。  
- 片方向(rsync)
[ホスト]   -> [コンテナ]  
- 双方向(unison)
[ホスト] <-> [コンテナ]  

## なぜやるの？
開発環境でDockerを使用しているが、ソースコードをマウントさせているため、
パフォーマンスが著しく悪い。
※特にRailsプロジェクト

[参考]
[File access in mounted volumes extremely slow](https://github.com/docker/for-mac/issues/77)

なのでコンテナ内に直接ソースコードを同期させて置きたい。

## どうやるの？

### Step1
必要なパッケージのインストール
```
$ gem install docker-sync
$ brew install fswatch
$ brew install unison
```
### Step2
docker-sync.ymlを作る

[unisonを使用する場合]

```
version: '2'

syncs:
  hoge-sync:
    src: '/Users/www/'
```
同期されるホストの元ファイルディレクトリを指定してあげる。
※unisonがデフォルトなので明示的指定はしていない。

[rsyncを使用する場合]

```
version: '2'

syncs:
  hoge-sync:
    src: '/Users/www/'
    sync_host_port: 10871
    sync_host_ip: '127.0.0.1'
    sync_strategy: 'rsync'
    sync_userid: '501'
    watch_strategy: 'fswatch'
```
### Step3
〜 さようならマウント 〜
docker-compose.ymlの記述をちょっと変えてあげるだけ。
```
    volumes:
      - /Users/www:/var/www
↓
    volumes:
      - "hoge-sync:/var/www:rw"
```
末尾に以下を追加
```
volumes:
 hoge-sync:
    external: true
```


### Step4
これで起動する！
どちらも同じなのでお好みで・・・

[Pattern1]
```
$ docker-sync start
$ docker-compose up -d
```
[Pattern2]
```
$ docker-sync-stack start
```


## 番外編
docker-composeを使用していなくてもdocker-syncだけで使えることに気づいた。

「docker run -v /User/www:/var/www」などで実行している場合、
「docker run -v hoge-sync:/var/www:rw」とするといけました。

## 追記
docker-sync.ymlに転送先のユーザ指定をするとさらに捗るかも！
```
    sync_userid: '1234'
```
Laravel5.7: Laravel Debugbarを使う

Laravelでの開発にはとても便利なので、追加することをお勧めします。

# 親記事
[Laravel 5.7で基本的なCRUDを作る - Qiita](https://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# Debugbarをインストールする
:link: [barryvdh/laravel-debugbar: Laravel Debugbar (Integrates PHP Debug Bar)](https://github.com/barryvdh/laravel-debugbar)
:link: [開発に欠かせない Laravel Debugbar の導入 - Larapet](https://larapet.hinaloe.net/2017/03/07/%E9%96%8B%E7%99%BA%E3%81%AB%E6%AC%A0%E3%81%8B%E3%81%9B%E3%81%AA%E3%81%84-laravel-debugbar-%E3%81%AE%E5%B0%8E%E5%85%A5/)

```txt:PowerShell
# 本来は --dev を付けますが、今回は本番環境でも使いたいので下記のように。
# ただし、パスワードも丸見えになるので注意!
> composer require barryvdh/laravel-debugbar
```

Laravel5.5からはAuto Discoveryの機能があるので、Composerでrequireするだけで使えるようになります。

### (補足) Auto Discoveryとは
本来なら、`app.php`でサービスプロバイダとファサードに登録する作業が必要です。

```diff:config/app.php
    'providers' => [
+       Barryvdh\Debugbar\ServiceProvider::class,
    ],

    'aliases' => [
+       'Debugbar' => Barryvdh\Debugbar\Facade::class,
    ]
```

しかしLaravel5.5以降は、このデバッグバーのようなパッケージの開発者が、そのパッケージの`composer.json`の`extra`セクションで記述しておいてくれれば、我々利用者が上のような作業をする手間が省けます。
:link: readouble.com: [パッケージディスカバリー](https://readouble.com/laravel/5.7/ja/packages.html#package-discovery)
:link: [[Laravel5.5]Package Auto Discoveryを理解する](https://qiita.com/k-kurikuri/items/4314ecaa126cad9722ee)

そして、このデバッグバーの開発者さんは、きちんと対応してくれています。
:link: [デバッグバーのcomposer.json(35行目)](https://github.com/barryvdh/laravel-debugbar/blob/master/composer.json#L35)


# Debugbarの設定を変更する
デバッグバーを画面に表示するかどうかは環境変数`APP_DEBUG`の値(true/false)で決まります。
しかし、下記のようにDebugbarの設定ファイルを生成すれば`APP_DEBUG`に左右されずに設定できます。

```text:PowerShell
# デバッグバーの設定ファイル(config/debugbar.php)を生成する
> php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
```

環境設定ファイルにDebugbarの設定を記述します。

```bash:.env
DEBUGBAR_ENABLED=null  # デフォルト。APP_DEBUGに応じて決まる
DEBUGBAR_ENABLED=true  # 必ず有効
DEBUGBAR_ENABLED=false # 必ず無効
```

今回のアプリは練習用であり、本番環境でもデバッグバーを表示させます。
本番の環境設定は下記のようになる予定です。

```bash:本番の環境設定
APP_ENV=production
APP_DEBUG=false # 一般的な本番環境と同じく、デバッグ表示は無効
DEBUGBAR_ENABLED=true # デバッグバーは有効
```

なお、ローカル環境でも上のようにするのはやりすぎです。
デバッグバーは万能ではなく、ソースコードにミスがあってアプリ自体が動かない場合はデバッグバーも表示されません。
そんな時は`APP_DEBUG=true`によるデバッグ表示が役に立ちます。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/27816/b959fd5c-3ff0-235d-224f-37afedd485a1.png)


# Debugbarを使う
:link: [Usage](https://github.com/barryvdh/laravel-debugbar#usage)

たとえばデータベースから取得した記事一覧を確認したい時、Postコントローラで下記のように記述すれば、`var_dump()`よりは分かりやすく表示できます。

```diff:app/Http/Controllers/PostController.php
     public function index()
     {
         $posts = Post::latest()->get();
+        \Debugbar::info($posts);
         return view('posts.index', ['posts' => $posts]);
     }
```

![001.png](https://qiita-image-store.s3.amazonaws.com/0/27816/d187c4f8-3535-b1ad-1202-87b21ff878ab.png)

また、`Queries`でSQLを確認できます。
記事一覧を新しい順に取得する時、<code>SELECT * FROM \`posts\` ORDER BY \`created_at\` DESC</code>というSQL文が実行されているようです。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/27816/9450d5f1-b8dd-ae69-2883-e0ff0c93f899.png)
Navisensサンプル動かしてみる

# 概要
空間認識としてカメラではなくbluetoothや内部センサーを使うNavisensというものがある
http://www.navisens.com/
>No WiFi. No GPS. No Bluetooth beacons. No environment fingerprinting or calibration.

とも書いてあるので内部加速度センサーだけでもなんとかなるのかな？

必要なドキュメントをまとめる、できれば動かしてみる

# 詳細
## 各種ドキュメント
### 公式
http://www.navisens.com/
### 開発ドキュメント
http://docs.navisens.com/
### sample(github)
https://github.com/navisens

## sampleをダウンロードしてきてビルド
- DeveloperKeyが必要らしい  
https://github.com/navisens/Android-SDK/blob/master/Example/app/src/main/java/com/navisens/example/MotionDnaClient.java

```java
    public MotionDnaClient() {

    }

    private static final String DEVELOPER_KEY = "your developer key";
```
- どこに書いてあるかわからないからとりあえずなんかSDK Formがあったので申請中・・・  
http://www.navisens.com/#  
申請したらきた、上記DEVELOPER_KEYに展開されたKEYを入れてビルドしたら動いた
<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">navsensテスト <a href="https://t.co/K9cg1YfzLO">pic.twitter.com/K9cg1YfzLO</a></p>&mdash; うさがに@AR㌠VR (@usaganikki) <a href="https://twitter.com/usaganikki/status/882167953956806656">2017年7月4日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
動き回るとwalkingの数字が変化したので歩いたイベントは取れている様子
ただし角度の変更イベントはあまりこなかったので変更があまり取れていない様子？？