OmniAICreator/Qiita-1.07M huggingface dataset:
Chainer v1からChainer v2への移行

Chainerが2.0へアップデートされて後方互換性がなくなったので，AlexNetを例に2.0.2で動かせるように修正した部分を書いていきます．


#ネットワーク部分
主にこの部分が変更になり，それ以外は特に変更する必要がないと思います．
v1.xの際は__init__部分で直接class継承を行なっていましたが，v2.xではwith self.init_scope():を用いるように変更になりました．
それに伴いinit部分の記法が変わっています．これまで` fc_n = L.function( ),` と記述していたのに対して，` self.fc_n = L.function( )`というように`self.`を追加し，最後の`，`が必要なくなります．

ここの`，`を削除し忘れると`TypeError: 'tuple' object is not callable `となるので注意．
このエラーでデータセットの方が悪いのかと思ってどハマりしました．
 
```python:v1.x_Alex.py
class Alex(chainer.Chain):
  def __init__(self):
    super(Alex, self).__init__(
      conv1=L.Convolution2D(None,  96, 11, stride=4),
      conv2=L.Convolution2D(None, 256,  5, pad=2),
      conv3=L.Convolution2D(None, 384,  3, pad=1),
      conv4=L.Convolution2D(None, 384,  3, pad=1),
      conv5=L.Convolution2D(None, 256,  3, pad=1),
      fc6=L.Linear(None, 4096),
      fc7=L.Linear(None, 4096),
      fc8=L.Linear(None, 1000),
    )
  self.train = True
...
```
```v2.x_Alex.py
class Alex(chainer.Chain):
  def __init__(self):
    super(Alex, self).__init__()
    with self.init_scope():
      self.conv1 = L.Convolution2D(None,  96, 11, stride=4)
      self.conv2 = L.Convolution2D(None, 256,  5, pad=2)
      self.conv3 = L.Convolution2D(None, 384,  3, pad=1)
      self.conv4 = L.Convolution2D(None, 384,  3, pad=1)
      self.conv5 = L.Convolution2D(None, 256,  3, pad=1)
      self.fc6 = L.Linear(None, 4096)
      self.fc7 = L.Linear(None, 4096)
      self.fc8 = L.Linear(None, 1000)
...
```

また，学習時にのみ反映させるtrainが関数内から削除され，`with chainer.using_config()`で指定しています．

```
model = L.Classifier(Alex())
with chainer.using_config('train',False):
  y = (x)
```
基本的にこの`chainer.config`で設定を行うのが共通になるらしく，`usecudnn`もこれで設定することになっています．
`chainer.config.use_cudnn = 'never'` と記述すると一括で使用しない設定にできます．

#反復部分
変えないと動かない部分はありませんが，trainer.extendの種類が増えています．

```
if extensions.PlotReport.available():
  trainer.extend(extensions.PlotReport(['main/loss', 'validation/main/loss'],
                 'epoch', file_name='loss.png'))
  trainer.extend(extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'],
                'epoch', file_name='accuracy.png'))
```
と記述することで自動でlossとaccuracyのグラフが出力されるようですが，自分の環境では入っているはずのmatplotlibがないと言われてうまく動きませんでした．


#動かしてみて
変更して実際に動かして見た感じですが，一般的なLinearだけで構成されているfeed-forwardネットワークは特に今までと変わらなかったのですが，AlexNetをベースにしたネットワークでは極端に学習が遅くなっている気がします．
おそらく書き方が悪いのかと…



こちらの公式にその他の変更点も書かれています
[Chainer docs](https://docs.chainer.org/en/stable/upgrade.html)
i18next tipsその1

PersoniumのOSS開発で下記の問題を解決したので、みなさんに共有します。

[Original記事](https://gist.github.com/dixonsiu/921d26bbc50632b6872a57465bc521c0)  

# 問題  
メッセージ/ラベルを英語に翻訳してHTMLタグに書き込みましたら、言語（例：日本語）を変換したでも該当メッセージ/ラベルは英語のままです。

# 悪い使い方  
1. 下記のコマンドを実行する。  

        $('dispMsg').html(i18next.t("msg.error.fileNotFound");

1. HTMLの結果。  

        <div id="dispMsg">File not found.</div>

1. 日本語に変換

        i18next.changeLanguage("ja");
        $('[data-i18n]').localize(); // need jQuery-i18next

1. HTMLの結果（英語のまま）  

        <div id="dispMsg">File not found.</div>

# 正しい使い方  
1. 下記のコマンドを実行する。  

        $('#dispMsg').attr("data-i18n", "msg.error.fileNotFound")
            .localize();

1. HTMLの結果。

        <div id="dispMsg" data-i18n="msg.error.fileNotFound">File not found.</div>

1. 日本語に変換

        i18next.changeLanguage("ja");
        $('[data-i18n]').localize(); // need jQuery-i18next

1. HTMLの結果（日本語になった!!!）  

        <div id="dispMsg" data-i18n="msg.error.fileNotFound">ファイルがないです。</div>
【MPAndroidChart】リアルタイムでデータを更新していく複数の折れ線グラフ

　Androidのアプリ内でグラフを描画する際にMPAndroidChartというライブラリを使うことがあるのですが，つい最近音声データをリアルタイムでグラフ化するアプリを作りました．
　リアルタイムで折れ線グラフを更新していくサンプルプログラムはライブラリを落とすことで見ることができます．しかし，サンプルコードには折れ線グラフ1本を描画するもので，複数のグラフの描き方は載っていませんでした．（どこかに載ってたのかもしれませんが）という訳で今回は複数の折れ線グラフをリアルタイムで更新していくプログラムのサンプルを載せます．

# サンプルプログラムを読む
　取り敢えず[MPAndroidChart](https://github.com/PhilJay/MPAndroidChart)のライブラリを落としてサンプルプログラムを見てみます．目的のプログラムは次の場所にあります．
`MPAndroidChart-3.0.2/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RealtimeLineChartActivity.java`

```RealtimeLineChartActivity.java

 private LineChart mChart;

 private void addEntry() {

        LineData data = mChart.getData();

        //dataの中身が空の場合mChartからグラフデータを取得
        if (data != null) {
            //リアルタイムでデータを更新する場合はILineDataSetを使う
            //データをセットする際にインデックスを指定
            ILineDataSet set = data.getDataSetByIndex(0);

            //setの中身が空の場合dataに追加
            if (set == null) {
                set = createSet();
                data.addDataSet(set);
            }

            //新しいデータを追加
            data.addEntry(new Entry(set.getEntryCount(), (float) (Math.random() * 40) + 30f), 0);

            //更新を通知
            data.notifyDataChanged();
            mChart.notifyDataSetChanged();
            mChart.setVisibleXRangeMaximum(120);
            mChart.moveViewToX(data.getEntryCount());
        }
    }
```
　上はデータを追加する関数です．サンプルではこの関数をなんども呼び出し，中でてきとうな値を生成して新しいデータとして追加しています．
　流れとしては次のような感じです．
　　　 LineDataを作成してLineChartからデータを取得
　　→ ILineDataSetを作成してデータをセット（この時インデックスを指定する）
　　→ LineData内にILineDataSetを追加（インデックスでどのグラフにデータを追加するかを指定）
　　→ 更新を通知
　ILineDataSetを作成する際にインデックスを指定しますが，ILineDataSetを複数作成しインデックスを変えることで複数のグラフを書くことができます．

# 複数のグラフを描画してみる
```RealtimeLineChartActivity_kai.java

 private LineChart mChart;

 private void addEntry() {

        LineData data = mChart.getData();

        //dataの中身が空の場合mChartからグラフデータを取得
        if (data != null) {
            //リアルタイムでデータを更新する場合はILineDataSetを使う
            //データをセットする際にインデックスを指定
            ILineDataSet set1 = data.getDataSetByIndex(0);
            //2本目のグラフ（インデックスを1に）
            ILineDataSet set2 = data.getDataSetByIndex(1);

            //setの中身が空の場合setを初期化してdataに追加
            if (set == null) {
                set1 = createSet();
                set2 = createSet();

                data.addDataSet(set1);
                data.addDataSet(set2)
            }

            //新しいデータを追加
            //引数でデータを追加するグラフを指定
            data.addEntry(new Entry(set1.getEntryCount(), (float) (Math.random() * 40) + 30f), 0);
            data.addEntry(new Entry(set2.getEntryCount(), /*Float型の何かてきとうな値*/), 1);

            //更新を通知
            data.notifyDataChanged();
            mChart.notifyDataSetChanged();
            mChart.setVisibleXRangeMaximum(120);
            mChart.moveViewToX(data.getEntryCount());
        }
    }
```
　これで複数のグラフを描画することができます．
![Screenshot_20170803-145625.jpg](https://qiita-image-store.s3.amazonaws.com/0/156796/e9eeddb5-733e-2ef9-bf8f-16593cca9de1.jpeg)
　全部で9本の線を描画しました．最大でどのくらいの本数を引くことができるかは不明ですが，特に問題なく動いています．
（メモ）position:sticky内のformにfocusあてたらスクロールしてしまう。

簡単なメモで恐縮です。

```
<section style="position:sticky; top:10px; z-index:10;">
<form>
<input type="text" />
</form>
</sction>
<section class="go-scroll">
</section
```
的なものがあった場合、

スクロールして、「position:sticky」が生きている（固定されている）状態でinputにfocusをあてると、

- andorid(chrome) ： 背後でスクロールしてた[.go-scroll]がトップに戻る
- PC(chrome) ： スクロール開始前の状態に戻る

という状況になっており...。

iOS(safari)で、時刻表示のところをタップするとトップに戻るを使えるように保つため、
どこかのsectionに「overflow-y: scroll;」的なことができないので...

- 「position:sticky」やめる
- jsでscroll量取得して、クラス付け替え
- 「position:fixed」で対応

にしなきゃなのね。。。
わーい！sticky便利～～って思ったのに残念。

しかも、focusあとに半角入力と、全角入力でもふるまい違うんだよな。。。
なんだろ。。。
印刷装置PRT01が見つからない。

### ジョブログを見ていると、こんなメッセージに出くわすことが良くある。

```
メッセージ. . :   印刷装置PRT01が見つからない。                      
原因−−印刷装置が見つかりません。回復手順−−印刷装置を作成(CRTDEVPRT
 マンド）するか，あるいは印刷装置名が正しくない場合には，印刷装置名を変更
 てからコマンドをやり直してください。 
```

上記のメッセージへの対策を V7R3 環境で試してみました。

## 何でこのメッセージが出るの
### 5250 画面からプログラム実行している場合

#### 例えば、下記の条件が重なっている

- サインオンしたユーザープロファイルの省略時の印刷装置が `*WRKSTN` 。
- サインオン中に使っている表示装置の記述の中で`PRTDEV(*SYSVAL) OUTQ(*DEV)` が指定されている。表示装置、とは `WRKDEVD` の画面で、タイプが `5555` と表示されるやつ
- システム値 `QPRTDEV` に `PRT01` が指定されている。

#### PRT01 に出力されてしまうまでの流れの例

1. サインオンしたユーザープロファイルの中で `*WRKSTN` が指定されているので装置記述 (DEVD) を見に行く。
2. 装置記述の中で `OUTQ(*DEV)` が指定されているので `PRTDEV` を見に行く。
3. `PRTDEV(*SYSVAL)` が指定されているので `QPRTDEV` を見に行く。という流れになる。

#### 対策

- `WRKUSRPRF` で省略時の印刷装置を変更するか、`WRKDEVD` の `OUTQ` か、`PRTDEV` を変更すれば、`PRT01` 以外に変更できます。
- システム全体のデフォルト値を変更する権限のある人なら、`QPRTDEV` そのものを変更してしまうという必殺技もあり。
- 表示装置がたくさん存在する場合は、`WRKDEVD` で変更するのは大変。`WRKDEVD` での変更は、5250 画面で操作する表示装置が `DSP01` だけ、とかごく少数しかない場合向き。
- もちろんのことですが、`PRT01` を用意するという対策もあります。物理的なプリンタを用意するにはお金がかかるので仮想装置 `*VRT` として作ってしまうのが楽です。下記はその２つの例です。
   - `CRTDEVPRT DEVD(PRT01) DEVCLS(*VRT) TYPE(5553) MODEL(B01) IGCFEAT(2424J2)`
   - `CRTDEVPRT DEVD(PRT01) DEVCLS(*VRT) TYPE(5583) MODEL(200) IGCFEAT(2424J2)`

### バッチプログラムとして実行している場合

#### さらにジョブ記述 (JOBD) が関わります。

- ジョブ記述の中でも、表示装置の記述と同じく `PRTDEV` と `OUTQ` が指定できます。
    - 装置記述では使用できなかった、`*WRKSTN` と `*USRPRF` がジョブ記述では使えます。
- ジョブ記述のなかで `USER` という項目もあって、特定のユーザープロファイル名を書くことも、`*RQD` としてジョブをリクエストしたユーザーとすることもできます。

#### PRT01 に出力されてしまうまでの流れの例。
5250画面の場合に比べ、流れが一段階長くなる感じです。

1. ジョブ記述に `USER(とあるユーザー) PRTDEV(*USRPRF)` が指定されているので「とあるユーザー」のユーザープロファイルを見に行く。
2. ユーザープロファイルの中で `*WRKSTN` が指定されているので装置記述 (DEVD) を見に行く。
3. 装置記述の中で `OUTQ(*DEV)` が指定されているので `PRTDEV` を見に行く。
4. `PRTDEV(*SYSVAL)` が指定されているので `QPRTDEV` を見に行く。という流れになる。

#### 対策

- ジョブ記述で `OUTQ` を変える。
- ジョブ記述で `OUTQ(*DEV)` にするなら `PRTDEV` を変える。
- 上記のほか、5250画面の場合も参照してください。
[localstack] ローカル環境にAWSサービスのモックを作り開発をする


[AtlassianのLocalStackを使ってみてなんとなく理解するまでのお話](http://qiita.com/kojiisd/items/8d7b98fb7f3c8f871f96) の通りなのですが本家のgithubを見るとこんな感じになってたので現行どうするかを備忘録としてメモします。

　
　![スクリーンショット 2017-08-02 16.33.49.png](https://qiita-image-store.s3.amazonaws.com/0/52141/230e0fbf-ea28-4116-ef63-62a99756bf68.png "スクリーンショット 2017-08-02 16.33.49.png")

Atlassian/localstack -> localstack/localstack に変更になってます。

# 前提
- Mac(macOS Sierra)
- Docker Commnity Edition (Version: 7.06.0-ce-mac19)

- dockerコマンドがコンソール上で実行可能であること
- AWS CLIの設定が完了していること

# イメージの準備

```bash:pull
docker pull localstack/localstack
```

# 起動

```bash:run
docker run -it -p 4567-4582:4567-4582 -p 8080:8080 localstack/localstack

```

起動させたらコンソールは放置



# 確認
ブラウザを立ち上げ

```
http://localhost:8080/
```


へアクセス


こんな画面が立ち上がってれば安心して大丈夫

# エンドポイント
githubから転記してきましたが、変わってる可能性があるので必ず本家で確認して下さい。
https://github.com/localstack/localstack

|サービス名|エンドポイントURL|
|:------:|:--------------:|
|API Gateway|http://localhost:4567|
|Kinesis| http://localhost:4568|
|DynamoDB|http://localhost:4569|
|DynamoDB Streams |http://localhost:4570|
|Elasticsearch| http://localhost:4571|
|S3| http://localhost:4572|
|Firehose| http://localhost:4573|
|Lambda| http://localhost:4574|
|SNS| http://localhost:4575|
|SQS| http://localhost:4576|
|Redshift| http://localhost:4577|
|ES (Elasticsearch Service)| http://localhost:4578|
|SES| http://localhost:4579|
|Route53| http://localhost:4580|
|CloudFormation| http://localhost:4581|
|CloudWatch| http://localhost:4582|

# AWS CLI
CLIコマンドを発行する場合
```--endpoint-url``` で上記のエンドポイントを指定して使用します。
デフォルトのリージョンをconfigで指定していない場合、コマンドで```--region``` を指定する必要があります。

```bash:サンプル(SQS)
aws sqs create-queue \
        --queue-name 'SAMPLE' \
        --region ap-northeast-1 \
        --endpoint-url http://localhost:4576 \
        --profile $myProfile
```

# SDK（nodejs）

```javascript:サンプル
'use strict';

const AWS = require('aws-sdk');
const endPoint = new AWS.Endpoint('http://localhost:4578');
const region = 'ap-northeast-1';
const s3 = new AWS.S3({ endpoint: endPoint, region: region });
```

基本的にはエンドポイントに上記URLを指定するだけでAPIをリクエストすることが出来ます。
ElasticSearchはすでに使用可能な状態のElasticSearchが動いています。ESの方はドメイン作成とかのAPI用のモックって感じですね。
開発の際に特にデータ系は何かレスポンスが必要なので地味に使えるツールですね
Running Jar Application on Docker Container


## 1. Compile Scala and Create a Jar File
Just follow the instuction here then you can create a jar file: https://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly

Note that if you are using Maven, set META-INF directory under main/resources folder instead of main/java. Refer the link: https://intellij-support.jetbrains.com/hc/en-us/community/posts/206872335-How-to-create-executable-JAR-using-Intellij-

## 2. Run Docker Container with Java 8
Here is the official repository for OpenJDK docker image. 
https://hub.docker.com/_/openjdk/

You can pull the docker image to your local repository.

```
docker pull openjdk:latest
```

Then, run a new container from the image.

```
[root@sunny ~]# docker run -it openjdk:latest bash;
root@6c5fbb0f16c3:/#
```

Check the version of Java

```
root@6c5fbb0f16c3:/# java -version
openjdk version "1.8.0_141"
OpenJDK Runtime Environment (build 1.8.0_141-8u141-b15-1~deb9u1-b15)
OpenJDK 64-Bit Server VM (build 25.141-b15, mixed mode)
```

Also, you can check the status of running docker containers with `docker ps` command.

```
[root@sunny ~]# docker ps
CONTAINER ID        IMAGE                                                                                      COMMAND             CREATED             STATUS              PORTS               NAMES
6c5fbb0f16c3        openjdk:latest                                                                             "bash"              17 minutes ago      Up 17 minutes
```

## 3. Run Jar Application on Container
You can copy files in the docker host onto a docker conainer using `docker cp` command: https://docs.docker.com/engine/reference/commandline/cp/

```
[root@sunny ~]# docker cp ./test.jar 6c5fbb0f16c3:/home/test.jar
```

Finally, run the jar as usual. 
(I used an app which send get request to Isilon REST API for the test.)

```
root@6c5fbb0f16c3:/# java -jar /home/test.jar
Sending HTTP Request to https://10.32.2.26:4088/platform/3/statistics/summary/drive
_platform_3_statistics_summary_drive
```
いまさら Google マップのマイマップを作成して共有する方法

# ほんにいまさら～～
って位、いまさら感がするネタｗ
仕事の合間で勉強する時間があったのでいまさらこんなネタ

単純に地図情報をのっける方法

> [【コピペOK】GoogleMapの地図をレスポンシブサイトに埋め込む方法](https://inthecom.net/718)

マイマップを作ってピン情報を共有する方法

> [新しいGoogleマップでのマイマップを作成して共有する方法](https://hep.eiz.jp/share-google-map/)

マイマップを使って移動経路を共有する方法

> [Googleマップに移動経路を描き込む（手書き）](http://blog.livedoor.jp/eienf/archives/1035923024.html)
> [新しいGoogleMapのマイマップをホームページに埋め込む時に、位置と縮尺を指定する手順](http://qiita.com/laqiiz/items/7d256108920ff7afbf08)

これも便利そう

> [初めて地図周りの技術に触れた時に作ったまとめ資料](http://qiita.com/laqiiz/items/7d256108920ff7afbf08)
MacのSlackアプリで突然チームに接続できなくなったので問い合わせた際のメモ

## 事象

昨日まで普通に使えてたのに、以下の表示がされて
Slackのデスクトップアプリで所属しているチームのチャットが
一切表示されなくなってしまう現象に見舞われた。

>For some reason, Slack couldn't load

![スクリーンショット 2017-08-02 10.39.40.jpg](https://qiita-image-store.s3.amazonaws.com/0/113982/e1d78b08-6f97-7f78-330b-a12a61d02f67.jpeg)

Test your connectionをやってみても正常に終了(ブラウザでは正常に表示できる)。

![スクリーンショット 2017-08-02 10.39.10.png](https://qiita-image-store.s3.amazonaws.com/0/113982/79f25b6e-3e85-d0a9-eb08-6c90383786ca.png)

Slackアプリをを何らかの設定でブロックしているかも？という記述には一切心当たりがなかった。
PC再起動してもSlackのアプリ再インストールしても改善せず、
途方に暮れてSlackのヘルプデスクへ問い合わせ。

## 解決に至った方法

Slackのメニューバーから
*Help > Clear Cache and Restart* を試してみて！
とご回答いただき、やってみたら正常に使えるようになった。

※Slackの問い合わせデスクは基本英語のみだけど、
　時間がかかってもいいなら日本語で対応させていただきますと
　問い合わせ1報目から5分後くらいに回答いただいていろいろやりとり進みました。対応早い・・・

<img width="367" alt="help.png" src="https://qiita-image-store.s3.amazonaws.com/0/113982/aef5f032-c1c3-3e8f-7025-ffaf11ef270a.png">
CentOS7でCouchDB2.0のインストールを試してみたメモ

# tl;dr
CentOS7.3にインストールしてみたメモ。
とりあえず、**実用する人はまだ1.6使ったほうがよさそう。**

[本家](http://couchdb.apache.org)のメインストリームが2.0になっているっぽいのに、いまのところ2.0まだソースからコンパイルしないと行けない様子。しかも[daemon化](http://docs.couchdb.org/en/2.0.0/install/unix.html#running-as-a-daemon)にも対応してないっぽい。試したい方だけ以下参考まで。

#インストール

2.0の動作をまだよく理解していないので、今回はSELinuxは無効にしています。

```
$ getenforce
Permissive
```

## 依存関係
[本家に乗っているもの](http://docs.couchdb.org/en/2.0.0/install/unix.html#redhat-based-fedora-centos-rhel-systems)だけではerlangのライブラリ等が不足しているのでコンパイルできません。
とりあえず以下で成功しました。

```bash:
$ sudo yum install autoconf autoconf-archive automake gcc-c++ curl-devel erlang-asn1 erlang-erts erlang-eunit erlang-os_mon erlang-xmerl erlang-erl_interface erlang-reltool help2man js-devel-1.8.5 libicu-devel libtool perl-Test-Harness
```

## ソースダウンロードしてインストール
ソースのダウンロード元は、[本家](https://www.apache.org/dyn/closer.lua?path=/couchdb/source/2.0.0/apache-couchdb-2.0.0.tar.gz)から好みのミラーを選んでください。

コンパイルは`make release`でいけますが、インストールは`make install`が2.0では未対応みたいなので、自分でコピーしろってコメントされています。(のちほどやります）

```bash:
$ curl -O http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/couchdb/source/2.0.0/apache-couchdb-2.0.0.tar.gz
$ tar -xvf apache-couchdb-2.0.0.tar.gz
$ cd apache-couchdb-2.0.0
$ ./configure
$ make release
$ sudo cp -r rel/couchdb /usr/local/lib
```

## 専用ユーザーの追加

本家では、システムユーザーでログインとか、ホームディレクトリ無効にしたユーザーで、ホームディレクトリにコピーとか意図がよくわからなかった。普通にcouchdbユーザー作って無難に`/opt`にでもインストールしたほうがよさそう。

さっきmakeした`apache-couchdb-2.0.0`ディレクトリでそのまま作業します。

ユーザーの追加

```
$ sudo useradd -r -s /sbin/nologin -c "CouchDB Administrator" couchdb
$ sudo passwd couchdb
```

ファイルのコピー

```
$ sudo cp -r rel/couchdb /opt
$ cd /opt/couchdb
$ sudo chmod 644 etc/*
$ sudo chown -R couchdb:couchdb .
```
## 起動

バイナリを起動するだけ

```
$ sudo /opt/couchdb/bin/couchdb
```

## systemd

一応systemdで使えるようにしてみました。

serviceファイルを作成します。

```
$ sudo vi /etc/systemd/system/couchdb.service
```

```ini:/etc/systemd/system/couchdb.service
[Unit]
Description = Apache CouchDB 2.0

[Service]
ExecStart = /opt/couchdb/bin/couchdb
ExecStop = /bin/kill ${MAINPID}
Restart = always
Type = simple
User = couchdb
Group = couchdb

[Install]
WantedBy = multi-user.target
```

追加したサービスをsystemctlで有効にする

```bash:
$ sudo systemctl daemon-reload
```

起動

```bash:
$ sudo systemctl start couchdb
```
停止

```bash:
$ sudo systemctl stop couchdb
```

自動起動を有効に

```bash:
$ sudo systemctl enable couchdb
```

# firewall

外からアクセスするため、TCPポート5984を開けておきます。

```
$ sudo firewall-cmd --add-port=5984/tcp --permanent
$ sudo firewall-cmd --reload
```
ちなみに5986 はローカル用、4369はEPMDポート（Erlangでクラスタやるときなどに使われる）

# CouchDB

ドキュメント指向DBってKVS以上列指向未満な使い勝手で好み。MongoDBだとそのままyumでインストールできて便利なんだけど、RDB脳に汚染されて複雑性を持ち込む悪癖がでるという勝手な偏見を持っている自分はあえてCouchDBとか使っています。

そのうち`yum`とか`apt`とか`systemd`対応してくれなかったら、2.0はつかわないかも。環境再現面倒なのはキライです。

思ったほど普及もしてなさそうだし日本語ドキュメント少なくて面倒なので、商用だったら素直に[Cludant](http://www-03.ibm.com/software/products/ja/ibm-cloudant)とか[CouchBase](https://www.couchbase.com)使えば良いと思います＾＾；ちなみにMobile用だと[TouchDB](https://github.com/couchbaselabs/TouchDB-iOS)っていうもあるようです。
Laravelのテストでテスト用のDBを使う

調べた対象、Laravel5.2
今更5.2とか言わないで諸事情…、しかしドキュメントによると5.4でも同じ感じっぽい。

まずはphpunit.xmlにテスト用のDB情報を追加。
これでテストを実行したときに.envでの定義を上書きする。

```phpunit.xml
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="DB_DATABASE" value="test_database"/>
        ...
    </php>
</phpunit>
```

artisanでmake:testして作られたテストファイルにtraitを追加する。
これでテスト開始前にテストDB上でマイグレーションが実行され、テストが終わると毎回リセットされる。

```
<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use DatabaseMigrations;

```

### 参考
https://laravel.com/docs/5.4/database-testing#using-migrations
gitのソースコードを読んでいると、hashmapを比較する関数にぶち当たった

gitのソースコードを読んでいると、hashmapを比較する関数にぶち当たった。

https://github.com/git/git/blob/master/attr.c#L79

```c
/* attr_hashmap comparison function */
static int attr_hash_entry_cmp(void *unused_cmp_data,
			       const struct attr_hash_entry *a,
			       const struct attr_hash_entry *b,
			       void *unused_keydata)
{
	return (a->keylen != b->keylen) || strncmp(a->key, b->key, a->keylen);
}
```
ここで興味深いのは、strncmpで比較する前に、長さを比較しているという点である。長さが同じでない場合は、strncmpの比較を実行せずに、1を返す。
そうでない場合は、strncmpによって比較した結果を返すのである。
二つのハッシュのエントリーが同じだった場合、０を返すべきであるので、利用方法としては、「同じであるか、同じでないか」のみを気にする関数であることが推測できる。
長さが同じでない場合は、必ず１を返すということは、例えば、この二つのハッシュエントリが、「どう違うか」ということを気にする場合には、論理的に整合性が合わないと思う。

（追記）
ここで比較するのは、hashmapのエントリーのキーの文字列同士みたいです。同じキーを探す処理ということで、同じか違うかの判断だけでいいみたいです。
uasiさん
shiracamusさん
ありがとうございました

この関数を引用しているのは、以下の部分である。

https://github.com/git/git/blob/master/attr.c#L90

```c
/* Initialize an 'attr_hashmap' object */
static void attr_hashmap_init(struct attr_hashmap *map)
{
	hashmap_init(&map->map, (hashmap_cmp_fn) attr_hash_entry_cmp, NULL, 0);
}
```
ここでは、hashmap_cmp_fnの関数の型で、attr_hash_entry_cmpの関数を、hashmap_initの関数に代入している。
hashmap_initについては、hashmap APIの関数の一つで、~~gitの中には、実装部分はない。~~ 実装は、以下のところにある。
https://github.com/git/git/blob/v2.14.0-rc1/hashmap.c#L153-L169


hashmap APIであることは、以下のところに書いてあった。
http://metaphor.ethz.ch/x/man/git/technical/api-hashmap.html

ちょっとソースコードトレースしても、C言語の構造がよくわからないので、解説はこれ以上できない。
知ってる人がいたら教えて欲しい
C言語は、僕は、各種の言語の中で最も難しいと思う。人によって異論はあるかもしれないが。
私が本当に業務で作成したRESTful APIで学んだこと - ①RESTfullにする目的と概要を考えよう

# はじめに

- 業務でRESTful APIを作ったので、それを開発するまでの道のりを記載していきます。
- 今回はざっとRESTfulについて知った上で、プロジェクト向けにまずは自分なりに目的や概要などをざっくりと纏め直しました内容を記載します。
- 今後、もう少し突き詰めたAPIの仕様や設計内容などを書いていければとおもいます。

# 背景

- フレームワークの特性上、通常はMVC（VC）として疎結合な思想であるはずだが、現状の他の案件だと設計や実装フェーズでの切り離しが難しい。
- 上記のように拡張性が乏しいため、改修工数が肥大したり影響範囲が広くなってしまう。
- モデル層のテストが困難。現状、ほとんどが画面ベース（コントローラ層、ビュー層）のテストしか満たされていない。
- ビューの依存度が高いため、HTMLやほかのプロジェクトとの一元化が困難となってしまう。
- データを扱う非同期処理が複雑になってしまう。
- 目的に合わせて似たようなモジュールを作ったり、複製したり冗長になってしまう。
- 画面や機能に応じたリソースの俯瞰ができない。（どこに何の情報を利用しているのかが不明）

# 目的

拡張性や保守性を重視するために、RESTful APIを用いた構成にする。
RESTful思想の中で、特に以下のようなリソース志向を重要視する。

- プログラムはリソースが表現するURIにアクセスする。
- ステートレスにすることで追加改修などに対応した影響を抑えた拡張性を持たせる。

# 具体的に実施する内容

## 画面出力部とリソース処理部をプロジェクトベースで分離する

- 役割として明確にし、役割に応じた機能だけをそれぞれ実現する

## 情報のREAD／WRITEを一元的に集約し表現する

- URL＋パラメータで表現ルールを設定することで、柔軟かつ拡張的に情報へのアクセスが可能にする。
- イメージとしてはSolrのURL構造形式。

## レスポンスをファイル形式にする

- 情報のレスポンスをファイル形式にすることで、プロジェクトやサービス、HTMLなどの静的ページを跨って利用できるようにする。

## リクエストメソッドは以下の４種類に定義する

|#|リクエストメソッド|CRUD|用途|
|:---|:---|:---|:---|
|1|GET|READ|リソースの参照|
|2|POST|CREATE|リソースの新規作成|
|3|PUT|UPDATE|リソースの更新|
|4|DELETE|DELETE|リソースの削除|

## URLの構成のルールについて

- URLに動詞を含まない。
- URLにadd/update/deleteを用いるのはリクエストメソッドと二重に意味を持たせるのでNG。
- URLにeditを用いるのは△（どうしてもというときのみ）。
- なるべく名詞に近づける（confirm→confirmation）。

### 例) GETの場合

```
× GET http://example.com/blog/getEntries
○ GET http://example.com/blog/entries
```

### 例) POSTの場合

```
× POST http://example.com/blog/entries/add
○ POST http://example.com/blog/entries
```

### 例) DELETEの場合

```
× POST http://example.com/blog/entries/30/delete
○ DELETE http://example.com/blog/entries/30
```

## 擬似静的化URLとパラメータの役割

例) http://example.com/blog/entries?page3=&lang=ja

### 擬似静的化URL

リソースの意味や場所を示す

```
http://example.com/blog/entries
```

### パラメータ

クライアント側の意思に基づく選択肢を示す

```
?page3=&lang=ja
```

## ステータスコードのルール

- 意識的に仕様するコードは概ね次のものに収束する。
- クライアント側が悪い場合は400系のステータスコードを用いる。
- サーバ側が悪い場合は500系のステータスコードを用いる。

### 200系
200	201	204

### 300系
301	303	307	(304)

### 400系
400	404	409	(401,403)

### 500系
500
Unity2017とVS2017でのHoloLens開発環境の構築


HoloLnesを開発できるようにするまでのメモです。
※記憶を元に書いておりますので、間違いなどありましたらご指摘お願いします。

# 参考
・HoloLensアプリの開発を始めるまでの資料を作りました
http://www.naturalsoftware.jp/entry/2017/01/17/112344
・HoloLens のアプリ開発はじめました
http://tips.hecomi.com/entry/2017/02/12/211458

# 必要なもの

## HoloLens実機
* Holographic Remoting
    * HoloLensでストアにアクセスし、インストール

## 開発PC
* Windows 10(Home/Pro)
* [Windows SDK](https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk) - (VisualStudioからインストール可)
* [Unity](https://unity3d.com/jp/unity)(今回は2017.1を使用)
* [VisualStudio](https://www.visualstudio.com/ja/downloads/?rr=https%3A%2F%2Fsupport.microsoft.com%2Fja-jp%2Fhelp%2F4015967%2Ftroubleshooting-visual-studio-2017-installation-and-upgrade-failures) - (Unityを入れると自動的に入る)
※インストールは下記を参照してください

# インストール・設定
## Unity
「Windows Store .NET Scripting Backend」を選択する

## VisualStudio
「Windows10 SDK」をインストールする
VisualStudio Installerを開き、お使いのVisualStudioの「変更」をクリック
（VisualStudio Installerを更新してくださいと出て起動できない場合は[ココ](https://support.microsoft.com/ja-jp/help/4015967/troubleshooting-visual-studio-2017-installation-and-upgrade-failures)を参照）
![2017-08-03_104922.png](https://qiita-image-store.s3.amazonaws.com/0/163818/96ae12ca-0cae-e583-de26-1bd31d70ca11.png)

「個別コンポーネント」タグを選択し、「Windows 10 SDK」をチェックし、右下の変更をクリック

![2017-08-03_105242.png](https://qiita-image-store.s3.amazonaws.com/0/163818/dbbf7186-c1ce-cd92-3249-e73864c38cb9.png)

# UnityとHoloLensでデバッグ
* Edit→Project setting→Playerを開き、「Virtual Reality Supported」にチェックを入れる。 
* Windows Holographicを追加する。
![2017-08-03_120148.png](https://qiita-image-store.s3.amazonaws.com/0/163818/d2e49b75-399c-1898-6623-fdb9a53e557b.png) 
* Window→Holographic Emulationを開き、Emulation Modeの「Remote to Device」を選択    
* HoloLensの「Holographic Remotiong」を起動    
* 「Remote Machine」にHoloLensに表示されているIPアドレスを入力    
* 「Connect」クリックし、状態が「Connecting」になれば接続完了   
* Unityで再生すると、HoloLens側で動作を見ることができる


# HoloLensにアプリを書き込む
## Unity でのビルド
* File→Build settingsかCtrl+Shift+Bでビルド画面を開く
* Universal Windows Platformを選択
    * インストールされていない場合は「Open Download Page」からダウンロード、インストールを行い再起動
    ![2017-08-03_113127.png](https://qiita-image-store.s3.amazonaws.com/0/163818/439b121a-d548-ac6e-ccc0-2dffe1430221.png)
* 「Target device」を「HoloLens」にする
* 「Build Type」を「D3D」にする（XAMLだとウィンドウタイプになるようです）
* 「SDK」にダウンロードしたバージョンを選択する
* 「Build」をクリックでビルド
![2017-08-03_113924.png](https://qiita-image-store.s3.amazonaws.com/0/163818/c9484927-a501-a33f-e20f-bb3fc37dccec.png)

## Windowsの設定を開発者モードにする
* Windowsの設定画面から「更新とセキュリティ」を選択    
* 左側にある「開発者向け」を選択    
* 「開発者モード」にチェックを入れる

## Visual Studioでのビルド
* Unityのビルドで作成された〇〇（プロジェクト名）.slnを開く
* ビルド設定を「Release」「x86」、[Remote machine」に設定する
* リモート接続ウィンドウが表示されるので、アドレスにHoloLensのIPアドレスを入力
* ビルドを行い、PINコードを聞かれた場合、入力する。PINコードの入手方法は[ココ](https://www.youtube.com/watch?v=JzzjKo0Aqk0&feature=youtu.be)を参照
* HoloLens上でアプリを起動する


# tutorial
https://developer.microsoft.com/en-us/windows/mixed-reality/academy
Makefile から、Go の変数を代入する

Go のプロジェクトで、Makefile を使っている例があるが、今日ちょっとした Tips を学んだので、メモしておきたい。

```go
package main

import "fmt"

var GIT_BASE_DIR = ""

func main() {
	fmt.Printf("GitCurrentBaseDir: %s¥n", GIT_BASE_DIR)
}
```

プロジェクトにこんな感じの go のコードがあった。明らかに `GIT_BASE_DIR` には何も入っていない。実行すると

```
$ go run cmd/*.go
GitCurrentBaseDir: ¥n
```
これは何だろう？と思ったら、Makefile から、 Go の変数に代入するテクニックがあるようだ。

先の main.go を、cmd ディレクトリ配下において、次のような Makefile を書いてみた。

```bash

GIT_BASE_DIR := $(shell git rev-parse --show-toplevel)

run:
	go run  -ldflags="-X main.GIT_BASE_DIR=${GIT_BASE_DIR}" **/*.go
```

実行すると、正しく、git のルートディレクトリが取得できていて、それが代入されているのがわかる。

```
$ make run
go run  -ldflags="-X main.GIT_BASE_DIR=/Users/ushio/Codes/gosample/src/github.com/TsuyoshiUshio/GoWithMake" **/*.go
GitCurrentBaseDir: /Users/ushio/Codes/gosample/src/github.com/TsuyoshiUshio/GoWithMake¥n
```

これは、[Go Tool Link](https://golang.org/cmd/link/) の機能らしい

```
-X importpath.name=value
    Set the value of the string variable in importpath named name to value.
    Note that before Go 1.5 this option took two separate arguments.
    Now it takes one argument split on the first = sign.
```

Go で、ディレクトリの絶対パスとか取りたい時に有効かもですね。

[参考](https://github.com/Azure/acs-engine/blob/master/Makefile)
ASP.Net MVC5 [Authorize(Roles="XXXX")]が正しく動作しない with Identity2

#Identity2を使った認証処理のカスタマイズ

VisualStudioを標準で生成する認証処理では、認証に使用するユーザー・テーブルのIDがstring型になります。
開発しているシステムではstring型では都合が悪いので認証処理をカスタマイズしました。

認証処理のカスタマイズは次の記事が参考になります。
[ASP.NET Identityで独自の認証処理を行う]("http://codezine.jp/article/detail/8868","ASP.NET Identityで独自の認証処理を行う")

ユーザー情報の登録、編集、削除処理を行うUserStoreクラス, ユーザー管理を行うUserManagerクラス、
ロール情報の登録、編集、削除処理を行うRoleStoreクラス, ロール管理を行うRoleManagerクラスを独自で作成したユーザー・テーブル(エンティティ)に合わせて実装します。

#[Authorize(Roles="XXXX")]はどこを参照するのか？
ユーザーのロールはSingInした時に、正常に認証処理のカスタマイズができていればCookieに保存されます。
[Authorize(Roles="XXXX")]をコントローラー内のアクション名の前に書いておくと、
ソフトウェアは、アクションが実行される前にCookieを参照しCookie内に該当するロールが存在する場合、そのアクションを実行します。

#ところが
ロールXXXXのユーザーでログインして、[Authorize(Roles="XXXX")]を適用したアクションにアクセスすると
ログイン画面に飛ばされてしまいました。
(独自でアクション・フィルターを実装？アクションが実行される前に毎回DBアクセス？
ありえん・・なんてことを考えていました。)

#SignIn時に呼ばれるCreateIdentityAsync()の戻り値にロールのClaimを追加してみた。

```C#:SignInManager.cs
var claimsIdentity = UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)
claimsIdentity .AddClaim(new Claim(ClaimTypes.Role, "XXXX"));
```

上記のようにClaimを追加してみたところ、先程までログイン画面に飛ばされてしまった画面にアクセスできるようになりました。
(なるほど、Claim情報はCookieに保存されるのかと納得しました。)


#わざわざロールをClaimに追加しないといけないの？
Identityでロールを管理する仕組みが用意されているのだから、自動でClaimにロールが登録されるようになってるだろうと、Identityライブラリのソースコードを読んでみました。

UserManagerクラスにはSupportsUserRoleフラグが定義されています。
IUserRoleStoreインターフェースを継承してUserStoreクラスが作成されている場合にSupportsUserRoleフラグがTrueになります。

SupportsUserRoleがフラグがTrueの場合に、SignIn処理が実行されるとIdentityライブラリ内でロールをClaimに追加する処理が実行されます。

#IUserRoleStoreインターフェースを継承していたのに、なぜClaimにロールが追加されなかったのか？
UserStoreクラスを実装する時に、IUserRoleStoreインターフェースとIRoleStoreインターフェースを継承していました。
IRoleStoreインターフェースはRoleStoreクラスを実装するためのインターフェースです。
IRoleStoreインターフェースを継承していたために、IUserRoleStoreインターフェースを継承しているか判定する処理で、IUserRoleStoreインターフェースは継承されていないと判定されていました。
従って、UserManagerクラスのSupportsUserRoleフラグがFalseになり、SignIn時にロールがClaimに追加されていませんでした。

#Identityライブラリ
ライブラリの中身を追わないと実装に使えないライブラリって・・・
[ARDUINO]ATMEL STUDIOでC Style UART 通信。

C styleでUARTを利用しようとします。
stdio.hを使っても良いですが、
メモリーを減りたいので
作ってみました。

```c:uart.c
/*
 * UART.c
 *
 * Created: 2017-08-03 10:57:22
 * Author: Dreamwalker
 */ 

 #include "UART.h"

 void UART_INIT(void){

	UCSR0A |= (1 << U2X0);

	UBRR0H = 0x00; 
	UBRR0L = 207;  // 9600bps
	
	/*
	asynchronous
	8bit data
	parity none
     stop bit : 1bit
	*/

	UCSR0C |= 0x06; 

	UCSR0B |= (1 << RXEN0);
	UCSR0B |= (1 << TXEN0);

 }

 unsigned char UART_receive(void){

	while(!(UCSR0A & (1 << RXC0)));
	return UDR0;
 }

 void UART_transmit(unsigned char data){

	while( !(UCSR0A & (1 << UDRE0)) );
	UDR0 = data;

 }

 void UART_printString(char *str){
	for (int i = 0; str[i]; i++)
	{
		UART_transmit(str[i]);
	}
 }

 void UART_print8bitNumber(uint8_t num){
	char numString[4] = "0";
	int i, index = 0;

	if (num > 0)
	{
		for (i = 0; num != 0; i++)
		{
			numString[i] = num % 10 + '0';
			num = num / 10;
		}
		numString[i] = '\0';
		index = i - 1;
	}

	for (i = index; i >= 0; i--)
	{
		UART_transmit(numString[i]);
	}
 }

 /***
 *  number -> string function
 *  @param : num
 */
 void UART_print16bitNumber(uint16_t num){
	char numString[6] = "0";
	int i, index =0;
	if (num > 0){
		for (i = 0; num != 0; i++){
			numString[i] = num % 10 + '0';
			num = num / 10;
		}
		numString[i] = '\0';
		index = i - 1;
	}

	for (i = index; i >= 0; i--){
		UART_transmit(numString[i]);
	}
 }

  void UART_print32bitNumber(uint32_t num){
	  char numString[11] = "0";
	  int i, index =0;
	  if (num > 0){
		  for (i = 0; num != 0; i++){
			  numString[i] = num % 10 + '0';
			  num = num / 10;
		  }
		  numString[i] = '\0';
		  index = i - 1;
	  }

	  for (i = index; i >= 0; i--){
		  UART_transmit(numString[i]);
	  }
  }

```

```c:uart.h

#ifndef _UART_H_
#define _UART_H_


#include <avr/io.h>

void UART_INIT(void);
unsigned char UART_receive(void);
void UART_transmit(unsigned char data);
void UART_printString(char *str);
void UART_print8bitNumber(uint8_t num);
void UART_print16bitNumber(uint16_t num);
void UART_print32bitNumber(uint32_t num);

#endif /* UART_H_ */
```
Flutterで画面の遷移のタイミングで処理を行う

[2019/05/13 追記] Issue#29596 は [プルリク 30422](https://github.com/flutter/flutter/pull/30422) で修正されました。 ~~[2019/04/01 追記] [#29596](https://github.com/flutter/flutter/issues/29596) によると、iOSでスワイプで戻ると didPop, didPopNext が呼ばれないようです。~~

----

FlutterのWidgetには、画面の遷移に関するイベントを処理するためのハンドラ(メソッド)がありません。これは当然で、Widgetは部品であるため、画面の一部なのか全体なのか、使う側次第だからです。

さて、Flutterにおいて画面遷移に関する処理を行っているのはNavigatorというクラスです。このクラスに対してpushやpopという操作を行います。このNavigatorに対してはNavigatorObserverのリストを渡すことができます。これにより画面遷移に関するイベントを受け取ることができます。

NavigatorObserverを実装したクラスを自分で実装して処理してもよいのですが、それをStateで処理することが目的であれば、RouteObserverというものを使うと便利です。

以下のようにMaterialAppやWidgetsAppにオブザーバーを設定しておきます。

```dart
final RouteObserver<PageRoute> routeObserver = new RouteObserver<PageRoute>();
```

```dart
Widget build(BuildContext context) {
  ...
  return new MaterialApp(
    ...
    navigatorObservers: <NavigatorObserver>[routeObserver],
    ...
  );
}
```

続いて、StateにRouteAwareをmixinして、routeObserverに対してsubscribe/unsubscribeします。

```dart
class YourPageWidgetState extends State<YourPageWidget> with RouteAware {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    routeObserver.subscribe(this, ModalRoute.of(context));
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    super.dispose();
  }

  // 上の画面がpopされて、この画面に戻ったときに呼ばれます
  void didPopNext() {
    debugPrint("didPopNext ${runtimeType}");
  }

  // この画面がpushされたときに呼ばれます
  void didPush() {
    debugPrint("didPush ${runtimeType}");
  }

  // この画面がpopされたときに呼ばれます
  void didPop() {
    debugPrint("didPop ${runtimeType}");
  }

  // この画面から新しい画面をpushしたときに呼ばれます
  void didPushNext() {
    debugPrint("didPushNext ${runtimeType}");
  }
}
```

新しい画面が呼ばれるときに:

- 呼び出し元で didPushNext
- 呼び出し先で disPush

画面を戻るときに:

- 戻る元で disPop
- 戻る先で disPopNext

が呼ばれます。

どの画面でも共通の処理があるのであれば、基底クラスとしてRouteAwareStateのようなものを作り、各画面のStateはそれをextendsするようにするとよさそうです。
非エンジニアがエンジニアに対してスムーズにバグ報告をする秘訣

# バグを見つけた
営業「エンジニアに報告しなきゃ！！エンジニアさんバグです！！バグなんですよ！！バグがあったんですよ！！！」
エンジニア「せやな・・・」
営業「直さなきゃ！！今すぐ直しましょう！！」
エンジニア「ほんまやなぁ・・・」

序文は相変わらずセンスがありません。
この記事は主にディレクター・営業向けのバグ報告手法です。
こうやってバグ報告をするとスムーズに処理が出来るよってことを主に伝えられればなと思います。
もし貴社・あなたが主に行っている方法などありましたら是非教えて下さい。

## バグ報告されるエンジニアの心境を理解する
バグ報告された場合エンジニアは内容にかかわらず以下の思考を考えます

- 今すぐ直すべきか
- 原因はなんだ
 - どうすれば原因が特定できるか
- そもそも直せるのか
- 今日は家に帰れるだろうか

などを考えます。
ここでわかってほしいのは
**テンションの上がるエンジニアはいない**
ということです。
なので報告者は剣幕立てて報告すると、さらにテンションが落ちおもむろにスケジュールをこっそり後ろ倒しにします（僕はしたことはないですが）

## 報告する前に営業・ディレクターで出来る前調査を行う
まずバグを見つけたときに**5Wを明確にすること**を忘れない。

## When（いつ） 
- バグの発生日時はいつなのか
- バグの発見日時はいつなのか
- その機能が正常に動いているのを最後に確認したのはいつか

ここで重要なのは**発生日時と発見日時を一緒に報告しない・発生日時と発見日時を明確に表記する**ということ。
なぜ発生日時と発見日時というと、サーバーにはだいたいアクセスログと言うものがあって、この機能をいつ使ったよなどが記録してあるファイルがあります。
このログを見て調査をし、この時間に使われたこの機能がトリガーになったんだ、と思い調査を行う可能性があるからです。
なので発生日時と発見日時を誤って伝えると、エンジニアが見当違いで無駄な調査が行われてしまう可能性があります。
あとはリリース（機能追加とか機能のアップデートとか）後にすぐに発見される場合もあるのでそのような場合は最後の、最後に動いていた日時が調査の鍵となる可能性もあります。

## Who（誰が）
- ユーザー属性を明確にする
 - 管理者
 - 利用者
 - 購入した人
 - などなど

ここで重要なのは**ユーザーと言う言葉を使用しない**ということです。
ユーザーという言葉は非常に危険で、管理者のことも含める可能性があり、自分はとても曖昧な言葉だと思っています。
属性がより明確であればあるほど、調査は楽になると思います。
またここで可能であればブラウザのバージョン・なんのブラウザを使っているか・OSのバージョンはいくつか・アプリのバージョンはなにかも確認してあると、更に調査が楽になると思います。

## Where（どこで）・What(何を）
- どのページのどの機能なのか

WhereとWhatは切り離して説明することができなかった・・・(´・ω・｀)
重要なポイントは**どのページなのか**をしっかり理解すること。
Whoでも触れましたがどのページで起きているかを把握することが大切です。
例えばECサイトで注文リストを閲覧する事ができる機能があったとします。
この注文リストで何かしらのバグが起きたとしましす、この際は以下の会話で完結してしまう可能性があります。
>報告者「注文リストで○○すると☓☓されるバグがあったんや！直してや！」
>わい「なんやて！今確認するからまってや！」
>わい調査内容 : 管理者用の管理画面の注文リストで○○してみる
>わい「バグなんてなかったやで、気のせいや」
>報告者「なんや気のせいか・・・」

となり、バグは放置されてしまう可能性があります。
ここでの失敗ポイントは、実は注文リストという機能はお客様用管理画面にも注文リストという機能があり、ここの画面でのバグでしたということが、把握できなかったというポイントです。
なので上記の会話は以下のような会話がベストでした。
>報告者「**お客様用管理画面の**注文リストで○○すると☓☓されるバグがあったんや！直してや！」
>わい「なんやて！今確認するからまってや！」
>わい調査内容 : お客様用の管理画面の注文リストで○○してみる
>わい「ほんまやバグやな、直すでー」
>報告者「お、サンキュー」

となるのです。

## Why（なぜ）
- そのバグはなぜ発生したのか
    - 特殊な操作
    - タイミングの問題
- なぜこの操作を行ったのか

どうして起きたんや・・・ということを説明する。
ここらへんは読んで字の如くなぜそのバグが発生したかを伝える、再現手順があるとベスト。
なぜこの操作を行ったのかを書くとベストなのは、バグだと思っていたが**仕様である可能性もある**ので報告者は
>私はこの機能で○○されることを期待したのですが、☓☓されてしまいました

というとベスト。
そうするとエンジニアは
>その機能の仕様は☓☓されてしまうんや、でも勘違いする可能性もあるから説明追加、UI改善も検討するか・・・

となるのです。
本記事と話はそれますが、バグではないがUIを直しておかないと勘違いするかもしれないものの可能性もあるのです。

## その他チェック項目
だらだら記事書いててそろそろエンジン切れそうなので、とりあえず箇条書きで確認しておくとスムーズにコミュニケーションが取れる項目も書いておきます。

- そのバグは再現できるのか
 - 再現できるなら手順はどのような手順なのか
- ディレクター・PM向け）今すぐ直す余裕はあるのか・直すべきなのか

とかこの辺でしょうか。
この辺は書いてくれると嬉しいなぁと思うわけです。
次思いついたら報告用テンプレみたいなの作って見ようかなと思います。
皆様も良いバグ報告ライフを
Excelの行の背景色を条件付き書式で変更する


## 条件付き書式

1. 条件付き書式 を選択する
2. ルールの管理... を選択する
3. 新規ルール(N)... を選択する
4. 数式を使用して、書式を設定するセルを決定 を選択
5. 次の数式を満たす場合に値を書式設定(O): に数式を入力
6. 書式 を選択
7. 書式を設定 OK を選択
8. 書式ルールの編集ダイアログの OK を選択
9. 条件付き書式ルールの管理ダイアログの OK を選択

## 数式

F列（6カラム）目の値が xx だった場合

```
=SEARCH("xx",INDIRECT(ADDRESS(ROW(),6)))=1
```
Officeドキュメントの中身検索をElasticSearch（mapper-attachmentsプラグイン）でやってみた

Officeドキュメントの中身検索をElasticSearchで行ってみた

※ 事前にkuromoji もインストールしていくこと

今回ポイントになる、mapper-attachment プラグインをインストール

```
mapper-attachment とは、
.pdfや.pptxに対応するためのプラグイン
これらに対応させるApache Tikaを扱うためのattachmentタイプを使えるようにしてくれる
```

./bin/elasticsearch-plugin install mapper-attachments

```
-> Downloading mapper-attachments from elastic
[=================================================] 100%   
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.lang.RuntimePermission getClassLoader
* java.lang.reflect.ReflectPermission suppressAccessChecks
* java.security.SecurityPermission createAccessControlContext
* java.security.SecurityPermission insertProvider
* java.security.SecurityPermission putProviderProperty.BC
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
-> Installed mapper-attachments
```

# kibanaでコマンド実行

インストールしたプラグインの確認

```
get /_nodes/plugins
```

Index作成
※ フィールドはcontent のみ

```
delete /search_doc
PUT /search_doc
{
   "settings": {
       "index": {
       "number_of_shards": 1,
       "number_of_replicas": 0,
        "analysis": {
           "tokenizer": {
               "kuromoji_search": {
                   "type": "kuromoji_tokenizer",
                    "mode": "search"
               }
           },
            "analyzer": {
               "default": {
                   "tokenizer": "kuromoji_search",
                   "filter": [
                       "kuromoji_baseform",
                           "kuromoji_part_of_speech",
                           "cjk_width",
                           "stop",
                           "kuromoji_stemmer",
                           "lowercase"
                       ]
                   }
               }
           }
       }
   },
   "mappings": {
       "series" : {
            "properties" : {
                "file" : {
                    "type" : "attachment",
                    "fields" : {
                        "content" : { "type": "text",
                                      "term_vector": "with_positions_offsets",
                                      "store": true
                                    }
                    }
                }
            }
        }
   }
}
```

シェルスクリプトでファイルとIndexing.

※ 実行場所にｔｅｓｔ．ｐｐｔｘを置いておかないとダメですよ。

```
#!/bin/sh
coded=`cat test.pptx | perl -MMIME::Base64 -ne 'print encode_base64($_)'`
json="{\"file\":\"${coded}\"}"
echo "$json" > json.file
curl -X POST "localhost:9200/search_doc/series/test.pptx" -d @json.file
````

検索実行

```
GET /search_doc/_search?pretty=true
{
  "query": {
    "match": {
      "file.content": "テスト"
    }
  }
}
```
Apple Newsroomみたいなホバーエフェクト

![Untitled2newsroomtransi.gif](https://media.giphy.com/media/l41K3JGDQyY69Y3RK/giphy.gif)

<a href="https://www.apple.com/jp/newsroom/">Apple Newsroom</a>のようなホバーエフェクトをCSSで再現します。
カーソルをのせると、シャドウが広がりパネルが一回り大きくなります。
tvOSのような効果を再現したものと思われますが、 ``transform`` ではなく ``margin`` ``padding`` を ``transition`` させることでパネル内のコンテンツに``transform``をかけず遠近感を出しています。

ホバーした時は、 **``padding`` の値を大きくして**  **``margin`` の値を小さくします**

## コード

````
.item {
  margin: 3rem;
  padding: 2rem;
  box-shadow: 0 0 3rem 0 rgba(0, 0, 0, .001);

  transition: box-shadow .1s linear, padding .1s linear, margin .1s linear;

 &:hover {
    margin: 2.5rem;
    padding: 2.5rem;

    box-shadow: 0 1.5rem 3rem 0rem rgba(0, 0, 0, .3);
  }
}
````

## サンプル
### JSFiddle
<a href="https://jsfiddle.net/kurogedelic/5k7ywouy/">
Newsroom Hover</a>
カーニング調整するやつ

ざっくり簡易的にカーニング調整するJS書いた

- 文頭のカッコ始まり
- 改行後の文頭のカッコ始まり
- __、「__ とか文字間が広いやつを狭める
- __」、「__ みたいな3文字のやつにも適応させる
- 文頭以外の単一約物にはアテない
- 引用符 __“” '’__ は無視した

くらいのものです。

```javascript
/**
 * CSS設定
 * @type {{first: string, rspace: string, rspace2: string}}
 */
var _defaultCSS = {
  first : "-.5em",
  rspace : "-.75em",
  rspace2: "-.5em"
};

/**
 * カーニングのやつ
 * @param $target
 */
var _kerning = function($target){
  $target.each(function(){
    var __$target = $(this);

    // altとtitleをいったん格納する
    var __alt = []
        ,__title = []
        ,__$img = __$target.find("img")
        ,__$a = __$target.find("a");
    if(__$img.length > 0){
      __$img.each(function(){
        __alt.push($(this).attr("alt"));
        $(this).removeAttr("alt");
      });
    }
    if(__$a.length > 0){
      __$a.each(function(){
        __title.push($(this).attr("title"));
        $(this).removeAttr("title");
      });
    }


    // もにょもにょする
    var __text = __$target.html();
    __text = __text.replace(/^(\s|\t|\n)+|(\s|\t|\n)+$/g,''); //文章の頭とケツの半角・全角スペース、タブ、改行削除
    __text = __text.replace(/(\n)((\s|\t)+)/g,''); //改行後の頭の半角・全角スペース、タブ削除
    __text = __text.replace(/^(（|〔|［|｛|〈|《|「|『|【)/g,"<span class='rspace-first'>$1</span>"); //文頭調整
    __text = __text.replace(/(<br \/>|<br>)(（|〔|［|｛|〈|《|「|『|【)/g,"$1<span class='rspace-first'>$2</span>"); //br改行後の文頭調整
    __text = __text.replace(/(、|。|，|．|）|〕|］|｝|〉|》|」|』|】)(、|。|，|．|）|〕|］|｝|〉|》|」|』|】)(（|〔|［|｛|〈|《|「|『|【)/g,"<span class='rspace2'>$1</span><span class='rspace'>$2</span>$3");
    __text = __text.replace(/(、|。|，|．|）|〕|］|｝|〉|》|」|』|】)(（|〔|［|｛|〈|《|「|『|【)/g,"<span class='rspace2'>$1</span>$2");
    __$target.html(__text);
    __$target.find(".rspace-first").css({
      position: "relative",
      left : _defaultCSS.first,
      letterSpacing : _defaultCSS.first
    });
    __$target.find(".rspace").css({letterSpacing : _defaultCSS.rspace});
    __$target.find(".rspace2").css({letterSpacing : _defaultCSS.rspace2});


    // altとtitleつけなおす
    __$img = __$target.find("img");
    __$a = __$target.find("a");
    if(__$img.length > 0){
      __$img.each(function(i){
        $(this).attr({"alt": __alt[i]});
      });
    }
    if(__$a.length > 0){
      __$a.each(function(i){
        $(this).attr({"title": __title[i]});
      });
    }
  });
};

_kerning($(".kerning"));
```
---
```html
<p class="kerning"> 「テスト」<br />テスト<br />「テスト」<br />
  　「テスト」</p>
<p class="kerning"> “テスト”<br />テスト<br />
  　“テスト”</p>
<p class="kerning"> 「テスト」<br />『テスト』<br />【テスト】<br />（テスト）<br />［テスト］<br />《テスト》<br />〔テスト〕<br />
  　｛テスト｝</p>
<p class="kerning"> 「テスト」、『テスト』、【テスト】。（テスト）、［テスト］。</p>
```
とかでもちゃんといけてるはず。

いろんなフォントで検証してないですけどね。
Unity でつくった Daydream アプリをリリースする際の設定や承認について

Unity で Daydream アプリをつくりリリースしました ([VR Music Visualizer](https://play.google.com/store/apps/details?id=ws.yuuki.spectrumvr))。
Daydream アプリに承認してもらうにあたり、リリース関連の設定や、承認までの過程などを記載します。

# 開発環境
- Unity 5.6.2f1 (Pro)
- Google Daydream View VR Headset
- Asus ZonFone AR

# Daydream アプリの必須事項
[Daydream App Quality Requirement](https://developers.google.com/vr/distribute/daydream/app-quality) に記載されている内容に準拠していないと、Daydream アプリとして承認してもらえません。
読まずに開発をすすめると、あとで困ることになるかもしれませんので、Daydream アプリの開発前には一度目を通しておくべきです。

# Unity の PlayerSettings の設定

![settings.png](https://qiita-image-store.s3.amazonaws.com/0/58807/9e5e702c-d310-1606-19bc-59372f258056.png)

### Virtual Reality Supported
PlayerSettings -> Other Settings -> Virtual Reality Supported

- Check On
- Virtual Reality SDKs で Daydream を選択

### Minumum API Level
- Android 7.0 'Nougat' (API level 24)

### VR Icon
VR Icon はDaydream のホームアプリで表示されるアプリのアイコンです。
Foreground Icon の画像が手前に浮いて見えるようになります。
仕様については[こちら](https://developers.google.com/vr/distribute/daydream/publishing-requirements#PB-P2
)。
以下のとおり、設定します。

PlayerSettings -> Other Settings -> Virtual Reality SDKs -> Daydream

▼ のボタンを押すと設定箇所が表示されます。
![daydreamicon.png](https://qiita-image-store.s3.amazonaws.com/0/58807/c4c426ce-c9cf-aec4-3649-325430a11e8a.png)
512 x 512px の解像度の Foreground Icon と Background Icon を設定します。

### Virtual Reality Splash Image
PlayerSettings -> Splash Image -> Virtual Reality Splash Image
![splash.png](https://qiita-image-store.s3.amazonaws.com/0/58807/cb76aa7f-7f69-2231-267b-f23acff78ac9.png)
Unityのドキュメントに仕様の記載が見つけられません。画像サイズは試してみたものです。
- アスペクト比は 2:1 ?
- 1024 x 512 px の解像度で大丈夫そう

# Google Play Console での設定
### Daydream の 360 度立体画像
4096 x 4096px の解像度の Equirectangular stacked stereo format (トップアンドボトムのEquirectangular) の画像をアップロードします。仕様は[こちら](https://developers.google.com/vr/distribute/daydream/publishing-requirements#PB-P3
)。

360 度立体画像は、[360 Panorama Capture](https://www.assetstore.unity3d.com/jp/#!/content/38755)というアセットで作成しました。必要なフォーマットのキャプチャが作成できます。このアセットの利用時は Build ターゲットを PC にしておく必要があります。


# リリースから承認まで

Google Play Consle のアプリのリリースで Daydream アプリにチェックを入れて、通常のAndroidアプリと同様にリリースをします。
この時点では、ストアに掲載はされますが、Daydream アプリの承認は受けていません。
Google により承認を受けると Google Play の Daydream program に加わり、Daydream のラベルが Play Store で表示されるようになります。

リリース後、翌日には承認の可否についてフィードバックの英文メールが Google Play Support から送られてきます。

私の場合、最初のリリース時、[☓ボタン、バックボタンを押した場合にアプリを停止させる](https://developers.google.com/vr/distribute/daydream/functionality-requirements#FN-A2)というのを実装していませんでした。そのため、リリース後、翌日に Google Play Support よりメールにて連絡があり、修正しました。

修正のリリース後、翌日には承認された旨のメールが来ました。

承認のレビューのために、こちらから特に申請することはありませんでした。Google Play Console でリリースするとレビューを行ってもらえ、翌日にはフィードバックのメールがきます。
Azureのテナント／ディレクトリ／アカウント／ロールについて

Microsoft Azureについての個人的備忘録メモ

# やりたいこと
- 社内ADとAzure ADを連携させてアカウントの一元管理をしたい
- 社内ADユーザーとパスワードを使って、各種SaaSにログイン（サインイン）したい
  - 退社時とかに一箇所でアクセス制限を行いたい

# Azureに決めたわけ
- 社内AD + ADFS(Active Directory Federation Service)だとサーバーを用意しないといけない
  - 冗長構成とか保守とかの面倒が発生する
  - SaaS連携時にいろいろ設定しないといけない（Azure対応を謳ってるサービスなら簡単に連携できるっぽい）
- Azure ADが提供している機能を使いたい
  - MFA(Multi Factor Authentication)とか
  - デバイス認証とか
  - 監査ログとか
- LDAP, Kerberos, RADIUS とも連携したい
- Windows PCとかのログオン(Hello?)と連携してPCにログオンするだけで各種SaaSにパスワードレスで使えるようになるらしい
  - 参考:[Azure Active Directory シームレス シングル サインオン](https://docs.microsoft.com/ja-jp/azure/active-directory/connect/active-directory-aadconnect-sso)
- 要は面倒は嫌

# 用語
## テナント
- Azureを使うときの管理スペース
  - Azure ADと1対1で対応
  - 基本1企業 = 1テナントで管理するのが良さそう（AWSだとシステム（請求)単位でアカウントわけるのが定石)

## ディレクトリ
- テナント内のユーザーやグループを管理するための認証基盤
- 「ディレクトリロール」はディレクトリに対する管理権限のこと
  - ユーザー／全体管理者／制限付き管理者から選べる
  - ユーザーの追加ができるとか、パスワード変更ができるとか
  - Azureサービスの利用権限とは別なので注意
  - 参考: [Azure Active Directory での管理者ロールの割り当て](https://docs.microsoft.com/ja-jp/azure/active-directory/active-directory-assign-admin-roles)

## ユーザー = アカウント
- 大きく「個人用Microsoftアカウント」と「組織アカウント（職場または学校アカウント）」の2種類がある
- 自分でAzureにサインアップした時には「個人用Microsoftアカウント」になる
  - Microsoftが管理しているディレクトリに作成されているユーザーという見方もある
- どこかのテナントのディレクトリで管理されている場合は「組織アカウント」になる
- AWSでいうアカウントとは意味合いが異なる
  - AWSでいうアカウントはAzureでは「サブスクリプション」に近い

## サブスクリプション
- Azureでの請求単位
- 1テナントで複数のサブスクリプションを持つことができる
- そのサブスクリプションを利用可能なユーザーや、利用可能なサービスを設定できる

## IAM
- そのサブスクリプションでユーザーがどんなサービス（Azureリソース）を利用できるかを設定する仕組み

# 組織でのAzureの始め方はこんな感じがいいんじゃないか
- Azure管理用のメールアドレス(メーリングリスト)を作成する
- 管理用アドレスでAzureにサインアップしテナントを作成する（このユーザーは個人用Microsoftアカウントになる)
  - なおOffice365を利用している組織ならすでにテナントがあるのでそこを使うのが良い
- サブスクリプションとかは、この管理者ユーザーで追加する
- ディレクトリに実際作業するユーザーを追加する（必要なら社内ADとAzure AD Connectを使って同期する）
- ユーザーにサブスクリプションのIAMを割り当てる（Virtual Machineの作成権限とか)

# ちょっと触ってみたAzureのツラミ
- 公式ドキュメントの日本語訳がおかしい
  - 日本語文章として意味が通じない
  - 結局英語文章をあたることになる
- 略語が多い
  - 二文字・三文字の略語が多用されてる
    - UPN = User Principal Name (ユーザー識別名 user@domain 形式)
    - gMSA = group Management Service Account (グループ管理サービスアカウント)
  - Windows (Server) 経験者ならすんなり理解できるのか
- ドキュメントの通りにやる → できない → 原因がわからない
  - エラーメッセージだけで原因ログがどこにもでてこない
- ポータルが多すぎて迷子になる
  - Azureポータル http://portal.azure.com
  - Azureクラシックポータル https://manage.windowsazure.com/
  - Azureアカウントポータル https://account.azure.com/
 
# Azureのいいところ
- 最初から「エンタープライズ」を意識して使ってる感ある
  - 特に請求まわりとか、リソースグループの考え方とか
  - （故に背景となる前提知識が求められることもあり取っ付きづらい感もあるが）
- サポートのレベル高い
  - 電話で1時間くらいかけて懇切丁寧に対応してくれた
Movable Typeをバージョンアップしてテーマをエクスポート

# エラー

Movable Typeをバージョンアップしてテーマをエクスポートしたらこんなエラーメッセージがでた。

> template_setのファイナライズ中にエラーが発生しました: テンプレートファイルの公開に失敗しました: '/tmp/?????/?????/?????.mtml'を開けませんでした: No such file or directory

# 原因は？

mt_templateテーブルのtemplate_identifierが深いからだった。
おそらく、ｍｔ４時点ではテーマの概念がなく「template_identifier」らへんが曖昧だったか無かったのかなぁ〜

template_identifierの中身「?????/?????/」

# 対策

SQLで置換

update mt_template set template_identifier=replace(template_identifier,'?????/','')

解決！
[ARDUINO]自分のISPを作ろう。

ARDUINOを使うと基本USBを使ってプログラムをアップロードしてますよね

##経路
```
C:\Program Files (x86)\Arduino\hardware\arduino\avr
```

##PROGRAMMERS.TXT

STK500V2をサポートするUSB-SERIAL MODULEをつかいました。

![IMG_4637.jpg](https://qiita-image-store.s3.amazonaws.com/0/137182/4cb48f71-bfdc-db03-4b52-078ae493bf0a.jpeg)


PROGRAMMER.TXTを開けて下の内容を追加します。

```
my_avrisp.name=MY AVRISP
my_avrisp.communication=serial
my_avrisp.protocol=stk500v2
my_avrisp.program.protocol=stk500v2
my_avrisp.program.tool=avrdude
my_avrisp.program.extra_params=-P{serial.port}
```
##結果

TOOL - PROGRAMMERをみると
![ARDUINO_01.png](https://qiita-image-store.s3.amazonaws.com/0/137182/edf0222b-7306-1f2c-d839-75de00886f01.png)