OmniAICreator/Qiita-1.07M huggingface dataset:
高解像度でスクリーンショットがはみ出る場合

### ノートPCなどで困るスクリーンショット
#### (1)キーボードレイアウトの問題
ノートパソコンの場合、デスクトップリプレースタイプ以外のものでは、キーボードはフルサイズ（テンキーがあるという意味で）ではなく、コンパクトサイズであり、キーボードのレイアウトは、メーカーごと、機種ごとにバラバラである場合が少なくありません。
スクリーンショット用のキーとして「PrtScn」などの表記があるキーが配置されていますが、デスクトップ用のキーと同じように単純な操作でスクリーンショットが取れないケースもあります。
#### (2)画面解像度の問題
そこでスクリーンショット用アプリの出番となる訳ですが、今度は近年の高解像度な画面が障害になります。
Windows 10の「ディスプレイ設定」では、「カスタム スケーリング」という機能で、アプリケーションの認識しているサイズと、人間が見て見やすいサイズの橋渡しをしています。
例えば、Surface Bookの13.5インチ液晶は、解像度としては3,000×2,000ですが、そのままだとすべてのアプリケーションの表示が細かすぎて見づらくなります。
そこで、「200％」というスケーリングを設定することによって、1,500×1,000相当の表示としている訳です。
#### (3)スクリーンショットソフトの不具合
この「カスタム スケーリング」で100％以外がデフォルト設定されているPCでは、スクリーンショットに関する不具合にしばしば直面します。
上述のSurface Bookの場合、デスクトップ全体のスクリーンショットを撮っても、取得した画像を見ると画面左上1/4のものしか撮れていないのです。
#### (4)解決方法
1. アプリケーションの実行ファイルを右クリックして、「プロパティ」を開きます。
2. 「互換性」タブをクリックします。
3. 「高いDPIスケールの動作を上書きします。」にチェックをつけます。
4. プルダウンで「アプリケーション」「システム」「システム（拡張）」のいずれかを選択します。（私の利用している「WinShot」の場合は、「アプリケーション」でした）
5. 
※ WinShotの場合は、上記操作後、アプリケーションの再起動は必要ありませんでした。

![WS000005.png](https://qiita-image-store.s3.amazonaws.com/0/90217/53e9b7bb-5531-1e0b-d339-280fc79ff0fe.png)

#### (5)備考
以前のバージョンのWindowsでは「高DPI設定では画面のスケーリングを無効にする」という項目だったようですが、現在のバージョン（Windows 10 15063.726 2017年11月15日版）では違っているようなので、記事にしてみました。
Docker で MySQL コンテナを起動しました

MySQL だけを Docker で起動してデータチェックをできたら便利かなと思いました。やってみます。


# 環境
Mac で Docker for Mac にて起動しています。

# MySQL の起動
Docker で MySQL を起動するにはまず以下のコマンドを実行します。

```bash:
docker run --name コンテナ名 -e MYSQL_ROOT_PASSWORD=secret -d mysql
```
mysqlはDockerのmysqlイメージを使うという指定です。
コンテナ名をmysql-pugiemonnとして起動してみます。

```bash:
docker run --name mysql-pugiemonn -e MYSQL_ROOT_PASSWORD=secret -d mysql
```

mysql-pugiemonnのコンテナが立ち上がっています。

```bash:
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
f961deaa5bb1        mysql               "docker-entrypoint..."   3 seconds ago       Up 1 second         3306/tcp            mysql-pugiemonn
```
コンテナが立ち上がったのでさっそくMySQLを操作したいです。

# MySQLを操作
dockerにログインします。

```bash:
docker exec -it mysql-pugiemonn bash
```

mysqlへログインします。

```bash:
mysql -u root -p
Enter password: 
```
MySQL イメージから作成したコンテナで MySQL の root ユーザーのパスワードは `secret` です。

```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
```
SQL が実行できるようになりました。


# 参考


- [Dockerの公式MySQLイメージの使い方を徹底的に解説するよ](http://dqn.sakusakutto.jp/2015/10/docker_mysqld_tutorial.html)

# 次にやること
コンテナ起動時に初期SQLを実行するところまでやりたかったけどまたこんど😳
IAMポリシー"認識されないアクション"に関して

## 参考
- http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_understand-service-summary.html

## 経緯
- IAMポリシーで認識されないアクションがあると!マークが出る
- **サービスとして使用できるIAMアクションなのに何故通知が出るのか気になったので備忘録**

## 説明

### IAMポリシーで認識されないアクションが表示された場合は以下が考えられる

- http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_understand-service-summary.html

```
Unrecognized actions – このポリシーには、このサービスのポリシー内で認識されない 1 つ以上のアクションが含まれます。
この警告を使用して、アクションにタイプミスが含まれている可能性があるかどうかを確認できます。
アクション名が正しい場合、サービスはポリシー概要を一部サポートしていないか、プレビュー中であるか、カスタムサービスである可能性があります。
一般公開された (GA) サービスの特定のアクションに対するポリシー概要のサポートをリクエストするには、「サービスが IAM ポリシー概要をサポートしていない」を参照してください。
```

### 僕の場合
- **プレビュー中のIAMアクションを使用していた**
- SMS MFA
 - http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_enable_sms.html
 - https://aws.amazon.com/jp/iam/details/mfa/

## IAMポリシーで認識されなかった場合の参考

- http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/troubleshoot_policies.html#unsupported-services-actions

```
ポリシーに認識されないサービス、アクション、またはリソースタイプが含まれている場合は、以下のいずれかのエラーが発生しています。

プレビューサービス – プレビュー中のサービスはポリシー概要をサポートしていません。

カスタムサービス – カスタムサービスはポリシー概要をサポートしていません。

サービスが概要をサポートしていない – ポリシー概要をサポートしていない一般公開された (GA) サービスがポリシーに含まれる場合、そのサービスは、ポリシー概要テーブルの [Unrecognized services] セクションに含まれます。一般公開されたサービスとは、プレビューやカスタムサービスではない、一般にリリースされたサービスです。認識されないサービスが一般公開されていて、名前のスペルが正しくない場合、そのサービスは IAM ポリシー概要をサポートしません。GA サービスに対するポリシー概要のサポートをリクエストする方法については、「サービスが IAM ポリシー概要をサポートしていない」を参照してください。

アクションが概要をサポートしていない – ポリシーに含まれるサービスがサポートされていても、アクションがサポートされていない場合、そのアクションはサービス概要テーブルの [Unrecognized actions] セクションに含まれます。サービス概要内での警告については、「サービス概要 (アクションのリスト)」を参照してください。

リソースタイプが概要をサポートしていない – ポリシーに含まれるアクションがサポートされていても、リソースタイプがサポートされていない場合、そのリソースは、サービス概要テーブルの [Unrecognized resource types] セクションに含まれます。サービス概要内での警告については、「サービス概要 (アクションのリスト)」を参照してください。

タイプミス – AWS の Policy Validator は JSON が構文上正しいことのみをチェックするため、タイプミスを含むポリシーが作成される可能性があります。ポリシーに、確実に上記のエラーが含まれていない場合は、ポリシーにタイプミスが含まれている可能性があります。サービス、アクション、およびリソースタイプの名前にタイプミスがないか確認してください。たとえば、s3 ではなく s2 を使用したり、ListAllMyBucketsではなく ListMyBuckets を使用する場合があります。アクションによくある別のタイプミスは、arn:aws:s3: : :* など、ARN に不要なテキストが含まれているものや、AWSAuthRuntimeService.AuthenticatePassword など、アクションにコロンがないものです。ポリシーシュミレーターを使用して、タイプミスを含む可能性のあるポリシーを評価し、そのポリシーが意図したアクセス許可を付与するかどうかを確認できます。
```

## 今後の教訓
- **サービスとして利用できても**プレビューサービスやカスタムサービスはIAMに認識されないということになる(実際自分がそうだったので)
Numpy > 2行3列のデータを5行3列の途中の行に入れる実装

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
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)
```

以下とする。

- xs: 挿入する行列
- v1: 挿入される行列

### code v0.1

```test_array_assign_171125.py
import numpy as np
import sys

# preparation
x1 = [3, 1, 4]
x2 = [1, 5, 9]
xs = [x1]
xs += [x2]
xs = np.array(xs).astype(float)
print(xs)
v1 = np.zeros((5, 3))  # 5: arbitrary

# assign
kidx = 2  # given
v1[kidx:kidx+2] = xs[0:2].copy()
print(v1)
```

```txt:run
$ python3 test_array_assign_171125.py 
[[ 3.  1.  4.]
 [ 1.  5.  9.]]
[[ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 3.  1.  4.]
 [ 1.  5.  9.]
 [ 0.  0.  0.]]
```

念の為.copy()を使う。


```
v1[kidx:kidx+2] = xs[0:2].copy()
```

は行の数が整合していれば以下でもいい。

```
v1[kidx:kidx+2] = xs.copy()
```

### MATLAB

MATLABでの以下のような実装に対応する。

```matlab
v1(k:k+1,:) = trisectEdge(x(tri(j,1),:),x(tri(j,2),:));
```

trisectEdge()により2行の行列が得られる。
Rails5 の System Test のスクリーンショットの発動で eshell が壊れるのを回避する方法

eshell 内でテストを走らせているときにスクリーンショットが発動すると、あろうことかインライン表示しようとして無造作に垂れ流される base64 文字列によって eshell が使いものにならなくなります。
# 対策1. インライン表示しないようにする

`ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"]` を **simple** に設定します。

```rb:rails_helper.rb
ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"] ||= "simple"
```

これで静まります。

eshell の中だと `ENV["TERM"]` が `dumb` になっているので、このときだけ `simple` にするのもいいかもしれません。

ちなみに上の設定を見るたびに simple って結局どういう状態だっけと私は毎回わからなくなります。

# 対策2. screenshot_opener gem を使う

screenshot_opener を使うと**対策1**をしてくれた上にスクリーンショットを、open コマンドで開いてくれるようになります。linux の場合は xdg-open や gnome-open を使ってくれます。

RSpec 経由の System Test (System Spec) では次の設定を追加すると動きました。

```rb:rails_helper.rb&nbsp;の&nbsp;RSpec.configure&nbsp;ブロックの中へ
config.include ScreenshotOpener, type: :system
```

# 参照

[Rails]System Testsでスクリーンショットの表示をどうにかする
http://y-yagi.tumblr.com/post/166896745740

Rails 5.1のSystemTestCaseを試してみた
https://qiita.com/jnchito/items/4d01f2faa1deee36bd27

rspec-rails 3.7の新機能！System Specを使ってみた
https://qiita.com/jnchito/items/c7e6e7abf83598a6516d
いつも忘れちゃうWindowsでnocapsする設定方法

WindowsでCapsLockをCtrlキーに変更するレジストリエディタの設定方法メモ

```
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00
```

![スクリーンショット_2017-11-25_11-32-46.png](https://qiita-image-store.s3.amazonaws.com/0/106949/b7f8d81f-f035-70b3-6b4d-3e9d4827f225.png)
podfileのビルドで「(SWIFT_VERSION) build setting must be set」エラーが出るときの対処法

podfileを使ったプロジェクトのビルドで、以下のエラーが出ました。

The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. This setting can be set in the build settings editor.

podfileの先頭に以下を記述して対応しました。

```rb
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.0'
    end
  end
end
```
My Stats Note #1

# 回帰分析で考慮すべき事項

体系的な学習が進んでいないので、過不足や誤認等あるかもしれないが、回帰分析で考慮すべき問題に以下があるというのが現状認識。

- 多重共線性
- 交互作用
- オーバーフィッティング

# 正則化

多重共線性についてのアプローチが正則化であり、[Lasso回帰](https://qiita.com/peristrophe/items/e7d415d78147a88628bf)等が正則化を含んだ回帰分析というのが現在の自分の認識。

glmnetは以前の記事に書いたとおり、クロスバリデーションの過程で最適なペナルティ $\lambda$ を決定しているが、参考記事をよく読んでみるとテストデータの予測や係数出力の際にはこの $\lambda$ を指定してあげなければ見つけた最適値を反映しない。
そしてその最適値は以下プロットの中に表現されている。(例示はRidge回帰の結果プロット)

![ridge.png](https://qiita-image-store.s3.amazonaws.com/0/134107/e0ed663e-68a6-f43b-21ee-7947a3645040.png)

グラフで表現されている赤点はモデルのMSE(誤差の総量の統計的な要約値＝偏差平方和)であり、縦の点線が二本並んでいるうちの、左側が**誤差が最小になる点**、右側が**最小点から1SE(標準偏差の1倍？)分の誤差を許容した点**。
この $\lambda$ を反映させるには、予測や係数出力の際に `s="lambda.min"` などと引数を指定してやる必要がある。

```r:予測時
> prd <- predict(lasso.cv, newx = tx, type = "class", s="lambda.min")   # 最小値
> prd <- predict(lasso.cv, newx = tx, type = "class", s="lambda.1se")   # 最小値から1SE
```

```r:係数出力時
> coef(lasso.cv, s="lambda.min")   # 最小値
> coef(lasso.cv, s="lambda.1se")   # 最小値から1SE
```

誤差が少ないほうが単純に精度が良いということだが、1SEは何のためにプロットに表示されているかと考えると、おそらく最小値の $\lambda$ でオーバーフィッティングしてしまう場合の第二候補なのだと思われる。

また、Lasso回帰の場合は係数がゼロになる形で変数選択されるが、選択されて残っている変数の次元数がグラフ上部に横軸に沿って表示されている。
例示のような超多次元データセットを扱っている場合等は、これを指標にモデルの $\lambda$ を決定する場面もあるのかもしれない。

![lasso.png](https://qiita-image-store.s3.amazonaws.com/0/134107/9ca0e995-ddd0-c384-ce50-26b74e61bbc7.png)
AWSのEC2へのAnsibleの確認（ping)

#作業メモ
VPSからAWSへのEC2へのAnsibleの接続テストではまったのでメモ

## ベース

### コマンド
```bash
ansible all -i ansible_hosts --private-key=.ssh/XXXXXX.pem -m ping -u ec2-user
```

### 準備
```text:ansible_hosts
#EC2のIPアドレス
xxx.xxx.xxx.xxx
```
## 実行結果
```bash
ansible all -i ansible_hosts --private-key=.ssh/XXXXXX.pem -m ping -u ec2-user
xxx.xxx.xxx.xxx | SUCCESS => {
    "changed": false, 
    "failed": false, 
    "ping": "pong"
}
```

## オプション

|オプション|内容| 例|
|---------|-----------|----------------------------|
| -i      | hostsファイルの指定| -i ansible_hosts |
|--private-key|秘密鍵の指定|--private-key=.ssh/XXXXXX.pem|
|-m|ansibleのモジュール指定（今回は疎通確認のためping）|-m ping|
|-u|ユーザ指定|-u ec2-user|

#参考URL
[Ansibleのドキュメントを読んでみたメモ](https://qiita.com/okochang/items/f264825e538dbce5dfac "Ansibleのドキュメントを読んでみたメモ")
MATLAB > IDE > 「K>>」 > デバッグモードのようだ

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
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)
```

### MATLAB

Command windowに表示される以下の違い。


```matlab
K>>
```

```matlab
>>
```

気になっていたが、bisectTri実装が終わるまではほっておいた。

デバッグモード時に「K>>」になるとのこと。
https://jp.mathworks.com/matlabcentral/answers/283542-how-do-i-get-rid-of-the-k-prompt

「dbg>>」だと一目瞭然だと思う。

Pythonのpdbだと以下。

```bash
(Pdb)
```
vim 練習中

キー	動作
i	カーソルの位置で挿入モードになります。iは「insert」の略として覚えます
I	カーソル行の行頭（空白は除く）で挿入モードになります。
a	カーソルの後ろの位置で挿入モードになります。aは「add」の略として覚えます
A	カーソル行の行末で挿入モードになります。
o	カーソルの次行の位置に行を追加して挿入モードになります。
O	カーソルの前行の位置に行を追加して挿入モードになります。




macproではescが物理ボタンではない
物理ボタンで打ち込む場合はcontrol+[
Scalaの連立方程式演算における特定解の状態判定

# 背景
Scalaの入門がてら連立方程式を解いてみた。
が、特殊な解の判定方法で悩んだのでメモメモ

# 解き方
解き方については参考させていただいたサイトに詳しく書いているので、省略する。

ざっというと連立方程式とは行列の演算を利用して解ける。
また、Scalaの線形代数のライブラリにBreezeというものがあるので、
これで用いて演算してみる
Breezeを用いると、ベクトルをDenseVectorオブジェクトで表現できる

計算自体は（以下サイト参考にすれば）割と簡単にできるのだが、
与えられた式によっては解のない場合及び解が複数ある場合がある。

## 解のない場合。

```
x + y = 1
x + y = 2
```

当然、上記両方満たすx,yは存在しない
これを計算すると
x = -Infinity, y = Infinityとなる。

判定方法は
```if (x.isInfinite) ```

## 解が複数ある場合。

```
x + y = 1
2x + 2y = 2
```

上記両方満たすx,yは無数に存在する
（実は等価の方程式であるから）

これを計算すると
x = NaN, y = NaNとなる。

判定方法は
```if (x.equals(Double.NaN) && y.equals(Double.NaN) ) ```


### どうでもいいけど、解がない時はinfinityで、複数ある時はNaNになるって、イメージとは逆

#　参考サイト
参考にさせていただきました。ありがとうございます。
http://modegramming.blogspot.jp/2016/05/breeze.html
https://qiita.com/TakashiOshikawa/items/20ba0e50d59b1b5ef93c
MATLAB: vs = [v1 v2 v3 v4] ここでv1..v4は列ベクトル > Numpy実装

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
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)
```

### MATLAB

```matlab
K>> wv1 = [3; 1; 4]

wv1 =

     3
     1
     4

K>> wv2 = [1; 5; 9];
K>> wv3 = [2; 6; 5];
K>> wv4 = [3; 5; 8];
K>> wvs = [wv1 wv2 wv3 wv4]

wvs =

     3     1     2     3
     1     5     6     5
     4     9     5     8
```

### Numpy 実装

```test_array_add_171125.py
import numpy as np


def add_to_array_vertical(vlist):
    ret = np.transpose(vlist).reshape(len(vlist[0]), len(vlist))
    return ret

v1 = np.array([3, 1, 4])
v2 = np.array([1, 5, 9])
v3 = np.array([2, 6, 5])
v4 = np.array([3, 5, 8])

res = add_to_array_vertical([v1, v2, v3, v4])
print(res)

```

```txt:run
$ python3 test_array_add_171125.py 
[[3 1 2 3]
 [1 5 6 5]
 [4 9 5 8]]
```
Qiita beta版のフロントエンドパフォーマンス改善案

ふとログインすると beta 版UIってのが使えた。完全に dev.to 意識してて笑った。

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

実際には自分が残してきたロードマップや、Component が使われているのであろうのがわかって、そうそうこれがやりたかったんだよって感じで、とはいえまだ改善点がたくさんって、今の中の人達もわかってると思うけど、元中の人として dev.to ぐらいやるにはどうすればいいってのを残しておきます。

## わかる変更点

- CSSの脱bootstrap色が強くなった
- トップ画面が、ユーザーごとのカスタムフィードから beta版 の人気の投稿が主になった
    - 元々そういう目的で企画を起こした記憶がある…
    - フレンドフィードもうあんまり使われてないよね
    - クエリが重いフレンドフィードより、静的にキャッシュできるランキングがトップにあるのはチューニングしやすい

## 改善案

やや無理難題だったり、中の都合も察してるけど、できるだけ目視とDevToolの数値みてわかる結果で色々言う。

- Header の仮HTMLを SSR したい
    - 非ログイン時のSSR結果を埋めておいて、ログイン情報を取得したら引き継ぐ
    - 一番最初に目にするクリティカルパスのコンポーネントなのでここは頑張りたい
- 記事のサイドパーツをSSRするかスケルトンスクリーンを出しておく
    - TTI までが長いパーツが重いのが悪印象
    - トップ画面のフィードでは既にやってるよね
- Mixpanel もう落としていいのでは
    - 自分が辞める時期にはほぼ使ってなかったはず
    - Chrome M70 で動かなくなるよって警告出てる(これはmixpanelの責任)
- JSのScripting 重い
    - ![](https://i.gyazo.com/0a4ca2c6325871a323359a446a00c3f5.png)
    - https://webpack.js.org/plugins/commons-chunk-plugin/ で、一部の画面でしか使ってない JS を評価しない(遅延評価する)ようにする。たしかd3とかのグラフ描画系も入ってたはず
    - 将来的に ServiceWorker 入れても Scripting は解消しない。
    - preact(+preact-compat) 使えるなら試してみるといいかも
- トップページのトレンドは毎時更新なのでイニシャルビューではキャッシュしてSSRで埋め込んで返す
    - Script の DL => Scripting => ReactDOM.render => componentDidMount => ajax => setState という形になってTTIが長い
    - ReactOnRails を使ってるのがわかる(グローバル変数で露出してる)ので、初期Stateにできるはず。
- そろそろホーム画面と個別の記事同士ぐらいはホワイトリストで history.pushState か Turbolinks か PRPL の
 ServiceWorker の onfetch ページ遷移を行いたい
    - ここも主に Header をSSRしたかどうかが、TTIまでの体感時間に効いてくる
    - 難しいのはわかるけど作り直した今やらないと、今後もずっと無理だぞ！

## 他

- ちょっと前から編集画面でのスクロール同期動いてなくない？

## 参考

http://mizchi.hatenablog.com/entry/2017/11/24/141301
https://qiita.com/mizchi/items/8af2cbbf827dd0567796
PythonとRubyでの「初期化していないローカル変数」の取り扱いについて

# はじめに

Pythonで以下のようなプログラムを書いたら例外（UnboundLocalError）が発生しました。

```py
def foo(a):
    if a > 0:
        bar = 1
    print(bar)

foo(-1)
```

まあそうだよね、というところではあるのですが、一方Rubyでは例外にはなりません。

```rb
def foo(a)
  if a > 0
    bar = 1
  end
  p bar
end

foo(-1) # => nil
```

Python的にもローカル変数barの領域は確保してあるだろうしNoneでいいんじゃない？というところですがそうにはならないようです。

#実装を見てみる

CPython、CRubyそれぞれでローカル変数がどう初期化されているかを確認します。

##CPython

関数実行情報を入れるPyFrameObject、それを作成しているPyFrame_New関数（Objects/frameobject.c）のうちローカル変数初期化に関する部分だけ抜き出すと、

```c
        extras = code->co_nlocals + ncells + nfrees;
        f->f_valuestack = f->f_localsplus + extras;
        for (i=0; i<extras; i++)
            f->f_localsplus[i] = NULL;
```

詳しい説明は省きますがf_localsplusがローカル変数に使われている領域です。NULLで初期化されています。Noneじゃないんですね。（NULLとNoneは別物です。C実装的にはNoneはPy_Noneというれっきとしたオブジェクトです）

##CRuby

一方、CRubyです。vm_insnhelper.cのvm_push_frame関数でローカル変数を初期化しています。

```c
    /* initialize local variables */
    for (i=0; i < local_size; i++) {
        *sp++ = Qnil;
    }
```

nilを入れていますね。というわけで「変数に初めて代入される個所」を通らなくてもnilが入っているということになります。

# 言語のスタンスの違い

先にRubyを学んで後からPythonを学んだ人間なので、「辞書で指定されたキーがないと例外」「リスト範囲外に代入しようとすると例外」というPythonの挙動に対し「いやそこはNone返してよ」「よしなにリスト拡張してよ」と思ったものですがPythonに慣れてくると「これはおかしな状況だし例外ぽーん」というPythonのスタンスもさもありなんと思うようになってきました。
今回の「初期化していないローカル変数」についても処理系実装知ってる分（＆Rubyの動作を考えると）「こう書けるだろう」としてましたが確かに「おかしな」状況です。

では、Pythonの動作とRubyの動作どちらが望ましいかというとまあどちらもありであり、言語設計者の思想の違いかなと思いました。個人的にはグイドさんもまつもとさんも好きです。
なお、個人的にはNoneで初期化されててくれる方がうれしいです:-P

# 余談

そもそもなぜ件のif文を書いたかですが、例外処理にて、

```py
bar = None
try:
    bar = some_func()
except:
    pass
print(bar)
```

みたいなコードが書いてあったのを、先頭行の「bar = None」消しても大丈夫なんじゃないの？（Javaとかみたいに例外処理の外側で変数初期化するのなんかダサい）→大丈夫だったということでやってしまったということになります。ちなみにこれsome_funcで例外起きると最終行のbar参照は例によってのUnboundLocalErrorになるので良い子は真似しちゃダメです。
Numpy: v1 = [[3, 1, 4],[1, 5, 9]] から [[3, 1, 4],[1, 5, 9],[3, 1, 4],[1, 5, 9]]を作る > np.concatenate()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
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)
```

numpy.array()同士の結合を実装する。

```test_array_plus_171125.py
import numpy as np

v1 = [
    [3, 1, 4],
    [1, 5, 9],
    ]
v1 = np.array(v1)

# case 1
vs = v1 + v1
print(vs)

# case 2
vs = []
vs += [*v1]
vs += [*v1]
vs = np.array(vs)
print(vs)
```

```txt:run
$ python3 test_array_plus_171125.py 
[[ 6  2  8]
 [ 2 10 18]]
[[3 1 4]
 [1 5 9]
 [3 1 4]
 [1 5 9]]
```

case1では要素同士の足し算になる。
case2により希望の動作になった。

v1, v2, v3がある時の結合を想定している。

### 教えていただいた事項

@redshoga さんの[コメント](https://qiita.com/7of9/items/49c101989f7ac8d8f1ec/#comment-3da282737a04d6c23474)
にてnp.concatenate()を教えていただきました。

実装中のコードにて使わせていただいてます。

情報感謝です。
vagrantのssh一発で設定する

# vagrantの一発でsshの設定
ログインの名前は、オプションで自分でつけることができる
例えば[test-user]の場合

```a:terminal
$ vagrant ssh-config --host test-user >> ~/.ssh/config
```

はい、終わりー。

```
$ ssh test-user
```
これで少し快適！
確率収束について


### 確率変数

定義をまずは思い出すと、
確率空間$(\Omega,\mathscr{F},P)$と距離空間$(S,d)$に対して確率変数(=Borel可測関数)

$$X,X_n :\Omega \rightarrow S$$

を考えます。

### 確率収束

$\{X_n\}$が$X$に確率収束するとは、

$$\forall \delta>0,
\lim_{n \rightarrow \infty}P(\omega\in\Omega|d(X_n(\omega),X(\omega))\geq\delta)=0\\
\left(
\Leftrightarrow
\forall\delta>0,
\lim_{n\rightarrow\infty}P(\omega\in\Omega|d(X_n(\omega),X(\omega))<\delta)=1
\right)$$

のことでした。limも書き下すと

$$\hspace{-100pt}\forall\delta>0,
\forall\varepsilon>0,
\exists N \in \mathbb{N},\\
\forall n\geq N,\,
P(\omega\in\Omega|d(X_n(\omega),X(\omega))\geq\delta)<\varepsilon$$

となります。


確率収束は距離が$\delta$以上の領域が小さくなっていく(距離が$\delta$未満の領域が大きくなっていく)ということを言ってるので、大雑把に見て関数のグラフが近づいていってる感じです。一点一点での値の収束は大事ではないです。


一般に上のような写像について、
各点収束(すべての点で収束)
$\Rightarrow$概収束(殆ど至るところ(=零集合を除き)収束)
$\Rightarrow$確率収束(測度収束)
が成り立ち、逆は反例があります。

例えば、$n\in\mathbb{N},k\in\{1,...,n\}$に対して

$$X_{n,k}=\chi_{(\frac{k-1}{n},\frac{k}{n})}
:(0,1)\rightarrow\mathbb{R}$$

と定め、これらを群数列のように一列に並べた確率変数列を考える。ここで$(0,1)$にはLebesgue測度を入れる。また、$\chi_A$は以下で定義され、$A$の特性関数と呼ばれる。
$$\chi_A(\omega):=\begin{cases}
1 \hspace{20pt} (\omega\in A)\\
0 \hspace{20pt} (\omega\notin A)
\end{cases}$$

$\delta \in (0,1)$を任意にとると、

$$\begin{eqnarray}
P(\omega\in (0,1)|\,\, |X_{n,k}(\omega)-0|\geq\delta)
&=&P(\omega\in (0,1)|\,\,\chi_{(\frac{k-1}{n},\frac{k}{n})}(\omega) \geq\delta)\\
=P\left(\bigl(\frac{k-1}{n},\frac{k}{n}\bigr)\right)
&=&\frac{1}{n}
\rightarrow 0 \,\,\,(n\rightarrow\infty)
\end{eqnarray}$$

よりこれは$0$に確率収束する。
しかし、任意の$\omega\in (0,1)$に対して$\{X_{n,k}(\omega)\}$は$0$と$1$を振動して収束しないため、この確率変数列は概収束しない。

この${X_{n,k}}$のグラフを書いてみたら確率収束の雰囲気(各点では収束していないかもしれないがグラフは近づいていく)が掴めるかと。

## 例題

確率変数列を

$X_{n}(\omega) = \begin{cases}
    2^{n} \hspace{10pt} \bigl(0 < \omega < \frac{1}{n} \bigr) \, \, n=1, 2, \cdots \\
    0 \hspace{10pt} (\text{その他})
  \end{cases}$
  
とする. $X_n$は$0$に確率収束することを確かめよ.

---

問の方は定義にしたがって確かめればOK。
ここでは上の記号で
$\Omega=(0,1), P=(\text{Lebesgue測度}), S=\mathbb{R}, X=0$
という設定ですね。

### 答え

任意に$\delta>0$をとる。$2^n\geq\delta$なる$n\in\mathbb{N}$に対して、

$$\begin{eqnarray}
P( \omega\in (0,1)| \,\,|X_n(\omega)-0|\geq\delta )
&=&P(\omega\in (0,1)|X_n(\omega)\geq\delta)\\
=P((0,1/n))
&=&\frac{1}{n}
\end{eqnarray}$$

したがって

$$\lim_{n \rightarrow \infty}
P( \omega\in (0,1)| \hspace{5pt}|X_n(\omega)-0|\geq\delta )
=\lim_{n \rightarrow \infty}\frac{1}{n}
=0$$

であり、$\{X_n\}$は$0$に確率収束する。


**解**
$\{X_n\}$は$0$に各点収束しているから$0$に確率収束する。
コードブロックの中にコードブロックを書く。

# やりたいこと

Markdownのコードブロック中に、Markdownのコードブロックを書きたい。
若干何を言っているかわからないと思うが、つまり

~~~markdown:pythonのコードブロックの例
```python　
print("hello")
```　
~~~

こういうことがしたい。
何らかのエスケープをしないと、コードブロック内のコードブロックの終了のバッククオート3つが誤作動するというわけです。

# 方法

どうもバッククオート3つの後ろに、何か文字が入っていると、コードブロックの終了とはみなされないらしい。ただ、半角スペースでは駄目なようなので、全角スペースを入ると良さそう。

```markdown:上のはこんな感じで書いている。■は全角スペースだと思って下さい。
```markdown:pythonのコードブロックの例　
```python
print("hello")
```■
```　
```

また、コードブロックは`` `(バッククオート)``ではなくて`~（チルダ）`を3つでも良いらしい。
「コードブロックを含むようなMarkdown」のコードブロックを書きたい場合は、記事のコードブロックなのか、コードブロック内のコードブロックなのかを区別するために、`~`を使うと良さそう。

~~~markdown:正確にはこんな感じで書いている（"編集リクエスト"参照)
~~~markdown:pythonのコードブロックの例
```python
print("hello")
```■
~~~ 　
~~~

ただ、見栄えに関してだけなので、コピペして使ってもらうような状況を考慮すると、かえって混乱を招くかもしれない・・・。

~~そして、書いていて気がついたのだが、バッククオートを含む文字列を、インラインのコードブロックに入れる方法がわからん！~~

**11/25追記:**
コメントで教えてもらいました。
@scivolaさんありがとうございました。
LimitSize ライブラリを作ってみた

# 2021/09/25 Update
[Delphi 11 Alexandria から FireMonkey の TForm で Constraints が実装されました！](https://qiita.com/pik/items/2f34b85c59b3fa5c149d)
もう LimitSize ライブラリは必要ありません！

# LimitSize とは

FireMonkey の TForm は無限に小さく、または無限に大きくできます。
レイアウトの問題などもあり無限に小さくされても困る時も多いと思います。

一方、[VCL には Constraints というプロパティ](http://docwiki.embarcadero.com/Libraries/Tokyo/ja/Vcl.Controls.TControl.Constraints)があり、フォーム（コントロール）のサイズを制限できます。

この VCL Constraints とほぼ同じ仕組みを提供するのが LimitSize ライブラリです。

## LimitSize ライブラリの歴史
FireMonkey が発表された当初からこの動作に不満を持っていたため、個人的に作って使っていましたが、

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Delphi 10.2のFireMonkeyで最小のフォームサイズを設定しようとしたけどプロパティとかから出来るのかどうかわからなかったからVCLで頑張ることにする( ﾟ∀ﾟ)・∵. ｸﾞﾊｯ!!</p>&mdash; ありさん@Web関連かテスターで求職中 (@arigayas) <a href="https://twitter.com/arigayas/status/926383792905863168?ref_src=twsrc%5Etfw">2017年11月3日</a></blockquote>

というツイートを見たため、これは公開せねば、と公開しました。
とはいえ、実は以前に [第2回 RAD Studio勉強会@Nagoya (Delphi / C++Builder)](https://rad-studio-nagoya.connpass.com/event/52624/)で公開する予定のものでした。
ソースは送ったのですが公開されなかったため、今回が初公開になりました。

なお、名古屋勉強会のスライドはコレです。

[ソースコードの共通化](https://www.slideshare.net/pik256/ss-76631711)

Delphi でどのような時に依存性が出てきて、どのような依存性排除の仕組みがあるのか、を解説したスライドです。
この中でサンプルとして TLimitSize が出てきます。

## LimitSize を使ってみる

LimitSize をリポジトリからダウンロードしてください。

[LimitSize リポジトリ](https://bitbucket.org/JunHosokawa/limitsize)

ライセンスは MIT License です。

使い方は簡単で FormCreate イベントなどで

```delphi
procedure TForm1.FormCreate(Sender: TObject);
begin
  FLimitSize := TLimitSize.Create(Self);
  FLimitSize.SetLimit(
    180,  // Minimum Width
    160,  // Minimum Height
    1024, // Maximum Width
    768); // Maximum Height
end;
```

と、最小・最大の幅と高さを設定するだけです。
設定すると、下記のツイートの動画のように大きさが制限されます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Delphi 用の TLimitSize ライブラリはフォームの大きさを制限します（VCL の Constraints プロパティと同様の動作です） <br>TLimitSize library for Delphi limits the size of the form (it is similar to the Constraints property of VCL)<a href="https://t.co/bvfLFvZ7k0">https://t.co/bvfLFvZ7k0</a> <a href="https://t.co/cXnQse8IG0">pic.twitter.com/cXnQse8IG0</a></p>&mdash; HOSOKAWA Jun (@pik) <a href="https://twitter.com/pik/status/931358106595950594?ref_src=twsrc%5Etfw">2017年11月17日</a></blockquote>

## LimitSize の問題点

公開後、神楽坂@Souryu工房さんが使ってくださり、問題点を教えていただきました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">TLimitSize使ってみましたが、スタイルが適用されている状況だと正しく動作しない様です。</p>&mdash; 神楽坂@Souryu工房 (@j_kagurazaka) <a href="https://twitter.com/j_kagurazaka/status/927848225377107968?ref_src=twsrc%5Etfw">2017年11月7日</a></blockquote>

どうやら FireMonkey のプレミアムスタイルと TSizeGrip を同時に使うとサイズが限定できないようでした。
FireMonkey プレミアムスタイルは少々特殊な作りになっていて TSizeGrip を使うとフォームの大きさではなく、フォームの上に乗っているパネルの大きさが変わってしまうようです。
なおかつ、フォームの Transparency が True になっていてフォームが見えなくなっているためたちが悪く原因が判明するまでに時間がかかりました。
何度か対策を打ったのですが、やはり TSizeGrip のバグなため、TLimitSize 側では特に何もしないようにしました。
通常のフォームや通常のスタイル、またプレミアムスタイルでも TSizeGrip を使わなければ問題は起きないので良しとしました。

# まとめ
FireMonkey に実装されていない機能を自分で実装するのも楽しいものです。
また、各 OS への理解も深まるのでおすすめです。
PAServer をコマンドラインから使う

# PAServer をコマンドラインから使う

Facebook の Japan RAD Studio User Group に中川さんが

[mac用のPAServerマネージャで追加したサーバーの情報は保存できない？](https://www.facebook.com/groups/jrsug/permalink/389645241456065/)

と投稿しました。
僕自身は PAServer マネージャを使っていなかったので、調べてみると確かに情報はオンメモリで管理されていて再起動するとクリアされていました。


[Mac での PAServer マネージャの実行](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/Mac_%E3%81%A7%E3%81%AE_PAServer_%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%A3%E3%81%AE%E5%AE%9F%E8%A1%8C)

>メモ： PAServer マネージャを使って作成したサーバーは、マネージャを閉じた後には残りません。サーバーのインスタンスを存続させたい場合は、PAServer マネージャを動作させたままにしなければなりません。

これでは不便だろうということで、コマンドラインから起動することにしました。

## PAServer のコマンドライン引数

コマンドライン引数の使い方については下記に詳しくあります。

[プラットフォーム アシスタントのオプションの設定](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0_%E3%82%A2%E3%82%B7%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%88%E3%81%AE%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%A8%AD%E5%AE%9A)

ここでは、３つだけ簡単に紹介します。

| 引数       | 説明                                         |
|------------|----------------------------------------------|
| port       | ポート番号を指定します                       |
| scratchdir | スクラッチディレクトリを指定します           |
| password   | パスワードを指定します（空の場合は文字なし） |

これらを指定したコマンドを

```bash
#!/bin/sh
/Applications/PAServer-19.0.app/Contents/MacOS/paserver -port=5656 -scratchdir=/Users/jun/PAServer/scratch-dir -password=
```
と書くと、ポート番号は 5656 、スクラッチディレクトリは /Users/jun/PAServer/scratch-dir パスワードは無し、となります。
後は好みのコマンドラインをつけたこの文をファイルに保存するだけです。

## shell コマンドファイルの作成

上記の PAServer 起動コマンドを run_paserver.command として保存します。
ファイル名は何でも良いのですが、拡張子は command とします。
こうすると macOS ではシェルコマンドであることを認識してダブルクリックすると実行するようになります。
ただ、このままでは権限の関係で起動できないのでターミナルを開いて

```bash
chdmod +x run_paserver.command
```

として、実行権限を付加してやります。

あとは、好みのコマンドライン引数や複数のバージョンの PAServer 用のコマンドファイルを作るだけです。

# まとめ
macOS は BSD Unix がベースになっているので普通にコマンドが使えるのですが .command という拡張子にすることがポイントでした。
Python Webスクレイピング実装例

## 前書き

コードをできるだけ書かず、手間のかかるフレームワークやミドルウェアを使わず、手軽さ重視で定期実行に対応した(cronで雑にまわせる)スクレイピングを実装する。
自然言語処理・機械学習の検証のため必要に迫られて実装したもの。似たような要件の方に少しでも役立てば、というところ。

## 概要

題材は何でもいいのですが、日刊工業新聞Webサイトからトップニュースのタイトルと本文(有料記事等の読めない部分は諦める)を抜き出してsqliteに記録します。
cronで雑に定期実行することを想定して、過去に収集済みの記事は重複して収集しないようにします。
なお、認証要ページや、javascriptで動的生成されるタイプのページには対応しません。

## 環境

* Python3
	* BeautifulSoup

必須じゃないですが、Jupyter notebook環境だとDOMまわりのトライアンドエラーが捗ります。

## 実装

```py:1
import requests
import re
import sqlite3
import hashlib

from time import sleep
from datetime import datetime
from bs4 import BeautifulSoup

domain = "https://www.nikkan.co.jp"
startpath = "/"
basesoup = BeautifulSoup(requests.get(domain + startpath).text, "lxml")
```
とりえあずhtmlを取ってきてBeautifulSoupに突っ込みます。
しっかりつくるならrequests関連は例外処理を入れておいた方がいいです。タイムアウト等でこけるので。

```py:2
links = []
for a in basesoup.find_all("a", href=re.compile("^/articles/view/[0-9]+")):
    links.append(domain + a.get("href"))
links = list(set(links))
```
トップページ内のaタグを拾いにいきます。その際にhrefに正規表現で条件を掛け、記事URL以外のaタグを弾きます。

```py:3
texts = []
for link in links:
    sleep(2)
    res = requests.get(link)
    res.encoding = res.apparent_encoding
    soup = BeautifulSoup(res.text, "lxml")
    title = "".join([x.text.strip() for x in soup.find_all("div", class_="ttl")])
    main = "".join([x.text.strip() for x in soup.find("div", class_="txt").find_all("p")])
    text = (title + " " + main).replace("\u3000"," ")
    texts.append(text)
```
拾ったリンク先URL各々に対してDOM解析し、今度はタイトルと本文を拾いにいきます。
このサイトの場合は、class=ttlのdiv要素にタイトル、class=txtの最初のdiv配下のp要素に本文が入っているので、それで検索を掛けます。
記事によっては複数要素が返ってくるので、joinでまとめて結合します。

```py:4
dbname = "text.db"
dbcon = sqlite3.connect(dbname)
dbcur = dbcon.cursor()

for text in texts:
    insert = "INSERT INTO rawtext(id, source, time, rawtext) VALUES(?, ?, ?, ?)"
    id = hashlib.md5(text.encode("utf-8")).hexdigest()
    source = "nikkan"
    time = datetime.now().isoformat()    
    args = (id, source, time, text)    
    try:
        dbcur.execute(insert, args)
    except sqlite3.Error as e:
        print('sqlite3:', e.args[0])
    
dbcon.commit()
dbcon.close()
```
DBに突っ込みます。dbファイルとテーブル定義は事前に作っておいて下さい。
id列はUNIQUE制約を付けておきます。
こうすることで、タイトル＋本文のハッシュ値が一致する記事はUNIQUE制約で勝手にはじいてくれるので、雑に定期実行してもデータが重複しません。あまり美しくはない気がしますが。
他のサイトからのデータも放り込むかもしれないのでsource列にデータソース名を入れておきます。あと取得日時も何かと使いそうなのでtime列に保存しておきます。

---

以上です。上記のスクリプトを収集したいサイト向けに適当に改修してcronで回せば概ね上手く動くんじゃないでしょうか。
今日日ヘッドレスブラウザ必須やろ、という気がしていたのですが、当方要件は堅めのニュースサイトが主だった為か、意外と必要に迫られませんでした。
きっとDBも、Read性能や分散化等を考えると、他に取るべき選択肢があるのでしょうが、中小規模レベルではsqliteの簡単さがやはり魅力です。別途分かち書き要ですがftsで全文検索できたり何気に高機能ですしね。

なお、相手サーバに不可を掛けすぎて怒られても責任は負えませんので、紳士的なクローリングを心がけましょう。
ちょっとずつ読むドメイン駆動設計 第三部 より深い洞察へ向かうリファクタリング 第十章 しなやかな設計4 表明

# これまでの第十章
- [序章](https://qiita.com/YasuhiroKimesawa/items/c240451e6746497fd446)
- [意図の明白なインターフェース](https://qiita.com/YasuhiroKimesawa/items/988ed817de9aac785633)
- [副作用のない関数](https://qiita.com/YasuhiroKimesawa/items/a035d872d630eadeaffb#)

# 表明
## どうしても副作用のある操作

[副作用のない関数](https://qiita.com/YasuhiroKimesawa/items/a035d872d630eadeaffb#)を値オブジェクトに実装することで、いつの間にか状態が変わってしまうような実装を防ぐことができました。

ただ、どうしても副作用が出る箇所、状態が変わるものはどこかで使わざるを得ない箇所がでてきます。それが、Entityですね。

状態が変わらないシステムなんてそうそうないですから、仕方がないですよね。

## 表明
副作用がEntityで出てしまうのは仕方がない。なので、できるだけ影響を減らそうというのが表明を使う目的ですかね。

いわゆる、保証されるメソッドの結果を記述する「事後条件」と、事後条件が成り立つことを保証するために満たすべき条件を記述する「事前条件」を使うことで、副作用は出るが、予測可能なメソッドにしましょうということですね。

## あまり使わない？
ただ、表明が使える言語は少ないですよね。書籍でも表明を使った例すら上げられていない・・・。
javaには表明の機能がありますが、コンパイルオプションを指定しないと使えない・・・。

実際使ったことないなぁ。。。

## テストで表明する
代替案としてはテストを書くことが上げられていて、こちらは例も出ていますね。

メソッドが取りうる条件と、テストで実行した結果が合っているかをテストで書いておくことで、それがドキュメントとして利用できるということですね。

Entityのテストとして、事前条件と事後条件を表明するという意図があるということです。

## そもそも意図の明白なインターフェースとモデルを頑張る

> 人は、頭の中に述語を溜め込むだけではない。モデルの概念を推測したり、補ったりするので、アプリケーションの要求を満たすことだけでなく、人にとって意味のあるモデルを見つけ出すことが重要だ。(第三部 第十章より)

元も子もないですが、やはりこれが大前提。ここを頑張ることが重要ですね。
tomcat8.5でSTRICT_QUOTE_ESCAPINGの設定をCATALINA_OPTSに書いても反映されない

tomcat5.5くらいからjspのスクリプトレット内でクォートを使おうとするとエスケープしないといけなくなっていたが
これをいちいちエスケープするのは面倒なので、
org.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false
と設定すればそのまま使えていた。
参考：http://d.hatena.ne.jp/guangda/20091215/1260836855

自分がいた環境では2の「CATALINA_OPTS」に設定を追加していたが、tomcat8.5にした際に本設定を追加しても効かず500エラーが発生！
プロセスを見ても引数として設定もされているが効いていなかった。

調査中にふとweb.xmlの差分を見てみると
tomcat8まで

```
  <!--   strictQuoteEscaping When scriptlet expressions are used for        -->
  <!--                       attribute values, should the rules in JSP.1.6  -->
  <!--                       for the escaping of quote characters be        -->
  <!--                       strictly applied? [true]                       -->
  <!--                       The default can be changed with the            -->
  <!--                       org.apache.jasper.compiler.Parser.             -->
  <!--                       STRICT_QUOTE_ESCAPING system property.         -->
```

tomcat8.5から

```
  <!--   strictQuoteEscaping When scriptlet expressions are used for        -->
  <!--                       attribute values, should the rules in JSP.1.6  -->
  <!--                       for the escaping of quote characters be        -->
  <!--                       strictly applied? [true]                       -->
```

？！この部分の記載が消えている事が判明

```
  <!--                       The default can be changed with the            -->
  <!--                       org.apache.jasper.compiler.Parser.             -->
  <!--                       STRICT_QUOTE_ESCAPING system property.         -->
```
そこでweb.xml側のこのコメントの後に

```
<servlet>
  <servlet-name>jsp</servlet-name>
  <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
  ~略~
  <init-param>
    <param-name>strictQuoteEscaping</param-name>
    <param-value>false</param-value>
  </init-param>
  ~略~
</servlet>
```

を追加した所、500エラーが消えた( ﾟдﾟ)wow……

以上。まだ誰もこの地雷を踏んでいないみたいなので、一応。
Vagrant上のNode.jsをchromeの開発ツールを使ってデバッグする

##概要
Vagrant上のNode.jsをホストOS上のChromeの開発者ツールを使ってデバッグする。

##環境
* Mac OS X Sierra 10.12.6
* Vagrant 2.0.0
* OSイメージ　Amazon Linux

##手順

1.デバッグモードで起動（ゲストOS）
デバッガーがポート9229番(デフォルト)で起動します。

```
$ node --inspect app.js
Debugger listening on ws://127.0.0.1:9229/27c2d3d8-b74a-4aac-8bd7-73723c0d0343
For help see https://nodejs.org/en/docs/inspector
```
ホストマシンからVarantのポート番号9229へのアクセスを可能とすることで、
Chromeの開発ツールからデバッグできるように設定します。

2.ポートフォワーディング設定(ホストOS)
ホストOSのポート9229番と、ゲストOSのポート9229番を接続します。

```:Vagrantfile
config.vm.network :forwarded_port, guest: 9229, host: 9229
```

Vagrantをリロードします。

```
$ vagrant reload
```

3.ポートを開ける(ゲストOS)

```
$ sudo iptables -A INPUT -p tcp --dport 9229 -j ACCEPT
```

4.Google ChromeのdevToolsの設定（ホストOS）
Google Chromeのアドレスバーに `chrome://inspect` と入力します。
以下のような画面が表示されます。
<img width="541" alt="devTools.png" src="https://qiita-image-store.s3.amazonaws.com/0/206741/e1b618b3-662f-c4d9-da17-c38cf4f2c4a5.png">

`Configure...`から、ゲストOSに接続するIPアドレスとポート番号９２２９を設定します。
<img width="310" alt="configure.png" src="https://qiita-image-store.s3.amazonaws.com/0/206741/155f761b-6fab-5825-ccab-15dca2b2b726.png">

上記では、IPアドレス:192.168.33.100、ポート番号:9229を設定しています。
IPアドレスはVagrantfileを確認してください。

```:Vagrantfile
config.vm.network "private_network", ip: "192.168.33.100"
```

5.Debuggerを起動
IPアドレスとポート番号を指定して、デバッグを実行します。

```
$ node --inspect=192.168.33.100:9229 app.js
```

`chrome://inspect` を入力すると、以下のように表示されます。
<img width="320" alt="debug.png" src="https://qiita-image-store.s3.amazonaws.com/0/206741/9f5b4f3a-03f8-d492-de3a-66df7e796e5f.png">
inspect のリンクを開くとデバッグがDebuggerが起動します。
Excelのテーブルをオブジェクトの集合へ変換する関数

# 概要

Excelのテーブル（ListObject）の各行を見出しをKeyとするDictionaryに変換し、Collectionに格納して返す関数。

全行全列を取り込むため、データ数が多いと処理速度・メモリ使用量が悪化する可能性があります。

# コード本体

```vbnet
''' <summary>
''' srcTableの各行を見出しをKeyとするDictionaryへ変換し
''' Collectionへ格納します｡
''' </summary>
''' <param name="srcTable">変換するテーブル。</param>
''' <returns>Scripting.Dictionaryを要素とするVBA.Collection</returns>
Function TableToDictionaries(ByVal srcTable As Excel.ListObject) As VBA.Collection
    
'テーブルからデータをメモリ上にロード
    
    '[Range].Value() はセル数が1個の時配列を返さないことへの対策
    Dim headers() As Variant
    With srcTable.HeaderRowRange
        If .Count = 1 Then
            ReDim headers(1 To 1, 1 To 1)
            headers(1, 1) = .Value()
        Else
            headers = .Value()
        End If
    End With 'srcTable.HeaderRowRange
    
    Dim tableBody() As Variant
    With srcTable.DataBodyRange
        If .Count = 1 Then
            ReDim tableBody(1 To 1, 1 To 1)
            tableBody(1, 1) = .Value()
        Else
            tableBody = .Value()
        End If
    End With 'srcTable.DataBodyRange
    
    
    Dim retCol As VBA.Collection
    Set retCol = New VBA.Collection
    
'オブジェクト化
    Dim r As Long, c As Long
    For r = LBound(tableBody, 1) To UBound(tableBody, 1)
        Dim dataDic As Object 'As Scripting.Dictionary
        Set dataDic = VBA.CreateObject("Scripting.Dictionary")
        
        For c = LBound(headers, 2) To UBound(headers, 2)
            Let dataDic.Item(headers(1, c)) = tableBody(r, c)
        Next c
        
        retCol.Add dataDic
    Next r
    
    Set TableToDictionaries = retCol
    
End Function
```

## サンプル

```vbnet
Sub Sample()
    Dim ws As Excel.Worksheet
    Set ws = Excel.ActiveSheet
    
    Dim tblData As VBA.Collection
    Set tblData = TableToDictionaries(ws.ListObjects.Item(1))
    
'テーブルの中身をイミディエイトウィンドウに出力
    '見出し
    Debug.Print VBA.Join(tblData.Item(1).Keys(), vbTab)
    
    'データ部
    Dim dic As Object 'As Scripting.Dictionary
    For Each dic In tblData
        Debug.Print VBA.Join(dic.Items(), vbTab)
    Next dic
    
    Stop
    
End Sub
```
ReactNative入門① ~インストールから起動まで~


# はじめに
公式を見ながらReact Nativeを動かしてみました。
Getting Startedに始まって、チュートリアルを進めていきます。

## React Nativeとは
React Nativeを使うと、JavaScriptとReactでモバイルアプリを作成できます。
React Nativeで作ったアプリは、HTML5で作成したアプリみたいなものではなく、Objective-CやJavaで作ったアプリと同様のものになります。

# React Nativeを動かす
## React Nativeのインストール
まずは、nodeとwatchmanというツールをHomebrewを使ってインストールします。

```bash
brew install node
brew install watchman
```

続いて、`React Native CLI`をnpmを使ってインストールします。

```bash
# npmを使う場合
npm install -g react-native-cli

# yarnを使う場合
yarn global add react-native-cli
```


## アプリケーションを作成する
先程インストールしたreact-native-cliを使ってアプリケーションを作成します。

```bash
react-native init AwesomeProject
```

## アプリケーションをビルド
では、作成したアプリケーションを起動してみましょう。

```bash
cd AwesomeProject
react-native run-ios
```

ターミナルとこんな感じにシミュレータが起動すれば上手くできています。
導入からアプリケーションの立ち上げまでは結構簡単でしたね。
次からはコードも書いていく予定です。

![iPhone_6_-_iOS_11_0.png](https://qiita-image-store.s3.amazonaws.com/0/45577/ee47f54c-1301-639f-aa7b-5dd3395f6ffc.png "iPhone_6_-_iOS_11_0.png")
MacでKinect v2のデプスデータを記録・再生するアプリ

# 概要
Macだと、少しだけKinectをいじりたいときに使うアプリがなかなか見つからなかったので作ってみました。
とりあえず自分用に作ったものですが、自分以外でも使えるようになるべくシンプルなものを心がけました。
[![https://gyazo.com/0f4c83f5fb43bf2f37d34e85184a66f6](https://i.gyazo.com/0f4c83f5fb43bf2f37d34e85184a66f6.gif)](https://gyazo.com/0f4c83f5fb43bf2f37d34e85184a66f6)

## できることのまとめ
- リアルタイムでKinectのデプス映像を見る
- リアルタイムでKinectのポイントクラウドを見る
- Kinectのデプスデータをレコード
- レコードしたデータをプレーバック（デプス映像もポイントクラウドも）
- レコードしたデータ(tiff画像の連番)のply形式への変換

## アプリ(バイナリ)のリンク
https://drive.google.com/open?id=1NuxqFngnRi-YWNyH9TcqE4hcrWNZEuOr
使い方は、以下のgithubページのHow to useをご参照ください。
アプリはすでにダウンロードしてあるので、箇条書き部分だけ見れば大丈夫です。

## githubのリンク
コードを見たい人用。openFrameworksで書いてます。
- kinectDepthRecorder
https://github.com/RyoheiKomiyama/kinectDepthRecorder
- kinectDepthPlayer
https://github.com/RyoheiKomiyama/kinectDepthPlayer
[Unity] AnimationコンポーネントでAnimationを管理する


StateMachineを使ってAnimationを管理すると確かに便利ですが、Animatorコンポーネントは処理が重たいので、ボトルネックとなって全体の処理が重くなってしまうこともあります。

簡単なように思えて、結構詰まってしまった＆これといった記事がなかったのでメモを残しておきます。

# Animationコンポーネントを用意する
![スクリーンショット 2017-11-24 23.12.06.png](https://qiita-image-store.s3.amazonaws.com/0/147930/76c5324e-0755-ddfb-d0ae-93a817aa0fdb.png "スクリーンショット 2017-11-24 23.12.06.png")

Animationの欄にAnimationClipを入れて、Play Automaticallyにチェックを入れれば、そのAnimationが再生されます。

# スクリプトで動的にアニメーションを変更する

```AnimationTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationTest : MonoBehaviour 
{
	private Animation anim;

	public AnimationClip test_1;
	public AnimationClip test_2;

	// Use this for initialization
	void Start () 
	{
		anim = GetComponent<Animation> ();
	}
	
	// Update is called once per frame
	void Update () 
	{
		if(Input.GetKeyDown(KeyCode.A))
		{
			StartCoroutine ("ChangeTest_1");
		}
		if(Input.GetKeyDown(KeyCode.B))
		{
			StartCoroutine ("ChangeTest_1");
		}
	}
	
	/* ---------- Test_1 Coroutine ------------
	 * AnimationをTest_1に変更して再生するコルーチン
	 */
	IEnumerator ChangeTest_1 ()
	{
			animation.Stop ();

		yield return null;

			animation.clip = test_1;

		yield return null;

			animation.Play ("test_1");

		yield return null;
	}
	
	/* ---------- Test_2 Coroutine ------------
	 * AnimationをTest_2に変更して再生するコルーチン
	 */
	IEnumerator ChangeTest_2 ()
	{
			animation.Stop ();

		yield return null;

			animation.clip = test_2;

		yield return null;

			animation.Play ("test_2");

		yield return null;
	}
}

```

![スクリーンショット 2017-11-24 23.25.25.png](https://qiita-image-store.s3.amazonaws.com/0/147930/441b640b-939c-7d5d-1178-2510168ecadb.png "スクリーンショット 2017-11-24 23.25.25.png")

Animationsの配列に再生したいAnimationClipを全て指定しておく必要がある。

## 解説

AnimationClipを動的に差し替えるだけなら、自前の変数で指定するだけで変更できる。
しかし、再生をスクリプトで制御する場合は、Animation.Play()関数に引数としてAnimationClipを渡す必要がある。
その際の参照先がAnimationsの配列なので、再生したいAnimationClipを全て入れておく必要がある。
決済処理時に使える注文情報を保存するSquare Order APIを試す

Squareは決済サービスなので、極端に言えば決済額と決済情報（クレジットカード情報など）さえあれば十分です。しかし、決済は金額だけの話ではなく、商品や発送先、値引き、税金など様々な情報が追加されます。

それらをすべて自社データベースに保存して、決済額だけをSquareに送るのも良いですが、逆にSquareに情報を残す方法も用意されています。それが Order APIになります。

## Order APIの特徴

Order APIは以下の情報で構成されます。

- 商品情報
- 税情報
- 値引き情報

これらはあらかじめAPIを通じて作成しておくこともできますし、管理画面で作成もできます。さらに商品などは作らずにその場で情報を作成することもできます。

例えば以下はRubyで実行する例です。 商品情報（`line_items`）、税情報（`taxes`）、値引き情報（`discounts`）にそれぞれ対応しています。

catalog_object_id というのは Catalog API で取得できるオブジェクトIDで、商品やカテゴリ、税、ディスカウント情報などが同じオブジェクトという形で取得できます。

```
response = api.create_order(location.id, {
  idempotency_key: SecureRandom.uuid,
  reference_id: 'my-order-001',
  line_items: [
    {
      name: 'New York Strip Steak',
      quantity: '1',
      base_price_money: {amount: 1599, currency: 'JPY'}
    },
    {
      catalog_object_id: 'UUAOONEUM2ROCL2UEW3VLH2I',
      quantity: '2',
      discounts: [
        {
          name: 'Sale - $1.00 off',
          amount_money: {amount: 100, currency: 'JPY'}
        }
      ]
    }
  ],
  taxes: [
    {
      name: 'State Sales Tax',
      percentage: '9'
    }
  ],
  discounts: [
    {
      name: 'Labor Day Sale',
      percentage: '5'
    },
    {
      catalog_object_id: 'SG353KJSVUWL35WMO23IIU3U'
    }
  ]
})
```

オブジェクトIDは以下のように取得できます。

```
api = SquareConnect::CatalogApi.new
opts = {
  types: [
    SquareConnect::CatalogObjectType::CATEGORY,
    SquareConnect::CatalogObjectType::TAX,
    SquareConnect::CatalogObjectType::ITEM,
    SquareConnect::CatalogObjectType::ITEM_VARIATION,
    SquareConnect::CatalogObjectType::MODIFIER,
    SquareConnect::CatalogObjectType::DISCOUNT
  ].join(',')
}
response = api.list_catalog(opts)
```

Order APIの返り値には id が入っていますので、それを使って決済処理が行えます。

```
api.charge(location.id, {
  idempotency_key: idempotency_key,
  amount_money: {
    amount: total_money, currency: 'JPY'
  },
  card_nonce: card_nonce,
  order_id: order_id,
  reference_id: 'optional reference #112358',
  note: 'optional note'
})
```

このように order_id として指定することで、決まった商品情報を使って決済ができるようになります。決済処理と注文情報を結びつけて管理したいときであったり、決まった商品、税、値引き情報を使って決済処理を行いたいときに便利でしょう。

[Orders API Overview](https://docs.connect.squareup.com/articles/orders-api-overview)

[Square Connect API Documentation](https://docs.connect.squareup.com/api/connect/v2#navsection-orders)
laravelのコマンドを指定したユーザーで実行したかった時のシェルスクリプト

testuserで`panappe:test`を実行する例

```bash:test.sh
#!/bin/sh

# テストユーザーでテストを実行
su - testuser -c 'php /var/www/project/artisan panappe:test'
```
プログラム超初心者メモ　Switch文

https://unity3d.com/jp/learn/tutorials/topics/scripting/switch-statements

Switch文とif文の比較
Unity Mac VScode 利用でのテスト

以下テストコード丸ごと

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class _Switch : MonoBehaviour {
	public int State=0;
	public enum MyState{Wait,Run,Sleep};
	private MyState e_MyState;
	
	// Use this for initialization
	void Start () {
		//本来はUpdateに書いた方が良さそうな内容だが、プリントがやたら出るのでStartにてテスト
		//------------------------------
		//スイッチ文のサンプル
		//条件には、string型,float型などは使えない。
		//intとenumが使える。
		//int を直接数値で使う場合は状態のイメージがわかないので、
		//書いてみると、レベルやhpなど数値で分かるものを利用すべきだと思った。
		switch (State)
        {
        case 1:
            print (State);
			 //breakは無いと VSCode上でエラーが出る。役目はスイッチ文からの脱出
			 //原語や環境によっては、break必須ではなさそう。
            break;
			//breakの下に命令を書いても意味がないし、これもVSCode上でエラーが出る。
        case 2:
            print (State);
            break;
        case 3:
            print (State);
            break;
		//default は書かなくても動く　elseと同じ役割
        default:          
            print (State);
            break;
        }
		//------------------------------
        //上のスイッチ文と同じ結果になるif文
		if(State==0){print (State);}
		else if(State==1){print (State);}
		else if(State==3){print (State);}
		else{print (State);}
		//必ずしもif文が長くなる訳では無いことが・・・・分かるなぁ・・・
        //特に複雑な条件で分岐させるには　if文が強そう。
		//------------------------------
        //なるほど enum と相性が良さそう！
		//状態を分けるのはif文を利用して、その後の処理はSwitch文を利用するのが良さそう。
		switch (e_MyState)
        {
        case MyState.Wait:
            print (e_MyState);	
            break;
        case MyState.Run:
            print (e_MyState);
            break;
		case MyState.Sleep:
            print (e_MyState);
            break;
        default:          
            print (e_MyState);
            break;
        }
	}
}
```
PlayframeworkでETagを使う

## Webのキャッシュの仕組み
HTTPの世界ではヘッダを使ってキャッシュを表現する方法がいくつかあります。

よくあるキャッシュの1つの仕組みとして、有効期限を設定してその範囲まではCacheを使い、越えたら再びリソースを取りにいく、というものがあります。このタイプのキャシュはExpireヘッダ、またはCache-Controlヘッダで主に表現します。

別のやり方として、条件付きGETと呼ばれる方法があり、これは自分が持っているCacheの状態を含めたGETリクエストを飛ばし、変更が無ければリソースの中身を省略して `304 Not Modified` を返すものです。Cacheの状態を表現する方法には、リソースの更新日時を条件にしたIf-Modified-Sinceと、リソースのバージョンやHash値が一致するかどうかで判定するIf-None-Matchがあります。

このIf-None-MatchでCache状態の表現で使う値をETagと言い、これをPlayframeworkのControllerで扱う方法を紹介します。静的ファイルは自動でやってくれた筈なので対象にしません。

## ETagの仕組み
まずはETagにどのような値を使うか考えます。リソースが変更されたら値が変わるようなものを使わないといけません。
リソース全体のHashを取るというのはシンプルな方法ですが、リソース全体をRDBなりから一度取得しないといけなくて無駄なのであまり良い方法とは言えません。idを絡めた方法などが考えられるでしょう。

## Playframeworkで実装
ETagに使う値を決めたら、ETagとIf-None-Matchの値を比較し、一致しなければ新しいリソースを返すControllerを書きます。簡単に作れますがこんな感じになります。

```scala
def list = Action { implicit req =>
  val eTag = ...
  withETag(eTag) {
    createResource()
  }
}

def withETag(eTag: String)(content: => Result)(implicit req: Request[Any]): Result = {
  if (req.headers.get(IF_NONE_MATCH).contains(eTag)) {
    NotModified
  } else {
    content.withHeaders(ETAG -> s""""${eTag}"""")
  }
}
```
macOS command-line-toolのTCP/IP socketでポート番号が指定できない

#問題となった挙動

　基本的なミスで1日もロスしてしまいました。次のようなコード（抜粋）をxcode commando line toolで作成し、xcodeで実行してもポート番号が付与されないという現象です。

```
// serverTest
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
using namespace std;

main(){
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  unsigned short port = 8081 ;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = INADDR_ANY ;
  addr.sin_len = sizeof(addr);
    
  bind(sock,(struct sockaddr*)&addr, sizeof(addr)) ;
  ;
  （以下略）
}
```

実行してターミナルでポートを調べてみると
```
$ sudo lsof -i -P | grep LISTEN
severTest 6059           (中略）       TCP *:53479 (LISTEN)
```
となり、実行しなおすたびに、ポート番号が変わります。このポートに対してパケットを送れば反応するので、あたかもポート番号に0を付与したような振る舞いです。

このコードをターミナルでg++でコンパイルして実行すると、ポート番号は正しく8081となります。

#原因
using namespace stdをコメントアウトすると正常に動作しました。
どうやらこの状態ではstd::bindが実行されており、期待しているsocketのbindが呼ばれていなかったようです。
確かに上記のコードで、
```
  if(bind(sock,(struct sockaddr*)&addr, sizeof(addr)) < 0 ){
   ;
  };
```
などとすると、コンパイルエラー
```
Invalid operands to binary expression ('__bind<int &, sockaddr *, unsigned long>' and 'int')
```
が発生するのでsocketのbindとは異なる関数になっています。

#バージョン情報
macOS 10.13.1 (High Sierra)
Xcode Version 9.1

-------------------------------------------

Raspberry piを使ったリモートコントロールに興味がある方は簡単にロジックを組めるフリーウェアを作りましたのでご利用ください。[こちら](https://www.instructables.com/id/Raspberry-Piでホームオートメーション導入編/)で紹介しています。
Go context.Context interfaceに Cancelが含まれていない理由

## 参考
Context API explained
https://siadat.github.io/post/context


Cancellation, Context, and Plumbing by Sameer Ajmani
https://vimeo.com/115309491

## context packageのメンバー

```go
   var Canceled = errors.New("context canceld")
   var DeadlineExceeded error = deadlineExceededError()
   
   type CancelFunc func()
   
   func Background() Context
   func TODO() Context
   func WithCancel(parent Context) (Context, CancelFunc)
   func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
   func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
   func WithValue(parent Context, key val interface{}) Context

   type Context interface {
       // Done returns a channel that is closed when this Context is canceled
       // or times out.
       Done() <-chan struct{}
   
       // Err indicates why this context was canceled, after the Done channel
       // is closed.
       Err() error
   
       // Deadline returns the time when this Context will be canceled, if any.
       Deadline() (deadline time.Time, ok bool)
   
       // Value returns the value associated with key or nil if none.
       Value(key interface{}) interface{}
   }
```

## context packageの背景にある考え

### Cancelation should be advisory


　cancelを実行した側は、実行中の処理をstopしたりするべきでなく、もはやその仕事が必要ないという情報を通知するにとどめる。
　cancelを通知された側がshot down, clean up, return errors等、なにをするかを決定する。

[golang 3ways to iterate](https://qiita.com/YmgchiYt/items/fe5936ccbc440cbb6214) にあった、channelを利用したiterate処理でも、cancelを呼んだ後にも channelをdrainしなければいけなかったのも、cancelがなにかの処理を強制するのではなくあくまで、advisoryだからと考えると自然だなと思えました。

### Context are hierarchical

　cancelという指示は常にparent(caller) から child(callee)にむかって流れなくてはいけない。
もし、 ``context.Context`` に ``Cancel()`` が定義されていると、``ctx``を渡された側が``ctx.Cancel()`` を呼べてしまうので、 ``WithCancel()``等のmethodは明示的に``Context``とは別に ``CancelFunc`` を返している。
``ctx`` を他のgroutineに渡してもその ``ctx`` はそれを作成したCode以外からはcancelされず、 cancel可能な ``ctx``が必要な場合は明示的に ``WithCancel()`` 等で新しい ``ctx`` を作成しなければいけない。
　context packageを既に理解されている方には、なにを当たり前なと思われるかもしれないですが、自分としては今週一番のなるほどでした。

## ついでに

### ``Done()`` がchannelを返す理由

booleanではなくてchannelが返ってくる明確な理由はわかりませんが

> closing a channel works well as a broadcast signal

とあり、context packageのcommentにも

>  Done is provided for use in select statement

とあるので、selectの中で利用することを意図しているからというのが現状の理解です。
また、 nil channelやcloseされたchannelをcloseするとpanicが起きてしまいますが、``Done()`` が返すchannelは ``WithCancel()``等で返された ``CancelFunc``によってのみ一度だけcloseされるようになっているようです。