OmniAICreator/Qiita-1.07M huggingface dataset:
CloudFrontでモバイル端末を判別する

サーバー側で `User-Agent` を見て端末を判別するとキャッシュ効率が落ちるので、代わりに下記の4つのHTTPヘッダをWhitelistに入れると、判別済みの情報が送られてきます。

- CloudFront-Is-Desktop-Viewer
- CloudFront-Is-Mobile-Viewer
- CloudFront-Is-SmartTV-Viewer
- CloudFront-Is-Tablet-Viewer

これらの動作を調べてみました。

## iOSスマートフォン (iPhone)

`User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13F69 Safari/601.1`

|Desktop|Mobile|SmartTV|Tablet|
|:-:|:-:|:-:|:-:|
|false|true|false|false|

## iOSタブレット (iPad)

`User-Agent: Mozilla/5.0 (iPad; CPU OS 9_3_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13F69 Safari/601.1`

|Desktop|Mobile|SmartTV|Tablet|
|:-:|:-:|:-:|:-:|
|false|true|false|true|

MobileとTablet両方trueになる

## Mac (Firefox)

`User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0`

|Desktop|Mobile|SmartTV|Tablet|
|:-:|:-:|:-:|:-:|
|true|false|false|false|

## Androidスマートフォン (Nexus 5X)

`User-Agent: Mozilla/5.0 (Linux; Android 7.1.1; Nexus 5X Build/N4F26I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36`

|Desktop|Mobile|SmartTV|Tablet|
|:-:|:-:|:-:|:-:|
|false|true|false|false|

## Androidタブレット (Nexus 7)

`User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MMB29O) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Safari/537.36`

|Desktop|Mobile|SmartTV|Tablet|
|:-:|:-:|:-:|:-:|
|false|true|false|true|

ちゃんとスマートフォンとタブレット判別できてる！

## Fire TV

`User-Agent: Mozilla/5.0 (Linux; U; Android 4.2.2; en-us; AFTB Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`

|Desktop|Mobile|SmartTV|Tablet|
|:-:|:-:|:-:|:-:|
|false|false|true|false|

## 検証に用いたソースコード

PHPで殴り書きしました。

```php
<?php
echo($_SERVER['HTTP_CLOUDFRONT_IS_DESKTOP_VIEWER']);
echo($_SERVER['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER']);
echo($_SERVER['HTTP_CLOUDFRONT_IS_SMARTTV_VIEWER']);
echo($_SERVER['HTTP_CLOUDFRONT_IS_TABLET_VIEWER']);
```

## 参考文献

- [リクエストヘッダーに基づいてオブジェクトをキャッシュするように CloudFront を設定する - Amazon CloudFront](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device)
- [[新機能] Amazon CloudFrontでモバイル端末を判定できるようになりました ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/cloudfront-mobile-device-detection/)
JSの非同期処理メモ

ES7 async/awaitはES6 Promiseのシンタックスシュガーなのだし、JavaScriptでの非同期処理のデファクトスタンダードはPromiseと言っていいだろう。

## Promiseについて

Promiseについては「[JavaScript Promiseの本](http://azu.github.io/promises-book/)」を読むべし。
注意事項は「[Promiseアンチパターン](http://p-baleine.hatenablog.com/entry/2014/03/14/085536)」にまとまっている。

### 非同期処理の例外対処

アンチパターンの1つは、非同期処理の例外はtry-catchで補足出来ないことに起因する。
参考：[プログラマが想定していなかった例外でプロセスが落ちる問題にPromiseで対応する](http://qiita.com/mookjp/items/43e57c707d8830929b22)

Promise内でthrowされるErrorはpromise.catch()で処理できるため、Promise化した方がエラー処理をまとめやすくなるといえる。

## ES7 async/await

結局のところES7 async/awaitは、Promise処理の記述を省略して書けるシンタックスシュガーなので、例外処理についてはPromiseと同様に扱う必要がある。

参考：[Promiseとasync-awaitの例外処理を完全に理解しよう](http://qiita.com/gaogao_9/items/40babdf63c73a491acbb)

これだとasync/awaitの利点は簡易的に書けることしかなくて、あまりメリットを感じない。
中身がPromiseなことに気を付けないといけないとか、関連するfunctionにasyncが付いて回ったりして、記述の見た目に反して逆にややこしさが増大していないだろうか。
ここは最初からPromiseで記述した方が、見た目と同じになり判りやすいように思える。

2017/06/12追記
async/awaitにはPromiseよりメリットがあるよ、という記事が出た。
参考：[JavaScriptのasync/awaitがPromiseよりもっと良い](http://qiita.com/Anders/items/dfcb48d8b27ceaffb443)
確かにメリットがあるので、「全員このasync/awaitを完全に理解して書く」がベストだ。


## Node.js

Node.jsでは、非同期処理のコールバックfunctionはエラーと戻り値の2つの引数を取るのが一般的なので、この辺Promiseと一致しなくてまごつく。

Node.js v8.0.0では[util.promisify](https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original)というユーティリティー関数が追加されている。
このpromisifyは、Node.jsで一般的なコールバックを取る非同期処理なfunctionをPromiseオブジェクトに換えてくれる。

積極的にPromiseを使う場合はこれでPromise化していきたい。

## げんじつ

あれっ？ [Promise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)って機能少なくない？
Promise.allとPromise.raceだけでがんばりたくないので、`npm install bluebird` しよう。
参考：[bluebird.js cheetsheet](http://ricostacruz.com/cheatsheets/bluebird.html)

「[node.js v8/v7 のPromise とBluebird Promise を雑にベンチ比較した](http://qiita.com/yutaszk/items/5e2f9d22434fd2160038)」によるとBluebird Promiseの方が高速なことだし。
CircleCIは複数の JUnit 形式の XML ファイルをマージしてくれる

結論はタイトルの通りです。
~~2.0 は試してないのでわからないですが、そっちでも同様かもしれません。~~
2.0でも同様にマージされます！

CircleCI 1.0では JUnit 形式の XML ファイルを `$CIRCLE_TEST_REPORTS` のディレクトリ内に出力することで、2.0では `store_test_results` ステップを使い XML ファイルの入っているディレクトリを CircleCI 側に保存すると、テスト結果をいい感じに表示してくれます。

こういうやつ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/208/f22285d7-3240-6bfd-b580-b668643d04f9.png)

時には一度に複数のテストフレームワークを実行したいこともあると思いますが、そういう場合どうすれば良いのか調べて見ました。

[ドキュメント](https://circleci.com/docs/1.0/test-metadata/#merging-test-suites-together)によるとこのように書かれています。

>If you have multiple JUnit test reports from running more than one test suite or runner, you can merge them together using the third-party NodeJS CLI tool, [junit-merge](https://www.npmjs.com/package/junit-merge).

>This tool can combine the reports into a single file that our test summary system can parse and give you correct test totals.

もしや junit-merge なるコマンドを使って手動でマージしないといけない? と思いましたが、試して見たところしなくても問題なさそうでした。

こんな感じの `circle.yml` を用意します。

```yml
test:
  override:
    - bundle exec rspec --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec_1.xml spec/test_1_spec.rb
    - bundle exec rspec --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec_2.xml spec/test_2_spec.rb
```

これは全然実用的な例でないですが、RSpec を 1 ファイルごとに 1 回ずつで合計 2 回実行し、それぞれ別のファイル名で JUnit 形式の XML を出力します。

すると CircleCI 上では見事マージした結果が出力されていました。 (上記のスクショの通り)

めでたしめでたし
Gulpの導入〜初期設定まで


#環境構築（Mac）
## Node.jsのインストール
gulp を使うためには、 Node.js がインストールされている必要があるため、確認します。

`$ node -v 
`
バージョンが表示されなければ、[Homebrew](
http://brew.sh/index_ja.html)（Mac用パッケージマネージャー）などでインストールします。
既にインストール済みの場合はHomebrewをアップデートしてから、node.jsをインストールします。

```
$ brew update
$ brew install node
```
**npm（node.jsのパッケージ管理ツール)は、homebrewでNode.jsをインストールすると一緒にインストールされます。**

## グローバルにgulpをインストール
グローバルインストールすると「gulp」というコマンドが使えるようになります。

`$ sudo npm install gulp -g
`
## package.jsonを作成
適当な場所にプロジェクトのディレクリを作成し移動します。
そこにnpm initを実行してpackage.jsonというnode.js用のプロジェクトファイルを作成します。
色々と聞かれますが、とりあえずYESで進めてください。

```
$ npm init

name: （20170608_test)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author: "kawachi"
license: "ISC"
```
npmの最新v5にアップデートした場合は、package-lock.jsonというファイルが作成されるようです。
[npm v5 がリリースされた - from scratch](http://yosuke-furukawa.hatenablog.com/entry/2017/05/30/090602)
## ローカル（プロジェクト）にgulpをインストール
`$ npm install --save-dev gulp
`
gulpがグローバルとローカル両方に入っているか確認しておきます。

```
$ gulp -v
CLI version 1.3.0
Local version 3.9.1
```
## 必要なパッケージをインストール
下記のコマンドで必要なパッケージをインストールしていきます。
`--save-dev`を付けるとpackage.jsonにインストールしたパッケージを記述してくれます。

`$ npm install gulp-sass --save-dev
`
下記、とりあえず私が最初にインストールしたパッケージです。

- [gulp-sass](https://www.npmjs.com/package/gulp-sass)（scssをcssに変換するパッケージ）
[gulp-scss](https://www.npmjs.com/package/gulp-scss)との違いがよく分かりませんが、こちらの方がメジャーなようです。

- [gulp-autoprefixer](https://www.npmjs.com/package/gulp-autoprefixer) （ブラウザ固有のプレフィックスを自動で付与する）
- [gulp-plumber](https://www.npmjs.com/package/gulp-plumber)（エラーが起こってもタスクが停止しないようにする）
- [browser-sync](https://www.npmjs.com/package/browser-sync)（ファイル保存時にブラウザをリロード）
- [gulp-csscomb](https://www.npmjs.com/package/gulp-csscomb)（プロパティ記述の順序を任意で設定）
.csscomb.jsonファイルを作成して記述順序などを設定する必要があります。私は[ジェネレーター](http://csscomb.com/config)を使って作成しました。
- [gulp-notify](https://www.npmjs.com/package/gulp-notify)（エラーが出た時にデスクトップに通知してくれる）
- [connect-ssi](https://www.npmjs.com/package/connect-ssi)（includeを読み込ませるのに必要のよう）
このパッケージは設定に苦労したので、設定方法を後述したいと思う。。
## gulpfile.jsファイルの作成
インストールしたパッケージを使えるように、プロジェクトディレクトリ内にgulpfile.jsファイルを新規作成します。
gulpfile.jsの設定内容は、ややこしいため割愛しますが、ジェネレーターを使うと楽です。
[gulp generator](http://steelydylan.github.io/gulp-generator/)
## gulpコマンドで実行する
`$ gulp
`
問題なく設定が出来ていれば、Webサーバーが起動し、`http://localhost:3000`に表示されます。
###参考サイト
[@wakamshaさんのAltJS,AltCSS課題をGulp, SCSS, TypeScript でやってみた ｜ Developers.IO](http://dev.classmethod.jp/client-side/javascript/yamada-san-altjs-examples/)
[ざっくりGulp.js入門（Mac向け） - Qiita](http://qiita.com/kazukichi/items/884a1379eea5918689ed)
基本的な正規表現の使い方

![正規表現.png](https://qiita-image-store.s3.amazonaws.com/0/160563/b0a67d93-4a62-0aa5-5e44-ac98b6e2911d.png)


#正規表現とは
複数の文字列を少なくまとめることができる記述方法。

```html:qiita.rb
<!-- 普通の書き方 -->
「Team」と「Template」

<!-- 正規表現 -->
「Te(am|mplate)」
```


#正規表現の書き方

##どれか1文字
|書き方|例|意味|
|:---|:---|:---|
|[文字列]|[123]|123のいずれか1文字|
|[^文字列]|[^123]|123以外のいずれか1文字|
|[文字列-文字列]|[6-9]|6〜9のいずれか1文字|
|\d|\d|0〜9のいずれか1文字|
|\w|\w|英数字1文字|
|\s|\s|空白 タブ|

##複数文字
|書き方|例|意味|
|:---|:---|:---|
|^文字列|^start|startから始まる|
|文字列$|end$|endで終わる|
|文字列&#124;文字列|start&#124;end|startもしくはend|
|?!文字列|?!stop|stopは含まない|

##パターン一致
|書き方|例|意味|
|:---|:---|:---|
|?|i?phone|iPhoneもしくはPhone|
|*|.*|0文字以上の任意の文字列|
|+|.+|1文字以上の任意の文字列|
|\{数字}|w\{3}|www(直前の文字列が3つ)|
|\{数字,}|Go\{2,}gle|Google,Gooogle(直前の文字列が2つ以上)|
|\{数字,数字}|Gre\{3,5}n|Greeen,Greeeen,Greeeeen(直前の文字列が3つ以上5つ以下)|
|+?|k+?|k,kk(直前の文字が1文字以上)|


#サンプル
##完全一致
前方一致と後方一致を両方とも使用する

```text:qiita.rb
^exaple\.com$
```

>一致結果
>example.com

#サブドメインのみに絞る
一文字以上の任意の文字列に一致する「.+」を利用し前方に何が来ても一致させる。

```text:qiita.rb
.+example\.com
```
> 一致結果例
> test.example.com
> sample.example.com


#正規表現のチェックツール
* [正規表現チェッカー](http://okumocchi.jp/php/re.php)

入力した正規表現が、意図した文字列と一致するかチェックができるツール

![正規表現サンプル.png](https://qiita-image-store.s3.amazonaws.com/0/160563/02af8916-7a41-8085-278f-275012a55e18.png)

```text:qiita.rb
<使用方法>
・正規表現の欄に正規表現を記載 
・文字列の欄に正規表現の結果を返すであろう文字列を入れる
・「チェック」ボタンを押す
・結果に「一致しました」が返って来れば、入力した正規表現は正しい
```


#参考
* [正規表現で文字列を含まない、否定の記述](http://uxmilk.jp/50674)
capistranoでcssが読み込まれない

capistranoで苦しみがちなので、解決するためのメモとして。



# capistranoで自動デプロイしてもエラー

```rails:環境
Rails5
AWS EC2
unicorn
nginx
```



最初はアプリにアクセスしても、HTMLのコードすら、読み込まれてなかった。
いろいろいじってみたが、最終的には、サーバー側のアプリを削除して、gitからcloneしなおしたら、本番環境でHTMLのコードは読み込まれるようになった。（バリバリ稼働してるアプリだったらアウトな手段な気がする。。）

しかし、CSSやjsなどのassetsは依然読み込まれず。
unicornで動いているプロセスをkillし、/var/www/app_nameに移動し、
``$ RAILS_ENV=production bundle exec rake assets:precompile assets:clean``
で、手動でassetsをぶち込んで、
ローカルで、
`$ bundle exec cap production deploy`
したら、assetsが読み込めるようになった。
Herokuでexpressを使うときに困ったこと（環境変数、ビルド、ポート）

# Herokuでexpressを使うときに困ったこと（環境変数、ビルド、ポート） 
Herokuにexpress（node）で作ったアプリを動かそうとしたら、立て続けに困ったことが起こったのを調べたことをメモしました。
何度もPRを送るのに気が引けましたが、なんとか乗り越えました。

* 環境変数を設定したい
* ビルドされない
* ビルドが通らない
* アプリが起動しない

「ローカルの開発環境では問題なく動いているのに・・・」というのがモチベーションを打ち砕くのですが、あと少しです。

## 環境変数を設定したい
やり方は2通りありました。Heroku Cliで設定する方法と管理画面から設定する方法。どちらでもいいので、2通り書きます。

### Heroku Cliで設定する
まず、Heroku Cliをインストールする必要があります。
Homebrew がインストールされているなら、以下のコマンドでサクっと入ります。

```bash
$ brew install heroku
$ heroku
 ▸    Add apps to this dashboard by favoriting them with heroku apps:favorites:add
See all add-ons with heroku addons
See all apps with heroku apps --all

See other CLI commands with heroku help
```

あとは設定するだけです。

```bash
$ heroku config:set KEY=VALUE
```

### 管理画面から設定する
ログイン後、Setting画面に行くと `Config Variables` というメニューがあります。 `Reveal Config Vars` というボタンをクリックすると `Config Vars` が表示されますので、そこに環境変数をaddしてください。

## ビルドされない
設定をしなければ、ビルドはされません。初期状態では `npm install` と `npm start` だけはやってくれるようでした。
なので、 package.jsonのscriptsにpostinstallを追加してインストール後にビルドを実行するようにします。
以下のような感じです。

```json:package.json
{
  "scripts": {
    "build": "webpack",
    "start": "node app.js",
    "postinstall": "npm run build"
  }
}
```

これはnpmの機能なのでローカルの開発環境でも `npm install` をしたあとにpostinstallが動くようになっているので、確認してみてください。

### 環境変数の受け取り方
環境変数をコードで受け取るには、 `process.env` から受け取ります。環境変数に `KEY=VALUE` を設定していると以下のようになります。

```bash
$ node
> process.env.KEY
'VALUE'
> 
```


### ローカルの開発環境でも確認したい
ローカルで動くか確認するには少し面倒ですが、 node-foremanを使えば簡単です。

```bash
$ npm install -D foreman
```

次に `.env` ファイルに環境変数を書きます。

```
KEY1=VALUE1
KEY2=VALUE2
KEY3=VALUE3
```

あとは環境変数を読んでからnpmを実行するようにするだけです。

```bash
$ node_modules/foreman/nf.js npm start
```

## ビルドが通らない
ローカルでビルドコマンドを叩いても問題ないのだから、大丈夫だと油断しているとハマります。ハマりました。
Herokuはproduction環境なので、package.jsonのdependecies、devDependeciesが正しく登録されていないと、ライブラリが足りずにビルドされません。
ローカルの開発環境で確認するには、npmの設定を変える必要があります。
以下のコマンドで変更して、ビルドをしてみてください。

```bash
$ npm config get production
false
$ npm config set production true
$ npm config get production
true
```

ちなみに、package.jsonの中を入れ替えたりしていると汚くなってしまいますが、 `fixpack` を使うと整形してくれるので便利です！
https://github.com/henrikjoreteg/fixpack
使い方は簡単です。npmでグローバルにインストールして、package.jsonのあるディレクトリでコマンドを叩くだけです。

```bash
$ npm install -g fixpack
$ fixpack
```

設定ファイルで自分好みに整形することもできますので、こういうのが気になる人は使ってみてはどうでしょうか。

## アプリが起動しない
ビルドも通ったのに、アプリはエラー画面のままでした。管理画面を見ても何も変化はないのです。エラー画面にログを見なさいと書いてあるので見てみましょう。

```bash
$ heroku logs --app my-app
```
my-appのところは自分のアプリ名を入れてください。そうすると、ログがバーっと出てきます。

```bash
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
```

こんなログが出てたら、ポートがあっていない可能性があります。
Heroku側から動的に生成されたポートで動くようにしていなければ、いけないそうです。こんな感じです。

```javascript:server.js
import * as express from 'express'
const app = express ()

app.set ('port', (process.env.PORT || 8080))
app.listen (app.get ('port'), (error: any) => {
    console.info (`PORT: ${app.get ('port')}`)
})
```

これでようやく動くようになりました！
Rails5アプリにBootstrap4を導入

#概要
Rails5でというかBootstrap4をインストールして試したことがなかったので試してみる。Rails5の環境です。

#手順

下記のリンクにしたがって進めて行く。
[Bootstrap Ruby Gem](https://github.com/twbs/bootstrap-rubygem)

```
gem 'bootstrap', git: 'https://github.com/twbs/bootstrap-rubygem'
```

`app/assets/stylesheets/application.scss`

```
// Custom bootstrap variables must be set or imported *before* bootstrap.
@import "bootstrap";
```

Rails5.1では`jquery-rails`が必要なようなのでGemを追加して、bundle installする。

```
gem 'jquery-rails'
```

```
$ bundle install
```

`application.js`に下記の3つを追加する。

```
//= require jquery3
//= require popper
//= require bootstrap-sprockets
```

これで完了。

ついでに表示がイマイチなウェブページを直してみる。現状はこんな感じ。

![Screen Shot 2017-06-08 at 18.07.27.png](https://qiita-image-store.s3.amazonaws.com/0/167850/73fa18c9-b970-eee2-4dea-2fadb130913f.png)

いじっていくコード。

```
<% @records.each do |r| %>
  <%if r.user_id == current_user.id %>
    <table>
      <tr>
        <th>日付</th>
        <th>ユーザーID</th>
        <th>出勤時間</th>
        <th>退社時間</th>
      </tr>
      <tr>
        <td><%= r.timein.strftime('%m月%d日') %></td>
        <td><%= r.user_id %></td>
        <td><% if r.timein.present? %><%= r.timein.strftime('%H:%M:%S') %><% else %>まだ<% end %></td>
        <td><% if r.timeout.present? %><%= r.timeout.strftime('%H:%M:%S') %><% else %>まだ<% end %></td>
      </tr>
    </table>
  <% end %>
<% end %>
```

試しにtableにクラスをつけてみる。特に変化がない。

```
<table class="table table-striped">
```

![Screen Shot 2017-06-08 at 18.20.07.png](https://qiita-image-store.s3.amazonaws.com/0/167850/abf79143-ed76-a485-e3b1-dd197bac3a16.png)

どうやら、assetsでbootstrapが呼ばれていない様子。

原因はapplication.scssファイル。指示通りにファイルを消さないでいたことが原因。


```
#application.scss　変更前

/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self

 * // Custom bootstrap variables must be set or imported **before* bootstrap.
 *@import "bootstrap";
 */

```

```
#application.scss　変更後

// Custom bootstrap variables must be set or imported *before* bootstrap.
@import "bootstrap";
```

変更後、ブラウザで確認してみると確かにbootstrapが反映されている！

![Screen Shot 2017-06-08 at 18.28.19.png](https://qiita-image-store.s3.amazonaws.com/0/167850/6f9e4b81-398e-3c74-09d2-f8efd3fc1cf8.png)

今日はここまで。

#参考資料
[Bootstrap Ruby Gem](https://github.com/twbs/bootstrap-rubygem)
[Bootstrap Download](https://v4-alpha.getbootstrap.com/getting-started/download/#package-managers)
Visual Studio / WPF > Error: CS0747 初期化子のメンバー宣言子が無効です。 > 引数の指定間違い

```txt:動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
```

http://gushwell.ldblog.jp/archives/52334146.html
を元に学習中。

途中まで写経していてひっかかった。

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//
using System.Collections.ObjectModel;

namespace _170608_t1820_treeview
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
    public class Category : ObservableCollection<Category>
    {
        public Category()
        {
        }
        public Category(string name)
        {
            Name = name;
        }
        public string Name { get; set; }
        public Category Children { get; set; }
    }
    public class OSAndBrowser
    {
        public Category Categories { get; set; }
        public OSAndBrowser()
        {
            Categories = new Category()
            {
                new Category("OS")
                {
                    Children = new Category("Windows")
                    {
                        Children = new Category
                        {
                            new Category("Windows 10"),
                            new Category("Windows 8.1"),
                        }
                    },
                    new Category("Mac OS X")
                }
            };
        }
    }
}
```

![2017-06-08_18h33_53.png](https://qiita-image-store.s3.amazonaws.com/0/32870/a46454a1-38e2-afb3-ecb2-b0b618ca60a9.png)


https://msdn.microsoft.com/ja-jp/library/windows/apps/bb384261(v=vs.90)
によると、`{}`でくくるなかで本来あるべきでないところにnew Category()をしてしまっているようだ。

見直したところ、"Windows"の指定部分での間違いに気づいた。
以下のように訂正したところ、エラーは出なくなった。

```snipped
   public class OSAndBrowser
    {
        public Category Categories { get; set; }
        public OSAndBrowser()
        {
            Categories = new Category()
            {
                new Category("OS")
                {
                    Children = new Category
                    {
                        new Category("Windows")
                        {
                            Children = new Category
                            {
                                new Category("Windows 10"),
                                new Category("Windows 8.1"),
                            }
                        },
                        new Category("Mac OS X")
                    }
                }
            };
        }
    }
```
WebRTC の仲間たち

# （私の考える）WebRTCの範囲

WebRTCって何を指すのか？というのが時々話題になります。そこで私が考えるWebRTCの範囲をAPIと通信仕様に分けて整理してみました。
間違っているところを見つけたら、ぜひコメントにてご指摘ください！

## API 

### プラウザ用API

ブラウザ用APIはW3Cの[Web Real-Time Communications Working Group](https://www.w3.org/2011/04/webrtc/)で策定中です。その一覧と、私の解釈を書き出してみます。

- [WebRTC 1.0: Real-time Communication Between Browsers](https://www.w3.org/TR/webrtc/) ... 狭義のWebRTCで、このファミリーの主役。いわゆるPeerConnectionのことで、堂々のNo.1のポジション
- [Media Capture and Streams (getUserMedia)](https://www.w3.org/TR/mediacapture-streams/) ... ファミリーのNo.2。いわゆるgetUserMedia/gUM で、PeerConnectionの相方
- [MediaStream Recording](https://www.w3.org/TR/mediastream-recording/) ... 録画/録音を行うMediaRecorder。個人的にはNo.3の存在
- [MediaStream Image Capture](https://www.w3.org/TR/image-capture/) ... gUMと組み合わせて静止画を取り出す機能。個人的にはいまいち使いどころが分からない
- [Media Capture Depth Stream Extensions](https://www.w3.org/TR/mediacapture-depth/) ... 深度カメラから、深度の情報をグレースケールの映像として取得。対応したカメラが必要
- [Media Capture from DOM Elements](https://www.w3.org/TR/mediacapture-fromelement/) ... CanvasやVideo, Audioタグから映像/音声ストリームを取得。個人的は大好きで、No.3の座を伺う存在
- [Audio output devices API](https://www.w3.org/TR/audio-output/) ... 音声出力先を選択できる。高度なサービスには役立ちそうだが、慎重に利用しないと「音が出ない」クレームにつながりそう
- [Identifiers for WebRTC's Statistics API](https://www.w3.org/TR/webrtc-stats/) ... 通信状況の統計情報を取得できる、実用的なサービスには不可欠な機能。早くきちんと策定、実装して欲しいと願っている人も多いはず
- [Screen Capture](https://www.w3.org/TR/screen-capture/) ... スクリーンの動画キャプチャーの仕組みで、世の中的には重要度No.3では。早く機能拡張不要で実現して欲しいところ

### 関連するAPI

- [Web Audio API](https://www.w3.org/TR/webaudio/) ... MediaStreamとWebAudioの相互変換をカバー。音の加工には必須

### ネイティブアプリ向けAPI

WebRTCはブラウザだけでなく、ネイティブアプリでも利用できます。PeerConnectionに相当する部分は[webrtc.org/native-code/](https://webrtc.org/native-code/)で整備されています。gUMに相当する部分も、プラットフォームに合わせて提供されています。


## 通信に関わる仕様

実際の通信に関わる部分は、[IETFのRTCWEB working group](https://tools.ietf.org/wg/rtcweb/)で策定されています。リンク先の一覧には多くのRFCが含まれますが、それ以前から存在するさまざまなRFCも利用されています。正直なところ、私は把握できていません。
詳しくは、こちらの記事をご参照ください。

- [WebRTC スタックを一から実装する場合読んでおくべき資料まとめ](https://gist.github.com/voluntas/193ab447d387532a659d3ede9ab7678f)
- [WebRTC スタック実装する場合読んでおくべき RFC まとめ](http://qiita.com/voluntas/items/63cb73e4c9373e726a34)
- [WebRTC トラノマキ](https://gist.github.com/voluntas/59a135343538c290e515)
- [WebRTC スタックコトハジメ](https://gist.github.com/voluntas/6fcece7f424607c957d5)
- [WebRTCの裏側](https://gist.github.com/voluntas/975bfa230e513d146965)
Laravel キャッシュクリア系コマンドなど

Laravelさんは、Apacheを再起動したとしても、内部のキャッシュが残っててしまって、更新したプログラムをうまく反映してくれない時がある。
キャッシュクリア系の方法をまとめた。

## 基本的なキャッシュクリアコマンド

APIなど、Webサービスを使っていなくてビューがないのであれば、 `view:clear` はしなくてよい。

```shell-session
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
```

## ちょっと踏み込んだキャッシュクリアコマンド

オートローディングをしなおして、オプティマイズも実行してと、まるっとキャッシュを作り直したい場合。

```
composer dump-autoload
php artisan clear-compiled
php artisan optimize
php artisan config:cache
```

## キーの作り直し

新しくキーを作り直して、完全に前のキャッシュを無効にするときとか。

```
php artisan key:generate
```

## Scheduler

Schedulerのキャッシュは、前述のコマンドを持ってしても消えてくれないという、ロックな仕様。
次のようなキャッシュファイルを明示的に消す。

```
$ pwd
/path/to/your/laravel/storage/framework
$ ls -l schedule-*
-rw-r--r-- 1 apache apache 0 Jun  8 18:02 schedule-0d894ecd1e342cc720e1556766671673
-rw-r--r-- 1 apache apache 0 Jun  6 12:09 schedule-c4b93c084c29f9c504d4f412f1540947
$ rm -f schedule-*
```

## Configのキャッシュ

`env("YOUR_PARAMETER")`といった形で使う `.env` で定義した値が読み込めなく（Nullになる）時がある。いやはやサイケデリックな仕様。
次のような感じで、該当キャッシュファイルを消す。（参考： [hasen's tech life](http://hasen.hatenablog.com/entry/2016/04/22/013518)）

```
$ pwd
/path/to/your/laravel/bootstrap/cache
$ ls -l
-rw-rw-r-- 1 apache apache 10780 May 28 15:48 config.php
$ rm -f config.php
```

**（追記）**
5.2以降の仕様で、キャッシュがある時は、`config/*.php`以外の場所で使われる`env()`は無効化（null）になる仕様になったようです。
[参考： Upgrade guide - Laravel](https://laravel.com/docs/5.2/upgrade#upgrade-5.2.0)
[参考： Laravel では env() を config 系ファイル以外の場所に書いてはいけない - Qiita](https://qiita.com/mpyw/items/34f37742d9a18b80a08c)
kotlin + realmの環境を構築するときにハマったこと

IllegalArgumentExceptionとでて死にまくった

build.gradleはこの順番で記述する

``` build.gradle
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android'
```


RealmMigrationNeededExceptionエラーが出たとき
DB作成後にカラムの変更をしようとしている
アプリ削除するとDBも消えるので、開発中はアンインストールをすることで回避
Bloccom Chapter1 LED

#**Bloccom Chapter1 LED　**

#SetUp
**はじめに**、マイコンボードにUSB書き込み装置と電池パックを結合。電池パックの電源が入っていることを確認!!!
![S__25632857.png](https://qiita-image-store.s3.amazonaws.com/0/185986/e79bac30-687a-2551-e9d2-e5cef51c9523.png)



PCにUSBを繋げたら、Arduinoを立ち上げ メニュー>ツール>シリアルポート>/dev/cu.usbserial-DJ00L7JG を選択。
**ここで表示されるシリアルポートは人によって違うため、各自で確認を忘れずに!!!!**
私の場合、/dev/cu.usbserial-DJ00L7JGと表示された。
Windows版のシリアルポート接続は下記より
http://qiita.com/Bloccom/items/d58dccfbe8ff17c4300f

![serialport.png](https://qiita-image-store.s3.amazonaws.com/0/185986/e73b454d-f964-8764-70bc-0571dbe6d29c.png)


PCにUSBを接続したが、/dev/cu.usbserial-DJ00L7JGが表示されない場合
- USBを挿し直す
- PCを再起動する
これで表示されるはず!!




**次に**、マイコンのプログラムをリセット!する。
USB書き込み装置に設けてある赤と黒のボタンを下記のように押す!!

1. 赤色ボタンを押す(押したまま離さない)
2. 黒色ボタンを押す(押したまま離さない)
3. 黒色ボタンを離す
4. 赤色ボタンを離す

以上でCPUに書き込まれていたプログラムをリセットできる。
新しいプログラムをCPUに書き込む際は、必ず事前にリセットするように。


以上がSetUpである。次に、プログラムを書く。


#LED点灯
**はじめに**、LEDを点灯させるプログラムを書き込む。
プログラムは以下の通りである。

```c
void setup(){
    //5番の場所にあるLEDに電流を流すことを宣言;
    pinMode(5,OUTPUT);
}

void loop(){
    //digitalWriteはON/OFFの宣言しかできない;
    //HIGHはLEDの強さを最大にして点灯させるという意味;
    digitalWrite(5,HIGH);
}
```

![LED1.png](https://qiita-image-store.s3.amazonaws.com/0/185986/843e2bae-bfa4-e9e1-4d69-ac68e907f55f.png)


左上のチェックボタンを押しコンパイルに成功したことを確認したら、その隣の矢印ボタンを押しCPUに書き込みを実行する。
書き込みに成功すれば、青色LEDが点灯するはず!!!!



#LED点滅
**次に**、LEDを点滅させる。
プログラムのリセットを忘れずに!!
プログラムは以下の通りである。

```c
void setup(){
    pinMode(5,OUTPUT);
}

void loop(){
    //delayは()の時間だけプログラムを止める;
    //delay(1000)　= 1秒　のことを意味する;
    //LOWは消灯を意味する;
    digitalWrite(5,HIGH);
    delay(1000);
    digitalWrite(5,LOW);
    delay(1000);
}
```

![LED2.png](https://qiita-image-store.s3.amazonaws.com/0/185986/429fd6a6-2d86-e676-6a97-6cfbc73bbc82.png)


プログラムは以上。
あとは、LED点灯と同様の作業を行う。


#LED強弱
**最後に**、時間に応じてLEDの強さを変えるプログラムを書き込む。
プログラムのリセットを忘れずに!!
プログラムは以下の通りである。

```c
void setup(){
    pinMode(5,OUTPUT);
}

void loop(){
    //analogWriteは256段階の光の強さを指定できる
    for(int i = 0; i < 256; i++){
        analogWrite(5,i);
        delay(10);
    }
    for(int i = 255; i > 0; i--){
        analogWrite(5,i);
        delay(10);
    }
}
```
![LED3.png](https://qiita-image-store.s3.amazonaws.com/0/185986/13b0bd03-4f53-d706-517b-72b101c34e5a.png)

プログラムは以上である。
あとはLED点灯と同様の作業を行う。


以上 Chapter1　LED 終了

[Chapter0 SetUpに戻る](http://qiita.com/Bloccom/items/9537a1228498dc5f061c)

[Chapter2 温湿度・気圧センサに進む](http://qiita.com/Bloccom/items/34252904c7cfa10cdd80)
CSS word-break: keep-all;での、記号で「改行するかしないか」少し調べた件

単語の途中で切れてしまうのが見栄えが悪いので、
スペースを入れることにより、改行を操作するようにしたい...との要望を受けた。

「word-break: keep-all;」で可能だが、そもそも
どのブラウザでもスペースで改行されるのか？
ブラウザで差異はあるのか？
...とのことで、どうなるか調べた備忘録。

ちなみに、対象の箇所は以下CSSがかかっている。
（長すぎてはみ出した場合、3点リーダーが入るようになっている。）

```
h3 {
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: keep-all;
    word-wrap: normal;
    width: 200px;
}
```

##スペースで改行されるか、記号を区切りとみなして改行するのか
以下、記号（&、括弧など）があると単語がくっついていても改行する場合があったので、
どの場合でそうなるのか調べてみた。

例）かっこで改行される
![かっこで改行される場合のスクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/40940/d057f2d0-8c37-9b51-5e04-6a20989b6ddd.png)
例）かっこで改行されない
![かっこで改行されない場合のスクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/40940/11ea709a-6eef-c441-dbfa-6bb579fbbea4.png)
※改行するのは、文字が右端に到達して、単語が中途半端に見切れる場合のみ。
スペースが入っても、文字数が少なければ改行はされない。

####下の図の見方
|改行される|改行されない|
|:---:|:------:|
|○|X|

**※2017/06/07現在の結果です。**

###PC(Mac)
|  | スペースで改行 | 「&」 |括弧（） |すみ括弧【】|句読点「、」|
|:---:|:------:|:------:|:------:|:------:|:------:|:------:|
| Google Chrome |○|○|○|○|○|
| Safari | ○（半角スペースのみ。全角スペース不可。）|X|X|X|X|
| FireFox | ○（半角スペースのみ。全角スペース不可。）|X|X|X|X|

###PC(Win)
|  | スペースで改行 | 「&」 |括弧（） |すみ括弧【】|句読点「、」|
|:---:|:------:|:------:|:------:|:------:|:------:|
| Google Chrome | ○|○|○|○|○|
| FireFox | ○（半角スペースのみ。全角スペース不可。）|X|X|X|X|
| IE11 | ○|X|○|○|○|
| Edge | ○|X|○|○|X|


###iPhone6 (iOS10.3.2)
|  | スペースで改行 | 「&」 |括弧（） |すみ括弧【】|句読点「、」|
|:---:|:------:|:------:|:------:|:------:|:------:|
| Google Chrome | ○（半角スペースのみ。全角スペース不可。）|X|X|X|X|
| Safari | ○（半角スペースのみ。全角スペース不可。）|X|X|X|X|


###Android(4.4系)
|  | スペースで改行 | 「&」 |括弧（） |すみ括弧【】|
|:---:|:------:|:------:|:------:|:------:|
| Google Chrome | ○（半角スペースのみ。全角スペース不可。）|○|○|○|



#まとめ
すべてのブラウザで、スペースを入れることにより改行が可能でした。
注意が必要なのは、スペースは **半角スペースでないと改行されない** 点です。

また、ブラウザによっては、括弧や、&マークを記号と見なして
改行が入るようなので、記号にもスペースを入れたほうが無難。

また改行は、overflow-wrap: break-word;にすると効かないらしいので注意。
Oracle Bulk Insert


先輩に「ここはBulk使うといいよ」と言われ、
色々調べてみたのでメモ。

お手軽に書けるわりに速くなることが多いみたい。

# Bulk Insert

```sql :PL/SQL実行部
OPEN "カーソル名";
LOOP
  FETCH "カーソル名" BULK COLLECT INTO "配列名" LIMIT 1000;
  EXIT WHEN "配列名".count = 0;
    FORALL I IN 1.."配列名".count
      insert into "テーブル名" values "配列名"(I);
      
END LOOP;
CLOSE "カーソル名";
```



# 解説

２段のループになっています。

１つめは、２行目のLOOP。
FETCH　－　LIMIT 
で指定した行（ここでは1000行）ごとに区切って
テーブル変数の配列に入れています。


２つめは、FORALLの部分。

```sql
FORALL I IN 1.."配列名".count
  insert into "テーブル名" values "配列名"(I);
```

ここをふつーのFOR文で書くと

```sql
FOR I IN 1.."配列名".count LOOP
  insert into "テーブル名" values "配列名"(I);
END LOOP
```

になります。

これでも動くのですが、
insertはSQLエンジンが実行し、
LOOP部分はPL/SQLエンジンが制御するため、
LOOP回数分オーバーヘッドが生じて遅くなるのだとか。

LIMITの数多くすればオーバーヘッドは減るけど
メモリなどは多く食うようになってしまうため要チューニング。


あと、カーソル、テーブル定義配列、その型は
宣言部で宣言しておく必要があります。



```sql :PL/SQL宣言部

CURSOR "カーソル名" IS (
  select hogehoge from tableA  --ふつーのSelect文
);

TYPE type1 IS TABLE OF "カーソル名"%ROWTYPE index by binary_integer;
"配列名" type1;
```

カーソルのカラム定義はもちろん
INSERT先と合わせる必要あります。


正直、調べれば調べるほど分からなくなり、
PL/SQLの基本が分かってないと痛感。

今は↑のようなおまじないがある、と理解しておく。


# 参考サイト
このシリーズすごく勉強になります。
http://www.istudy.ne.jp/training/serial/plsql/063.html
[Thread-3] FATAL stacktrace_log - Cannot load JDBC driver class 'com.mysql.jdbc.Driver' org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'

# はじめに
tomcatのcatalina.outで以下のログが出力されました。

```text:エラー
[Thread-3] FATAL stacktrace_log - Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
```

# 原因
```Cannot load JDBC driver class 'com.mysql.jdbc.Driver'```となっているので、どうやらJDBC (Java Database Connectivity)のドライバが無いのが原因のようです。

# 対処
1. まずは MySQL の[ダウンロードページ](https://dev.mysql.com/downloads/)にアクセスします。

2. MySQL Connectorsの[Download](https://dev.mysql.com/downloads/connector/)をクリックします。
![スクリーンショット 2017-06-06 22.36.40.png](https://qiita-image-store.s3.amazonaws.com/0/82090/ac289294-1523-cd8f-37d3-03ff44ec8310.png)

3. [Connector/J](https://dev.mysql.com/downloads/connector/j/)をクリックします。
![スクリーンショット 2017-06-06 22.39.42.png](https://qiita-image-store.s3.amazonaws.com/0/82090/da7b8b47-a5ee-e4f5-d753-4544f449ff34.png)

4. "Download Connector/J"ページへ移動するので、"Generally Available (GA)"の"Platform Independent"を選択し、tar.gzまたはzipファイルをDownloadします。
![スクリーンショット 2017-06-06 22.47.50.png](https://qiita-image-store.s3.amazonaws.com/0/82090/3f1c2504-1732-f838-b7de-5131daa76c77.png)

5. ダウンロードしたドライバを解凍してtomcatのlib配下に配置します。

6. tomcatを再起動し、再ロードして完了です。


# おわりに
SQLデータベースなどのデータファイルにアクセスするにはアクセス先ごとに専用のドライバが提供されているので事前にインストールしてあげる必要があるんだと今回学びました。たしかに言われてみればapacheとかでもモジュールを必要に応じてインストールしてあげる必要があるのと同じですね。
マハラノビス距離 まとめ

## What is the Mahalanobis' Distance

[Main source] (http://www.angletry.com/modules/smartsection/item.php?itemid=23)


Mahalanobis' distance is the way of detecting outlier or changing point.
So how does it work?

It will go with 'correlation'.

For example, 
'Sales of the umbrella' and 'precipitation(降水量)'has the correlation.
If the amount of precipitation increases, then the sales of the umbrella will increase too. 
And, if I say the conclusion first, the ellipse(楕円) below is the Mahalinobis' distance. 
 

![Screen Shot 2017-06-08 at 17.02.45.png](https://qiita-image-store.s3.amazonaws.com/0/161691/00981d1d-c2c8-e9f6-b56d-a96604414217.png)
Extracted from [アングルトライ株式会社](http://www.angletry.com/modules/smartsection/item.php?itemid=23)

If the point is inside the ellipse, the we can say that the point belongs to the same group. 
However, if the point is outside the ellipse, then we can say that the point is the outlier. 


## How does the shape of ellipse determined? 

As I said, the shape of ellipse will be determined by the correlation. 

If the correlation is 1, that means that all the points will be on the one straight line. And if the correlation is 0, it means that the points will be dispersed everywhere. 

Therefore, if the correlation is bigger, the ellipse will be more thin. 



 

![Screen Shot 2017-06-08 at 17.15.43.png](https://qiita-image-store.s3.amazonaws.com/0/161691/924913af-a3a3-c5d1-c395-590b816a36c8.png)
extracted from [アングルトライ株式会社](http://www.angletry.com/modules/smartsection/item.php?itemid=23)


## What happens if the variable became more than 2 ?

In the example above, the variable was only 2 (Sales of the umbrella and precipitation). 
But, even though the variables became more than 2, it still calculates according to possible pair combinations of variables. 

For example, 3 variables A, B, C has 3 possible pair combination, 
which are 
A, B and A, C and B,C.

Thus, if there are 14 variables, the possible pair combination will be 91 and it will make 91 ellipses. 

![Screen Shot 2017-06-08 at 17.27.33.png](https://qiita-image-store.s3.amazonaws.com/0/161691/f92e0c23-b486-531d-a533-4196e81f2f50.png)
extracted from [アングルトライ株式会社](http://www.angletry.com/modules/smartsection/item.php?itemid=23)
BitBucketからGitHubに移行するための手順（とデプロイ時の落とし穴）

BitBucketからGitHubに移行する移行手順とcapistranoを利用してrailsアプリをデプロイしている場合の落とし穴について書きました。
[こちら](http://tackeyy.com/blog/process-of-migration-github-from-bitbucket)にも投稿したのですが、Qiitaにもあげておきます。

# 移行手順

基本的な流れは以下の通りです。

1. GitHubにBitBucketのリポジトリをインポートします
2. GitHubにインポートしたリポジトリをローカルにcloneします
3. ` bundle install --path vendor/bundle ` しながらお茶します
4. capistranoの設定を修正します
5. デプロイが通るか確認します

ポイントになりそうな1, 5だけ説明します。

# GitHubにBitBucketのリポジトリをインポート

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

Your old repository’s clone URL にBitBucketのリポジトリURLを入れます。

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

Begin importをクリックすれば終わり。

# デプロイ

ソースの修正とサーバー側での作業が必要になります。
ソースの修正はデプロイ時に[ソースをpullするリポジトリを指定している箇所](https://github.com/tackeyy/blog/blob/master/config/deploy.rb#L5)をBitBucketからGitHubのリポジトリURLに変更します。
SSH方式で指定するためGitHubに公開鍵を登録していない場合は以下のリンクを参考に公開鍵を登録してください。

http://vdeep.net/github

次にサーバー側のリポジトリ設定を変更します。
capistranoではサーバーの ` /var/www/app_name/repo/ ` 以下にリポジトリの設定を持っています。
そのため ` /var/www/app_name/repo/ ` でリモートリポジトリをGitHubのものに変更してあげる必要があります。
もし変更しないとデプロイは通るけど、BitBucketのリポジトリを参照しているため変更が反映されないという状態になります。

```
$ git remote -v # BitBucketのリポジトリになっています
$ cd /var/www/app_name/repo/
$ git remote set-url origin git@github.com:organization_name/repo_name.git
$ git remote -v # git@github.com:organization_name/repo_name.git になっていればOK
```

これで移行作業が完了しました。

# まとめ

BitBucketからGitHubへの移行自体に工数はかからずに簡単に移行できたのですが、
サーバー側も修正が必要という点が調査漏れしていたため少しハマってしまいました。
もしこの投稿を見てから移行作業していたら30分もかからずに移行できたのではないかなと思います。
【Unity】CommandBufferで画面にポストエフェクトをかける

# はじめに
CommandBufferの理解を深めるため、CommandBufferを使って画面にポストエフェクトをかけるだけのシンプルなものを作ってみました。

# 環境
Windows 10
Unity5.6.1f1

# 作ったものについて
シーンを再生すると画面の色が反転するだけのシンプルなものを作りました。

<img width = 320 src ="https://qiita-image-store.s3.amazonaws.com/0/44288/9ccdb129-7cb1-911e-b1dc-ed4e6f49ea27.gif">

# C# スクリプト
コマンドバッファで画面にポストエフェクトをかけるスクリプトです

```TestCommandBuffer.cs
using UnityEngine;
using UnityEngine.Rendering;

public class TestCommandBuffer : MonoBehaviour
{
    [SerializeField] Shader shader; // ポストエフェクト用のShader

    void Start()
    {
        if (shader == null) { return; }

        var cam = Camera.main;
        if (cam == null) { return; }

        var mat = new Material(this.shader); // Shaderからマテリアルを作成する
        var buf = new CommandBuffer();

        // 適当な名前のTemporaryRTを作成
        int temp = Shader.PropertyToID("_Temp");
        buf.GetTemporaryRT(temp, -1, -1, 0, FilterMode.Bilinear);

        // ポストエフェクトをかける
        buf.Blit(BuiltinRenderTextureType.CurrentActive, temp);
        buf.Blit(temp, BuiltinRenderTextureType.CurrentActive, mat);

        // TemporaryRTを解放
        buf.ReleaseTemporaryRT(temp);

        // カメラへCommandBufferを追加
        cam.AddCommandBuffer(CameraEvent.AfterEverything, buf);
    }
}
```

# イメージエフェクト用のシェーダー
色を反転させるポストエフェクト用シェーダーです。

```
Shader "Hidden/NewImageEffectShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Cull Off ZWrite Off ZTest Always

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);

				// プラットフォームによってはUVの上下が逆になるので補正をいれる
				#if UNITY_UV_STARTS_AT_TOP 
				o.uv = float2(v.uv.x, 1.0 - v.uv.y); 
				#else
				o.uv = v.uv;
				#endif

				return o;
			}
			
			sampler2D _MainTex;

			fixed4 frag (v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				return 1 - col; // 色を反転させる
			}
			ENDCG
		}
	}
}
```

# 使う
シーンの適当なオブジェクトに**TestCommandBuffer.cs**をアタッチして、シェーダーを
割り当てます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/1a87aeca-98cf-ed87-9c60-99a570be6566.png)

シーンを再生すると画面の色が反転します。 (完)
<img src ="https://qiita-image-store.s3.amazonaws.com/0/44288/9ccdb129-7cb1-911e-b1dc-ed4e6f49ea27.gif">

# 参考URL
Unity 5 の CommandBuffer を利用したレンダリングパイプラインの拡張について調べてみた
http://tips.hecomi.com/entry/2016/02/19/090000
CasperJS使い方メモ

CasperJSを使ってスクレイピングをする機会があったのでこちらもメモっておきます。
まずは、[phantomJS](http://phantomjs.org/documentation/) とそのラッパーである[CasperJS](http://docs.casperjs.org/en/latest/)をインストールします。

# 1.インストール

```
sudo npm install -g　phantomjs
sudo npm install -g casperjs

phantomjs --version
2.1.1
casperjs --version
1.1.4 
```

# 2. 必要なライブラリをimport
今回は下記４つ

```js
var util = require('util');
var fs = require('fs');
var system = require('system');
var casper = require('casper').create({ verbose: true, logLevel: "debug"});
```

# 3. イベントハンドラを設定する

**クリックイベント**と**ナビゲーションイベント**をハンドリングしてログ出力

```js
casper.on('click', function() {
    // クリックで発生したナビゲーションリクエストのURL
    this.echo(debug_tag + 'on click event: request url:\n\t' + this.requestUrl);
    this.then(function(response) {
        // クリック後に行きついたページのURL
        console.log('on click event -> then: current url:\n\t' + this.getCurrentUrl());
    });
});
casper.on('navigation.requested', function(url) {
    // 動作確認用のログ出力
    this.echo(debug_tag + 'navigation.requested url:\n\t' + url);
});
```

# 4. 処理の開始
casper.runを実行するとcasper.start内の処理が実行されます。
casper.evaluate内でダウンロードしたページの評価を行えるので特定のAタグをぬきだしています。
util.inspectでオブジェクトを見やすくデバック出力する事が可能です。

```javascript
var tag = "[murotani]";
var url_search = 'xxxxxxxx'
var links;

// リンクを一括取得
casper.start(url, function() {
    links = casper.evaluate(function(){
        var q = document.querySelectorAll('.area-abc>div>ul>li>a');
        return Array.prototype.map.call(q, function(e){
            return {'name': e.innerHTML, 'url': e.href};
        });
    });
    casper.echo(tag + util.inspect(links, false, null));
});
casper.run();
//URLをデバック表示
console.log(util.inspect(links,false,null));
```


# 5. 処理の追加
先程のURLの配列をループで回して1ページづつ取得します。
ここで注意しないといけないのが、[casper.each](http://docs.casperjs.org/en/latest/modules/casper.html#each)を使う事。
通常のFORループだと非同期で動作してしまうので使えません。
[casper.thenOpen](http://docs.casperjs.org/en/latest/modules/casper.html#thenopen)でURLを開きます。
[casper.then](http://docs.casperjs.org/en/latest/modules/casper.html#then)で後続処理を次々に記載する事が可能です。
[casper.waitFor](http://docs.casperjs.org/en/latest/modules/casper.html#waitfor)で特定タグの出現を待つ事ができるのでAJAXのページなどに対応できます。
waitFor内のthenに処理を追加していきましょう。

```javascript
casper.then(function(){
    //  URLをループで一つづつ開く
    //for(var idx1 in links) {
    casper.start().each(links,function(self,link){
        var URL = link.url;
        console.log(tag + URL);

        casper.thenOpen(URL, function () {

            casper.waitFor(function check() {
                return this.evaluate(function () {
                    return document.querySelectorAll('.sch-panel-word-input').length　> 0;
                });
            }, function then() {
               //　　ここに後続処理を記載

            }, function timeout() {

            }, 3000);
        });

    });
    casper.run();
});

```

# 6. クエリセレクタ
JQueryと同様のセレクタの書式で問題なさそう。

- 単一取得の場合  
　document.querySelector
- 複数取得の場合  
　document.querySelectorAll

フォーム入力には、[fillSelectors](http://docs.casperjs.org/en/latest/modules/casper.html#fillselectors)が使えるみたいだ。
ファイル暗号化コマンドとしての StreamRelay.jar

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar`
⇔
`StreamRelay.bat`

### 暗号化コマンドとしてのStreamRelay.jar

圧縮と同じように、暗号化処理も[javax.crypto.CipherInputStream](https://docs.oracle.com/javase/jp/6/api/javax/crypto/CipherInputStream.html)/[javax.crypto.CipherOutputStream](https://docs.oracle.com/javase/jp/6/api/javax/crypto/CipherOutputStream.html)クラスになっているので、StreamRelay.jarがあれば、ファイルの暗号化もできるという事

ファイル暗号化なので、入出力はファイルとなる
つまり、入力ファイル→(暗号化された)出力ファイルなので、
「local」の入力ソース(実体)にファイル、「remote」の出力ソース(実体)に暗号化ファイルとすればいい

つまり、

- アルゴリズム : AES
- モード : CBC
- パディング : PKCS5Padding
- 鍵 : abcdefgh
- 鍵の攪拌 : SHA512 (実際の鍵は「abcdefgh」のSHA512の先頭128bit)
- Cipherクラスのinit()に渡す初期値 : 0410e448928a9e2d81d6551a90642074019d

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar -LocalPort 0 -RemotePort 0 -LocalInputFile a.txt -RemoteOutputFile
 a.txt.aes -RemoteCipherAlgorithm AES/CBC/PKCS5Padding -RemoteCipherPassword abcdefgh -RemoteCipherPasswordHashAlgorithm SHA-512 -RemoteAlgorithmParameters 0410e448928a9e2d81d6551a90642074019d`

とすると、上記の条件で a.txt→(暗号化)→a.txt.aes となる

### 復号コマンドの代替

復号コマンドは、(暗号化された)入力ファイル→(復号された)出力ファイルなので、
「local」の入力ソース(実体)に暗号化ファイル、「remote」の出力ソース(実体)に結果ファイルとすればいい

上記の暗号化されたファイルの復号は

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar -LocalPort 0 -RemotePort 0 -LocalInputFile a.txt.aes -RemoteOutputFile
 a.txt.out -LocalCipherAlgorithm AES/CBC/PKCS5Padding -LocalCipherPassword abcdefgh -LocalCipherPasswordHashAlgorithm SHA-512 -LocalAlgorithmParameters 0410e448928a9e2d81d6551a90642074019d`

### 暗号アルゴリズムの一覧

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar -ListCipher`

### 鍵を攪拌するハッシュ関数の一覧

- SHA-384
- SHA-224
- SHA-256
- MD2
- SHA
- SHA-512
- MD5
- MD4

### -[Local|Remote]CipherAlgorithm に渡す文字列

`"暗号アルゴリズム名"/"モード"/"パディング"`

[Cipherクラス](https://docs.oracle.com/javase/jp/8/docs/api/javax/crypto/Cipher.html)を作成する時の引数と一緒

モードの一覧とか、パディングの一覧は、
[JavaTM 暗号化拡張機能 (JCE)リファレンスガイド](https://docs.oracle.com/javase/jp/1.5.0/guide/security/jce/JCERefGuide.html#AppA)を参照かな。

### -[Local|Remote]AlgorithmParameters

Cipherクラスのinit()に渡すパラメータです

nullとなるようなアルゴリズムとかモードとか選ぶと楽かも(この指定をしなくてもよい)

例えば
- RC4
- AES/ECB/PKCS5Padding (ECBモードがポイント)

---
### 暗号通信

[zebedee のような vpn の代替としての StreamRelay.jar](http://qiita.com/tomoki0sanaki/items/6b2f97df60b34da099f2)

---
### StreamRelay.jar で入力ダイアログで暗号鍵を与える

[StreamRelay.jar で入力ダイアログで暗号鍵を与える](https://qiita.com/tomoki0sanaki/items/4071d5e73bd2810e18a6)

---
### Rabbit(ver8.4以降)

ver8.4 以降で[Rabbit](https://en.wikipedia.org/wiki/Rabbit_(cipher))が使えるようになった。


---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
JavaのString#getBytesはKotlinでどう書く？


Kotlinでは`toByteArray`という関数で同じことができます。charsetはデフォルト値が提供されており、引数で指定しない場合は`Charsets.UTF_8`が使用されます。

```Kotlin
val foo = "foo"
foo.toByteArray()
```

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/to-byte-array.html
S3+CloudFrontのHTTPS静的ウェブサイトでwwwありからwwwなしにリダイレクトする

+ 2017.06.08　create

S3+CloudFrontのHTTPS静的ウェブサイトでwwwありからwwwなしにリダイレクトする設定です。
SEO対策として必要になったのでメモしておきます。
本文ではhttps://www.hogehoge.com を https://hogehoge.com にリダイレクトするものとします。

---
参照URL：　[AWS 独自ドメインを使用して静的ウェブサイトをセットアップする]
(https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html)

---
####トピック
1. HTTPS静的サイト本体（wwwなし）を作る
2. リダイレクト用のS3バケットを作る
3. CloudFrontのDistributionを作る
4. DNS設定をする

1. HTTPS静的サイト本体（wwwなし）を作る
---
まずリダイレクト先であるHTTPS静的サイト本体を作る必要があります。
[S3+CloudFront+ACM(AWS Certificate Manager)でHTTPS静的サイトを作ってみた](http://qiita.com/toshihirock/items/914f408cd565b66fe9f9)の投稿がとても分かりやすかったので参照してください。
toshihirock様リンクさせていただきます。ありがとうございます。

2. リダイレクト用のS3バケットを作る
---
ここからが本題。
分かりやすくwww付きのドメイン名でS3バケットを作成します。
バケット名：*www.hogehoge.com*

作成できたらSバケットプロパティタブのStatic website hostingで「リクエストをリダイレクトする」を有効にします。
- [x] リクエストをリダイレクトする
  　　ターゲットバケットまたはドメイン: *hogehoge.com*
  　　プロトコル: *https*
「ターゲットバケットまたはドメイン」はwwwなしのドメイン、「プロトコル」はhttpsを指定します。

ここでStatic website hostingのエンドポイントはcloudfrontのオリジンに設定するのでメモっておきます
エンドポイント：*www.hogehoge.com.s3-website-ap-northeast-1.amazonaws.com*

3. CloudFrontのDistributionを作る
---
HTTPSなので「1.HTTPS静的サイト本体（wwwなし）を作る」と同様にcloudfrontの設定が必要になります。
先ほどメモったStatic website hostingのエンドポイントをオリジンにする以外は同様に作成します。

Origin Domain Name：*www.hogehoge.com.s3-website-ap-northeast-1.amazonaws.com*

CloudfrontのDomain NameはDNSの設定で必要になるのでメモっておきます。
Domain Name: *hogehoge.cloudfront.net*

4. DNS設定をする
---
Route53でDNSレコードを作成します。
ここではaliasレコードを使用しますがroute53以外のDNS環境ではCNAMEでも問題ないと思います。

Create Record Setから
　Name:*www.hogehoge.com*
　Type:*A-IPv4 address*
　Alias:*YES*
　TTL (Seconds):3600
　Value:*hogehoge.cloudfront.net*
でCreateします。Valueの値にCloudfrontのDomain Nameを指定します。

cloudfrontとDNSが反映されるまでに数分かかりますがhttps://www.hogehoge.com にアクセスしてhttps://hogehoge.com へリダイレクト出来たら成功です。
条件付き多変量正規分布

# n変量正規分布

n変数正規分布の確率密度関数は、任意の$x\in{}\mathbb{R}^n$として、

```math
f(x) =f(x\ |\ μ, \Sigma) = \frac{1}{(\sqrt{2\pi})^{n}\ \sqrt{|\Sigma|}}\ exp\Big\{-\frac{1}{2}(x-μ)^T\Sigma^{-1}(x-μ)\Big\}  \tag{1}
```

(1)に従う集合$X$について、

```math
\vec{X} \sim N(\vec{μ}, \Sigma) \tag{2}
```
と書くが、この時、

```math
E(\vec{X}) = \vec{μ} ,\ var(\vec{X})=\Sigma \tag{3}
```

$\Sigma$は、$n\times{}n$行列で分散共分散行列。



# 条件付きn変量正規分布

```math
( \vec{X_1},\ \vec{X_2}) \sim{} N(\vec{μ}, \Sigma) \tag{4}
```

ならば、　

```math
\Sigma=\begin{bmatrix}\Sigma_{11} & \Sigma_{12} \\ \Sigma_{21} & \Sigma_{22}\end{bmatrix}
```
($\Sigma_{21}=\Sigma_{12}^T$ですね。)

として、

```math
\vec{X_2}\ |\ \vec{X_1} \sim{} N(\vec{μ_{2|1}},\ \Sigma_{22|1}) \tag{5}
```
ただし、

```math
\begin{eqnarray}
\vec{μ_{2|1}} &=& \vec{μ_2}+\frac{\Sigma_{21}}{\Sigma_{11}}(\vec{X_1}-\vec{μ_1}) \tag{6}\\
\Sigma_{22|1} &=& \Sigma_{22}-\Sigma_{21}\Sigma_{11}^{-1}\Sigma_{12} \tag{7}\\
\end{eqnarray}
```


と書ける。

# 小考
という訳で、この$\Sigma_{ij}$に対して、カーネル関数$k(x_i, x_j)$を設計するわけですね。

例えば、

```math
k(x_i,x_j)=\Sigma_{ij}=\eta^2exp\big(-\rho^2(x_i-x_j)^2\big)+σ^2δ_{ij}
```
($\delta_{ij}$はクロネッカのデルタ)

すると、既知の$X_1$を条件とした未知$X_2$の予測分布が得られる。
つまりこれって観測データに基づく非観測データの推定なので、(多変量正規分布を仮定した)回帰や分類に使える、という事。


# cf.
第12回 多変量正規分布,
http://www.eco.osakafu-u.ac.jp/osakafu-content/uploads/sites/9/2014/06/us-ln12.pdf

二変量正規分布の条件付き分布の解釈 
http://www.creativ.xyz/bivariate-normal-distribution-328
Karabiner の Use KANA as KANA/EISUU (toggle) を hammerspoon で

# init.lua

```lua
local KEY_CODE_JIS_EISUU = 102
local KEY_CODE_JIS_KANA  = 104

local function isInputSourceKana()
  -- 利用中の IME に合わせて要修正
  -- cf. hs.logger.new('IM', 'debug'):d(hs.inspect(hs.keycodes.methods()))
  return hs.keycodes.currentMethod() == 'ひらがな（ATOK）'
end

local toggleInputSource
toggleInputSource = hs.hotkey.bind({}, KEY_CODE_JIS_KANA, function()
  if isInputSourceKana() then
    return hs.eventtap.keyStroke({}, KEY_CODE_JIS_EISUU, 0)
  end

  toggleInputSource:disable()
  hs.eventtap.keyStroke({}, KEY_CODE_JIS_KANA, 0)
  toggleInputSource:enable()
end)
```

# 備考

- [hs.keycodes.setMethod](http://www.hammerspoon.org/docs/hs.keycodes.html#setMethod) で `IM` をセットするとメニューバー上のアイコンは変わるものの、実際にキーを叩くと意図通りにはならなかったので、英数／かなキーをストロークさせる様に
アプリ間でリンクする方法

![wfc20161109045.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/47a247a0-5239-97ea-a510-f2db0a158139.jpeg)

アプリから、他のアプリにリンクを張る方法はいろいろあると思いますが、SaaSForceの場合は次のような手順で行います。

![wfc20161109046.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/14a5cb7b-8ccc-12ef-b4a0-70577bb1046a.jpeg)

このリンクと言うアイコンを押すと、リンクのパーツが出てきます。

このパーツをクリックすると、ふちが赤くなるので、そうなるとそのまま引っ張って来れます。

さらに右クリックをして｢ハイパーリンク｣を押すと次の画面がポップアップされます。

![wfc20161109047.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/680cbb6d-b0f0-e2d8-d2fb-e6a4979c93ec.jpeg)

「リンク追加＆更新」をクリックするとこのような画面になります。

![wfc20161109049.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/bc4ad5b7-71ed-5d18-e62e-cd81f1ae3279.jpeg)

まず、内部画面を選択してください。

これで、今まで作成したほかのアプリにリンクができるようになります。

次に、｢遷移先リンク」のリストの中から「g」を選んでください。

そして、リンク名を入力して保存をしたら一度全てのポップアップ画面を消します。

それからもう一度、リンクのパーツを右クリックでハイパーリンクをクリックして、「リンク追加＆更新｣を押して、今作ったリンクを選び、項目名を変えて保存します。

![wfc20161109051.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/54ef34e3-fc83-9167-dd81-b6cb1cadd508.jpeg)

ここまで着たら、画面自体を保存してから一度ログアウト、そしてテストサーバーで確認するだけです。