OmniAICreator/Qiita-1.07M huggingface dataset:
VS Code でフロントマターのある AsciiDoc を扱う

Jekyll とか Hugo とかで AsciiDoc や Markdown を書くとき，ファイルの先頭に YAML (たまに TOML) を入れることがあります．
フロントマター (front matter) と呼ばれるやつです．

```
---
title: hello
description: hello to the world
---
```

このフロントマターが入った AsciiDoc を VS Code で扱うのにいろいろ設定をしたので，ここにメモしておきます．

ちなみに，設定がうまくいったときのスクリーンショットはこんな感じです．

![adoc_preview.png](https://qiita-image-store.s3.amazonaws.com/0/81643/13cc8237-a8bf-e0c9-8034-996de452f8f0.png)

## AsciiDoc プラグインのインストール

まずは AsciiDoc 用のプラグインをインストールします．

- AsciiDoc - João Pinto<br />
  https://marketplace.visualstudio.com/items?itemName=joaompinto.asciidoctor-vscode

Ctrl+P を押して次のコマンドを叩けば，インストールできます．

```
ext install joaompinto.asciidoctor-vscode
```

普通の AsciiDoc 文書を編集するだけなら，もうこれでシンタックスハイライトもプレビュー機能も使えるようになります．

## asciidoctor のインストール

フロントマターのある AsciiDoc 文書の場合，シンタックスハイライトは特に問題ないみたいですが，プレビュー機能がうまく動かなかったりします．
例えば，次のような ``:source-highlighter:`` を指定した AsciiDoc 文書をプレビューしようとすると，エラーが出てしまいます．

```adoc
---
title: hello
description: hello to the world
---

:source-highlighter: coderay

= hello

A _hello world_ program in C can be writtern as follows:

[source,c]
----
int main(void) {
    printf("hello, world\n");
    return 0;
}
----
```

```
CodeRay: uninitialized constant CodeRay
```



どうやら，プラグインが内部で使用している [Asciidoctor.js](https://github.com/asciidoctor/asciidoctor.js) はフロントマナーをうまく処理できないみたいなので，本家の [Asciidoctor](https://github.com/asciidoctor/asciidoctor) をインストールしてそれを使わせるようにします．

というわけで，[Asciidoctor](https://github.com/asciidoctor/asciidoctor) をインストールします．
インストールは gem で出来ます．

```
$ gem install asciidoctor
```

次のコマンドが通ったら，Asciidoctor のインストールは成功です．

```
$ asciidoctor --version
Asciidoctor 1.5.6.2 [http://asciidoctor.org]
Runtime Environment (ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]) (lc:UTF-8 fs:UTF-8 in:- ex:UTF-8)
```

## VS Code 側の設定

[File] - [Preferences] - [Settings] を開き，以下の 2 行を追記します．

```json
    "AsciiDoc.use_asciidoctor_js": false,
    "AsciiDoc.asciidoctor_command": "asciidoctor -a skip-front-matter",
```

これで VS Code を再起動すれば，プレビュー機能も問題なく動作するはず．
ERROR: Docker has been previously configured for use with devicemapper graph driverを解消しました

たまたまCentOS起動時に赤い字で「FAILURE」を見つけました。直接何か問題を感じたわけではなかったのですが、気持ち悪いので、このERRORは解消しておくことにしました。

# 現象

/var/log/messagesに、docker起動時にエラーが記録されます。ただ、このエラーがあるからと言って、dockerをちょこっと使う範囲で何か問題を感じる、見ることはありませんでした。

```log:/var/log/messagesの抜粋
Apr  1 09:36:03 centos7 container-storage-setup: ERROR: Docker has been previously configured for use with devicemapper graph driver. Not creating a new thin pool as existing docker metadata will fail to work with it. Manual cleanup is required before this will succeed.
Apr  1 09:36:03 centos7 container-storage-setup: INFO: Docker state can be reset by stopping docker and by removing /var/lib/docker directory. This will destroy existing docker images and containers and all the docker metadata.
Apr  1 09:36:03 centos7 systemd: docker-storage-setup.service: main process exited, code=exited, status=1/FAILURE
Apr  1 09:36:03 centos7 systemd: Failed to start Docker Storage Setup.
Apr  1 09:36:03 centos7 systemd: Unit docker-storage-setup.service entered failed state.
Apr  1 09:36:03 centos7 systemd: docker-storage-setup.service failed.
```

ちなみに、この時のイメージやコンテナは以下のような状況です。

```console
[devel@centos7 ~]$ docker images
REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE
tacchang/centos7_apache24_python3   latest              ef312ad111cd        7 months ago        658 MB
[devel@centos7 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
590beb9ad1e4        ef312ad111cd        "container-entrypo..."   7 months ago        Exited (137) 4 months ago                       webapp1
```

# 解消

末尾に挙げた[suguru03さんのブログ](http://suguru03.hatenablog.com/entry/2017/02/14/085000)を拝見して、そのまま真似てみました。これで、ERRORはなくなりました。

```console
[devel@centos7 ~]$ docker system prune
WARNING! This will remove:
        - all stopped containers
        - all volumes not used by at least one container
        - all networks not used by at least one container
        - all dangling images
Are you sure you want to continue? [y/N] y
Deleted Containers:
590beb9ad1e4c76955bf72bdac8a3726e77b0d2d1610f33ff3f4d70b2aa9660a

Total reclaimed space: 155 kB
```

# 参考

  * [Dockerのお掃除](http://suguru03.hatenablog.com/entry/2017/02/14/085000)

# 環境

  * Windows 10 version 1709(16299.309)
  * VirtualBox 5.2.6 r120293
  * CentOS 7.4.1708
  * docker 1.13.1
クリックイベント等を無効にするpointer-eventsが便利

cssプロパティpointer-eventsを教えてもらい、意外に便利！と思ったので書きます。
ここだけJSを使うのも面倒だし、cssだけでクリック無効にできないかな…って思った時に使えるプロパティです。

## 概要

cssプロパティ``pointer-events``は
特定の要素がマウスイベントの対象になる場合に、クリックされた際の挙動を指定します。
普通の要素では、使えるプロパティの値は``auto``と``none``だけですが（グローバル値を除く）、
SVGには様々なプロパティ値が指定できます。
## こんな時
- 特定の条件下で、``a``タグ等の動作を無効にさせる
- スマホで画像を長押し保存させない
- ボタン上に、デザインのために置いた要素をクリックできないようにする

## 使い方
クリックされたくない要素に``pointer-events:none``を指定。
逆に、クリックできなくしていたものを、できるようにしたい時は、``pointer-events:auto``を指定。

## 注意
IE10以下のブラウザでは未対応です。
また、キーボードでの指示は無効にならないみたいです。
PyMieScatt > MiePiTau() > Equation of Pi() and Tau() > Off-by-one errorを起こしそうな実装

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

### Reference

- Bohren C.F. and D. R. Huffman, "Absorption and Scattering of Light by Small Particles", John Wiley, New York, NY (1983)
- PDF: [MATLAB Functions for Mie Scattering and Absorption, Research Report No. 2002-08, June 2002](https://omlc.org/software/mie/maetzlermie/Maetzler2002.pdf) by Christian Mätzler

### Equation of Pi() and Tau()

https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py#L365

```py
  for n in range(2,int(nmax)):
    p[n] = ((2*n+1)*(mu*p[n-1])-(n+1)*p[n-2])/n
    t[n] = (n+1)*mu*p[n]-(n+2)*p[n-1]
```

対応する式はonline user's guideに記載されている。

http://pymiescatt.readthedocs.io/en/latest/forward.html#MiePiTau

しかしながら、online user's guideに記載の式と上記の実装ではnの扱いが異なる。

実装の式は以下のようになっている。

```math
\pi_n = \frac{(2n+1)\mu \pi_{n-1} - (n+1)\pi_{n-2}}{n}
```

user's guideの式は以下のようになっている。

```math
\pi_n = \frac{2n-1}{n-1}\mu \pi_{n-1} - \frac{n}{n-1}\pi_{n-2}
```

user's guideの式のnをn+1にすると実装と同じになる。

インデックスの取り方により、こういうことをしないといけないのだろうか。

Off-by-one errorを起こしそうな実装である。
Pythonを用いて日経225を分析する



# 目標
2017年1月1日から2017年12月31日までの日経225の日時データを入手し、日次リターンの平均と分散及び、ドリフトとボラティリティを計算する。
その結果を用いて、ヒストグラムを描く。
#準備
株価の変動が幾何ブラウン運動に従うと考える。つまり株価は、
$$ \frac{dS_t}{S_t} = {\sigma}dW_t+\mu{dt} $$
に従う。これを離散化すると、
$$  \frac{{\Delta}S_t}{S_t} = {\sigma}{\Delta}W_t+\mu{{\Delta}t}   $$
となる。ここで、$ \Delta{S_t}=S_{t+{\Delta}t}-S_t $とする。$\Delta{t}$は約1/250と以下で計算される。これは取引所が開いている日数がおよそ250日であることによるものであり、休日ににおける資産の価格形成は無視するとする。株価の日次リターンとは、$\frac{\Delta{S_t}}{S_t}$のことであり、推定される$\mu$と$\sigma$はこの平均と分散それぞれを$\Delta{t}$で割ったものである。

#分析
まず以下をimportする。

```Python

import numpy as np
import datetime
from scipy.stats import norm
import pandas_datareader.data as web
import matplotlib.pyplot as plt
```

`pandas-datareader`で日経平均225を取得。`dropna`で株価がNaNの部分を除く。

```Python
start = datetime.datetime(2017, 1, 1)
end   = datetime.datetime(2017, 12, 31)
ni225 = web.DataReader("NIKKEI225", "fred", start, end) 
ni225modi = ni225.dropna(how='all', axis=[0, 1])
nikkei225 = ni225modi.as_matrix()
```

株価の日次リターン、平均、分散等を計算する。

```Python
L = len(nikkei225)
#delta = 1/len(nikkei225)

S = np.zeros(L, dtype = float)
for i in range(0,L-1):
    S[i] = (nikkei225[i+1]-nikkei225[i])/nikkei225[i]
    
mu = S.mean()*L
sigma = np.sqrt(S.var()*L)
mean = S.mean()
var = S.var()

```

ドリフトとボラティリティはそれぞれ0.1566,　0.1150と推定された。

次に、ヒストグラムと正規分布のグラフを表示する。binsの値は9。

```Python
#スタージェスの公式を用いて`bins`を求める
HistBins = int(np.round(np.log2(L)+1))
count, bins_edges, patches = plt.hist(S, bins = HistBins)

X = np.arange(-0.08,0.08,0.001)
#確率密度関数に,平均mean、標準偏差var^(1/2)を代入
Y = norm.pdf(X,mean ,np.sqrt(var))
plt.plot(X,Y,color='r')
plt.show()
```
赤のグラフが日次リターンの平均と分散を用いた正規分布。青のグラフが日次リターンのヒストグラム。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/227645/215eb10c-663f-2f27-db86-8f35dabde8bd.png)
PyMieScatt > MieS1S2() > Equation of S1, S2

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

### Reference

- Bohren C.F. and D. R. Huffman, "Absorption and Scattering of Light by Small Particles", John Wiley, New York, NY (1983)
- PDF: [MATLAB Functions for Mie Scattering and Absorption, Research Report No. 2002-08, June 2002](https://omlc.org/software/mie/maetzlermie/Maetzler2002.pdf) by Christian Mätzler

### Equation of S1, S2


https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py#L354
http://pymiescatt.readthedocs.io/en/latest/forward.html#MieS1S2

```py
  n2 = (2*n+1)/(n*(n+1))
  S1 = np.sum(n2[0:len(an)]*(an*pin[0:len(an)]+bn*taun[0:len(bn)]))
  S2 = np.sum(n2[0:len(an)]*(an*taun[0:len(an)]+bn*pin[0:len(bn)]))
```

E0に対するtransverse components of the scattered electric fieldsを計算するときに登場するS1,S2は上記の通り実装されている。

これらの式はBohren and Huffman(1983)
4.4.4 Scattering Matrix
Eq. (4.74)
として掲載されている。

```math
E_{s\theta} \sim E_0 \frac{e^{ikr}}{-ikr}cos\phi S2(cos\theta),
```

```math
E_{s\phi} \sum = -E_0 \frac{e^{ikr}}{-ikr}sin\phi S1(cos\theta),
```

S1とS2の名前は忘れた。
JavaScript で Promiseを返す非同期/同期的に動作する複数の関数を並列に呼び出し、その結果を取得する

JavaScript で Promiseを返す関数を並列に呼び出しその結果を取得するには、Promise.all と Array#map を併用し、
`const values = await Promise.all([fn, fn, fn].map(fn => fn())` のようにします。

```js
(async() => {
  const fn = (index) => {
    return new Promise(resolve => {
      setTimeout(() => resolve(index), 1000 * index);
    });
  };

  const process = async() => {
    console.log(`fn call begin`);

    const source = [ fn, fn, fn ];
    const values = await Promise.all(source.map((fn, index) => {
      console.log(`fn[${index}] called`);
      return fn(index);
    }));

    console.log(`fn call end`);

    return values; // [ 0, 1, 2 ]
  };

  console.log(`values ${await process()}`); // log(`values 0,1,2`)
})();
```

```
fn call begin
fn[0] called
fn[1] called
fn[2] called
fn call end
values 0,1,2
```

- イテレータや Array like Object を Promise.all に渡す場合は、 `await Promise.all(Array.from(iter).map(...))` とします。

- 同期関数の結果を Promise.all に渡す場合は `Promise.resolve(sync_fn())` のようにして Promise でラップします。
パッケージ管理ツール 類似コマンド一覧

よく使うパッケージ管理ツールについて、機能毎のコマンドを一覧化します。

|機能| yum | apt | pip | npm | homebrew |
|:--|:----|:----|:----|:----|:---------|
|リポジトリから検索                                                                                |yum search *word*|apt search *word*|pip search *word*|npm search *word* |brew search *word*|
|リポジトリからインストール                                                                          |yum install *pkg*|apt install *pkg*|pip install *pkg*|npm install *pkg* |brew install *pkg*|
|リポジトリからアップデート有無チェック                                                                 |yum check-update|                 |pip list --outdated|npm outdated    |brew outdated|
|リポジトリから最新にアップデート                                                                     |yum update [*pkg*]|apt upgrade  |pip install -U *pkg*|                  |                      |
|インストール済みのパッケージの情報                                                                 |yum info *pkg*    |apt show *pkg*  |pip show *pkg*   |                  |                      |
|インストール済みのパッケージ一覧                                                                   |yum list installed|                |pip list         |npm ls            |brew list --versions  |
|アンインストール                                                                                 |yum remove *pkg* |apt remove *pkg*|pip uninstall *pkg*|npm uninstall *pkg*|brew uninstall *pkg*|
|リポジトリ一覧                                                                                   |yum repolist all |                 |                 |                  |                 |
|リポジトリ追加                                                                                   |yum install *repo*|                |                 |                  |                 |
|設定ファイル                                                                             |/etc/yum.conf     |                |                 |                  |                 |
|パッケージ管理ツールのバージョン確認                                                                  |---               |                |pip -V           |npm -v            |brew -v          |
|パッケージ管理ツールのアップデート                                                                    |---               |---     |pip install --upgrade pip|npm i -g npm      |brew update      |
YAML のハマりどころ

Ansible とかで YAML 書いててハマったところ．

## YAML にはデータ型がある

何をいまさらといった話ですが，YAML のスカラ型には文字列型以外に数値型や論理型もあるということを意識していないと，気を抜いた瞬間にハマります．

```yaml
---
id: 0010
name: sato
```

ここで ``id`` を文字列 "0010" の意図で書いたつもりでも，実際には 8 進数の 10 とみなされます．
つまり，次のようにみなされます．

```yaml
---
id: 8
name: sato
```

## ブール値リテラルはたくさんある

データ型の話の続きになりますが，今度はブール型の話です．YAML のブール値リテラルはいろいろ種類があるので注意です．

```yaml
---
no: 3
name: kato
```

こんなふうに不用意に ``no`` と書いてしまうと，実装によってはその部分が ``false`` とみなされてしまいます．

```yaml
---
"false": 3
"name": "kato"
```

``yes``，``no`` あたりは，実装によってブール値扱いされるかもしれないしされないかもしれないグレーゾーンです．
下記のページに，グレーゾーンなブール値リテラルがたくさん載ってます．

- http://yaml.org/type/bool.html

## コロンのつけ忘れ

あまり大した話ではないですが，コロンを付け忘れても構文エラーにならず，見た目上も気づきにくいようなケースがあります．

例えば，次のようなデータを書こうとしてコロンを付け忘れたとします．

```yaml
---
- tasks:
  - foo
  - bar
  - baz
```

つまり，次のように書いてしまったとします．

```yaml
---
- tasks
  - foo
  - bar
  - baz
```

インデントも正しくそれっぽく書けているので，構文のハイライト機能がない環境だと間違いに気づきにくかったり．
しかも構文エラーになることもなく，次に示すものと等価の妥当なデータとみなされるのが厄介なところです．

```yaml
---
- "tasks - foo - bar - baz"
```

## ブロックスタイル文字列の改行

YAML の文法を熟知していれば済む話ですが，文字列をブロックスタイルで書くときは，改行の扱いをどうするかによって，使用するブロックスタイルの種類の吟味が必要です．

```yaml
---
- msg: |
    lorem
    ipsum

- msg: |+
    lorem
    ipsum

- msg: |-
    lorem
    ipsum

- msg: >
    lorem
    ipsum

- msg: >+
    lorem
    ipsum

- msg: >-
    lorem
    ipsum
```

こう書くと，次のように改行文字が入ります．

```yaml
---
- msg: "lorem\nipsum\n"
- msg: "lorem\nipsum\n\n"
- msg: "lorem\nipsum"
- msg: "lorem ipsum\n"
- msg: "lorem ipsum\n\n"
- msg: "lorem ipsum"
```

## 参考リンク

- http://www.yaml.org/
PyMieScatt > ScatteringFunction() > normalization: 'N','number','particles'に関する記載はない

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

### Reference

- Bohren C.F. and D. R. Huffman, "Absorption and Scattering of Light by Small Particles", John Wiley, New York, NY (1983)
- PDF: [MATLAB Functions for Mie Scattering and Absorption, Research Report No. 2002-08, June 2002](https://omlc.org/software/mie/maetzlermie/Maetzler2002.pdf) by Christian Mätzler

### SF_SD() > normed | normalization

https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py#L339

```
  if normalization in ['n','N','number','particles']:
```

normalizationには上記の文字列が入っているかのチェックがある。

対応するドキュメントの記載は以下の通り
http://pymiescatt.readthedocs.io/en/latest/forward.html#SF_SD

> normalization :str or None, optional
...

> - normalization = ‘n’ will normalize by the total number of particles (the integral of the size distribution). Can lead to weird interpretations, so use caution.

`'N','number','particles'`に関する記載はない。

tとmaxについても同じように記載されていない文字列の確認を実装では行っている。
PyMieScatt > ScatteringFunction() > measureの式 | scattereing wave vector | phase difference

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

### Reference

- Bohren C.F. and D. R. Huffman, "Absorption and Scattering of Light by Small Particles", John Wiley, New York, NY (1983)
- PDF: [MATLAB Functions for Mie Scattering and Absorption, Research Report No. 2002-08, June 2002](https://omlc.org/software/mie/maetzlermie/Maetzler2002.pdf) by Christian Mätzler


### ScatteringFunction() > measure

https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py#L317

```py
  if _q:
    measure = (4*np.pi/wavelength)*np.sin(measure/2)*(diameter/2)
  return measure,SL,SR,SU
```

measureというのは
http://pymiescatt.readthedocs.io/en/latest/forward.html#ScatteringFunction
を見ると下記のthetaに対応するようだ。

>Returns
>`theta :numpy.ndarray`
>An array of the angles used in calculations. Values will be spaced according to angularResolution, and the size of the array will be (maxAngle-minAngle)/angularResolution.

上記の実装は

```math
measure = \frac{4\pi}{\lambda}sin(\frac{measure}{2})\frac{diameter}{2}
```

[Sorensen, M. Q-space analysis of scattering by particles: a review. J. Quant. Spectrosc. Radiat. Transfer 2013, 131, 3-12](https://www.sciencedirect.com/science/article/pii/S0022407313000083)
を購入しないとわからない式のようだ。

上記、Sorensen(2013)のAbstractに下記の記載がある。

> This analysis involves plotting the scattered intensity versus the scattering wave vector q=(4π/λ)sin(θ/2) on a double log plot. 

~~measureというのはscattering wave vectorというもののようだ。~~

~~論文の用語とReadTheDoc上の説明用語と実装変数がそれぞれ別にする必要はあるのだろうか?~~

以下の式が成り立つようだ。

measure = scattering vector * (diameter / 2)

### phase difference

式についてBohren and Huffmanを眺めていて、下記の似たような式を見つけた (p106)。

```math
\Delta \phi = \frac{2 \pi}{\lambda}2a(N1 - N) = 2x(m-1)
```

diameter/2=aなので、係数$4\pi a/\lambda$は同じではあるが、scattering wave vectorと関係があるのかは不明。

Bohren and Huffman (1983)
p106

> For if we adopt the viewpoint of elementary optics, the phase difference $\Delta \phi$ between a ray that traverses a large transparent sphere wihout deviation (i.e., the forward-scattered or centray ray) and a ray that traverses the same physical path outside the sphere is ...

透明な球内部をdeviationなしで通過するray(前方散乱)と球外側を同じ物理距離通過するrayとの位相差ということのようだ。
firewalld/firewall-cmd メモ

# 1. ルール

設定のこと。

## 1-1. ランタイムルール

メモリ上に保存されるルール。
firewalldをリスタートすると消える。

# 1-2. パーマネントルール

ファイル(/etc/firewalld/zones配下)に保存されるルール。
firewalldをリスタートすると、ファイルからルールが読み込まれメモリに展開される。

# 2. 確認

設定の確認方法を示す。

## 2-1. ゾーンの確認

ゾーンについて：http://www.server-memo.net/centos-settings/firewalld/firewalld.html#i

```
firewall-cmd --get-default-zone
```

## 2-2. 現在のゾーンの全ての設定を確認

```
firewall-cmd --list-all
```

## 2-3. 全てのゾーンの全ての設定を確認

```
firewall-cmd --list-all-zones
```

## 2-4. ポートへの設定を確認

```
firewall-cmd --list-ports (--zone=<ゾーン名>) (--permanent)
```

## 2-5. サービスへの設定を確認

```
 firewall-cmd --list-services (--zone=<ゾーン名>) (--permanent)
```

## 2-6. サービスの一覧を確認

```
firewall-cmd --get-services #or
ls -lta /usr/lib/firewalld/services/
```

## 2-7. 各サービスごとの設定を確認

```
cat /usr/lib/firewalld/services/ssh.xml
```

# 3. 設定

ルールの設定方法を示す。

## 3-1. サービスの設定

### 3-1-1. 単純な設定

```
firewall-cmd --add-service=<サービス名> (--zone=<ゾーン名>) (--permanent)
firewall-cmd --remove-service=<サービス名> (--zone=<ゾーン名>) (--permanent)
```

--permanentを付けると設定が永続化される。

### 3-1-2. 複雑な設定

#### ・既存のサービスの設定を書き換える

```
cp /usr/lib/firewalld/services/hoge.xml /etc/firewalld/services/
vim /etc/firewalld/services/hoge.xml
firewall-cmd --reload #セッションごと完全にリロードしたいなら--complete-reloadを使用する
```

#### ・新規にサービスを作成する

```
cp /usr/lib/firewalld/services/hoge.xml /etc/firewalld/services/
mv /etc/firewalld/services/hoge.xml /etc/firewalld/services/fuga.xml
vim /etc/firewalld/services/fuga.xml
firewall-cmd --reload
```

## 3-2. ポートの設定

```
firewall-cmd --add-port=<ポート番号>/<プロトコル> (--zone=<ゾーン名>) (--permanent)
firewall-cmd --remove-port=<ポート番号>/<プロトコル> (--zone=<ゾーン名>) (--permanent)
```

## 3-3. ゾーンの設定

### 3-3-1. デフォルトゾーンの変更

```
firewall-cmd --set-default-zone=<ゾーン名>
```

### 3-3-2. NICに割り当てられているゾーンを変更

#### ・一時的に変更

```
firewall-cmd --zone=<ゾーン名> --change-interface=<NIC名>
```

#### ・永続的に変更

```
vim /etc/sysconfig/network-scripts/ifcfg-<NIC名>
```

```:vim
+ ZONE=<ゾーン名>
```

```
systemctl restart network
```
epic-tester で redux-observable のマーブルテストを簡潔にする

マーブルテストは強力ですが、そのための準備(before,after)は面倒で極力書きたくありません。ここでは、`epic-tester`を使って簡潔に書く方法を見ていきます。

マーブルテストについては以下のブログが詳しいです。

[redux-observable の処理を marble testing で簡単にテストする](https://jyane.jp/2016/12/26/redux-observable.html)
[RxJS(5.x)で行うテストファーストな機能開発 | MMMブログ](https://blog.mmmcorp.co.jp/blog/2016/06/25/testing-rxjs-5/)

## 準備

準備として以下のような Epic を用意します。

```js
const success = payload => ({ type: 'success', payload })
const failure = error => ({ type: 'failure', error })

const epic = (action$, _, { API }) =>
  action$.ofType('fetchUser').mergeMap(() => {
    return API.getUser()
      .map(v => success(v.data))
      .catch(err => Observable.of(failure(err)))
  })
```

## マーブルテスト

まずは、`epic-tester`導入前のテストを見てみます。一つの`it`が大きいので、数が増えると記述量も増えていくのが予測できます。

```js
import { Observable } from 'rxjs'

beforeEach(() => {
  jest.resetModules()

  testScheduler = new TestScheduler((expected, actual) => {
    expect(expected).toEqual(actual)
  })

  cold = createCold(testScheduler)
})

afterEach(() => {
  testScheduler.flush()
})

describe('API success', () => {
  it('fetchUser', () => {
    const values = {
      a: { type: 'fetchUser' },
      b: { type: 'success', payload: 'result' }
    }

    const input$ = '--a'
    const expect = '--b'
    const test$ = epic(
      new ActionsObservable(cold(input$, values)),
      {},
      {
        dependencies: {
          API: { fetchUser: () => Observable.of({ data: 'result' }) }
        }
      }
    )
    testScheduler.expectObservable(test$).toBe(expect, values)
  })
})
```

`epic-tester`を導入しこれを解消していきましょう。

## インストール

```
yarn add --dev epic-tester
```

## 使い方

title、epic、tests プロパティが必須です。
tests プロパティはオブジェクトの配列を取ります。それぞれ、`input$`に入力、`expect$`に期待する出力をマーブル記法で書きます。values はマーブル記法で使ったプロパティを指定します。

```js
import { Observable } from 'rxjs'
import { epicTester } from 'epic-tester'

epicTester({
  title: 'API success',
  epic,
  dependencies: {
    API: {
      getUser: () => Observable.of({ data: 'result' })
    }
  },
  tests: [
    {
      title: 'fetchUser',
      input$: '-a',
      expect$: '-b',
      values: {
        a: { type: 'fetchUser' },
        b: {
          type: 'success',
          payload: 'result'
        }
      }
    }
  ]
})
```

`beforeEach`や expect 部分が抽象されたので、対象のマーブル記法を書くだけになりました。これで、新しくテスト対象が増えても`tests`プロパティにテスト対象を加えるだけです。

## まとめ

欠点としては`epicTester`では複雑な`Observable`のテストに対処できないでしょう。しかし、簡単なものを複雑なものに合わせる道理はありません。簡単なものは、簡潔に書くべきです。

何かあれば、コメントまたは Twitter でフィードバックお願いします 🙏

さて、ここで、reducer のテストも同様に簡潔に書けることに気づきます。reducer については、以下の記事を見てください。

[どのように redux の reducer のテストを書くか？ - Qiita](https://qiita.com/akameco/items/31e2078c38ff2fd60213)
オープン・クローズドの原則(OCP: The Open-Closed Principle)

## ソフトウェアの構成要素(クラス、モジュール、関数など)は拡張に対して開いていて、修正に対して閉じていなければならない
- 「硬い」設計をしてしまうと、プログラムのちょっとした変更でさえ、その箇所と依存関係を持つ全てのモジュールに影響を与えてしまう
- OCPはあとで似たような変更もっと出てきたときにコードを修正しないで済ませるにはどうすれば良いのかを教えてくれる
- OCPをうまく適用してシステムをリファクタリングできれば既に動いている既存のコードには一切修正を加える必要がない

## オープン・クローズドの原則(OCP)の概要
#### オープン・クローズドの原則(OCP)に従って設計されたモジュールには次のような特徴的な2つの属性がある
- **1. 拡張に対して開かれている(オープン: Open)**
 - これはモジュールの振る舞いを拡張できるという意味である。アプリケーションの仕様要求が変更されてもモジュールに新たな振る舞いを追加することでその変更に対処できる。つまり、そのモジュールの処理内容を変更できる。 
- **2. 修正に対して閉じている(クローズド: Closed)**
 - モジュールの振る舞いを拡張してもそのモジュールのソースコードやバイナリコードは全く影響を受けない。既にモジュールがコンパイルされてバイナリ形式になっているものはDLLであろうとJavaの.jarファイルであろうと手を触れる必要はない。
- この２つの属性は一見矛盾しているように思える
 - モジュールの振る舞いを拡張するにはそのモジュールのソースコード自体を変更しなければならない
 - また、ソースコードを変更できなければそのモジュールの振る舞いを変更することはできないと思うのが普通

## 鍵は「抽象」にあり
- C++やJavaなどのオブジェクト指向言語では宣言が固定されていても、それが特定の実装に結合していないメソッドを「抽象」を使って表現できる
- これらの言語では「抽象」は抽象基本クラスを使って記述され、特定の実装に結合していないメソッドはその派生クラスで実装される
- モジュールの設計では、こういった「抽象」のメカニズムを巧みに利用できる
- モジュールをある固定した「抽象」に従属させておけば修正に対してコードを閉じることができる
- なぜなら「抽象」を使えばコードを修正しなくても、その「抽象」の派生クラスを新たに追加するだけでモジュールの振る舞いを拡張できるからである

## まとめ
- いろいろな意味でオープン・クローズドの原則(OCP)はオブジェクト指向設計の核心である
- この原則に従うことでオブジェクト指向技術から得られる最大の利益(柔軟性、再利用性、保守性)を享受できる
- しかしオブジェクト指向のプログラミング言語を使えば自動的にOCPに準拠できるわけではない
- アプリケーションのあらゆる部分で抽象を無闇に使えばいいわけでもない
- 開発者が担当する部分で最も頻繁に変更されるプログラム部分にだけ的を絞って抽象を適用するように務めるべきである
- 早まった「抽象」をしないことも「抽象」を使うのと同等に重要なことである
GetOldTweets-python で遊んでみる 

#Introduction
こんばんは、はにおかさいです。<a href="https://qiita.com/haniokasai/items/9eba9e232a144a0f8805">前回</a>概要を書きましたので、実践のコーナーです。
今回はツイートデータを取得して、それをSQLite3に書き込ませます。
#Code
```python
#!/usr/bin/env python
# encoding: utf-8
import datetime
import got
import sqlite3

#username
username = "twitter"
#いくつツイートを取得するか
max = 100

now = datetime.datetime.now()
dbpath = 'tt_{0:%Y%m%d%H%M}'.format(now)+username+".sqlite3"

# データベース接続とカーソル生成
connection = sqlite3.connect(dbpath)
#実行後即座に書き込む
connection.isolation_level = None

cursor = connection.cursor()

#テーブル作成
cursor.execute("CREATE TABLE IF NOT EXISTS tweets (id INTEGER PRIMARY KEY, permalink TEXT, text TEXT, date TEXT, retweets INTEGER, favorites INTEGER , unixtime INTEGER)")


def savesql(v):
    try:
    # data2 = ["id", "permalink", "text", "date", "retweets", "favorites",(ココマデ） "mentions", "hashtags", "geo"]
        unixtime = int(v.date.timestamp())#v.dateはdatetime型です
        cursor.execute("INSERT INTO tweets VALUES (?, ?, ?, ?, ?, ?, ?)", (v.id, v.permalink , v.text, v.date, v.retweets, v.favorites, unixtime))
    except sqlite3.Error as e:
        print(str(e))

tweetCriteria = got.manager.TweetCriteria().setUsername(username=username).setTopTweets(True).setMaxTweets(max)
tweet = got.manager.TweetManager.getTweets(tweetCriteria)
for v in tweet:
    savesql(v)
    print(v.text)

connection.close()

```

#Result
例:tt_201804010204twitter.sqlite3
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/68eae763-e12a-c772-0b8d-94489286a833.png)
確かに取得できます。（自分のテストでは３０００件は余裕でした）

#Conclusion
この方法の良いところはAPIキーなしでツイートがほぼ無制限に取得できることだと思います。
この手法を活用して、ユーザーの感情分析や複数ユーザーとの共通項を発見し、ツイッターユーザー同士のマッチングサービスを作りたいと思っています。

#Reference
https://www.craneto.co.jp/archives/1248/
Seleniumを使ってみた

# はじめに
Daiさんのnoteを購入したのでチャレンジしようと思ったけど、そもそもスクレイピングの知識がないのでまずはSeleniumを使ってみます。これでぼくもスケベに足を突っ込むわけですね、ぐへへ。
noteはこちら→[スケベAI「スケベ博士」をPythonとGoogle Apps Scriptで作るスケベ・チュートリアルを公開します](https://note.mu/daikawai/n/n252b3f8d1138)

# 環境
-OS X 10.11.1
-Python 3.6.3

# 事前準備
##Seleniumインストール
Seleniumは使ったことがないのでインストールします。
これでWeb操作を自動化できるようになります。

```
pip3 install selenium
```
##Google Chrome Driverのインストール
ブラウザを操作するには、各ブラウザに合わせてドライバーを用意する必要があるとのこと。
[公式サイト](https://www.seleniumhq.org/download/)からダウンロードします。
![スクリーンショット 2018-04-01 0.06.28.png](https://qiita-image-store.s3.amazonaws.com/0/245442/7a31009d-bbe4-a32e-1720-9c3c716a44b3.png)

ダウンロードしたzipを解凍して中のファイルをPATHが通っているフォルダに移動して実行権限をつけます。

```
mv desktop/chromedriver /usr/local/bin/
chmod +x /usr/local/bin/chromedriver
```

#実験
クロームを起動して[自分のブログ](https://norinorinozakki.hatenablog.com/)を開いてみます

```python
from selenium import webdriver
#ブラウザオープン
driver = webdriver.Chrome()
#URLを指定してWebページを開く
driver.get("https://norinorinozakki.hatenablog.com/")
```
成功！
![スクリーンショット 2018-04-01 0.25.29.png](https://qiita-image-store.s3.amazonaws.com/0/245442/60d588f7-1171-ea0a-d958-168bd3e98dc8.png)


次はHTMLの要素からなんか取得しましょう。とりあえず記事のタイトルとかにしますか。
ちなみにChromeの開発者ツールはMacだと[Command+Option+I]で開けます。
該当箇所を調べると…
![スクリーンショット 2018-04-01 1.53.49.png](https://qiita-image-store.s3.amazonaws.com/0/245442/cf9085bb-4d4a-69ed-3757-1938246cb8d0.png)

というわけでこんな感じで書きました。

```python
ARTICLES = "h1.entry-title"
TITLE = ".entry-title-link.bookmark"
articles = driver.find_elements_by_css_selector(ARTICLES)
#記事数表示
print(len(articles))

#記事名出力
for article in articles:
    title = article.find_element_by_css_selector(TITLE)
    print(title.text)
```

結果

```
6
Python学習中
ラズパイでTweepy
ラズパイでLチカ(Python)
ラズパイ3を買ってきた
Mac上で仮想環境を作ってみる
思い立ったがなんとやら
```

というわけで成功です！
これを女優一覧のサイトに置き換えれば名前が取れるというわけですね。

# 感想
そもそもHTMLとCSSの知識がないので苦しみました。
そっちもインプットしていきたいと思います。

#参考URL
下記の記事を参考にさせていただきました、ありがとうございます！
[PythonでSeleniumを使ってスクレイピング (基礎)](https://qiita.com/kinpira/items/383b0fbee6bf229ea03d)
[Seleniumクイックリファレンス](http://www.seleniumqref.com/api/python/element_infoget/Python_text.html)
コンパイル・リンク・ロードの結果を一覧する

「リンカ・ローダ実践開発テクニック」が面白かったので何か作りたくなり、ELFファイルのいろんな要素（セグメントとかセクションとかシンボル）を読み取って、実際に展開された後のメモリマップに合わせて並べる簡単なプログラムを作ってみました。
できたものは[<こちら>](https://github.com/s0sasaki/SymbolMap)です。
本書はFreeBSD、32bit、C言語だけど、自分の環境はLinux、64bit、C++です。

例えば下記の変数たちがどのセクションに行くかみたいな話はよく聞くけど、それがどのセグメントに行ってプロセスのメモリ上のどこに配置されるのかまで合わせて一覧したいというのがモチベーション。

```c
#include <stdlib.h>

int global_val = 5;
int global_arr[1000] = {1,2,3};
const int global_const_val = 5;
const int global_const_arr[10000] = {1,2,3};
int global_empty_val;
int global_empty_arr[2000000];
char  global_char_arr[] = "global_char_arr";
char *global_char_ptr   = "global_char_ptr";

int global_func(int x){
    return x + 1;
}

int main(){
    int local_val = 1;
    int local_arr[1000] = {1,2,3};
    const int local_const_val = 1;
    const int local_const_arr[10000] = {1,2,3};
    int local_empty_val;
    int local_empty_arr[2000000];
    char  local_char_arr[] = "local_char_arr";
    char *local_char_ptr   = "local_char_ptr";
    static int local_static_val = 1;
    static int local_static_empty_val;
    static const int local_static_const_val = 1;
    int *local_heap;
    local_heap = malloc(100000);
    sleep(10000);
    free(local_heap);
    return 0;
}
```


結果の概要は下記。
一番左列がメモリのアドレス、一番右列がシンボル名です。


![linker_loader.PNG](https://qiita-image-store.s3.amazonaws.com/0/142619/652b21ed-caf8-39b8-b638-bea7ec64ddee.png)

出力の完全版は[<こちら>](https://github.com/s0sasaki/SymbolMap/blob/master/hello.symbolmap_result.txt)です。
セグメントが分割されて順序が変わったりなど想定外に複雑な箇所も…。
でもだいたい期待通り動いていそうだ。

以上
npm(javascript)とpipenv(python)の対応表

## Pythonの世界でnpmと似たものが欲しい

node.jsやってて`npm`なしでは生きていけない体になった人がpythonやるときに似たようなツールないかなー、と探したら`pipenv`がいいらしいのでよく使いそうな使い方をまとめてみた。

ちなみに`npm`だと`package.json`があるディレクトリ下を作業領域にするけど、`pipenv`は`Pipfile`があるディレクトリで`pipenv shell`を実行して作業領域（仮想環境と呼ばれる）に入る。

## 対応表

### `npm init`

`npm`では`package.json`を生成する。

```
$ pipenv install
```

`Pipfile`がない場合は新しく`Pipfile`と`Pipfile.lock`を生成する。


### `npm install`

`npm`では`package.json`に記述されたモジュールのインストールを行う。

```shell
$ pipenv install
```

`Pipfile`がある場合`Pipfile`に記述されたモジュールの仮想環境へのインストールを行う。

`Pipfile`の`python_version`にインストールされていないバージョンが指定されていたらインストールするかどうか聞かれて、自動インストールできるらしいけど試してみたところエラーで止まってしまった……。

### `npm install -g (モジュール名)`

```shell
（多分）
$ pipenv install --system
```

※Python力が足りなくて適切な実験例が思いつかなかったので自信ない

### `npm install --save (モジュール名)`

```shell
$ pipenv install (モジュール名)
```

特にオプションをつけなくても`Pipfile`の`[packages]`に追加してくれる。

### `npm install --dev (モジュール名)`

```shell
$ pipenv install --dev (モジュール)
```

`-d`でもOK。`Pipfile`の`[dev-packages]`に追加してくれる。



### `npm uninstall (モジュール名)`

```shell
$ pipenv uninstall (モジュール名)
```

### `npm list [-g]`

```shell
$ pipenv graph
```

ちなみに

```shell
$ pipenv check
```

で脆弱性チェックをしてくれるらしい。優秀すぎないか？

### `npm test`

たぶん対応するコマンドはない？

### `npm run (任意)`

~~たぶん対応するコマンドはない？~~

ありました（コメントで @tanamon さんに[教えてもらった](http://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#custom-script-shortcuts)）。

```config
[scripts]
printfoo = "python -c \"print('foo')\""
```

`Pipfile`にこのように書いておいて

```shell
$ pipenv run printfoo
```

こうやって呼び出す。

### その他

```shell
$ pipenv --rm
```

で仮想環境の削除ができる。


---

参考文献
---

* [Pipenv: 人間のためのPython開発ワークフロー](http://pipenv-ja.readthedocs.io/ja/translate-ja/)
TestCafeでページスクロールしてキャプチャしたい

TestCafeでwindow.scrollBy()などの呼び出し方がわからなかったので、そのメモです。
ClientFunctionをimportしていけました。

```javascript:test.js
import {Selector, ClientFunction} from 'testcafe';

fixture('スクショ')
  .page('https://github.com/DevExpress/testcafe')


test('ページ下部までスクショ撮り続ける', async t => {

  const scrollHeight = ClientFunction(() => window.scrollBy(0, window.innerHeight));
  const getMaxHeight = ClientFunction(() => document.body.clientHeight );
  const getViewHeight = ClientFunction(() => window.innerHeight );
  let maxHeight = await getMaxHeight();
  let viewHeight = await getViewHeight();

  for (let index = 0; viewHeight < maxHeight + viewHeight; index++) {
    await t.takeScreenshot(`capture${index}.png`);
    maxHeight = maxHeight - viewHeight;
    await scrollHeight();
  }
})
```
ClientFunctionでなく、eval( )でもいけるっぽい。

```javascript
const scrollBy = await t.eval(() => window.scrollBy(0, window.innerHeight));
```

あとは以下のようなコマンドでスクショが取れます。

```shell
testcafe chrome ./test.js --screenshots ./
```

実行してから気づいたけども、C#で書いたseleniumのキャプチャの方がスピードが早かった気がする
API Gateway の Lambda プロキシ統合でバイナリデータをレスポンスする(Python3.6)

結構情報転がってる割になぜかハマり続けたので一応メモ

# Lambdaのコード
bodyにbase64エンコードしたバイナリデータを指定、isBase64EncodedをTrueに指定します。

```python
def lambda_handler(event, context):

    # binary_dataを用意(省略）
    binary_data = xxxxx
    
    response = {
       "statusCode": 200,
       "headers":{
           "Content-Type": "image/jpeg",
       },
       "isBase64Encoded": True,
        "body" : base64.b64encode(binary_data).decode('utf-8')
       }
    return response
```

# API Gatewayの設定
## 統合リクエスト

Lambda プロキシ統合の使用にチェックを入れないと、PythonコードのレスポンスがそのままHTTPのレスポンスとして返却されるので注意。

<img width="603" alt="スクリーンショット 2018-04-01 1.18.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/220908/53801ff1-5537-40e6-2951-3508cb0337c4.png">

## バイナリメディアタイプの指定
<img width="213" alt="スクリーンショット 2018-04-01 1.19.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/220908/829bc194-7703-b8ca-e89a-a44be9136b21.png">

設定から指定できます。

<img width="788" alt="スクリーンショット 2018-04-01 1.19.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/220908/75b11653-831d-2bef-49f3-d9abc59701cb.png">

バイナリメディアタイプに、バイナリとして扱いたいコンテンツタイプを指定します。
これがないと常にエンコードされた文字列がそのまま返却されます。

## エンドポイントを叩く

これだとデコードされずに返却されます。

```
curl https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test > image.jpeg
```

バイナリメディアタイプに指定したコンテンツタイプをAcceptに指定するとデコードされて返却されます。

```
curl -v --request GET -H "Accept: image/jpeg" https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test > image.jpeg
```

CloudFrontをかませてAcceptの指定をせずともバイナリを返却させる場合は以下の記事が参考になりました。
https://qiita.com/akitsukada/items/e6d8fe68c49973d1edf6#cloudfront
【WebアプリUI】  非活性と非表示どっちを使う？

#非活性と非表示使い分け

Webアプリを作っていると避けて通れないのが、非活性と非表示です。

ネットサーフィンしても中々、この手の話が出てこない。

エンタープライズ向けの業務アプリとコンシューマー向けWebアプリのUI設計を
考える機会があったので、まとめてみました。

#非活性と非表示の違いを知る
全てのUIが表示されている通常表示と非活性と非表示を比較。

ボタンを例に非活性と非表示を違いをおさらいします。

##通常と非活性
まずは、非活性

非活性は、ボタンが表示されているけど押せない状態のこと。

何か必要な情報が入力されていないと押せない場合に、よく使われます。

例えば、ログインボタンでユーザーIDやパスワードが入力されていない時のUIとしてよく使われます。

![非活性.jpg](https://qiita-image-store.s3.amazonaws.com/0/106459/e9edd86d-ee08-b4c8-2571-c88d03b11724.jpeg)


##通常と非表示
非表示は、ボタンがそもそも表示されていない状態のこと。
もちろん、ユーザーは操作することができません。
権限などによって使えないボタンの場合に、使われます。
ex)管理者メニュー

![非表示.jpg](https://qiita-image-store.s3.amazonaws.com/0/106459/62f89451-6cab-9963-4946-6c896e00af01.jpeg)


#コンシューマー向けアプリでは、非表示と非活性はあまり使わない？
コンシューマ向けアプリは、必要な機能を基本的にユーザーに提供していくことを目的にしているはず。

仮に、ユーザー登録をしなければいけないアプリだったとしても基本的にはボタンを押せるようにするため、
表示して活性状態しておく。ボタンをユーザーが押した時に登録済か判断する。そうすることによって離脱率を低くしています。

#エンタープライズ向けでは、非表示と非活性はよく使う！
私がこれまでやってきたエンタープライズ向けのアプリだとよく非表示と非活性の概念を用います。

なぜなら、エンタープライズ向けのアプリは往々にしてボタンの数や入力エリアの数が多い。

例えば、以前私が携わったアプリでは、一覧の一つのリストから行えるメニューが20個以上ありました。

理由は、人によって使うボタンが変わります。

会社で行われる業務を賄うように作られるから機能がモリモリになって操作が多くなってしまいます。

#どう使い分ける？

**非活性**

- ユーザーが操作できない。何かしらの操作すればできる。
- UIが使えないのに表示されているので、鬱陶しい


**非表示**

- ユーザーが操作できない。そもそもわからない。 
- 非表示になることでUIがずれる


私の見解としては、基本的にはコンシューマー向けだろうが、エンタープライズ向けだろうが表示して、活性状態であることが望ましいです。
つまり、非活性と非表示を極力使うべきではないと思います。

押せないボタンや入力できないフォーム、消えているボタンがたくさん発生する場合は、
そもそもユーザーに使いやすい導線になっていないことが考えられます。

導線の見直しや機能分割をするべきである。

ユーザーへ極力、オープンなUI！そして、シンプルイズベスト！
エディター拡張画面を、巷にあるような、メニューを実装する方法

#コードの使用に当たっての注意事項
コードの使用によって不利益が生じた場合は、責任を負いません。
その上で、コード使用する場合は使用してください。
参考とか、使用の場合にコメントとかに残していただけると、やる気がでて助かります。

#こんな事ってないですか？

編集している素材の保存のボタンの場所を、いつものようにメニューバーみたいな使い方できたらいいのに…

そう、青のWのソフトとか緑のXとか他のソフトみたいにエディターの画面の上部に
**メニューバー**みたいなのがあればもう迷わないのに…

え？それできますよ？っていう話。

以下

``` sample.cs
public class EditorSamapleMain : EditorWindow
{
    [MenuItem("Tools/SampleMenu")]
    static public void open_tool()
    {
        GetWindow<EditorSamapleMain>();
    }

    /// <summary>
    /// 描画部分
    /// </summary>
    private void OnGUI()
    {
        Rect _rect = EditorGUILayout.BeginHorizontal();
        {
            if(GUILayout.Button("File", EditorStyles.toolbarButton, GUILayout.Width(100.0f)))
            {
                Rect _main_rect = this.position;
                _main_rect.size = new Vector2(_rect.width, _rect.height);
                EditorSampleSub.file_menu_open(_main_rect);
            }
        }
        EditorGUILayout.EndHorizontal();
    }

}

public class EditorSampleSub : EditorWindow
{
    static public void file_menu_open(Rect _main_window)
    {
        var _window = CreateInstance<EditorSampleSub>();

        _window.position = new Rect(_main_window.x -100, _main_window.y + _main_window.size.y,200,200);

        _window.ShowPopup();
        _window.Focus();
    }

    private bool close;

    private EditorSampleSub()
    {
        close = false;
    }

    private void OnGUI()
    {
        EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.ExpandWidth(true));
        if(GUILayout.Button("緊急終了",EditorStyles.toolbarButton))
        {
            this.Close();
        }
        EditorGUILayout.EndVertical();
    }


    private void Update()
    {
        if(close)
        {
            this.Close();
        }

        
    }

    private void OnLostFocus()
    {
        close = true;
    }

}
```


上記を実行すると以下のようになります。


![editor_sample.png](https://qiita-image-store.s3.amazonaws.com/0/101366/3fc0c252-8e07-c081-7c33-23d6309a922e.png)


少し画面的な見栄えは、たぶん枠組みとかをつける処理をつければ、
おそらくかなりよくなると思われる。



#コード解説#
さて、少しコード解説

コードを参照するので、別画面で、上記コードぱくって、見ると良いかも。

###注目する所はRect
今回ソースの場合
画面を作る前に、別途、Rectを二つ取得しています。

１つは、HorizontalBlockから
もう１つはthisの値から取得しています。

まず1つ目の説明から
EditorSamapleMain 側のonGUI()のrectの値の値。
これは、このHorizontalBlockの中身を見せた時の大きさを見ています。
その為、今回の場合だと、Fileという書かれているボタンの大きさが値として返ってきます。
これは、このBlockの大きさを取得するために行っているものです。

２つめ
この画面の表示部分の位置からを位置と大きさを取得しています。



つまり。
![editor_sample.png](https://qiita-image-store.s3.amazonaws.com/0/101366/332786cf-8c5d-4b2f-9182-2579d0e612c6.png)


１が青の枠の部分
２が赤の枠の部分

の領域を取得しています。
（青の部分だけでいいじゃん！）って気づいた人。
そう思った場合は実行してください、おそらく左上部分にメニュー顔面が出てくると思います。

赤の位置情報を取得しているのは左上起点のXとYを取得しているためです。
これによって、現在の赤枠のWindowの位置を取得しています。
その位置情報に対して、青部分のサイズのYを取得して、Fileを押した時に出てくる
ウィンドウの位置を計算しています。

そのため、2か所のRect情報が必要となってくるわけです。
２からウィンドウ位置
１からウィンドウから、コマンド分ずらした位置
Xcode9.3 から git で管理するファイルが増える



`IDEWorkspaceChecks.plist` というファイルが増える。
 Workspace での必要なチェック項目の状態を保存しておくものらしいので .gitignore に入れず管理するようにしましょう。

・参考：
https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html
会議が長いし議事録が役に立たないのでGoogleDocsを使うことで改善しようとしている話

役に立たない、は言い過ぎ。だけど人の書いた議事録って痒いところに手が届かないこともあるのでどうしたら良いかなー？と思って考えたこと。

# 背景
インフラ（SRE的な仕事を進める）チームにおける週一回の定例ミーティングがある。
いわゆるスプリント的な役割で、進捗共有と困り事相談、新規案件共有、新技術簡易説明などを行う。
※補足： 技術を深掘りする会は、インフラ読書会とインフラ勉強会が別にあるので、軽く説明して使えるようなものとか、基本だけ押さえておいて欲しいものだけ定例で話す。


# 問題点
### 時間がかかりすぎる
ミーティングに確保している時間は１時間。実際は１時間半はかかっていた。いつも夜にやるので帰る時間が遅くなるし、終わる頃にはみんな憔悴している。

### 議事録が後から見返して役にたたない
議事録というのは、思考の過程と結論、次のステップについて書いてあるべきだと思うが、結論だけ、もしくは適当なメモしか残っていない。

# 上記問題点が発生している原因

### 学習のために新人が議事録をとっている
* 画面はスクリーンで共有してみんなで見ている（これはOK）
* 新人さんに議事録にとって欲しい内容を説明するためみんなで寄ってたかって0から10まで説明する。結果新人は混乱して爆発。会議は止まる。
* 平凡なタイプミスへの指摘など無駄な時間が発生する
* 細かい情報を渡すためのリンク受け渡しなどでタイムロス
* 【一番の問題】案件を進める上で重要な情報が残らないことがある。議論の過程が見えない。（例：「案は3つあって、それぞれこういうメリットデメリットがあって、最終的にこういう結論になったのでこれを選ぼう」と言う話になったとして、何も言わないと新人は結論だけ、もしくは適当な単語だけを引っ張って議事録としようとする。）
* 上記のような議事録の取り方を毎回口頭で説明を試みるが、やってみせた方が早い！ 

### 議事録フォーマットの問題
* 「今週の進捗」と「来週のタスク」の項目が分かれている
* 同じタスクについて話しているのに、会の前半ではこれまでの話、会の後半ではこれからの話を話そう、と言う風にフォーマットができていた
* 同じタスクについて二回話すのが時間の無駄

### 障害報告も同じ会でやっている
* 障害があるか無いかで会の時間が大きく変わってしまう
* その説明や対策を考えるだけで30分前後かかっている（ちゃんと細かい対策を考えるともっとかかることも）


# 暫定解決策
### 議事録の取り方について
GoodleDocsでみんなで同時編集して、みんなで作り上げる。
個々人の進捗は30分前にSlackで@hereでメンションを飛ばして書いておいてもらう。普通のWikiやConflenceだとコンフリクトを気にしないといけないが、GoogleDocsなら気にしなくて良い。
同じドキュメントにリアルタイムで反映されるので、込み入った話でも話を聞いて理解した人が「こういうことですか？」と言うのを書いて意識共有ができるようになった。


### フォーマットについて
進捗内容は「今ここ」「ここまで終わった」「来週ここまでやる」のポインタを変えてもらうだけで二回同じことを書く必要をなくした。

案件担当者は自分の案件の進捗を書くが、他の人がそれを聞いて懸念点や補足を議事録に追記していく。可能なかぎり議論の流れも書く。書いてなかったら誰か（現状では主に私になってしまっている）が補足する

### 障害報告会について
障害報告についてはインフラ勉強会の方へ移動した。障害があった週の勉強会は障害をネタにその対策を練って学習を進める。特に障害がなければ誰かが学んだ新技術か先輩が継承していきたい技術について話す。たまに読書会。
障害はインフラ分野の偉大なる先生。
  
### 課題
* 新人の理解度が甘くなりがち。少なくとも議事録をとってもらってれば最低限の当事者意識があるが、単に聞いているだけだとなかなか。
* しかし先輩含めて数人の時間をその理解のために全部消費するかと言うと悩ましい。結果、とりあえず新人はドメイン知識を含めて100パーセントを理解してもらうのは諦めた。80パーセントわかっていればよく、重要なことは先輩たちがその場もしくは後で説明する。覚えておいて欲しいことはちゃんと説明しておくという先輩の意識が必要になる。
* 議論の時間があるぞ、となると話したい内容はもっとあるので結局時間は結構かかる。
新規作成アプリをBitbucketにあげる

覚書として＊＊＊

- アプリのあるディレクトリに移動してから以下のコマンドを実行していく

        $ cd C:\App\app_name
        $ git init Initialized empty Git repository in C:\App\app_name/.git/
        $ git remote add origin https://[ユーザー名]@bitbucket.org/-----/-----.git
        $ git add .
        $ git commit -m "first commit"
        $ git push -u origin master
ベイズ推定とグラフィカルモデルを受講して思ったこと 3 (条件付き独立)

# 条件付き独立 になる実例を考えた

条件付き独立の定義（おさらい）
P(X,Y∣Z)=P(X∣Y,Z)P(Y∣Z)の式は、Zが与えられたときの Xの分布が、YとZが与えられたときのXの分布と等しいことを示す。

[ComputerVision](https://www.amazon.com/Computer-Vision-Models-Learning-Inference/dp/1107011795/ref=sr_1_1?s=books&ie=UTF8&qid=1334662414&sr=1-1)の１２章では、ノイズ消去で、隣合わないセルは、隣のセルが入ることにより、条件付き独立であるという実例がでている。（と解釈した）

その他、身近？で実例考えてみた。

1 目的地到着時刻において、100m手前の場所の到着時刻は、50ｍ先の場所の到着時刻の情報があるときは条件付き独立
2 株価において、 PERと成長性評価の情報があるときは、従業員のスキルレベルは条件付き独立。（株価は、複雑なので、真実はわからないが、このケースはありえるかなと思った）

ここで、はて？　恋人になれる可能性において、その人の魅力度は、相手に彼氏、彼女がいる場合は独立、いない場合は、影響するケースは、グラフィカルモデルでモデリングできるのかな？

#### 次回は、無料でGPU使ってAI作れる [Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb#recent=true)というサービスを本日知ったので、試してブログ書きます。

[前回はこちらへ](https://qiita.com/rmlhello/items/1a6a06dccb565b6a6661)
プロジェクトにペルソナを導入してみてわかったこと

## この記事を書こうと思った背景
- 学生時代に人間中心設計やユーザーエクスペリエンス(UX)の研究に励み、会社でそのへんの知識持ってますよとアピールしていたら、ありがたいことにペルソナ導入してみないか的なお声を頂戴しました
- もともとものづくりの会社にSEとして入ったのも、人間中心設計とかの知識が発揮できるのでは?!という淡い期待を抱いてのことです
- そんな折に、ここ数年の間に2つのプロジェクトでペルソナを扱う機会がありました
- そこで、実践してみるとどうにも上手くいかないことやもっとこうできたらいいのにがたくさん出てきたので、書き留めておこうと思い綴っています

## Case1
### 自分の役割とプロジェクトの特徴
- インフラエンジニアとして、小売業向けのWebアプリケーション開発を行っているプロジェクトに参加
- 参加時期は立ち上げて、少し進んだあたり
- 25人くらいの規模
- 中堅以上の男性多め（ベテラン多い）
- Agile開発

### 取り入れたペルソナ
- プラグマティックペルソナ（「Lean UX」より）
    - 内容はProfile, Work, Goal, Needs/Pain Solution, One Dayをシナリオ調書いた
    - 「Lean UX」で紹介されているフレームに"One Day"というそのペルソナのある日を切り取った記述を添えたものを作った
- 関係者の役職ごとにセグメント分けして6人も作った
    - 直接ペルソナ対象となる関係者に会ったことがある人と4人ほどで付箋に特徴を発散的に書き出し、その情報をもとに想像する部分も含めながら作った
    - 1人作るのに大体1時間くらい
- 似顔絵はデジタルな絵を得意な人が描いてくれた

### そして導入
- プロジェクト全員にペルソナって何？どんな効果をもたらすの？をプレゼン
- そして作ったペルソナを紹介
- プロジェクトメンバーがよく目にする場所（Web上＋居室の壁）にペルソナを置いた

### 結果
- 良かったこと
    - 今までペルソナに触れてこなかった人たちにペルソナという概念をインプットできた
    - 企画層の人たちにとってはウケが良かった（実際のステークホルダーをイメージしやすいなど）
    - ペルソナをとっかかりに人間中心設計の分野で用いられる手法に興味を持って、検証的に導入する人が現れた
- 上手くいかなかったこと
    - どう活用して良いかわからずに形骸化してしまった
        - 実際に自分はインフラチームだったため、アプリチームなどガンガン使って欲しいところに情報共有がうまくできなかった
        - それもあって、アプリ開発時にペルソナを意識するよう促すことができなかった
    - ある程度プロジェクトが走り出してから導入したので、ペースやイメージができていて、定着しなかった
    - 「良さそうなものってわかるけど気恥ずかしい」とか「定性的すぎて有効性が見いだせない」などの意見をもらった
        - そのときにこうなんですよ!と説得ができなかった

### わかったこと
- プロジェクトの立ち上げ時からいないとだめ
    - ペルソナは立ち上げ時から当たり前のような存在としていないと、なかなか受け入れてもらえない
    - プロジェクト自体の企画段階からいるもの
- ある程度はそのプロジェクトに所属する人のキャラクターに合った内容にする
    - 例えば、"One Day"という項目にその人の休日の過ごし方をしっかり書いたのだが、そういう人間らしすぎるところに気恥ずかしさを覚えてしまった人がいた
    - 極端だけれども、シナリオ調を捨てて、箇条書きで簡潔に書くなどしたほうがクールで少しは受け入れてもらえそう
- どういう場面でペルソナが登場して、開発に活かせるのか開発者に知ってもらう取り組みが必要
    - 例えば、作りたい機能が複数ある場合にペルソナが最も必要としている価値は何かに立ち戻る
    - 機能が決まったらUI検討時にペルソナの性格や特徴に合わせて、文字サイズは大きめにしてみようなどの検討をいれたりできる

## Case2
### 自分の役割とプロジェクトの特徴
- インフラ〜フロントエンジニアとして、業務支援を行うWebアプリケーション開発を行っているプロジェクトに参加
- 参加時期は立ち上げて、ほんの少し進んだあたり
- 10人くらいの規模
- 若手多め
- Agile開発
- もともとペルソナがいた

### 取り入れたペルソナ
- プラグマティックペルソナ（「Lean UX」より）
    - 内容はProfile, Work, Goal, Needs/Pain Solutionを箇条書きで書いた
- エンドユーザーの求める価値でセグメント分けして4人作った
    - 直接ペルソナ対象となる関係者に会ったことがある人とプロジェクトメンバー全員で付箋に特徴を発散的に書き出し、それをそのままペルソナとした
    - 1人作るのに大体1時間くらい
- 似顔絵は絵が得意な人がフリーハンドで描いてくれた

### そして再導入
- プロジェクト全員にペルソナって何？どんな効果をもたらすの？をプレゼン
- もともといたペルソナを提案するフレームに移し替えながら作り直した
- プロジェクトメンバーがよく目にする場所（Web上）にペルソナを置いた
- ロードマップ的に長期の計画を立てる時には壁に貼った

### 結果
- よかったこと
    - POがものすごくペルソナに対して理解を示してくれて、プロジェクト全体に浸透した
    - ペルソナについてプロジェクト全員で語り合う時間ができ、ペルソナが生き生きした
        - 自ずとキャッチフレーズまでできた
    - 機能検討時やUI検討時に⚪︎⚪︎さんにとって何が良いだろうを考えるようになった
    - 雑談にもペルソナが登場するようになった
- 上手くいかなかったこと
    - プロジェクトが佳境を迎えてくるにつれて、エンドユーザーの声がどんどん大きくなり、ペルソナ起点で議論することがなくなってしまった
        - 「エンドユーザーとすぐに話せるのになんでペルソナが必要なの？」と質問されてしまった
        - そのときは「エンドユーザーの声が大きくなりすぎると、冷静に客観的な判断ができなくなります。偏った考えになってしまったりします」とお伝えした
    - ペルソナの更新頻度がだんだん下がってきて、少し古くなってしまった

### わかったこと
- エンドユーザーと距離の近いプロジェクトほど、しっかりペルソナを立てるほうが良い
    - 結果としてエンドユーザーの直接的な声に耳を傾けすぎたために、４人のペルソナのうち3人のペルソナに該当するグループのことが置き去りになってしまったり、エンドユーザーの声に盲目的に従うことが増えてしまったのはよくなかった
- エンドユーザーの声を聞くたびにペルソナに変化はないかみなしたほうが良い
    - ペルソナも成長させないと、初期の要件に従い続けるウォーターフォール開発と変わらなくなってしまう


## まとめ
- ペルソナ実践するの難しい、と日々痛感しているので、試行錯誤しながら良いやり方を見つけていくしかないと感じる今日この頃です
- 失敗から得られることが多いです
同じプロパティを何度も参照するより変数に代入してから参照するほうが速い

同じプロパティを何度も参照しているコードを見かけ、「それは遅いだろう」と思ったのですが、実際にどのくらい遅くなるのか気になったので、簡単なベンチマークスクリプトで確認してみました。

```php
<?php
$obj1 = new stdClass;
$obj1->foo = 'bar';

$obj2 = new stdClass;
$obj2->foo = new stdClass;
$obj2->foo->bar = 'baz';

$obj1_foo = $obj1->foo;
$obj2_foo_bar = $obj2->foo->bar;

$start = microtime(true);
for ($i = 1; $i <= 10000000; $i++) {$obj1->foo;}
$end = microtime(true);
echo '$obj1->foo      : ', $end - $start, "\n";

$start = microtime(true);
for ($i = 1; $i <= 10000000; $i++) {$obj2->foo->bar;}
$end = microtime(true);
echo '$obj2->foo->bar : ', $end - $start, "\n";

$start = microtime(true);
for ($i = 1; $i <= 10000000; $i++) {$obj1_foo;}
$end = microtime(true);
echo '$obj1_foo       : ', $end - $start, "\n";

$start = microtime(true);
for ($i = 1; $i <= 10000000; $i++) {$obj2_foo_bar;}
$end = microtime(true);
echo '$obj2_foo_bar   : ', $end - $start, "\n";
```

```
$obj1->foo      : 0.19446301460266
$obj2->foo->bar : 0.30430507659912
$obj1_foo       : 0.094012975692749
$obj2_foo_bar   : 0.094088077545166
```

というわけで、`$obj1->foo` なら変数を2回、`$obj2->foo->bar` なら変数を3回、参照するのと同じくらい時間がかかるのだと分かりました。雑な理解ではありますが、リファクタリングの効果を推測する際の参考にはなるかと思います。
配列をforで初期化

#配列をfor文を使って初期化する方法

こんな感じで作成できる。

```python
list1 = [i for i in range(5)]
print(list1)

list2 = [str(i + 1) for i in range(5)]
print(list2)
```

＜出力結果＞
[0, 1, 2, 3, 4]
['1', '2', '3', '4', '5']