OmniAICreator/Qiita-1.07M huggingface dataset:
UDPで3Gbpsくらいのデータを常時受信する場合(WinSock)


10GbE NICで3Gbpsくらいの常時データをUDPで受信する事があったので、
その際に必要だったことについてまとめた。

　1.ノンブロッキングソケットに設定する
　2.受信バッファの拡張
　3.ドライバ側のパラメータ設定
　4.スレッドのプライオリティを高くする
  
# ノンブロッキングソケットに設定する

ブロッキングソケットで受信する場合、以下のように連続受信すると、recvfromでほぼ毎回(多くの場合、パケットバッファは空なので)、スレッドがパケット到着まで待機状態になる。そのため、オーバヘッドが大きくなり、パケットを取りこぼすことがあるようだ。

```c++
while(1){
   len = recvfrom(...); //パケットを受信
   if(len!=sizeof(buf)){
     continue; //パケットがなかった場合
   }
   copy_pkt(...);//パケットを保存
}
```
ノンブロッキングソケットで受信すれば、基本的にrecvfromでスレッドが待機状態にならないので、パケット取りこぼしがなくなった。
*その代り、CPU負荷は高くなった。

ioctlsocketでブロッキング/ノンブロッキングを切り替え可能
以下MSDNのサンプル抜粋
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms738573(v=vs.85).aspx


```c++
u_long iMode = 1; //iMode==0:blocking, iMode!=0:non-blocking
int iResult = ioctlsocket(m_socket, FIONBIO, &iMode);
if (iResult != NO_ERROR)
  printf("ioctlsocket failed with error: %ld\n", iResult);
  }
```

# 受信バッファの拡張
受信バッファが少ないと、OSによるスレッド切り替えが行われて受信できない間に、バッファが溢れる可能性が高くなるため、setsocketoptでネットワーク受信バッファを拡張する。

```c++
	int buffSize = (1024 * 1024) * 512; //512MB
	ret = ::setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (const char *)&buffSize, sizeof(int));
	if (ret != 0) {
		TRACE(_T("割り当て失敗")); 
	}
```

# ドライバ側パラメータ設定
NICのパラメータを調整する。
ネットワークアダプタを右クリックして、起動したダイアログの構成ボタンをクリックする。
さらにダイアログが起動するので、詳細設定タブを選択すると、受信バッファ等の値を変更できるので、受信バッファを最大にする。

# スレッドのプライオリティを高くする。

受信スレッドを、THREAD_PRIORITY_HIGHEST等に設定して,OSにより実行中にスレッドを切り替えられにくくする。
form_forで強制的にhttp methodを変更する

form_forは対象modelが存在するかどうかで自動的にhttp methodを判別しますが、
時にはこちらでmethodを決めたい時もあります。その時は以下のようにやるとうまくいきます。

誤
`= form_for(@form, url: target_path,　　html: { method: :patch }) `
正
`= form_for(@form, url: target_path,　method: :patch ) `
Windows10ではvssver2.sccが見えない

win10の標準エクスプローラーでは隠しファイルの表示ONにしてもvssver2.sccが見えないようです。
でも実態としてはあるので、消したいときはコマンドで消しましょう。

`DEL /S /A:H /F vssver2.scc`
Scala勉強はじめました。3

##プログラミングの基本
- 代入
- 繰り返し
- 条件分岐

でした。前回は代入について勉強しました。
今回は、繰り返しについて勉強していこうと思います。

#Scalaでの繰り返し分の書き方

Scalaには

- for
- while
- do-while

の三通りの書き方があるそうなので、一通り試してみました。

##for loop

参考サイト様

- http://www.ne.jp/asahi/hishidama/home/tech/scala/for.html

```
for(i <- 1 to 10){
  println("hoge")
}
```

for()の中に回数を数える変数を宣言し、1から10までループするように指定しました。ループの内容は"hoge"を10回表示するというもの

実行結果

```
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge

Process finished with exit code 0
```

###他の書き方
プログラミングは一般的に0をスタートとして扱うので・・・
0を含めた10回のループは以下のように書くそうです

```
for(j <- 0 until 10){
  println("shobon" + j)
}
```

0 until 10
と書けば、0を含めた10回ループの完成です

実行結果

```
shobon0
shobon1
shobon2
shobon3
shobon4
shobon5
shobon6
shobon7
shobon8
shobon9

Process finished with exit code 0
```

回数を数える変数(フィールド)はjで、文字列"shobon"のあとにjを表示するように書いてあるため、"shobon"のあとに0から9までの10個の数字が表示されるようになりました。

##while loop
参考サイト様

- http://hydrocul.github.io/wiki/programming_languages_diff/control_flow/while.html


while(条件)が基本となる構文。
今回は10回のループを行いたいと思います

```
var k = 0
while(k < 10){
  println("while" + k)
  k++
}
```

実行しようとしたら・・・

```
Error:(25, 8) value ++ is not a member of Int
      k++
```

コンパイラ様に怒られました。
調べてみたところ、インクリメントとデクリメントが存在しないそうなので、別の方法でインクリメントを行わないといけません

```
var k = 0
while(k < 10){
  println("while" + k)
  k = k + 1
}
```

ループの中でkに1ずつ足していってます。
k = 9 回目のループでkに1が足されると、k = 10 となりwhile(...)の条件に合致しなくなり、ループは終了します。

実行結果

```
while0
while1
while2
while3
while4
while5
while6
while7
while8
while9

Process finished with exit code 0
```

できました。0から9までの10回ループをwhile文で実現しました。

##do-while loop
参考サイト様

- http://www.tutorialspoint.com/scala/scala_do_while_loop.htm


do-whileは必ず1回はなんらかの処理を行ってほしい時に用います。
書き方はwhileに似ています。

do{...}while(条件)

が構文です
ではサンプルコードを

```
var l = 0
do{
  println("do-while" + l)
  l = l + 1
}
while(l < 10)
```

10回繰り返すだけのコードなので、do-while文を使う必要はありませんが、良い例が思い浮かばなかったのでこれで。
初めの一回は必ず実行されます。
サンプルだと、"do-while0" と表示した後に l に1が足されます。

実行結果

```
do-while0
do-while1
do-while2
do-while3
do-while4
do-while5
do-while6
do-while7
do-while8
do-while9

Process finished with exit code 0
```

順調に0から9までの10回ループしてくれています。

```
var m = 1
do{
  println("do-while:" + m)
  m = m + 1
}
while(m < 0)
```

こちらがdo-whileをうまく(？)使った例です。
m にはもともと1が代入されていたため、while(m < 0)の条件には合致していません。

実行結果

```
do-while:1

Process finished with exit code 0
```

ですが、しっかりと1度だけ処理を実行してくれました。
これがdo-while文の効果(？)と言えます。

##まとめ

- for

        for(変数 <- 条件){...}

- while

        while(条件){...}

- do-while

        do{処理(必ず1回はしたい)}while(条件)
Paperclipのファイル名変換の仕様について


Paperclipでファイルをアップロードした際に、特定の記号がファイル名に含まれていると自動的に「_(アンダースコア)」に変換されます。

```
[sample]ドキュメント.pdf => _sample_ドキュメント.pdf
```


数年前のStackOverflowにこのような記事がありました。
[Does Paperclip automatically clean up filenames?](http://stackoverflow.com/questions/7328423/does-paperclip-automatically-clean-up-filenames)

PaperclipはURLフレンドリな形式にするため、ファイル名に

```
[&$+,/:;=?@<>[]{}\|\\^~%# ]
```

の記号が含まれた場合にデフォルトでアンダースコアに変換する処理が実装されているようです。

[https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/attachment.rb#L601](https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/attachment.rb#L601)


filename_cleanerの中身はこうなっていました。
(invalid_character_regexに置き換え対象の記号を含んだRegexpオブジェクトが渡されます)

[lib/paperclip/filename_cleaner.rb](https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/filename_cleaner.rb)

```ruby
module Paperclip
  class FilenameCleaner
    def initialize(invalid_character_regex)
      @invalid_character_regex = invalid_character_regex
    end

    def call(filename)
      if @invalid_character_regex
        filename.gsub(@invalid_character_regex, "_")
      else
        filename
      end
    end
  end
end

```

単純に指定した記号がファイル名に含まれている場合は全てアンダースコアに変換するようです。
この挙動については、"restricted_characters"というオプションを渡すことで変更可能です。

```ruby
has_attached_file :attachment,
  restricted_characters: nil
```
コナミコマンドで動くJavaScriptコードを書いてみる

※このエントリーは [コナミコマンドで動くJavaScriptコードを書いてみる | SDN Memo](http://memo.sdn-project.net/post/156616847319/konamicommand) を書き直したものです。

#<i class="fa fa-book"></i> はじめに

Webサイトにイースター・エッグ（隠し要素）を仕込んだりするのもたまには面白いなぁという事で、「コナミコマンドをキーボードで打つと何かが起こるスクリプト」を書いてみる事にしました。
コナミコマンドって何だ、という人はWikipediaを見てください。

[コナミコマンド - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%8A%E3%83%9F%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)

#<i class="fa fa-puzzle-piece"></i> まずどう組むか考える

お遊びでも作るからには簡単な仕様を決めておかねばなりません。

##<i class="fa fa-keyboard-o"></i> キーボード入力によるJavaScriptの操作

JavaScriptには `keydown` / `keypress` / `keyup` などのキーボードのキーの操作によって発火するイベントが用意されています。
`keydown` はキーが押された瞬間、`keypress` はキーが押されて文字が入力された瞬間（なので矢印キーなどには無反応）、`keyup` はキーが上がった（キーを放した）瞬間に動くイベントです。
コマンドは基本的に押された瞬間なので `keydown` を使います。

```js
(function () {
  'use strict';

  document.addEventListener('keydown', function () {
    // 何かやらせる
  });
})();
```

##<i class="fa fa-code"></i> コマンドのキーコードを取得する

キーボードには特殊なキーをのぞきほとんどのキーに「キーコード」という数字が割り当てられています。
キーコードを確認するための簡単なHTMLでも用意しておきましょう。

```html:キーコード確認
<input type="text" id="keyCode">
<script>
document.addEventListener('keydown', function (ev) {
  document.getElementById('keyCode').value = ev.keyCode;
});
</script>
```

コナミコマンドは `↑↑↓↓←→←→BA` なので、そのキーコードを見ると `38 38 40 40 37 39 37 39 66 65` である事がわかります。
これを配列にして、n番目のコマンドが合っていたらn+1番目のコマンドを確認するといった感じに書きます。

```js
(function () {
  'use strict';

  var
    // コマンドのキーコード
    command = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65],

    length = command.length,
    index = 0;

  document.addEventListener('keydown', function (ev) {
    if (ev.keyCode === command[index]) {
      index++;

      if (index >= length) {
        index = 0;

        // 全てのコマンドを入力したら何かする
      }
    } else {
      // コマンド入力を間違えたらリセット
      index = 0;
    }
  });
})();
```

これでもいけなくないですが、コマンド入力としてはまだ物足りないかも。

##<i class="fa fa-clock-o"></i> コマンドの入力受付の猶予時間を設定

n秒以内に次のコマンド入力がない場合はコマンド入力をリセットした方がよりそれっぽくなるかと思います。

```js
(function () {
  'use strict';

  var
    // 入力受付時間（1.5秒）
    wait = 1500,

    // standby = false の時は入力を受け付けない
    standby = true,

    // コマンドのキーコード
    command = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65],

    length = command.length,
    index = 0,
    timer = null;

  document.addEventListener('keydown', function (ev) {
    // タイマーのリセット
    clearTimeout(timer);

    // コマンドの確認
    if (standby && ev.keyCode === command[index]) {

      index++;

      if (index >= length) {
        // すべてのコマンドを入力した！

        standby = false;  // 処理中にコマンドを受け付けないようにする
        index = 0;  // コマンドリセット

        /*

          何かしらの処理
          処理が完了したら standby = true に戻す

        */

      } else {
        // 一定時間入力がなかったらリセット
        timer = setTimeout(function () {
          index = 0;
        }, wait);
      }

    } else {
      // コマンドが間違っていたらリセット
      index = 0;
    }
  });
})();
```

やりました。これで完成です。
あとは好きな処理を書いてページに設置するだけです。
ざっくりbrowserify入門

`browserify`について、全く理解していなかったので勉強してみました。

長期間運用すると`javascript`の記述が増えて行き、管理が大変になってくるし、他人の書いた長い記述の中で目的の処理を探すのは大変。
その`javascript`の記述を機能ごとに別ファイルに分割して管理する為に`browserify`が便利。
ということらしいです。

## 導入すると何が嬉しいか
ざっくりというと以下2点かなと。

- <a href="https://www.slideshare.net/SatoshiTakami/intoroduction-nodejs" target="_blank">Node.js</a>スタイルで書かれたコードをブラウザ上で動くものに変換することができる。
- `javascript`にはないモジュール機能が使えるようになる(`require機能`など)。

## 使いかた

まずは`browserify`をグローバルインストール

````
$ npm install -g browserify
````

`main.js`というファイルを用意し、以下のように記述します。
同階層にある`parts1.js`と`parts2.js`を`require`で参照。

````js:main.js
var parts1 = require('./parts1.js');
var parts2 = require('./parts2.js');

parts1(5);
parts2(5);
````

今回は`console.log`の機能と`alert`の機能を分割。

`parts1.js`には`console.log`の機能。

````js:parts1.js
module.exports = function(num1) {
    console.log(num1);
};
````

`parts2.js`には`alert`の機能。

````js:parts2.js
module.exports = function(num2) {
    alert(num2);
};
````

`main.js`
`parts1.js`
`parts2.js`
以上3つのファイルの準備ができたら同階層で以下のコマンドを打つ

````
$ browserify main.js -o app.js
````

すると、同階層に`app.js`が生成されます。
一行目にある記述は`require機能`を定義している箇所です。

````js:app.js
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var parts1 = require('./parts1.js');
var parts2 = require('./parts2.js');

parts1(5);
parts2(5);
},{"./parts1.js":2,"./parts2.js":3}],2:[function(require,module,exports){
module.exports = function(num1) {
    console.log(num1);
};
},{}],3:[function(require,module,exports){
module.exports = function(num2) {
    alert(num2);
};
},{}]},{},[1]);
````

ブラウザで確認する為に、生成された`app.js`を`html`から読み込む。

````html:index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Browserify Sample</title>
    <script src="./app.js"></script>
</head>
<body>
</body>
</html>
````

`console.log`と`alert`にそれぞれ「5」が出力されたと思います。

## おわりに
かなり簡単でしたが、なんとなく概要は掴んでいただけたのではないかと思います。
このままだとコンパイルするたびにコマンドを打たなくてはならないのですが、変更を監視してくれる<a href="http://qiita.com/mizchi/items/b59a6c27558d238658c6">watchify</a>などもあります。
`browserify`は`webpack`や`gulp`や`npm-scripts`でも使えたり、やり方次第で`css`の記述も`javascript`の中に含めることができるので、使いこなせばとてもファイル管理が楽になると思います。
大規模案件や長期間運用する前提でないとあまり使わないかもなと思いますが、いざというときの為に概要だけでも知っておいていいと思います。

### 参考

<a href="http://qiita.com/megane42/items/2ab6ffd866c3f2fda066">npm とか bower とか一体何なんだよ！Javascript 界隈の文脈を理解しよう</a>
Azure で Web hosting する

# やりたいこと
Azureで静的フアイルを上げたり、Web hostingがやりたい。
S3だと簡単なんだけど、Azureはよくわからんのでメモ。

1. Azure Storage Account の作成  
![Screenshot 2017-03-31_11-00-45.png](https://qiita-image-store.s3.amazonaws.com/0/87900/4e5bb975-f113-f542-2f92-74dfecafb1cc.png)  
ここで大事なのはアカウントの種類で、BLOBストレージを選択すること。  
~~というかアカウントって言葉がどうなんだろ~~
3. コンテナーを作成する  
<img width="906" alt="スクリーンショット 2017-03-31 11.43.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/87900/0f04afc7-663e-39f7-82d0-960878bb46d8.png">
3. Azure Portal から Explorer を開く  
![Screenshot 2017-03-31_11-21-41.png](https://qiita-image-store.s3.amazonaws.com/0/87900/723e71dc-f1c4-e70b-708d-f43f4a30b93c.png)
4. ファイルアップロード or フォルダアップロード  
![Screenshot 2017-03-31_11-31-45.png](https://qiita-image-store.s3.amazonaws.com/0/87900/a5f4f1e6-fb51-bbf3-4149-d895547d4efe.png)
ここで静的ファイルのホスティングが出来る。  
5. Azure Portal で URLを確認する  
![Screenshot 2017-03-31_11-35-58.png](https://qiita-image-store.s3.amazonaws.com/0/87900/4dfef45c-60c0-d693-1b6e-816ce2bb6b1c.png)
6. ブラウザでアクセスしてみる  
<img width="75" alt="スクリーンショット 2017-03-31 11.46.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/87900/2b5265e4-69fb-ff94-c239-545fe950315b.png">
環境変数設定は基本cross-envだけどたまにenv-cmdも使う

個人的に、タスクランナーをなるべく使わず`package.json`の`scripts`を書くようにしています。このとき、スクリプトが環境依存にならないように、いくつかのnpmパッケージを使用します。

今回は、環境変数の設定を行うパッケージを2つ紹介します。


## cross-env

[cross-env](https://www.npmjs.com/package/cross-env)は有名どころで、OSごとの環境変数設定の違いを吸収してくれるパッケージです。

```
cross-env ENV1=abc ENV2=def node foo.js
```

これで、環境変数`ENV1`に`abc`が、`ENV2`に`def`が設定された状態で`node foo.js`が実行されます。シンプルでわかりやすいです。


## env-cmd

[env-cmd](https://www.npmjs.com/package/env-cmd)も同様に、OSごとの環境変数設定の違いを吸収してくれるパッケージです。cross-envとの違いは、**引数で指定するのではなく、ファイルを使って指定する**点です。

```text:values.env
# コメント行
ENV1=ABC
ENV2=DEF
ENV3=SET LONG TEXT HERE
```

```
env-cmd values.env node foo.js
```

以下のようなケースで便利です。

* 設定したい変数がたくさんある
* 設定したい値が長い
* 複数の環境変数をセットで管理したい（テスト用セット、ビルド用セットなど）

ここまではcross-envのドキュメントを見るとすぐにわかるのですが、[Environment File Formatsの項目](https://www.npmjs.com/package/env-cmd#environment-file-formats)をよく見ると、対応ファイルは以下のようになっています。

> * `key=value`
> * Key/value pairs as JSON
> * JavaScript file exporting an object
> * `.env-cmdrc` file (as valid json) in execution directory

**JavaScriptのファイルを使える**と書いてあります。
[ソースコード](https://github.com/toddbluhm/env-cmd/blob/master/lib/index.js)を読んでみると、指定されたファイルが`.json`もしくは`.js`だった場合は`require`を使ってファイルを読み込んでいます。

`.js`ファイルが使えるということは、設定する環境変数の内容をプログラムで制御できるということです。使いどころとしては以下のようなケースが想定できます。

* OS等で分岐して異なる環境変数を設定をしたい
* ランダムな値を設定したい（テスト用途）
* 変数名と値を連番でたくさん生成したい（テスト用途）

私が実際にこれを活用することになったのは、**`NODE_PATH`に複数のパスを指定する場合、Windowsだとセミコロン、他だとコロンで区切るように分岐する必要があった**からでした。

```set_node_path.js
var paths = ['path/to/dir', 'path/to/dir2'];
if (process.platform === 'win32') {
  exports.NODE_PATH = paths.join(';');
} else {
  exports.NODE_PATH = paths.join(':');
}
```

```
env-cmd set_node_path.js node foo.js
```


## まとめ

* 基本的にはcross-envでよい
* コマンドが長くなりすぎる場合はenv-cmdの方が見易い
* env-cmdならプログラム制御ができるので色々できる
electronでTray Iconを使った時、メニューバーからアイコンが消える

## 解決策
new Tray() を代入する変数を app.on('ready')のコールバック関数のブロック外で宣言する。

## 原因
Trayのインスタンスが入る変数をapp.on('ready')のコールバック内に宣言するとGCされる事がある。

### GC(ガベージコレクション)とは 
>ガベージコレクション（英語: garbage collection; GC）とは、プログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能である。「 ガベージコレクション」を直訳すれば「ゴミ集め」「ごみ拾い」となる。

プログラムがもうアクセスしないと判断した変数を自動的に破棄する機能。

## コード例

良い例

``` javascript
let tray = null;

app.on('ready', () => {
  tray = new Tray('path/to/icon');
});
```


悪い例

``` javascript
app.on('ready', () => {
　　const appIcon = new Tray(icon);  //一定時間アクセスがない場合はGCされる
});
```

## 背景

appの起動が完了するより前にTrayのインスタンスは作れない（electronがエラーを返す）。  
そのためnew Tray()をapp.on('ready')　等のコールバック内に書くのが一般的。
FUELPHP 1.8のORMバグについて

#FUELPHP 1.8のORMバグについて
もう最近まったく話題に上がることもないFUELPHPですが、
[ORMのバグ　has_many で from_cache=false にすると関連レコードが 1件しか取得されない](https://wiki.fuelphp1st.com/wiki/index/FuelPHP%20%E3%81%AE%E3%83%90%E3%82%B0%E6%83%85%E5%A0%B1)　

このバグはこの表題だと普通に使っていれば問題ないように見えたんだけど
例えば

```
$where = [
    ['status', '=', 'active']//こっちは有効
    ['bbb.tcx_id', '>', 0],//こっちは効いていない
];
$query = \Model_Aaa::query()->related('bbb')->where($where)->get();

```
みたいなクエリの `bbb`に対するWHEREが無視される、って現象があった。
最初はXDEBUGでずっとデバッグして？？？と思ったけど、`var_dump()`祭りして気づいた。
コレ致命的なバグじゃねぇか!

詳しい状況は覚えていないけどかなりハマったのでメモ。
その時は急いでいたので、```DB::query()```で書き直してとりあえず解決したけど
何かいい解決方法はないのかな？
S3×Athena×Re:dashでデータ可視化してみた

前にいた会社ではデータの可視化にTableauを使ってましたが、すごい良いツールだけに値段も高く、出来たてのスタートアップにはキツイ価格帯。。。
そこで、他のBIツールを探してみるとRe:dashが勢いがあるので使ってみました！！

## データの可視化(=visualization)の必要性
### そもそもなぜデータを可視化するのか？
前職では広告プロダクトのパフォーマンス向上のために仕事の大半をデータ分析&施策立案に費やしてきたのですが、データを分析すればするほど運用者には知見がたまり、センスが磨かれていく。しかし、ともすると施策の決定者やプロダクトの責任者クラスとの共通認識にギャップができてしまう。

つまり、**正しく理解させるためのコミュニケーションのハードルが上がってしまう。**
その原因は
  1. *数字*を読み込み、
  2. *数字*を理解して、
  3. 決済者が運用者の主張を理解する必要があり、
とてもコストがかかってしまう。
データの可視化(=visualization)することは、そのコストを一気にショートカットする可能性を大いに秘めているのです。

*例)割合は可視化したほうがわかりやすい！！*
Excelみたいにマトリックスだけだと、`video_complete`の比率が大きいことはなんとかわかるくらい。
<img width="872" alt="Screen Shot 2017-03-31 at 10.59.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/756d34d9-3607-9a43-31c2-f61218710ebe.png">

同じデータも可視化することで、その比率も感覚的に掴みやすくなる。
<img width="555" alt="Screen Shot 2017-03-31 at 10.59.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/893460b3-de96-a4b4-0575-318a123fef63.png">


## 導入手順
サンプルのテキストファイルとして、日付とアクション項目のあるデータを用意しました。
<img width="575" alt="Screen Shot 2017-03-31 at 11.21.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/1d65f1dd-180e-ca66-76aa-f2efdb26a733.png">

### まずは、S3にログをおく
##### 可視化したいデータをS3上に置きます。
<img width="1279" alt="skitch.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/19b3e6fc-b61e-ba02-35aa-cca23ab9bc38.png">

### 次に、Athenaの設定をする
##### Step1: Name&Location
…データベース/テーブル/インポート元の設定を行う
 指定したS3のフォルダ配下のファイルが全てクエリの対象範囲になる(PARTITIONの設定に有用)
 S3パスの最後の「/」は必須なので注意(Table作成時の”Location of Input Data Set”)
<img width="1278" alt="skitch.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/d199a089-a3ea-e0f3-9672-4a8a5ed726f8.png">

##### Step2: Data format　
…用意したデータのフォーマットを指定
 今回はtsvでサンプルデータを用意したので’TSV’を選択する
<img width="1280" alt="step2.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/0b466211-4968-2002-2459-3637fac8317b.png">

##### Step3: Columns
…各カラムのデータ型を左から順に指定していきます
<img width="1280" alt="step3.png" src="https://qiita-image-store.s3.amazonaws.com/0/52634/f257b92c-9c60-8303-47c1-1fc5dd076b39.png">


### 最後にRe：dashで可視化する
[Redash が Amazon Athena を正式サポートしたので試してみた](https://blog.manabusakai.com/2017/02/redash-and-athena/)の通りにやるだけ！
とても簡単でした。

## ハマったこと&ハマっていること
### [解決済み]Athenaにおけるtimestampのデータ型の指定は*string*
ログのタイムスタンプをAthenaで`データ型: timestamp`でテーブルを作ると、Re:dashで上手くvisualが作れない

### [解決中]Re:dashでログのタイムスタンプを日付で集計するためにはどんなクエリを書くべきか
Re:dashでどんなクエリを書けば良いのかわからず、下記のクエリで暫定対応。パフォーマンスがよろしくない。。。良い方法あったらどなたかおしえてくださいm(_ _)m

```sql
SELECT SUBSTRING(req_timestamp, 1, 10) AS req_timestamp,
       action_name,
       count(*) AS count
FROM sampledb.sample_log
GROUP BY SUBSTRING(req_timestamp, 1, 10), action_name;
```

######  参考にしたサイト
[Redash が Amazon Athena を正式サポートしたので試してみた](https://blog.manabusakai.com/2017/02/redash-and-athena/)
[Amazon Athena + Redash = ♥️](https://blog.redash.io/amazon-athena-in-redash-support-6b71c91aa747)
PHPのstrtotime関数で日付を操作をするときの注意点

PHPのstrtotime()では2017-03-31の1ヶ月後は「2017-04-31」となり、
「2017-04-31」は「2017-05-01」として解釈される

例）以下のように月が重複して作成される

```PHP
<?php
// 現在の日付から半年間の月のリストを作成する

$target_date = "20170331";

for ($i=0; $i < 6; $i++) {
    $target_ym_list[] = date('Ym', strtotime($target_date . '+' . $i . ' month'));
}
var_dump($target_ym_list);
?>

array(6) {
  [0]=>
  string(6) "201703"
  [1]=>
  string(6) "201705"
  [2]=>
  string(6) "201705"
  [3]=>
  string(6) "201707"
  [4]=>
  string(6) "201707"
  [5]=>
  string(6) "201708"
}
```

昔から現場ではよく問題となっていましたが、今だ撲滅はされていません。
（「PHP　1か月前」とかでググると以下のようなソースが簡単に見つかるため）

```PHP
<?php
// 1ヶ月後の日時を取得
echo date("Y-m-d",strtotime($target_day . "+1 month"));
?>
```

解決方法としては、以下のように指定日時を月はじめに変換するとよい。

```PHP
<?php
// 現在の日付から半年間の月のリストを作成する

$target_date = "20170331";
// 指定日時を月はじめに変換する
$target_date = date("Ym01", strtotime($target_date));

for ($i=0; $i < 6; $i++) {
    $target_ym_list[] = date('Ym', strtotime($target_date . '+' . $i . ' month'));
}
var_dump($target_ym_list);
?>

array(6) {
  [0]=>
  string(6) "201703"
  [1]=>
  string(6) "201704"
  [2]=>
  string(6) "201705"
  [3]=>
  string(6) "201706"
  [4]=>
  string(6) "201707"
  [5]=>
  string(6) "201708"
}
```
Movable Typeに複数選択のチェックボックスを追加するプラグイン「MultiCheckbox」

### はじめに

MTで複数選択チェックボックスでググったら「MoreCustomFields」が真っ先に出ると思います。
この記事を見るということは、既に上のプラグインを試してみて、うまくいかなかったんだと思います。
それでいろいろ探して見つけたのがこれ。使用例がどこにも書かれてなかったので書いてみた次第。

### 前提

Movable Type Proを使用していること

### ダウンロード

https://github.com/endevver/mt-plugin-cf-multicheckbox

### インストール

mt/pluginsの中に「MultiCheckbox」って名前のディレクトリを作ってそこに中身を放り込む。以上！

### 使用方法

導入後、カスタムフィールドの種類に「Checkbox (Multi)」というものが追加されます。
あとはオプションのところに「北海道,青森県,秋田県…」とドロップダウンに書くような形で入力して登録すれば、
複数選択のチェックボックスが出現します。
（もちろん「1=北海道,2=青森県」みたいに入力すればvalueの値を数字で登録可能です。）

### 不具合

これ、オプションに入力した文字列をカンマ区切りで判別して、チェックボックスをループで生成してるようなんですけど、
コンソールを見るとエラーが発生しています。ただ、実運用で問題は起きていないですし、
原因を特定する時間もないのでこれはそのうち追記します。多分。
Firefox 52, Selenium WebDriver がエラー、Geckodriver 0.15 が必要

# Error 
Ruby on Rails Seleium WebDriverで Firefox を動かしていたら、ある日エラーで止まる。

> `#<Selenium::WebDriver::Error::SessionNotCreatedError: TypeError: Given browserVersion [object String] "any", but current version is [object String] "52.0.2">`


# bundle update
geckodriver 0.15 には selenium-webdriver 3.3.0 以上が必要とのことなのでUpdateする。

```
$ bundle update
```

> Installing selenium-webdriver 3.3.0 (was 3.0.4)


# geckodriver

## 現 version 確認
```
$ /usr/local/bin/geckodriver --version
```

> geckodriver 0.11.1

## 0.15 を取得

https://github.com/mozilla/geckodriver/releases

## 上書き
```
$ tar -zxvf ./geckodriver-v0.15.0-macos.tar.gz
$ mv geckodriver /usr/local/bin/
```

## version 確認
```
$ /usr/local/bin/geckodriver --version
```

> geckodriver 0.15.0

# 以上
【初心者向け】作業効率化のためにwindowsをおつかいの方はこのショートカットを最低限使ってくださいお願いします。

## コントロールキーを押しながらボタンを押してください。
* 左クリック　：別タブで開く
* z　：1つ前の作業を取り消す
* c：コピー
* v：貼り付け
* s：保存
* w：ウィンドウを閉じる
* f：検索
* a：全部選択する
* n：新しいウィンドウを開く
SQLServerでIDENTITYの設定をする

###現在のIDENTITYを表示する。
```
DBCC CHECKIDENT('テーブル名', NORESEED);
```
###IDENTITYを0に設定
```
DBCC CHECKIDENT ('テーブル名', RESEED, 0);
```
###IDENTITYを8に設定
```
DBCC CHECKIDENT ('テーブル名', RESEED, 8);
```
[C++] C言語ライブラリの関数の、関数ポインタの型エイリアスを定義する

以下の記事で `pthread_create` の関数ポインタの型エイリアスを定義していたけれども、そういえば `decltype` で型を取れるのではと気がついたので方法メモ。

[[Linux][C/C++] tid (thread id) を取得する / pthread_createをラップして子スレッドのtidの取得 - Qiita](http://qiita.com/koara-local/items/a7c39f82909f7e2e3ece)

基本的には `using type_alias = decltype(&func);` が楽そうです。

```cpp:test.cpp
#include <iostream>
#include <string>
#include <typeinfo>
#include <memory>
#include <cassert>

#include <cxxabi.h>

int main(void) {
	auto demangle = [](auto&& t) {
		const char* type_name = typeid(t).name();
		int status = -1;
		std::unique_ptr<char, decltype(&std::free)> realname {
			abi::__cxa_demangle(type_name, 0, 0, &status),
			std::free
		};
		assert(status == 0);
		return std::string(realname.get());
	};

	{
		// 直接取得
		std::cout << "[0]: " << demangle(&pthread_create) << std::endl;
	}

	{
		// 型エイリアスで同じ型を定義（非推奨）
		using pthread_create_t =
			int (*)(pthread_t *, const pthread_attr_t *, void *(*) (void *), void *);

		pthread_create_t t;
		std::cout << "[1]: " << demangle(t) << std::endl;
	}

	{
		// 型エイリアスとdecltypeを使用
		using pthread_create_t = decltype(&pthread_create);

		pthread_create_t t;
		std::cout << "[2]: " << demangle(t) << std::endl;
	}
}
```

```console:実行結果
$ clang++-3.8 -pthread -std=gnu++14 -stdlib=libc++ test.cpp  && ./a.out
[0] : int (*)(unsigned long*, pthread_attr_t const*, void* (*)(void*), void*)
[1] : int (*)(unsigned long*, pthread_attr_t const*, void* (*)(void*), void*)
[2] : int (*)(unsigned long*, pthread_attr_t const*, void* (*)(void*), void*)
```

# 参考
[decltype - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/decltype.html)
PacketiX VPNをコマンドラインで使う

PacketiX VPNをインストールすると、vpncmd(Windowsの場合はvpncmd.exe もしくは　vpncmd_x64.exe)というCUIで制御するアプリケーションがついてきます。
このアプリケーションに引数を与えることでPacketiX VPNを制御出来ます。

## 例:接続と切断

今回は既に「クライアント接続マネージャ」で接続が出来る設定が登録されており、それを用いて接続と切断を行います。

![vpns.png](https://qiita-image-store.s3.amazonaws.com/0/76058/b179143d-b197-0580-7bf6-bf3077461a12.png)


### 接続

Windowsの場合はコマンドプロンプトで実行出来ます。

```bat:connect
vpncmd localhost /client /CMD AccountConnect 接続設定名
```

### 切断

```bat:disconnect
vpncmd localhost /client /CMD AccountDisconnect 接続設定名
```

## ファイルを指定して実行

コマンドをテキストファイルに書き込んでおいて、ファイルパスを指定して動作させることも出来ます。
例えば下記はtest.txtというファイルの内容です。

```bat:test.txt
AccountConnect 接続設定名
```

これを下記コマンドで実行することが出来ます。実行すると接続処理が行われます。

```bat:file
vpncmd localhost /client /IN:"(ディレクトリパス)test.txt"
```

## 使えるコマンド一覧表
> https://ja.softether.org/4-docs/1-manual/6/6.5
【Salesforce初心者】入力規則の作成について

Salesforceの練習で、入力チェックのロジックをformulaで書いて見ました。
リクエストは以下の通り：

Trailheadの原文は以下：

To complete this challenge, add a validation rule which will block the insertion of a contact if the contact is related to an account and has a mailing postal code (which has the API Name MailingPostalCode) different from the account's shipping postal code (which has the API Name ShippingPostalCode).

Name the validation rule 'Contact must be in Account ZIP Code'.
A contact with a MailingPostalCode that has an account and does not match the associated Account ShippingPostalCode should return with a validation error and not be inserted.
The validation rule should ONLY apply to contact records with an associated account. Contact records with no associated parent account can be added with any MailingPostalCode value. (Hint: you can use the ISBLANK function for this check)

日本語でいうと、下記のようになります：
概要：ContactsにMailingZipCodeを入力する時のチェックメソッド
①．ContactsにAccountが紐づいてない場合、MailingPostalCodeは何を入力しても良い（特にチェックしない）
②．ContactsにAccountが紐づいている場合、MailingPostalCodeはAccountのShippingPostalCodeに一致しないといけない

ロジックとしては難しくないと思いますが、一個引っかかりやすい「ワナ」（ワナでもないかw）があります。
Salesforceで用意されているValidation（チェックメソッド）は、判定の結果がTrueのときに発動する。
つまり、判定式がTrueの場合、Error Messageを出すと言う仕組みです。
普通のプログラムだと、Trueが正常系で、Falseの場合がエラーを返すというのが一般的な感じがしますね。

では、上記二つの条件を分岐にしました：

分岐１：ContactにAccountが紐づいていない　→　エラーを出さない（Falseを返す）
分岐２：ContactにAccountが紐づいている、かつ
　　　　　　　　　　Contact.MailingPostalCode＝Account.ShippingPostalCode　
　　　　　　　　　　→　エラーを出さない（Falseを返す）
分岐３：ContactにAccountが紐づいている、かつ
　　　　　　　　　　Contact.MailingPostalCode≠Account.ShippingPostalCode
　　　　　　　　　　→　エラーを出す（Trueを返す）

上記の分岐に基づいて、下記のロジックを組みました：

ロジック１：
IF((ISBLANK(AccountId),false,
  IF(MailingPostalCode  <>  Account.ShippingPostalCode, , )
)

ロジック２：
AND( 
NOT (ISBLANK(AccountId)) ,
(MailingPostalCode  <>  Account.ShippingPostalCode)
)

両方ともテスト済みで機能するので、好きな方を使えばいいと思います。
自分は２の方がいいです^^
Androidのテキスト読み上げ機能TextToSpeechからCallbackを取得するときの注意点

androidでTextToSpeechを使ったアプリを作った時のメモ

# 注意点
1. utterance_idを設定しないとCallbackを受け取れない。
2. 再生中にstopしたときのcallbackが異なる場合がある。
3. callbackでの処理はUIスレッドで行う。


# 1. utterance_idを設定しないとCallbackを受け取れない。
 callbackを取得するにはTextToSpeechのonInitで
textToSpeech.setOnUtteranceProgressListener(…)
をするのですが、
実際に音声を再生するメソッドのutteranceIdをセットしておかないとcallbackは受け取れません。特に4系以下ではHashMapでちゃんと設定しないといけないのでわかりにくい。

```java:tts.java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
	      //lollipop以上
                String id = String.valueOf(orderNo);
                textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
            } else {
	      //kitkat以下
                HashMap<String, String> params = new HashMap<String, String>();
                String id = String.valueOf(orderNo);
                params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, id);
                textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, params);
            }

```

# 2. 再生中にstopしたときのcallbackが異なる場合がある。

 再生が終わった時に呼ばれるonDoneの挙動に手持ちの端末で違いがあってかなりはまりました。
4系のGalaxyと5系のNexusではstopした時にonDoneが呼ばれるのですが、
6系のXperiaではstopした時にonDoneが呼ばれない。。。
自分の場合は停止ボタンで再生を停止する場合と、
再生が終わった時に次のTextをセットして再生を開始する制御に困った。

自分の対処法としてはTextToSpeechのステータスをenumで持っておいて、
stopボタンを押した時は停止状態のステータスにし、
onDoneの時に、ステータスを見て停止状態なら次の再生をセット
onStartのcallbackの時にステータスを再生状態にして対処。

```java:tts.java
//stopボタンのsetOnClickListener時点で
//ttsStatus =　TTSStatusEnum.STOP;にする

textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                @Override
                public void onStart(String utteranceId) {
		          ttsStatus = TTSStatusEnum.PLAY;
                }

                @Override
                public void onDone(String utteranceId) {
		          if (ttsStatus == TTSStatusEnum.STOP) {
		            //既にstop
		            return;
		          }
		          ttsStatus = TTSStatusEnum.STOP;
		          //次の再生の処理…
                }
...

```

# 3. callbackでの処理はUIスレッドで行う。
　callbackで再生している文言の色を変えたい的なUIの処理は
明示的にUIスレッドで処理しないとダメ。

```java:tts.java
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                @Override
                public void onStart(String utteranceId) {
		            runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                           //textの色を赤にする処理
                        }
                    });
                }

                @Override
                public void onDone(String utteranceId) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
			           //textの色を戻す処理
                       }
                    });
                }
...
```
参考：[Android TTS onUtteranceCompleted callback isn't getting called](http://stackoverflow.com/questions/4652969/android-tts-onutterancecompleted-callback-isnt-getting-called)
Hyper-VのRemoteFXでUSB転送

P2Vをすすめる中、USBはシンクライアント扱いのクライアントPCに繋いだものを使おうと考えていました。
電子入札用の端末のSmart　Card Readerを共有するのに手間がかかりました。

切り分けとして、まずUSB Redirectが出来ているか確認するためスキャナーなどをつなげてみるのが良いと思います。

## 環境

| ホスト | ゲスト |　RDP　クライアント　|
|:--|:--|:--|
| Windows 10 Pro 64bit |Windows 10 Pro 32bit |　 |
| - 　| Windows 7 Pro 32bit |　Windows 7 Pro 32bit　|


### ホスト側での作業

転送できるUSBデバイスはデフォルトではスキャナーなどかなり限定的です。
CDドライブ、メモリーカードリーダーなどはドライブ扱いでマウントされUSB転送されるわけではないので、別途、登録が必要です。

追加するUSBデバイスのクラス名を見つけます。SmartCardとかで検索すればいいのかな。CD-DRIVEのクラス名が公開されているので、そちらで検索して同じディレクトリを掘りました。

[Some USB devices are not available through RemoteFX USB redirection](https://support.microsoft.com/ja-jp/kb/2653326)

とあるように、Remote Desktopで

|Device type |Interface class GUID |
|:--|:--|
|Hard Drive |{53F56307-B6BF-11D0-94F2-00A0C91EFB8B} |
|CD-ROM |{53F56308-B6BF-11D0-94F2-00A0C91EFB8B}     |

```
- HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\\ この辺にたくさんある
      - `{50dd5230-ba8a-11d1-bf5d-0000f805f530}`
      - DeviceClasses\\`{50dd5230-ba8a-11d1-bf5d-0000f805f530}`
      - SafeBoot\Network\\`{50DD5230-BA8A-11D1-BF5D-0000F805F530}`
      - CurrentControlSet\Control\Class\\`{50dd5230-ba8a-11d1-bf5d-0000f805f530}`
-  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DeviceDisplayObjects\InterfaceInformation\\`{084F9363-E31A-4BDE-9CA5-6FA0D86E009F}`
```

```
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DeviceDisplayObjects\InterfaceInformation\\
```

| key                                      |Category |
|:--------|:--|
|`{50dd5230-ba8a-11d1-bf5d-0000f805f530}` |Component.SmartCardReader|
| `{084F9363-E31A-4BDE-9CA5-6FA0D86E009F}` |Media.SmartCard |
|`{0850302a-b344-4fda-9be9-90576b8d46f0}|Network.Bluetooth|
上記で見つけたClassIDを


```
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\Client\UsbSelectDeviceByInterfaces
```

に文字列値 REG_SZ を追加。名前はユニークであればなんでも。1001とかシリアル値を入れました。

`{50DD5230-BA8A-11D1-BF5D-0000F805F530}`

### ゲストマシン側での作業

Windows 7でRDP8.0が入っていないようなら、入れておきます。
7.1以上ならRemoteFX USB Redirectに対応しているそうです。ホストマシンがUSB3.0の場合で、ゲストがUSB2.0だとRedirectできません。
罠としてはWindows 7に後からUSB 3.0のドライバーをインストールするのは一苦労でした。

### 結論

セキュリティ上、大切なIC認証カードなどをローカルマシンにつなげてRemote Desktopを利用できるのは便利です。
同じフロアという環境なのでRDPサーバに証明書を入れたりはしていませんが、リモート接続の場合は考慮に入れたほうがよいでしょう。

### 注意点

Mac OSのRDPではUSB Redirectはできません。


途中まで書いて放置していたのを公開。現状、動いている仮想ゲストの構成を確認して加筆修正します。
既存のvimをluaオプション付きのvim8.0に入れ替える。

## **step1 既存のvimをアンインストールする。**

自分の環境にインストールされているvimにluaオプションが有効されているか確認する。

```vim
vim --version | grep lua
#結果
+dialog_con      -lua             +rightleft       +writebackup
```

ないのでvimをアンインストールします。

```vim
#一旦、vimに関する依存関係を確認する。
sudo apt-cache -i depends vim

# 異存パッケージをまとめて消去する。
sudo apt-get remove --purge vim vim-runtime vim-common


#(すでにコンパイル時に入れてしまっている場合は直接rmコマンドで消去して下さい。)
sudo rm -rf /usr/local/share/vim
sudo rm /usr/local/bin/vim


#確認
vim
No such file or directory

```

## **step2 luaに必要なファイルをインストールしてくる。**

```vim
#(python-dev python3-dev ruby-devは個人的にPythonとRubyを使いたい為にいれているので、個人の環境に合わせて下さい。)

sudo apt-get install -y git build-essential ncurses-dev lua5.2 lua5.2-dev luajit python-dev python3-dev ruby-dev
```

## **step3 vim8.0をインストールする。**

```
#ディレクトリ移動。
cd /opt/
sudo git clone https://github.com/vim/vim 
cd vim/

#ビルドファイル生成

sudo ./configure --with-features=huge --enable-multibyte --enable-luainterp=dynamic --enable-gpm --enable-cscope --enable-fontset --enable-fail-if-missing --prefix=/usr/local --enable-pythoninterp=dynamic --enable-python3interp=dynamic --enable-rubyinterp=dynamic 

## makeファイルを生成(時間がかかります。)
sudo make 

# vim8.0をインストールする。
sudo make install

#vim8.0が正常にインストールされているか確認する。
vim --version

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Feb 23 2017 05:23:35)
Included patches: 1-348
```

以上でvim8.0のインストールは終わりです。
お疲れ様でした。







## **Tips**

### makeファイル生成の途中で失敗した。

srcディレクトリにcdコマンドで移動して`make distclean`コマンドを実行して下さい。

```
cd vim/src/
make distclean
```


### インストールが正常に終わって、vimコマンド叩いてみたけどvimが立ち上がらない。

`/usr/local/bin/vim`にインストールされてるが、vimコマンド自体が認識されてなかった場合は以下のコマンドでPATHを通して下さい。

```
export PATH=$PATH:/usr/local/bin/
```

## 参考

- [Installing vim 8.0.X with lua, python on Ubuntu 16.04](https://gist.github.com/dyzajash/9cfd2c821fc599cbb1a5d1c72305a0b7)
HoloLensでオブジェクトを壁に貼る

#はじめに
３月初めよりインターンで株式会社ゆめみ(https://www.yumemi.co.jp/ja) にてHoloLensの研究開発をしている近大生のよっしーです。
国内でこの１月から提供を開始したMicroSoft製MRデバイスのHoloLensについての記事を書いていきます。

「HoloLens +他社製の外部入力」や「動きを３Dモデルにして配信」など、いろいろな方たちが面白い試みを数多く試されていますが、HoloLens開発の基本的部分の記事があまりなかったので、それをメインに書いていこうと思います。

#すること
**オブジェクトを壁に接着させる**

Holographic academy　Holograms230で出てくるPlacementのところです。
物体を触ったときに接着したまま動かすコードは動画で出てきましたが、生成時に壁に貼り付けるところの説明はなかったのでしていきます。

#前提環境
- HoloLensの開発環境セットアップ済み
- Unityでの開発
- HoloToolkit-Unityの利用
- HoloLens開発の基礎用語
- PlaySpaceManager(Holographic Academy 230で出てくる）の利用で、メッシュを取り除いた平面へと変換が出来ている。

#実装例
```csharp:adhereObjectOnTheWall.cs
RaycastHit hitInfo;

bool hit = Physics.Raycast(GazeManager.Instance.GazeOrigin,GazeManager.Instance.GazeNormal, out hitInfo, 20f, SpatialMappingManager.Instance.LayerMask);
if (hit) {
    //ヒットした表面の取得
    GameObject surface = hitInfo.transform.gameObject;

    //表面からどれから浮かすかの値
    float hoverDistance = 0.15f;
    float offsetDistance = hoverDistance;

    //設定したhoverDistanceよりGazeと衝突判定の発生した平面との距離が少ない場合0fにする。
    if (hitInfo.distance <= hoverDistance) {
        offsetDistance = 0f;
    }
    //衝突判定のあったポイントを少し浮かせる
    Vector3 placementPosition = hitInfo.point + (offsetDistance * hitInfo.normal);

    // ぶつかった壁の方向を向かせる
    Quaternion rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
    Instantiate(SomePrefab,placementPosition,rotation);
}
```

#縦にペラペラの場合
Holograms230のように、ポスターであったりして縦にペラペラなオブジェクトは上のコードで問題ないかと思います。絵にかくと下図のような感じ。
![PosterOnTheWall.png](https://qiita-image-store.s3.amazonaws.com/0/114709/d82a90ff-63f5-c9ca-63bc-ce25c659cd86.png)

#横に長い場合
これはこのままだと下図のようになります。
![CatOverWall.png](https://qiita-image-store.s3.amazonaws.com/0/114709/aff13845-dc29-6887-3fd5-62babeef4a4a.png)

##対応策
Quaternionを足してあげましょう。上図のようなはみ出方の時は

```csharp:AddQuaternion.cs
Quaternion rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up) * Quaternion.Euler(new Vector3(-90, 0, 0));
```

というふうに書き換えてみてください。（上を向かせる場合）

そうするとこうなるはずです。
![CatOnTheWall.png](https://qiita-image-store.s3.amazonaws.com/0/114709/01077e23-537e-ef8a-a800-dec7c0f8f028.png)

#参考・関連
Holographic academy Holograms230
https://developer.microsoft.com/en-us/windows/holographic/holograms_230

HoloLensで壁、床、机、天井の分類をする
http://qiita.com/guitar_char/items/b06ef68777e10c6482c5
geometry > 2017-03-31: 2つの緯度経度から距離を求める > Haversine formula使用 | 2019-01-08 Vincenty法

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 3.6.0 on virtualenv
```

### 追記 (2019-01-08)

***@knoguchi さんの[コメント](https://qiita.com/7of9/items/4ea7356a8806eaa08d5e/#comment-8b584fc3d15249477719)に記載がありますように、Haversine formula法はGPSウォッチの実測値と少し乖離があるそうです。
より精度の高い計算については 同コメントを参照ください。***

### 情報とv0.1

関連 [要検討 > geometry > 緯度経度から距離を求める式の理解 > 極座標から直交座標変換 / 天頂角 / 方位角](http://qiita.com/7of9/items/7e02f4a6cf0d9c5fbdb7)

[緯度経度より距離を（地球の丸さも考えて）求める。](http://qiita.com/s-wakaba/items/e12f2a575b6885579df7)のコードをHaversine formula版に変更してみました。

参考 [Haversine formulaを使ってローケーションベースでソートする](http://qiita.com/akirahrkw@github/items/3ddd5bbb51bb912981ad)
参考 https://en.wikipedia.org/wiki/Haversine_formula

```calc_distance_170331a.py
from math import sin, cos, radians, sqrt, asin
EARTH_RADIUS_km = 6378.137


def dist_on_sphere(pos0, pos1, radius=EARTH_RADIUS_km):
    '''
    distance based on Haversine formula
    Ref: https://en.wikipedia.org/wiki/Haversine_formula
    '''
    latang1, lngang1 = pos0
    latang2, lngang2 = pos1
    phi1, phi2 = radians(latang1), radians(latang2)
    lam1, lam2 = radians(lngang1), radians(lngang2)
    term1 = sin((phi2 - phi1) / 2.0) ** 2
    term2 = sin((lam2 - lam1) / 2.0) ** 2
    term2 = cos(phi1) * cos(phi2) * term2
    wrk = sqrt(term1 + term2)
    wrk = 2.0 * radius * asin(wrk)
    return wrk

Osaka = 34.702113, 135.494807
Tokyo = 35.681541, 139.767103
London = 51.476853, 0.0

print(dist_on_sphere.__doc__)

print("%.2f km" % dist_on_sphere(Osaka, Tokyo))  # 403.63km
print("%.2f km" % dist_on_sphere(London, Tokyo))  # 9571.22km
```

```txt:実行
$ python calc_distance_170331a.py 

    distance based on Haversine formula
    Ref: https://en.wikipedia.org/wiki/Haversine_formula
    
403.63 km
9571.22 km
```

### v0.2

radiusの定義を関数内に移した。
キーワード引数で指定すればradiusを変更できるように。

関連 [Python > defualt argumentにおいてmutableなobject (例: list)を初期化しない / 定義時に初期化されるため]( http://qiita.com/7of9/items/5893e79819613d7f3c17 )

```calc_distance_170331a.py
from math import sin, cos, radians, sqrt, asin


def dist_on_sphere(pos0, pos1, radius=None):
    '''
    distance based on Haversine formula
    Ref: https://en.wikipedia.org/wiki/Haversine_formula
    '''
    if radius is None:
        radius = 6378.137  # km (Earth's radius)
    latang1, lngang1 = pos0
    latang2, lngang2 = pos1
    phi1, phi2 = radians(latang1), radians(latang2)
    lam1, lam2 = radians(lngang1), radians(lngang2)
    term1 = sin((phi2 - phi1) / 2.0) ** 2
    term2 = sin((lam2 - lam1) / 2.0) ** 2
    term2 = cos(phi1) * cos(phi2) * term2
    wrk = sqrt(term1 + term2)
    wrk = 2.0 * radius * asin(wrk)
    return wrk

Osaka = 34.702113, 135.494807
Tokyo = 35.681541, 139.767103
London = 51.476853, 0.0

print(dist_on_sphere.__doc__)

print("%.2f km" % dist_on_sphere(Osaka, Tokyo))  # 403.63km
print("%.2f km" % dist_on_sphere(London, Tokyo))  # 9571.22km
```
twigで、改行コードを`<br />`に変換するnl2brで、htmlエンティティさせない




# 概要

FuelPHPでtwigを活用するケースが多いです。

そして、改行コードを含むテキストをtwigに表示させる際には、twigのnl2brというフィルターを使う方も多いとおもいます。

ところが、nl2brをそのまま使おうとすると、htmlエンティティが自動で適用されてしまうので、それを外してしまおう、というお話です。

~~完全に、備忘録レベルです・・・。~~

# 手順

FuelPHPを利用されている場合は、`fuel/app/classes/vendor/`ディレクトリにtwigをインストールされている方も多いとおもいますので、その前提で。

`fuel/app/classes/vendor/twig/extension.php`に、以下を追記しましょう。

	```
	public function getFilters()
	{
		return array(
			new Twig_SimpleFilter('nl2br', 'nl2br'),  // この1行を追記
		);
	}

これで、快適なnl2brライフが送れます。
もちろん、必要に応じて`escape`などのフィルターも通すようにしましょう。
iOS 10以降のNotificationの見た目

# はじめに
- iOS 10でNotificationを利用したコードを実装して、しばし悩みました
- その理由は、追加したカスタムAction（ボタン）が表示されなかった（ように見えた）ためです
- その辺りを、整理してみます

# 検証環境
- Xcode 8.2.1
- iOS 10.2

# カスタムActionが表示されない？
- SettingsからNotificationの表示形式でAlertを選択しても、見た目上はBannerです
    - 放置しても消えないBannerがAlert
    - 機能としても、放置して消えるか残るかの違いのみ
- ユーザが操作をしなければ、カスタムActionは表示されません
    - これまでのBannerと同じ挙動ですね
- 以下の画像はiPhone 5sですが、3D Touch非対応のデバイスではよく見るとBannerの下部に引っ張れそうなハンドルが表示されてます

    <img width="375" alt="banner.png" src="https://qiita-image-store.s3.amazonaws.com/0/100115/467ff0b2-53df-0f10-3a6d-035f52904972.png">

    <img width="375" alt="banner2.png" src="https://qiita-image-store.s3.amazonaws.com/0/100115/0c4996b7-e1a9-0849-7366-e8c982a75309.png">

# カスタムActionの表示条件
- 便宜上、HOME画面と書いてますが当然、何らかのアプリがフォアグラウンドにいても同じです
    - Popは、3D Touchの強く押し込む動作です（軽く押すのがPeek）
- Banner表示でもAlert表示でも、操作は共通です

| 画面 | 3D Touch | カスタムActionの表示方法 |
|:--|:--|:--|:--|
| HOME画面 | あり | Pop or 下にスワイプ |
| HOME画面 | なし | 下にスワイプ |
| 通知センター |  あり | Pop|
| 通知センター | なし | 左にスワイプ -> Viewをタップ |

# まとめ
- iOS 10におけるNotificationの**カスタムActionは、Alert表示でも最初から表示されているわけではない**ので気付きにくいです
    - iOS 9まではAlertでの表示がアラートダイアログ形式だったので、カスタムActionは初めから表示されていました
- ~~Popが利用できないデバイス（3D Touchがないデバイス）では、通知センターにおいてカスタムActionを表示する術がありません~~
    - ~~下にスワイプしても画面全体が下に動くだけで、個別のNotificationには何も起こりません~~
    - 3D Touch無効でも、左にスワイプ -> Viewをタップで表示できます（コメントにてご指摘頂き、修正しました）
- iOS 9までは通知センター上ではカスタムActionを表示できなかったので、**高機能になった（3D Touch対応デバイスでは）**と言えると思います
- わざわざユーザがカスタムActionを表示させる必要があるので、**従来のアラートダイアログ形式と異なり、気づかれにくい**という点が少し残念です
    - とは言え、これまでもアラートダイアログ形式のNotificationは操作の邪魔になるので、Banner表示に変更するユーザが多かったのではないかと思います
    - そう考えると、そんなに気にしなくてもいいのかもしれませんね
Mackerelのログ監視で日本語の文字列をキーワードにする

# 概要
ログ監視は、ログファイル内の特定の文字列を検出するとアラートを出すのが一般的ですが、Mackerelのログ監視（check-logプラグイン）で**日本語の文字列**をキーワードにする場合、設定にひと手間必要でした。

## やること
1. `mackerel-agent.conf`を**UTF-8**で作成する
2. `--encoding`でログファイルの文字コード指定する


# 手順
### mackerel-agent.confをUTF-8で作成する

検出したい文字列に日本語（全角文字）を含む場合、**設定ファイル自体のエンコーディングをUTF-8**にする必要があります。
ここがはまりどころです。テキストエディタなどを使ってUTF-8で保存しましょう。

Windowsの場合コンフィグは以下にあります

*C:\Program Files (x86)\Mackerel\mackerel-agent\mackerel-agent.conf*

### --encodingでログファイルの文字コード指定する

ログファイルの文字コードを指定します。
今回監視するのはWindowsに保存されたログファイルなので文字コードはSJISを指定しました。
検出したいキーワードは"ネットワークエラーが検出されました"です。

### できあがり

```bat:mackerel-agent.conf
(中略)
[plugin.checks.log]
command = '''check-log.exe --file C:\log\test.log --pattern ネットワークエラーが検出されました --encoding Shift_JIS --return'''
```

`--return`オプションは**キーワードを含む行**をMackerelへ送信してくれます。
そのためEndToEndで暗号化されているとはいえ、個人情報やアカウントを含む行は注意が必要です。

# アラート

キーワードを検出するとMackerelのAlertsへ以下のように表示されます。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/172195/a6ca96fd-63cf-41b4-3642-a4a449f755cd.png)

"ネットワークエラーが検出されました"を含む行も表示されました。


### 参考：encordingオプションで指定可能な文字コード
https://github.com/mackerelio/go-check-plugins/tree/master/check-log
Python > function > Docstrings > help()で表示する説明文 / .__doc__ 

```txt:動作環境
CentOS release 6.8 (Final)
Python 2.6.6
```

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 2599 / 12833)

Docstringsというものが紹介されていた。
試してみた。

```test_170331a.py
def my_echo(anything):
	'''
	prints [anything]
	with an air of reserve
	does not take [anything] seriously
	'''
	print("(in a small voice)"),
	print("...")
	print(anything)
	print("...")
	return

help(my_echo)
```

```txt:実行
$ python test_170331a.py
Help on function my_echo in module __main__:

my_echo(anything)
    prints [anything]
    with an air of reserve
    does not take [anything] seriously
```

### 参考

Docstrings関連の慣例
https://www.python.org/dev/peps/pep-0257/

### `__doc__`

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 2628 / 12833)

`__doc__`を使う例が紹介されている。
試してみた。

```test_170331b.py
def my_echo(anything):
	'''
	prints [anything]
	with an air of reserve
	does not take [anything] seriously
	'''
	print("(in a small voice)"),
	print("...")
	print(anything)
	print("...")
	return

#help(my_echo)
print(my_echo.__doc__)
```

```txt:結果
$ python test_170331b.py 

	prints [anything]
	with an air of reserve
	does not take [anything] seriously
```
技術英語 > ..., pick the style that [seems the most clear to] you. / exact: correct in every detail

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 3047 / 12833)

> ..., pick the style that **seems the most clear to** you.

http://qiita.com/7of9/items/247fc1c1019e56e2c41a
> I would like to make it **crystal clear**.

<hr>
関連して思い出したのは 
exact

@ カシオ EX-word XD-N8600 搭載辞書

> exact
> correct in every detail
Go + echoでfetch APIを使ってPOSTする

今回作ったのはfetch APIを使ってPOSTしたデータを再度受け取るという簡単なもので、バリデートなどは入れていません。
基本的にはEchoの公式サイトを見ながら進めました。
https://echo.labstack.com/

## 作ったもの

イメージはこんな感じです。
![qiita-go-echo.gif](https://qiita-image-store.s3.amazonaws.com/0/54502/560769ee-7e54-7021-af03-fcce05a6047b.gif)

```
├── template
│   └── index.html
└── server.go
```

```sever.go
package main

import (
	"net/http"
	"github.com/labstack/echo"
	"io"
	"text/template"
	"github.com/labstack/echo/middleware"
)

type Template struct {
	templates *template.Template
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
	return t.templates.ExecuteTemplate(w, name, data)
}

func main() {
	e := echo.New()
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	t := &Template{
		templates: template.Must(template.ParseGlob("template/*.html")),
	}
	e.Renderer = t
	e.GET("/", rootHandler)
	e.POST("/signup", PostHandler)
	e.Logger.Fatal(e.Start(":1323"))
}

func rootHandler(c echo.Context) error {
	return c.Render(http.StatusOK, "index", nil)
}


type User struct {
	Name string `json:"name"`
	Mail string `json:"mail"`
	Password string `json:"password"`
}

func PostHandler(c echo.Context) error {
	post := new(User)
	if err := c.Bind(post); err != nil {
		return err
	}
	return c.JSON(http.StatusCreated, post)
}

```

```index.html
{{define "index"}}
<!DOCTYPE html>
<html>
<head>
  <meta charset='UTF-8'>
  <title>post</title>
</head>
<body>
<div id="content"></div>
NAME : <input type="text" id="js-store-name"><br>
MAIL : <input type="email" id="js-store-mail"><br>
PASS : <input type="password" id="js-store-password"><br>
<button id="js-submit">submit</button>
<script>
  const submit = document.getElementById("js-submit");
  submit.addEventListener("click", () => {
    const name = document.getElementById("js-store-name").value;
    const mail = document.getElementById("js-store-mail").value;
    const password = document.getElementById("js-store-password").value;
    fetch(`/signup`, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        name,
        mail,
        password
      })
    }).then((response) => {
      return response.json();
    }).then((res) => {
      document.getElementById('content').innerHTML = `
      name：${res.name}<br>
      Mail：${res.mail}<br>
      PASSWORD：${res.password}<br>`;
    });
  });
</script>
</body>
</html>
{{end}}
```

## まとめ
すごく簡単にできました。
Echo自体がシンプルなフレームワークなので、とても使いやすいと感じました。
次はDBに接続しようかなと思います。
webpack2でSemantic UI Reactを使う

超かっこいい[Semantic UI React](http://react.semantic-ui.com/introduction)をwebpack2で使う方法をメモります。

# Semantic UI Reactをインストール

```
$ npm install --save semantic-ui-react 
$ npm install --save-dev semantic-ui
```

コマンドライン上で色々質問されるので、答えます。どれを選んでもいいですし（カスタマイズしたい場合はCustom）どこに保存させてもいいです。完了すると指定したフォルダに、semanticフォルダが出てきます。これはまだ完成品ではないのでgulpでビルドする必要があります。

# Gulpでビルド

```
$ npm i -g gulp
$ cd semantic
$ gulp build
```

これでsemanticフォルダの中にdistフォルダができて、その中にsemantic.min.cssがあります。これをindex.jsでインポートします。

```
import '../semantic/dist/semantic.min.css';
```
上記パスはsemanticフォルダを保存した場所に合わせます。

# ボタンを表示させてみる

```Hoge.js
import { Button } from 'semantic-ui-react'

class Hoge extends Component {
  render() {
    return (
      <Button>Hello</Button>
    );
  }
}
```

これでスタイルも反映されたかっこいいボタンが表示されます。
[Swift]Optional<Wrapped>周りのメモ

##非オプショナル型
```swift
// 何もついてない場合は、非オプショナル型
let nonOptional: Int = 1
// type(of)で型名を調べてみると
type(of: nonOptional) //-> Int
```
##オプショナル型
```swift
// ?がついてたらOptional<Wrapped型>
let optional: Int? = 1
type(of: optional) //-> Optional<Int>

// ?は実はシンタックスシュガーで以下と同義
let optionalFull: Optional<Int> = 1
type(of: optionalFull) //-> Optional<Int>
```

###オプショナル型を非オプショナル型にアンラップする方法は２つある
```swift
// ① オプショナルバインディングを使う
if let notOptional1: Int = optional {
    // アンラップ対象のオプショナル型がnilの場合はこのIf文に入らない
    type(of: notOptional1) //-> Int
}
// ② 強制アンラップする
let nonOptional2: Int = optional!
// 非オプショナル型に代入する時に!をつけることでアンラップされる
// ただし、nilが入っていると例外が発生する。
```

##ImplicitlyUnwrappedOptional型
```swift
// 変数名ではなく型名に!をつけることで、
// 「暗黙的に矯正されるオプショナル型」を宣言できる
let impUnwrappedOptional: Int! = 1
type(of: impUnwrappedOptional) //-> ImplicitlyUnwrappedOptional<Int>
// これを非オプショナル型に代入できる
let unwrappedOptional: Int = impUnwrappedOptional
// ただし、これも強制アンラップと同じでnilの場合に例外が発生する。
```