OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptのvarとlet

#JavaScriptでのvarとletの違いについて
最近JavaScriptの勉強を初めて衝撃的だったので備忘録として。

##varだと同じ変数名が使えてしまう
例えばvarだと以下のような事が許されてしまいます。

```JavaScript
var a = 'str';
console.log(a); // strと出力

var a = 1;
console.log(a); // 1と出力
```

Javaとか静的型付け言語をやっていた身としては恐ろしい・・・

##letだと変数名の重複は許されない
先ほどのコードを以下のようにletに直すと

```JavaScript
let a = 'str';
console.log(a); // strと出力

let a = 1;
console.log(a); // 1と出力
```
その変数名はもう使われているという旨のエラーが出てくれます。
Uncaught SyntaxError: Identifier 'a' has already been declared

#スコープの違い
上記の他にブロックスコープ/関数スコープの違いがあるようです。
以下の記事がわかりやすかったです。
[letとvarの違い](https://qiita.com/y-temp4/items/289686fbdde896d22b5e "letとvarの違い")

#基本的にはlet
変数名の重複やスコーピングを考えると基本的にはletを使った方が良いのかなと思います。
Pythonで競プロに挑む日誌 vol.17 ~テストケースが思いつかない（解決済み）~

# 現在の目標
* 2018年内に茶色になる**←イマココ**
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の A, B 問題を全部解く
* 2018年度内に緑色を取得する
* 水色になったら, [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す

# 今日のおはなし
### 結論
提出前のテストのやり方も学ぶ必要がありそう.

#### 解いた問題
[B - 3人でカードゲームイージー / Card Game for Three (ABC Edit) ](https://beta.atcoder.jp/contests/abc045/tasks/abc045_b)

#### 入力例 1,2 は通ったけど, 提出したら WA となった解答

```WA_answer.py
# coding: utf-8
A, B, C = [input() for _ in range(3)]
 
x = A[0]
while True:
    if x == "a":
        if A:
            x = A[0]
            A = A.lstrip(A[0])
        else:
            print("A")
            break
    elif x == "b":
        if B:
            x = B[0]
            B = B.lstrip(B[0])
        else:
            print("B")
            break
    else:
        if C:
            x = C[0]
            C = C.lstrip(C[0])
        else:
            print("C")
            break
```


#### AC だった解答

```AC_answer.py
# coding: utf-8
A, B, C = [input() for _ in range(3)]
 
x = A[0]
cnt_a = 0
cnt_b = 0
cnt_c = 0
for _ in range(len(A)+len(B)+len(C)):
    if x == "a":
        if cnt_a < len(A):
            x = A[cnt_a]
            cnt_a += 1
        else:
            print("A")
            break
    elif x == "b":
        if cnt_b < len(B):
            x = B[cnt_b]
            cnt_b += 1
        else:
            print("B")
            break
    else:
        if cnt_c < len(C):
            x = C[cnt_c]
            cnt_c += 1
        else:
            print("C")
            break
```
なぜ前者がダメで, 後者が通るのか理由がわからない.  有効なテストケースも思いつかず... うーむ, 何がいけないのだろう.

#### 追記
その後, Twitter で親切な方がアドバイスしてくれた.  lstrip を使うべきではなかった模様.  たとえば、「aabc」を入力した場合, lstrip("a") とするとその出力は「bc」になってしまう.


同じような罠にハマった人がほかにもいる模様([コチラなど](https://rcmdnk.com/blog/2016/05/09/computer-python/)).  削除対象の文字が連続する場合は一気に削除されてしまうので, 今後も使い方には注意が必要ですね.

初歩的な内容ですが, 勉強になりました.  感謝.
Dockerコンテナイメージをファイルに保存、読み込み( save, load )

## 1. はじめに

コンテナイメージはレジストリにpushしたものをpullして使う以外にも、ファイル( `*.tar` ) として保存( `docker save` )したり、ファイルから読み込ませる( `docker load` ) ことも可能です。

コンテナイメージをファイルとして保存することで、コンテナレジストリにアクセスできない環境などにコンテナイメージを持ち込んで活用することが可能となります。

## 2. コンテナイメージをファイルに保存する

`docker save`コマンドでtarファイルとして保存できます。

```
$ # ファイルに保存
$ sudo docker save image_name > image.tar
$ 
$ # 例として SSH で別マシンに送りつけるなど
$ scp ./image.tar 192.168.1.100:/hoge/image.tar
```

## 3. コンテナイメージをファイルから読み込む

`docker load`コマンドでtarファイルから読み込むことができます。

```
$ # ファイルから読み込む
$ sudo docker load < /hoge/image.tar
$ 
$ # 読み込んだイメージを確認するなど
$ sudo docker images
```
LXDでZFSストレージプールを使っていて、dataset is busyと言われたとき

# 発生した現象

LXDで使い終わったコンテナを終了、削除しようとしたら、こんなメッセージが。

~~~
$ lxd stop TEST
$ lxd delete TEST
Error: Failed to destroy ZFS filesystem: cannot destroy 'LXDPOOLS/containers/TEST': dataset is busy
~~~

LXDのコンテナは正常に終了しているのに、ZFSストレージプールから削除ができない。

# 環境

* Ubuntu Server 18.04
* LXD 3.6 (snap版)

# 対処法

`grep "/コンテナ名" /proc/*/mountinfo`として、そのZFSボリュームをマウントしているプロセスを見つける。

`/proc/10704/mountinfo`のうち、`10704`がそのプロセスのPID。

~~~
$ grep "/TEST" /proc/*/mountinfo
/proc/10704/mountinfo:1306 623 0:121 / /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST rw,relatime - zfs LXDPOOLS/containers/TEST rw,xattr,posixacl
/proc/1626/mountinfo:1306 623 0:121 / /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST rw,relatime - zfs LXDPOOLS/containers/TEST rw,xattr,posixacl
/proc/2420/mountinfo:1306 623 0:121 / /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST rw,relatime - zfs LXDPOOLS/containers/TEST rw,xattr,posixacl
/proc/2559/mountinfo:1306 623 0:121 / /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST rw,relatime - zfs LXDPOOLS/containers/TEST rw,xattr,posixacl
/proc/3116/mountinfo:1306 623 0:121 / /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST rw,relatime - zfs LXDPOOLS/containers/TEST rw,xattr,posixacl
/proc/5824/mountinfo:1306 623 0:121 / /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST rw,relatime - zfs LXDPOOLS/containers/TEST rw,xattr,posixacl
~~~

以下のコマンドでアンマウントする。

~~~
$ sudo nsenter -t 10704 -m -- umount /var/snap/lxd/common/lxd/storage-pools/ZFS/containers/TEST
~~~

もう1度`grep "/コンテナ名" /proc/*/mountinfo`を実行して、残るプロセスに対しても同様にアンマウントする。

全部なくなっていたら、コンテナが削除できる・・・はず。

~~~
$ lxc delete TEST
~~~

# 参考

* https://github.com/lxc/lxd/issues/4656
ディレクトリ中のファイルを任意の数値から始まる連番にリネームする方法


## 環境

* macOS 10.13 (High Sierra)
* zsh 5.3.1

## コマンド

11個あるファイルを，拡張子はそのままに129から始まる連番にリネームしています．

```sh:
$ ls
0e5f3ae0.jpg  63a62a6f.jpg  97077661.jpg  e416494c.jpg  f35dc873.jpg  f56c0eaf.jpg
4f50958b.jpg  81a05a5c.jpg  c4e3c9bd.jpg  e73c2b8f.jpg  f4fc4ef0.jpg

$ i=129; for f in *; do mv $f $i.${f##*.}; i=`expr $i + 1`; done

$ ls
129.jpg  130.jpg  131.jpg  132.jpg  133.jpg  134.jpg  135.jpg  136.jpg  137.jpg  138.jpg  139.jpg
```

0埋めする場合は次のような感じです（6桁に揃える場合）．

```sh:
$ ls
0e5f3ae0.jpg  63a62a6f.jpg  97077661.jpg  e416494c.jpg  f35dc873.jpg  f56c0eaf.jpg
4f50958b.jpg  81a05a5c.jpg  c4e3c9bd.jpg  e73c2b8f.jpg  f4fc4ef0.jpg

$ i=129; for f in *; do mv $f `printf "%06d" $i`.${f##*.}; i=`expr $i + 1`; done

$ ls
000129.jpg  000130.jpg  000131.jpg  000132.jpg  000133.jpg  000134.jpg  000135.jpg  000136.jpg  000137.jpg  000138.jpg  000139.jpg
```
8. M5stackでECHONET Liteデバイス（一般照明）を作る

M5stack（ArduinoIDE）用のECHONET Liteライブラリを作って見ました。
下記にサンプルとともにおいてあります。

https://github.com/Hiroshi-Sugimura/EL_dev_arduino

この記事はその細かい使い方事例を説明しています。

# 前記事

前に紹介した下記の記事はVer. 0.10のときの古いやつです。今回の記事はVer. 1.1.0です。

```
 7. ArduinoでECHONET Liteデバイスを作る
 https://qiita.com/Sugimura-Laboratory/items/6dfe1cb9f75a67a80b40
```

# どんなもの？

このライブラリで作成したプログラムはECHONET Liteプロトコルに対応したデバイスになることを想定しています。
サンプルは一般照明オブジェクトになっていて，M5stackについているLCDディスプレイをON，OFFできます。

![m5stack.jpeg](https://qiita-image-store.s3.amazonaws.com/0/120396/099be381-dce6-3515-e3f9-fa5a04879b21.jpeg)


ここでは簡単に使い方を紹介します。


# 環境・準備

必要に応じてWiFiルータやコントローラ用のPCなども必要です。

- M5Stack
- 開発用ArduinoIDEの動作するPC
 - M5stackを開発できるようにしてあること

- M5Stackの準備(ボードマネージャ，2018.11.08)
https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md

- M5Stackライブラリをインストールする
 - 「スケッチ > ライブラリをインクルード > ライブラリを管理」
 - m5stackで検索する。
 - m5stack by m5stack というのをインストールする。

- Macの場合はUSBドライバもインストールしておきましょう。（つないで認識しなければこれかな）
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

# サンプルの実行手順

簡単ステップで実行できます。

### 方法1 Githubから手動でインストールする

1. 上記のURL（Github）からソースをZIPでダウンロードします。

2. ZIPの中身をEL_dev_arduinoフォルダを下記に配置します。
 - (Win) $(USERHOME)\Documents\Arduino\libraries
 - (Mac) ~/Documents/Arduino/libraries
3. ArduinoIDEを起動して「ファイル > スケッチ例 > EL_dev_arduino > GeneralLighting」を選びます。
4. GeneralLighting.ino(5行目あたり）を編集してWiFiのSSIDとパスワードを自分のルーターに合わせます。

5. 実行します。

6. ArduinoIDEのシリアルモニタにIPアドレスなどのログが表示されればOK!

7. ECHONET Liteプロトコルは電源のON，OFFのみ対応しています。

### 方法2 Arduino IDEからインストールする（簡単！2018.11.08追記）

1. ライブラリマネージャを起動する
　「スケッチ > ライブラリをインクルード > ライブラリを管理」

2. ECHONETで検索する。
3. 該当ライブラリを選択してインストールしてください。
<img width="912" alt="2018-11-07 22.07.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/120396/ab9e4d7e-7fc2-9702-0091-f246be2ee799.png">

4. ArduinoIDEを起動して「ファイル > スケッチ例 > EL_dev_arduino > GeneralLighting」を選びます。

5. GeneralLighting.ino(5行目あたり）を編集してWiFiのSSIDとパスワードを自分のルーターに合わせます。

```C++:GeneralLighting.ino
#define WIFI_SSID "ssid"  // !!!! change
#define WIFI_PASS "wifipassword" // !!!! change
```

6 実行します。
7. ArduinoIDEのシリアルモニタにIPアドレスなどのログが表示されればOK!
8. ECHONET Liteプロトコルは電源のON，OFFのみ対応しています。


# 動作テストの方法

ECHONET Liteコントローラのアプリケーションで制御できます。iOSなら下記のEL Lightingがおすすめです。

- EL Lighting: https://itunes.apple.com/jp/app/el-lighting/id1296697112?mt=8

このアプリなら同一LAN上で，ONとOFFができます。

<img width="375" alt="ELLighting.png" src="https://qiita-image-store.s3.amazonaws.com/0/120396/1e501340-d1eb-8a0a-8508-e3170d8f0459.png">


他，各環境のおすすめを下記に記します。

- Windows なら下記URLにある「Super Speed Node Generator for ECHONET Lite Ver.3.0.1」が良いでしょう。
 - SSNG: https://smarthouse-center.org/sdk/download/

- iOS　なら下記URLのSSNG for iPhoneか，EL Lightingがよいでしょう。
 - SSNG for iPhone: https://itunes.apple.com/jp/app/ssng-for-iphone/id1076467789?mt=8



## ZIPの内容

下記の4モジュールでできています。

- examples/GeneralLighting/GeneralLighting.ino: サンプル
- EL.h, EL.cpp: ECHONET Lite プロトコルのクラス
- ELOBJ.h, ELOBJ.cpp: ECHONET Lite デバイス状態を保存しておいてあげるクラス

自分で新しいデバイスを作りたい場合はサンプルを書き換えていけば大丈夫です。

# 参考文献

- エコーネットコンソーシアム: https://echonet.jp
- ECHONET Lite入門 スマートハウスの通信技術を学ぼう！: http://amzn.asia/fIyglVQ
CircleCIでGitHubのプッシュをフック

![circleci.png](https://qiita-image-store.s3.amazonaws.com/0/258841/d5a25574-5929-c0e7-39d5-2421afc25e07.png)

# 背景

普段はCIなんて言葉目にしないけどなんとなく知っておこうと思いCircleCIなるサービスを
知り実施してみました。
普段はJenkinsでCIのような事はやってます。

# CircleCIって？

GitHub / BitBucketのPUSHに反応して、ビルドからテストを自動化してくれるCIサービス
jenkinsと比較して一番にあがるのは、Jenkinsは自前でJenkinsサーバを立てる必要があるのに対してCircleCIはクラウドのwebサービスって言う点です。

他にもいろいろメリット/デメリットはあるようです。

https://circleci.com/

# CI(継続的インテグレーション)とは

特に言及せずwikiを引用

```
CI（英: continuous integration）とは、主にプログラマーのアプリケーション作成時の品質改善や納期の短縮のための習慣のことである。
エクストリーム・プログラミング (XP) のプラクティスの一つで、狭義にはビルドやテスト、
インスペクションなどを継続的に実行していくことを意味する[1]。
特に、1990年代後半以降の開発においては、継続的インテグレーションをサポートするソフトウェアを使用する傾向が強まってきた。
```

# ネイティブDockerのサポート

1.0でもDockerサポートは存在しています。しかし、CircleCI自身がベースコンテナとしてLXCを利用していることの影響で、独自パッチを当てた古いバージョンに限定されています。

2.0では仮想マシンが起動して純粋なDockerを動かせるようになったため、最新の機能がフルに利用できるようになりました。CIのベースとしてこの仮想マシンを起動することも、Dockerイメージをベースにしつつ、途中でこの仮想マシンを起動することもできます。

# 必要なもの/前提知識

* GitHubのアカウント
* gitの知識(pushできればオッケー)

# 流れ

* ① githubアカウントを作る
* ② githubでCI対象のリポジトリを作成
* ③ CircleCI上でgithubアカウントと連携する
* ④ ローカルでリポジトリに設定ファイル（.circleci/config.yml）を作る
* ⑤ pushしたら自動でビルド/実行して結果が見れる

手順①②は割愛します。

# ③ CircleCI上でgithubアカウントと連携する

<img width="1186" alt="スクリーンショット 2018-11-06 20.17.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/258841/bdf1c3e2-97a0-0203-0cff-d94d76711690.png">

リポジトリを作成したらCircleCIのホームから「ADD Project」を選択し、
先程作成したリポジトリをSet UPします。

# ④ ローカルでリポジトリに設定ファイル（.circleci/config.yml）を作る

リポジトリのルートディレクトリ配下に下記ファイルを作成してください。
このファイルが設定ファイルとなりビルド命令等をもとに実行されます。

``` bash
# pwd
circleci_sample

# ls .circleci/config.yml 
.circleci/config.yml
```

とりあえず「Hello world」を出力する

``` yaml:config.yml
version: 2
jobs:
  build:
    docker:
      - image: alpine

    steps:
      - checkout
      - run:
          name: Install dependencies
          command: echo "hello world!"
```

# ⑤ pushしたら自動でビルド/実行して結果が見れる

あとはgithubへpushすれば自動的に上記の命令が実行されます。

``` bash
$ git add -A .
$ git commit -m "hello world!"
$ git push
```

push後は再度CircleCIのページへ戻りJobを確認。
エラー等がなければ実行完了です。

<img width="804" alt="スクリーンショット 2018-11-06 20.28.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/258841/28ef0017-6201-54b7-b24d-38ce9d27eee9.png">

実行結果を簡単に取得可能です。

<img width="1021" alt="スクリーンショット 2018-11-06 20.30.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/258841/6464b310-4023-631a-6af4-4d8c4150ca69.png">

# yamlのローカルテスト方法

上記yamlの確認はgithubへのpushが必須だと思っていましたがそんな事はなく
ローカルでのテスト実行も可能。素晴らしい。。。

以下のように「circleci」をインストール

``` bash
# インストール
$ curl -o /usr/local/bin/circleci https://circle-downloads.s3.amazonaws.com/releases/build_agent_wrapper/circleci && chmod +x /usr/local/bin/circleci

# アップデート
$ circleci update

# テスト
$ cd ${プロジェクトroot}
$ circleci build
~
  #!/bin/sh -eo pipefail
echo "hello world!"
hello world!
Success!
```

# 所感

Jenkinsのような面倒な手順なくCIが出来るのはすごいと思う
凝ったことをやらない限りは十分な機能だと思いました。
JavaScript でリトライ付きの Promise を作る

例: サーバが 502 を返したときに sleep(setTimeout) を入れつつ 10 回までリトライしたい。


## コピペ用

### 最後のエラーだけ返す版

reject 時に最後のエラーが返ってきます

```ts
function retry<T>(asyncFunc: ()=> Promise<T>, retry = 3): Promise<T> {
    const uniqueObj = {};
    const nums = Array.from(Array(retry));
    return nums.reduce((prm, _, i)=>
        prm.catch((err)=>
            err !== uniqueObj
                ? Promise.reject(err)
                : asyncFunc()
                    .catch((err)=>
                        sleep(i*1000)
                            .then(()=> Promise.reject(uniqueObj)) )
        )
    , Promise.reject(uniqueObj));
    function sleep(ms: number): Promise<void> {
        return new Promise((r)=> setTimeout(r, ms))
    }
}
```



### 全てのエラーを配列で返す版

reject 時に過去の失敗すべてのエラーが配列で返ってきます

```ts
function retry<T>(asyncFunc: ()=> Promise<T>, retry = 3): Promise<T> {
    const errs = [];
    const nums = Array.from(Array(retry));
    return nums.reduce((prm, _, i)=>
        prm.catch((err)=>
            err !== errs
                ? Promise.reject(err)
                : asyncFunc()
                    .catch((err)=>{
                        errs.push(err);
                        return sleep(i*1000)
                            .then(()=> Promise.reject(errs))
                    })
        )
    , Promise.reject(errs));
    function sleep(ms: number): Promise<void> {
        return new Promise((r)=> setTimeout(r, ms))
    }
}
```




## usage

リトライしたい非同期関数をクロージャで囲むだけで使える

```ts
const body = await retry(()=> fetch("https://example.com").then((res)=> res.text()));
```

あるいは async 関数を渡す

```ts
const body = await retry(async ()=>{
   const res = await fetch("https://example.com")
   const body = await res.text();
   return body;
});
```
コンテナやPodをポイ捨てするワンライナー ( Docker, Kubernetes )

使いどころ：ワンポイントリリーフでコンテナやPodに仕事を任せたい時(そして不要になったら速やかに抹殺したい時)

#### Dockerコンテナをポイ捨てする

```
docker run -it --rm --name poisute alpine sh -c "while true; do date; sleep 3; done"
```

--rmオプションによりCtrl + c でコンテナ終了とともにコンテナは削除されるので不要になったらポイ捨てできる

#### kubernetesのPodをポイ捨てする

```
kubectl run -it --rm --restart=Never poisute --image=alpine -- sh -c "while true; do date; sleep 3; done"
```
--rmオプションによりCtrl + c でPod終了とともにPodは削除されるので不要になったら使い捨てにできる

今回は動作確認用に、shには以下のように3sec毎にdateするコマンドを渡している。
テスト対象Webアプリにwgetするコマンドなどに置き換えるなどすると役立つことがあるかもしれない。
`while true; do date; sleep 3; done`
gnomADが新しくなった

##新しいgnomADができていた
gnomADのあたらしいサイトr2.1ができていた。
変異データの扱いにはHail0.2がおすすめ、と公式に書いてあったので、インストールを試みた。

##Hailのインストール
マシン : Mac Pro (Mid 2012)
OS : MacOS Sierra

Hailの[公式](https://hail.is/docs/devel/getting_started.html)では、`pip`でインストールしてね、とあったのだけど、
Jupyter notebookで`import hail`してもエラーになってしまう。

コンパイル済みのパッケージも上記ページで配布していたので、
それを使ってインストールを試みることにした。
`pip`を使わないときは**Spark2.2.x**が必要ということで、
それも[公式](https://www.apache.org/dyn/closer.cgi)からspark-2.2.2-bin-hadoop2.7.tgzをダウンロードしておく。

あとは上記ページのインストールマニュアルに沿ってインストール。
まずSparkの解凍から。

```
tar xvf <path to spark.tgz>
```

SparkのフォルダパスをSPARK_HOMEという変数に入れておく。

```
export SPARK_HOME=<path to spark>
```
これで準備はOK。SPARK_HOMEがないとインストールがうまくいかないので、
公式に書いてある順番は守らなくちゃいけない（当たり前だけど）。

Hailのパッケージを解凍して、Hailのフォルダにある/binをPATHに追加しておく。

```
unzip <path to hail.zip>
export HAIL_HOME=<path to hail>
export PATH=$PATH:$HAIL_HOME/bin/
```

Pythonの依存モジュールをAnacondaのenvironmentを作ってそこにいれておく。
environment.ymlに必要なモジュールが書かれているようなので、
以下のとおりにターミナルに入力する。

```
conda env create -n hail -f $HAIL_HOME/python/hail/environment.yml
```

environmentを有効化する。公式には`source activate`とあるけど`conda activate`でもOK。

```
conda activate hail
```

Jupyter notebook形式で書かれたチュートリアルのフォルダに移動してjhailコマンドでHailを立ち上げる。

```
cd $HAIL_HOME/tutorials
jhail
```

通常のJupyter notebookからはHailのインポートのところでコケてしまうので注意。
かならず`conda activate hail`　→　`jhail`で起動。

environmentを終了するには`conda deactivate`と入力する。

Hailを使って変異データを扱うことについてはまた後日。
Dockerfileとは


## Dockerfile
DockerfileはDockerコンテナのビルド時や起動時の作業を一つの設定ファイルにまとめたものです。
Dockerfileを使うことで、手順の簡略化による工数削減と作業手順の誤りを防止できます。

### Dockerfileの基本命令
- **FROM**：元となるイメージ
 - コロンの後にタグを指定
 - タグなしの場合、latest(最新)が選択される

```dockerfile
FROM イメージ[:タグ]
# example
FROM python:3.7-alpine
```

---

- **RUN**：ビルド時に実行するコマンド

```dockerfile
RUN <コマンド>
# example
RUN apt-get update
RUN apt-get install iputils-ping net-tools
```

- **CMD**：起動時に実行するコマンド
 - 1つのDockerfileで1度だけ指定できる

```dockerfile
CMD <コマンド>
# example
CMD python -m http.server 80
```

---

- **ENV**：環境変数の定義

```dockerfile
ENV <環境変数名>=<値>
# example
ENV TZ=Asia/Tokyo
# イコールの代わりに半角スペースでもOK
ENV DB_ENDPOINT 172.16.0.2
```

- **COPY**：ホストやURLからコンテナへファイルをコピー
 - コピー元がディレクトリの場合、ディレクトリ内すべてコピーされる
 - コピー先ディレクトリが存在しない場合は作成される
 - コピー元にはワイルドカードも使える

```dockerfile
COPY <コピー元ファイル名(orディレクトリ名)> <コピー先ディレクトリ名>
# example
COPY ../web/src/index.html /var/www/
COPY ../web/script/ /var/www/script/
COPY *.txt /var/www/docs/
```

---

- **WORKDIR**: 命令を実行するディレクトリを指定
 - ディレクトリを指定したいRUN、CMD、COPY等の命令の直前に記述する  
 - 1つのDockerfileに複数回書くこともできる

```dockerfile
WORKDIR <コンテナ内ディレクトリ名>
# example
WORKDIR /var
RUN mkdir www
WORKDIR /var/www
CMD python -m http.server 80
```

- **USER**: 命令を実行するユーザを指定

```dockerfile
USER <ユーザ名 or UID>
# example
USER john
```

---

その他の命令(公式リファレンス): http://docs.docker.jp/engine/reference/builder.html
## Return
Dockerコンテナ構築手順① Dockerfile編:
https://qiita.com/aminosan000/private/ef8778cbd880aa6e655c
Jupyter Notebook の Dockerコンテナを立ち上げる

[Jupyter Notebook](http://jupyter.org/index.html)はブラウザ上でコーディングや実行ができ、
グラフなどの成果物を手軽に共有できるオープンソースのWebアプリケーションです。
[GitHub( jupyter/notebook )](https://github.com/jupyter/notebook)

## コンテナを起動する
Dockerイメージは[Docker Hub( jupyter )](https://hub.docker.com/u/jupyter/)に公開されています。

起動コマンド
`jupyter/datascience-notebook`を使用しています。

``` shell
$ sudo docker run -d --name jupyter-notebook \
--user=root  \
-e NB_UID=$(id -u) \
-e NB_GID=$(id -g) \
-e GRANT_SUDO=yes \
-p 8888:8888 \
-v /home/hoge/fuga:/home/jovyan/share \
jupyter/datascience-notebook
```

| パラメータ | 設定値 |
| --- | ---
| p | ホスト側(左側の`8888`)をホストマシンの空きポート番号とする |
| v | ホスト側(`/home/hoge/fuga`)の`hoge`をあなたのユーザ名、`fuga`を配下のお好きなディレクトリとする。<br>成果物を出力するコンテナ内のディレクトリ(`home/jovyan/share`)としてマウントされます。

成果物がコンテナ内に生成されると何かと不便ですので、volume設定しています。
さらに、マウントされたdockerホスト側ディレクトリのファイルをコンテナ内で読み書きできるよう、コンテナ内はrootユーザで動作するようにしています。
これをしないとコンテナ内からvolume領域にファイルを生成できません。

## token取得

取得コマンド

```
docker exec -it jupyter-notebook jupyter notebook list
```
実行すると以下のようなtoken付きのURLが表示されます。
このURLにアクセスするとWeb画面を使用できます。
`http://localhost:8888/?token=123456789012345678901234567890`

コンテナ外からアクセスする場合は以下のようなURLになります。
`http://{コンテナのIPアドレス}:{コンテナ内のport}/?token={トークン}`
コンテナ内のportは固定値で8888です。
コンテナのIPアドレスは以下コマンドで調べられます。

```
docker inspect jupyter-notebook | grep IPAddress
```

もしくは以下でもアクセスできます。
`http://{ホストマシンのIPアドレス}:{ホスト側のport}/?token={トークン}`


Web画面上で`/share`配下に新規ファイルを作成してみて、ホストマシンのディレクトリ(`/home/hoge/fuga`)に生成されていれば成功です。

ボリューム設定により、コンテナ内だけでなく、
ホストマシン側ディレクトリでファイルの入出力ができますので、
入力データを格納したり成果物を共有するのに便利です。
VSCodeへLive Sync for AWS Cloud9を導入した時にハマったこと

## 何の記事？
[こちらの記事](https://qiita.com/funabashi800/items/de7d33989d0d2030148c)で紹介されている[Live Sync for AWS Cloud9](https://marketplace.visualstudio.com/items?itemName=iann0036.live-share-for-aws-cloud9)というプラグインのインストールを実際にやってみたのですが、
自分で実践したところ、いくつか詰まったので自戒のためにメモ

## VScodeでIAMユーザーの認証後、Environmentsにワークスペースが表示されない
リフレッシュしても `Unable to connect to list environments` と表示され、何も表示されない

### 原因： 入力したAWSのアクセスキーに,(カンマ)が混ざっていた。 
`CloudSync: setup` でAccess key ID、Secret access key、region を入力時に
特に間違っていたとしても何かエラーメッセージが出るわけではないので、気づきませんでした。。。
アクセスキーはAWSからcsvでダウンロードしたものをコピペしたのですが、その時に混ざったみたいですね。

これのおかげで３０分位時間を無駄にしました。
【Swift4】UITextFieldで文字数制限を実装する

# 要件
指定文字数以上はテキストフィールドに入力させない実装がしたい。

# 実装

```swift:
var maxLength: Int = 4
// 適当な所でこのターゲットアクションを設定してください。
@objc func textFieldEditingChanged(textField: UITextField) {
    guard let text = textField.text else { return }
    textField.text = String(text.prefix(maxLength))
}
```

UITextFiledDelegateを使わないのは、[こちらの記事](http://blog.niw.at/post/92806309874)でヤバそうだと思ったからです。

# 説明
指定文字数以上はテキストフィールドに入力させない。という要件を、
**「指定文字数以上は切り取る。」**という実装で解決します。

[String](https://developer.apple.com/documentation/swift/string)の`prefix(_:)`メソッドは先頭から指定した文字数までを切り取って返してくれるメソッドなので、こいつを使います。

しかし `prefix(_:) ` メソッドの返り値は`String` ではなく [SubString](https://developer.apple.com/documentation/swift/substring)なので、直接`textFiled.text` への代入はできません。

ドキュメントを読むと、
> Stringのイニシャライザに渡してあげれば、SubStringからStringに変換できるよ。

と書いてあるので、その通りにします。
イニシャライザは [init(_ substring: Substring)
](https://developer.apple.com/documentation/swift/string/2892895-init)ですね。

共有状態からスタンドアロンのStringを生成するために初期化を呼んであげるようです。

# TIPS
## SubStringは高速らしい
今回初めて知ったのですが、 `SubString` は元になった `String`と保存領域を共有しているらしく高速らしいです。へぇー。

## 計算量はO(n)らしい
ドキュメントの `Discussion` の欄に
> Complexity: O(n), where n is the length of substring

と書いてありました。どんな処理をしてるのかは分からないですが、文字数が多ければ多いほど処理が重たくなるって感じですね。
Windows 使いの十徳ナイフ Windows Sysinternals

この記事は [eeic Advent Calendar 2018](https://qiita.com/advent-calendar/2018/eeic) 14日目の記事です。

# はじめに

Windows, 好きですか?
大体こういう質問をすると、まあ荒れるわけですが、実際 Windows が好きでないという方はかなりの数いると思います。

嫌いな人が多い理由の一つとして、管理者・開発者向けのツール・コマンド群が貧弱である(と一般的には思われている)ということが挙げられるのではないでしょうか。

そこで、この記事では管理者や開発者として Windows を使うときにぜひ覚えておいてほしい便利な十徳ナイフ Windows Sysinternals について紹介していきたいと思います。

# Windows Sysinternals

Windows Sysinternals の[公式ページ](https://technet.microsoft.com/ja-jp/sysinternals/) には、次のように紹介されています。

> Windows Sysinternals は、IT 担当者や開発者が、Windows システムやアプリケーションを管理、トラブルシューティング、および診断する際に役立つ無償の Windows トラブルシューティング ツールの総称です。

簡単に言えば、Windows には標準で組み込まれていないけれども、痒い所に手が届く開発者向けの GUI / CLI ツール群の総称、といったところでしょうか。

もともとは個人の開発者の方が製作したツール群でしたが、現在は Microsoft が買い取って(?)提供されているようです。

この記事では、Windows Sysinternals で提供されている膨大な数のツールの中から、特によく使われそうな数個のツールに限ってご紹介します。

## Process Explorer

Windows Sysinternals を知らない方でも聞いたことがあるかもしれない、言わずと知れた高機能タスクマネージャーが [Process Explorer](https://docs.microsoft.com/ja-jp/sysinternals/downloads/process-explorer) です。

Windows 10 でタスクマネージャーは大幅に改善されましたが、それの斜め上をいく機能を備えています。
具体的には、

- ツリー表示
- デジタル署名の正当性確認
- VirusTotal へのハッシュ送信とチェック
- プロセスへのデバッガのアタッチ
- 各プロセスの
  - 呼び出された際のコマンドライン引数
  - 各種使用率
  - 環境変数
  - スレッド一覧と詳細
  - ネットワーク通信の詳細
- などなど...

という感じで、タスクマネージャーに期待するであろう機能が全部盛りになっています。
標準のタスクマネージャーでフラストレーションが溜まったという方も、そうでない方も一見の価値ありです。

![pe.jpg](https://qiita-image-store.s3.amazonaws.com/0/278460/4fc92441-79e7-5f5b-1e4e-186818082865.jpeg)

## Autoruns

知らず知らずのうちに登録されていた、ということも多い Windows の自動起動を一元管理できるのが [Autoruns](https://technet.microsoft.com/ja-jp/sysinternals/bb963902) です。

タスクマネージャーや `msconfig` から設定できる自動起動に加えて、以下の自動起動項目を一か所で制御できます。

- エクスプローラーのコンテクストメニュー
- IEのアドオン
- スケジュールされたタスク
- システムサービス
- デバイスドライバー
- 印刷モニター
- などなど...

また、登録されている各エントリに関して

- デジタル署名の正当性確認
- VirusTotal へのハッシュ送信とチェック

といった操作を行えるので、そのエントリが信頼できるか手軽に確認することができます。

![ar.jpg](https://qiita-image-store.s3.amazonaws.com/0/278460/9d31763d-cb26-b949-5331-1321ab913788.jpeg)

## Process Monitor

プロセスが呼んだシステムコールや、操作したファイル・レジストリをトレースできる GUI アプリケーションが [Process Monitor](https://technet.microsoft.com/ja-jp/sysinternals/bb896645) です。

何に使うのかは人次第だと思いますが、ぼーっと眺めるのも面白いですよ()

![pm.jpg](https://qiita-image-store.s3.amazonaws.com/0/278460/0054209b-b673-316a-d335-da4267c23af0.jpeg)

# 終わりに

もう少し計画的に書き進めようと思っていたのですが、結局直前になってしまいました...
当初の予定よりだいぶエントリが短くなってしまいましたが、余裕があれば書き足そうと思います。

Qiita に投稿するのはこれで2回目なので、優しい心で読んでもらえるとうれしいです。
mini_racerと、シンプルさのメリット

Railsのプロジェクトを書いていたところ、ある1つのGemの存在を知りましたが、そこから派生していろいろなことに考えが思い至っていきました。

## `therubyracer`とは

Railsでは、JavaScriptやCSSといったアセットの生成用としてSprocketsという仕組みが組まれていますが、CoffeeScript、Uglifier、autoprefixerなど、アセットのコンパイルにはJavaScriptで書かれたコードを多用するものなので、`execjs`という仕組みが入っています（[過去に自分が書いたもの](https://qiita.com/jkr_2255/items/b9a5f712cabe7a7deb33)）。

そして、JavaScriptを動かすランタイムが必要なのですが、Unix系では多くの場合、V8エンジンを組み込んだ`therubyracer`がよく使われて…いました。

### 問題点

`therubyracer`はV8を細かく制御できる…のはいいのですが、細かなところまで使っているのが仇となって、

* テストも回しづらい
* V8のアップデートに追随するのが困難

というような状況になり、ついにはセキュリティ問題も含んだ古いV8でしか動かない状態が固定化してしまいました。

## 新顔の`mini_racer`

ここで登場したのが[discourse/mini_racer](https://github.com/discourse/mini_racer)です。自称「最低限のブリッジ」を謳ってはいますが、ふつうにJavaScriptのコードを呼んで実行する以上のこともできますし、よほど極限的な用途でもない限り事足ります。

ブリッジ部分をシンプルにしたことで、V8のバージョン依存性も緩やかになり、バージョンアップに追随しやすくなっています。そして、`libv8`自体もバージョンが上がったことで、インストール性が改善されているようです。

## シンプルさの価値

Unix哲学にも、「一つのことを行い、またそれをうまくやるプログラムを書け。」という言葉があります。「RubyからJavaScriptを実行するランタイム」の場合、大半のユーザーが求めるものは「`execjs`で実行できること」でしょうから、あまり複雑なバインディングを取らずに簡潔化する、`mini_racer`の戦略も間違いなく合理的なものです。

### もっとシンプルにしようとすると、別な問題が

とはいえ、`libv8`もまだまだ巨大なプロダクトで、Rubyに組み込むのがうまくいかないこともあります。これをシンプル化する方策もいくつか考えられます。

* [Duktape](https://github.com/svaarala/duktape)のような、もっと軽量で組み込みに向いたJavaScriptエンジンを使う
* 別にインストールしたNode.jsを呼び出す形にして、組み込みの煩雑さを回避する

これらの方策でシンプルさは増しますが、引き換えに速度面ではハンデを負うことになります。これは多くの場合に問題となることですが、速度と性能のバランスも時を減れば移り変わっていくので、最適な形を選ぶのが難しいものです。

ただ、`execjs`のようなレイヤーが入っていれば、使うランタイムも適宜切り替えられますので、このような抽象化レイヤーを入れて部品を入れ替え可能にしておく、というのもあとあと役に立ちうる設計です。

### 別解

もはやSprocketsには見切りをつけて、アセット類はすべてWebpackに任せる、というような分業も1つの方法かもしれません。ただ、CommonJSやES Modulesで標準化されているJavaScriptはいいとして、CSSをWebpackに載せてしまうと、Webpackが廃れたときに行き詰まる危険性が考えられます。

## 外部リンク

* [Railsの難所についてと、therubyracerはすでに終わっていた話](https://note.mu/konpyu/n/na213a14ad1e3)
console.log() いろいろ

Vue.jsの勉強をしていた時、何気なく書かれていた`console.log('new: %s, old: %s',...)`という記述を見つけて、**ん？%sって使えるんか？**ってなったので調べてみた。
どうやらconsole.log()には引数として出力する変数を取る書き方がいくつかあるらしい。


###基本的な使い方(例)
```.js
console.log("hoge");
```

###出力結果
```
hoge
```

###引数として出力する変数を取る書き方(例)
```.js
const str = 'Hello',
    intNum = 19,
    floatNum = 72.5141919,
    obj = {hoge: 'hoge'},
    sty = 'color:#fff;background:#000;';



console.log(str, intNum, floatNum, obj);
console.log('文字列: %s', str);
console.log('数値(整数): %i', intNum);
console.log('数値(整数): %d', intNum);
console.log('数値(浮動小数点): %f', floatNum);
console.log('オブジェクト: %o', obj);
console.log('%c:スタイルを指定して出力', sty);
```
###出力結果
```
Hello 19 72.5141919 {hoge: "hoge"}
文字列: Hello
数値(整数): 19
数値(整数): 19
数値(浮動小数点数): 72.5141919
オブジェクト: {hoge: "hoge"}
:スタイルを指定して出力 (※実際には黒背景＋白文字になる)
```
OpenSSHで生成したed25519形式の秘密鍵はputtygenで読み込めない

そんな話があるか！と思いググっていると、[stackoverflow](https://stackoverflow.com/questions/49083709/how-to-convert-ed25519-private-key-to-putty-ppk)に先駆者がおりました。
人生の疑問は大体stackoverflowに書いてある！

>
down vote
>
The command in the above answer is just printing public key portion in RFC4716 format.
At some point, ssh-keygen generates openssh private key which doesn't use cipher supported by puttygen.
ssh-keygen doesn't provide option to specify cipher name to encrypt the resulting openssh private key.
There is a workaround: remove the passphrase from the key before importing into puttygen.
>
$ cp ~/.ssh/id_ed25519 ~/.ssh/id_ed25519-for-putty
$ ssh-keygen -p -f ~/.ssh/id_ed25519-for-putty
>
Enter old passphrase: <your passphrase>
Enter new passphrase (empty for no passphrase): <press Enter>
Enter same passphrase again: <press Enter>
>
Then, use puttygen to convert ~/.ssh/id_ed25519-for-putty into .ppk and set the passphrase from puttygen.
Don't forget to shred and remove ~/.ssh_id_ed25519-for-putty afterwards for obvious reason.

とのことなので**生成した後に空パスにしてputtygenに放り込めば**おｋです。

### 上記に関しての補記

コメントより、指摘を頂いたので修正させていただきました。

>OpenSSH 7.6でOpenSSH形式の秘密鍵の暗号化に使う方式がaes256-cbcからaes256-ctrに変わったからですね。PuTTY 0.70まではaes256-cbc(と非暗号化であるnone)にしか対応していませんでした。
>なので、OpenSSH 7.6より前のバージョンで生成した鍵ならば暗号化されていてもPuTTY 0.70で読めますし、OpenSSH側の変更に合わせてPuTTY側でもaes256-ctrでの暗号化に対応したので対応したので、PuTTY 0.71以降ならばではOpenSSH 7.6以降で生成した鍵も読めます。

単に`putty`のバージョンが**古くて**対応していなかっただけで、現在では読み込めるようです。下の解決方法を試す前に、`putty`の**バージョンアップ**も検討してみて下さい！

## 解決方法

1: ssh-keygenで普通にed25519形式のキーを生成します。ここでは普通にパスワードを入力して平気です。

```bash
cd ~/.ssh
ssh-keygen -t ed25519 -C "コメント(メルアドとか入れとく)"
```

2:  加工するのでコピーを取る

```bash
cp ~/.ssh/id_ed25519 ~/.ssh/id_ed25519-for-putty
```

3: 2.で作成したコピーを編集して、パスワードを空にしましょう。

```bash
ssh-keygen -p -f ~/.ssh/id_ed25519-for-putty

Enter old passphrase: <your passphrase>
Enter new passphrase (empty for no passphrase): <press Enter>
Enter same passphrase again: <press Enter>

// 後始末
sudo chown あなたのユーザ名:あなたのユーザ名 id_ed25519
sudo chmod 600 id_ed25519
```

5: 生成した`id_ed25519-for-putty`をwindowsに移動させて、puttygenに`import`します！

### 終わり！

参考URL: [stackoverflow](https://stackoverflow.com/questions/49083709/how-to-convert-ed25519-private-key-to-putty-ppk)
CVPixelBufferからCMSampleBufferを生成する

CMSampleBufferを受け取って、編集済みのCVPixelBufferだけ差し込みたいときはCMSampleBufferにformatDescriptionやtimintInfoを加えてCMSampleBufferを作り直す。


```swift
extension CMSampleBuffer {
  static func make(from pixelBuffer: CVPixelBuffer, formatDescription: CMFormatDescription, timingInfo: inout CMSampleTimingInfo) -> CMSampleBuffer? {
    var sampleBuffer: CMSampleBuffer?
    CMSampleBufferCreateForImageBuffer(allocator: kCFAllocatorDefault, imageBuffer: pixelBuffer, dataReady: true, makeDataReadyCallback: nil,
                                       refcon: nil, formatDescription: formatDescription, sampleTiming: &timingInfo, sampleBufferOut: &sampleBuffer)
    return sampleBuffer
  }
}
```

CMFormatDescriptionは、元のPixelBufferからではなく編集済みのPixelBufferを元に作る必要がある。
そうじゃないとOSStatusのエラーが返ってくる。

```swift
extension CMFormatDescription {
  static func make(from pixelBuffer: CVPixelBuffer) -> CMFormatDescription? {
    var formatDescription: CMFormatDescription?
    CMVideoFormatDescriptionCreateForImageBuffer(allocator: kCFAllocatorDefault, imageBuffer: pixelBuffer, formatDescriptionOut: &formatDescription)
    return formatDescription
  }
}
```
PHPでメールフォームを作る

## 環境
* Debian9
* PHP7
* nginx/1.14.0
* exim4.91

webページはすでに公開している。PHPも動く。
mailコマンドでeximからgmailにメール送信できている。

## HTML
下記の\<form>を書く

```html:mail.html
<form name="contact" method="POST" action="mail.php">
    <p>
        <label> 名前：<br> <input type="text" name="name" id="input_name"/></label>
    </p>

    <p>
        <label> メールアドレス：<br> <input type="email" name="email"id="input_mail"></label>
    </p>

    <p>
        <label> 件名：<br> <input type="text" name="subject" id="input_subject"></label>
    </p>

    <p>
        <label> 問い合わせ内容：<br> <textarea name="message" id="text_content"></textarea></label>
    </p>

    <p>
        <button type="submit">送信</button>
    </p>


```

## PHP 

```PHP:mail.php
<?php

$message = "name: " . $_POST["name"] . "\nsubject: " . $_POST["subject"] . "\nfrom: " . $_POST["email"] . "\nbody: \n" . $_POST["message"];
if (!mb_send_mail("test@gmail.com", $_POST["subject"], $message)) {
  exit("error");
}

?>

```

ブラウザでmail.htmlにアクセスして、gmailに送信されるか確認する

## 注意
* PHPの`mail()`および`mb_send_mail()`は第４引数以降に追加パラメータを設定できるが、これらは適切にエスケープしないと不正なコマンドをsendmail(mail)コマンドに渡される危険性があるらしい。そのため今回は第４以降を使用しなかった。

## (2019/02/21追記)エスケープする
[How to sanitze user input in PHP before mailing?](https://stackoverflow.com/questions/1055460/how-to-sanitze-user-input-in-php-before-mailing)にある回答よると**メールのタイトルに改行コードが入るのを許すと任意のメールヘッダを追加される**恐れがある。これを防ぐために`$_POST["subject"]`をエスケープして使う。

```PHP:mail.php
<?php
$message = "name: " . $_POST["name"] . "\nsubject: " . $_POST["subject"] . "\nfrom: " . $_POST["email"] . "\nbody: \n" . $_POST["message"];
$safe_subject = str_replace(array("\r","\n"),array(" "," "), $_POST["subject"]);
if (!mb_send_mail("test@gmail.com", $safe_subject , $message)) {
  exit("error");
}
?>
```

以下、エスケープについてのメモ

* **メール本文はエスケープする必要はない。**
* 宛先メールアドレスをユーザに入力させるときは`filter_var()`を使う。

```php
filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
```
* `htmlspecialchars()`はHTMLに出力するときのエスケープであり、メール(やサーバ上でのコマンド実行)には関係ない。

この節の参考文献：

* [Contact Form Sanitized Inputs](https://codereview.stackexchange.com/questions/82361/contact-form-sanitized-inputs)
* [サニタイズ/入力値検証/エスケープの考え方](https://qiita.com/rana_kualu/items/11cd41de5f0364ba2ee8)←とても勉強になる

## 参考
[PHPでメールフォームから宛先(Gmail)へ送信できない](https://teratail.com/questions/4936)
[Why mail() is dangerous in PHP]
(https://blog.ripstech.com/2017/why-mail-is-dangerous-in-php/)
[mb_send_mail()，mail()で第5引数を設定する際の注意点 ](http://d.hatena.ne.jp/t_komura/20131223/1387804821)
各デザインパターンのまとめ(個人メモ)


## はじめに
各デザインパターンをどの場面で使うのか。といったことをまとめました。

## 生成パターン
`Abstract Factory`
 ・ Factoryクラスを切り替えることでインスタンスを切り替えることが可能
 ・ Xだったら、A、B、C。Yだったら、D、E、Fを返す

`Builder`
 ・ 複数のオブジェクトを生成する上で、専用のクラスを用意する際に便利
 ・ オブジェクトの生成が複雑な時に使う

`Factory Method`
 ・ 機能が複雑になりクラスが多くなった際に使える
 ・ どの具象クラスを使うのかを隠す時に使う
 ・ 一緒に使いたいオブジェクトを生成する際に利用

`Prototype`
 ・ 同じクラスで複数のオブジェクトを作成する際に便利です。毎回コンストラクタを使ってオブジェクトを生成することなくクローンを生成できる。clone()したいときに使う

`Singleton`
 ・ オブジェクトを一つだけ生成させるデザインパターン。
 ・ 1つのクラスから1つのオブジェクトだけと制限する際に使えます。
 ・ オブジェクトの唯一性を保証するために使う

## プログラムの構造に関するパターン
`Adapter`
 ・ インタフェースに互換性の無いクラス同士を組み合わせることを目的としたパターン
 ・ 本来繋がっていないクラス同士を関連づける時など、利用したいインタフェースを強制的に変えたいような場合に利用できる

`Bridge`
 ・ 機能と実装を分離して、それぞれを独立に拡張することができるようにするためのパターン
 ・ 機能の上位クラスが、集約している実装の上位クラスに処理を委譲することによって、２つの階層を橋のように結びつけることができる

`Composite`
 ・ 器と中身を同一視することで、再帰的な構造の取り扱いを容易にすることができるパターン

`Decorator`
 ・ 飾り枠と中身を同一視することで、より柔軟な機能拡張方法を提供することができるパターン
 ・ 継承以外の手段で機能を追加することができる

`Facade`
 ・ 既存のクラスを複数組み合わせて使う手順を、「窓口」となるクラスを作ってシンプルに利用できるようにするパターン

`Flyweight`
 ・ 同じインスタンスを共有することで無駄なを生成を削減し、プログラム全体を軽くすることを目的としたパターン
 ・ 小さなオブジェクトを数多くロードする状況で効率的に処理できる
`Proxy`
 ・ 要求を代理人のオブジェクトが受け取り、処理をするようなパターン

## オブジェクトの振る舞いに関するパターン
`Chain of Responsibility`
 ・ 責任者を鎖状につないでおき、いずれかの段階で、「誰か」が処理をすることを表現するようなパターン
 ・ メッセージを他のクラスのオブジェクトに送って処理することが可能

`Command`
 ・ 命令を表すオブジェクトをメソッドの引数にすることで、1つの引数で複数のデータと処理を伝えることができるパターン

`Interpreter`
 ・ インターフェースを使って、構文解析の結果をツリー構造で表示するパターン

`Iterator`
 ・ 要素の集まりを保有するオブジェクトの各要素に順番にアクセスする方法を提供するためのパターン
 ・ 集約オブジェクトの種類や実装に依存しない、統一的な走査方法を提供したいような場合に利用できる
 ・ forEachしたい時

`Mediator`
 ・ 適宜判断を行い指示を出す「仲裁人」の役割を果たすクラスを利用するパターン
 ・ クラス間の疎結合を綺麗に整理することができ、複数のオブジェクトを組み合わせて機能を実装する際に利用できる

`Memento`
 ・ 必要な情報のみを保持しておき、必要なデータのみを復元できるようなパターン

`Observer`
 ・ 通知の仕組みをより汎用的に利用できる形で提供するためのパターン
あるオブジェクトの変化を別のオブジェクトに通知させることが可能

`State`
 ・ モノではなく、「状態」をクラスとして表現するパターン
 ・ if文を利用することなく、状態に対応した処理を行うことができる

`Strategy`
 ・ 戦略の部分を意識して別クラスとして作成することで、柔軟でメンテナンスしやすい設計をするためのパターン
 ・ クラスを使う人のコードを変更することなくアルゴリズムを変更することが可能

`Template Method`
 ・ テンプレートの機能を持つクラスを作成するパターン
 ・ 処理の流れをテンプレート化したいような時に利用できる

`Visitor`
 ・ 受け入れる側に処理を追加することなく、処理を追加することができるパターン
 ・ オブジェクトに動的に機能を追加するために利用できる
emacsでIbufferにinit.elの変更を再起動なしで反映させようと思ったけど失敗した時の臨時対策

`~/.emacs.d/init.es`
を修正

`M-x eval-buffer`

した後に既に開いているibufferを開いたら反映されるはず・・・だった

でもだめだったのでとった方法

`ibuffer`にて ` を入力

以上
npxでnodeモジュールを実行する

## npxについて

バージョン5.2.0以上のnpmには[npx](https://www.npmjs.com/package/npx)というツールがバンドルされています。
npxを使うとローカルにインストールしたモジュールをお手軽に実行できます。


## 特徴

個人的に良いと思った点は主に以下の三点ですかね。

- シンプルに実行できる
- ローカルに存在しないパッケージでも実行可能
- nodeのバージョンを指定してnpm-scriptを実行できる

### シンプルに実行できる
モジュールを実行しようとすると、以下のような形になりますが、

```
$ ./node_modules/.bin/パッケージ名　// パスを指定してモジュールを実行する
```
```
$ $(npm bin)/パッケージ名
```
```
$ npm run タスク名 // package.json内のnpm-scriptsで定義したタスク
```

npxだと以下でOK。

```
$ npx パッケージ名
```

ローカルパッケージを、パスを気にしたり npm-scripts でタスクを定義しなくても実行できるのはいいですね。


### ローカルに存在しないパッケージでも実行可能

もし指定したパッケージがローカルに存在しない場合は、一旦グローバルにインストールされ一度だけ実行できるという機能があります。処理が完了したらそのパッケージはグローバルから削除されるので汚染の心配もありません。
試しに[cosway](https://www.npmjs.com/package/cowsay)というコマンドライン上で指定した文字列を牛に喋らせるというパッケージを実行してみます。

```
$ npx cowsay hoge
npx: installed 10 in 2.796s // インストールにかかった時間
 ______
< hoge >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
```

終了後、npmでcowsayを実行すると削除されているのがわかります。

```
$ $(npm bin)/cowsay
-bash: 〜/node_modules/.bin/cowsay: No such file or directory
```

また、github上のリポジトリを実行することも可能です。バグフィックス済みだけど、npmに公開はされていないみたいなこともままあるみたいので、そういう時には有効かもしれません。

```
$ npx githhub:ユーザー名/リポジトリ名 
```

### nodeのバージョンを指定してnpm-scriptsを実行できる

書いて字のごとく、nodeのバージョンを指定してnpm-scriptsを実行できます。
バージョンを上げたいけど、問題が起きないかどうかの検証を簡単に行えるのはいいですね。

 ```
$ npx -p node@10.3.0 npm run build
 ```
 
こちらも実行完了後にそのバージョンは削除されます。

 
## 最後に
プロジェクトのポータビリティを担保すると、結局ローカルインストールして、npm-scriptsにタスクを定義する方が無難なのかな、と思いますが、便利だしメリットも大きいのでもう少し使い所を考えたいところです。
Tomcat.jdbc に置ける connection pool に関する設定

原因：以下のエラーログでJDBCに接続できなくなった。

````
 Cased by: java.sql.SQLRecoverableException: クローズされた接続です。
```
対策：setValidationQuery に　"SELECT 1 FROM DUAL"　(Oracle) の検証用クエリを入れ setTestOnBorrow(true) を指定すると検証してオブジェクトを破棄して再接続しますが、他にも沢山のパラメータがあるので、一覧でコメントを振って見ました。


    public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
        org.apache.tomcat.jdbc.pool.DataSource datasource = null;
        PoolConfiguration p = new DefaultProperties();
        // コネクションプールをConnectionPoolMBeanとして登録 初期値は true
        p.setJmxEnabled(true);

        // 検査するアイドル接続に validationQuery を発行して DB との接続を確認するかどうか。 ようするに testOnBorrow, testOnReturn のスレッド版。 true を指定した場合、実際に DB との通信が出来なくなっているオブジェクトを破棄する。 validationQuery が未指定の場合は何もしない。 この検査は、上記の minEvictableIdleTimeMillis での検査後に行われる。 初期値は false 。
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(false);
        p.setTestOnReturn(false);

        // クローズ漏れコネクションの検知を行う場合はtrueに設定
        p.setRemoveAbandoned(false);

        // クローズ漏れを検知した際に、コネクションをクローズしていないアプリのスタックトレースをログに出力する場合に設定
        p.setLogAbandoned(false);

        // コネクションの死活を検証する際に使用するクエリを設定します。 nullもしくは空文字を指定した場合、検証は行われません。デフォルトはnullです。
        p.setValidationQuery(null);

        // プールから取得されるコネクションがここに指定した間隔（ミリ秒）よりも長い間プールされていた場合、コネクションの死活を検証します。初期値は 10000
        p.setValidationInterval(1800000);

        // スレッドの実行間隔 (ミリ秒) を指定する。 1 未満だとスレッドは実行されない。 よって、その場合以下のパラメータ群は指定しても意味を持たない。 初期値は -1 なので、デフォルトではこのスレッドは動作しない。
        p.setTimeBetweenEvictionRunsMillis(10);

        // クローズ漏れとみなすまでの時間 初期値は 60 sec
        p.setRemoveAbandonedTimeout(180);

        // アイドル接続がプール中に居座れる時間。（ミリ秒単位）接続がアイドル状態になってからこの時間を過ぎていると、切断し破棄する。 1 未満は無制限を意味し、決して破棄されなくなる。 次の testWhileIdle の機能を利用するなら、無制限を指定するのも無意味ではない。 初期値は 1800000 (30 分) 。
        p.setMinEvictableIdleTimeMillis(1800000);

        // プールの起動時に作成されるコネクションの初期サイズ 初期値は10
        p.setInitialSize(1);

        // 同時にプールから割り当てることのできるアクティブなコネクションの最大数 初期値は100
        p.setMaxActive(1);

        // プールに保持しておく最大のコネクション数 初期値は maxActive
        p.setMaxIdle(1);

        // プールに保持する最小のコネクション数 初期値は initialSize
        p.setMinIdle(1);

        // 利用可能なコネクションが存在しないときに待機する最大時間（ミリ秒単位） 初期値は 30000 = （30秒）
        p.setMaxWait(30000);

        // コネクションを保持する時間（ミリ秒単位）コネクション返却時に接続時間からmaxAge以上経過していたら、そのコネクションをクローズ。maxAgeによるチェックを行わない。初期値は 0
        p.setMaxAge(180000);

        // getConnectionの呼び出しが FIFO方式で公平に扱われることを希望する場合はtrueに設定。trueに設定することで、アイドル状態のコネクションリストに、org.apache.tomcat.jdbc.pool.FairBlockingQueue実装が使用され、スレッドが到着した順番でコネクションを獲得することが保証される 初期値はtrue
        p.setFairQueue(false);
        datasource = new org.apache.tomcat.jdbc.pool.DataSource();
        datasource.setPoolProperties(p);
        return datasource;
    }
[WIP] MySQLでcreated_atを持つレコードを5分間隔で集計する

```sql
mysql> create table event (created_at timestamp);
Query OK, 0 rows affected (0.02 sec)

mysql> insert into event values ('2018-01-01 00:01:00');
Query OK, 1 row affected (0.02 sec)

mysql> insert into event values ('2018-01-01 00:02:00');
Query OK, 1 row affected (0.01 sec)

mysql> insert into event values ('2018-01-01 00:03:00');
Query OK, 1 row affected (0.01 sec)

mysql> insert into event values ('2018-01-01 00:04:00');
Query OK, 1 row affected (0.00 sec)

mysql> insert into event values ('2018-01-01 00:05:00');
Query OK, 1 row affected (0.00 sec)

mysql> select concat(date_format(created_at, '%Y-%m-%d %H:'), lpad(truncate(date_format(created_at, '%i') / 5, 0) * 5, 2, '0')) as created_at__interval_5, count(*) from event group by 1 order by 1;
+------------------------+----------+
| created_at__interval_5 | count(*) |
+------------------------+----------+
| 2018-01-01 00:00       |        4 |
| 2018-01-01 00:05       |        1 |
+------------------------+----------+
2 rows in set (0.00 sec)
```

### 説明

TBD
Freenomで取得できる無料ドメインはアクセスできる状態にないと停止される


[Freenom](https://www.freenom.com/ja/index.html)では無料でドメイン(.tk/.ml/.ga/.cf/.gq)が取得できる。
先日ドメインが停止された旨のメールが届いた。

![freenom_mail.png](https://qiita-image-store.s3.amazonaws.com/0/296108/739e030b-5dd6-5e5e-f62b-5798e9c06ff6.png)

理由は下記のいずれかとのこと

* 取得したドメインがアクセス可能ではなかった
* 規約に示されたガイドラインに従っていなかった

ガイドラインにはドメインを使用して公開するコンテンツに関する項目があったと思う。
技術ブログにするつもりで、wordpressの構築手順などを書いていたが、
今回の停止の理由は、取得したドメインを割り当てたGCEのインスタンスで、停止/起動を繰り返していたのでアクセスできなかったためだと思う。


## 参考：
[無料のドメインを取得する](https://qiita.com/teekay/items/135dc67e39f24997019e)
[Freenomで取得した無料ドメインが停止されました](https://anlovegeek.net/freenom-domain-cancelled/)
[Why My .tk Site Was Deleted by Freenom?](https://gist.github.com/ilyaigpetrov/d7b06b7ea15143124b930f2dde3addfd)
JuliaからFortranのsubroutineを呼び出す


Julia 1.0を使っているときに、Fortranで作ったルーチンを呼び出したいこともあるかと思います。
そのような時にどうするか、ということをまとめました。例えば、MKLを使ったFortranの高速なコードをわざわざJuliaに移植せずにそのまま使いたい、などがあるかもしれません。


まず、以下のようなFortran90のmoduleがあるとしましょう。

```fortran
module multi
  contains
    subroutine mat(val,col,row,val_l,col_l,row_l,x,n,b) !複素数行列の行列ベクトル積を計算
      implicit none
      integer(8),intent(in)::val_l,col_l,row_l
      complex(8),intent(in)::val(1:val_l)
      integer(8),intent(in)::col(1:col_l),row(1:row_l)
      integer(8),intent(in)::n
      complex(8),intent(in)::x(1:n)
      complex(8),intent(out)::b(1:n)
      integer::i,j
      b = 0d0

      call mkl_zcsrgemv("T", n, val, col, row, x, b) !MKLのスパースBLAS レベル2を使用

      return
    end subroutine mat
end module multi
```
このmoduleの中のsubroutineのmatでは、MKLのスパースBLAS レベル2を利用することによって、疎行列ベクトル積を計算しています。最近はMKLの利用は無料となっています。
https://software.intel.com/en-us/mkl
このコードをコンパイルするために、ifortを使っても良いのですが、ifortは有料ですので、gfortranを使います。

```bash
gfortran test.f90 -o test.so -shared -fPIC -lmkl_intel_ilp64  -lmkl_sequential -lmkl_core -lpthread -lm -ldl
```
ここで、このmoduleを共有ライブラリ化するために、-shared -fPIC というオプションをつけています。後ろのmkl関連は、OSなどによって異なると思います。今回はMacのgfortranでMKLを呼んでいます。なお、ilpにするとinteger(8)、lpにするとintegerをMKLのルーチンに入れることになりますので、MKLのルーチンに入れる整数の引数に合わせてオプションを指定しないと変な結果が返ってきますので注意してください。
ここでできたtest.soは

```bash
nm test.so 
```
とすることによって、中に入っているsubroutineの名前を見ることができます。gfortranかifortかで変わります。
このコードをJulia側から呼び出すには、


```julia
using SparseArrays
using Random

Random.seed!(1234) #乱数シードを固定
n = 10
A = spzeros(ComplexF64,n,n)
for i=1:n
    j = rand(1:n)
    A[i,j] = rand()+im*rand()
end
#10x10の適当な行列を用意した。

col = A.colptr #疎行列の列
val = A.nzval #疎行列の値
row = A.rowval #疎行列の行
#行列ベクトル積 b = A*xを実行したい
x = rand(Float64,n)+im*rand(Float64,n) 
b = zeros(ComplexF64,n) 
val_l = length(val)
row_l = length(row)
col_l = length(col)
println("Ax ", A*x)

ccall((:__multi_MOD_mat,"./test.so"),Nothing, #gfortranでコンパイルした場合
#ccall((:multi_mp_mat_,"./test.so"),Nothing, #ifortだと:multi_mp_mat_となる。
    (Ref{ComplexF64}, #val
    Ref{Int64}, #col
    Ref{Int64}, #row
    Ref{Int64}, #val_l
    Ref{Int64}, #col_l
    Ref{Int64}, #row_l
    Ref{ComplexF64}, #x
    Ref{Int64}, #n
    Ref{ComplexF64}), #b
    val,col,row,val_l,col_l,row_l,x,n,b)
println("Ax from Fortran ", b)
```
とすればよいです。
ここで、Fortranを呼び出す時には、Ref{Float64}やRef{ComplexF64}などとします。ここでのFloat64は引数が配列であれば配列の要素の型となります。Int64はFortranではinteger(8)となることに注意してください。どの型であれRef{}の形で定義しておけば、問題なく引数を渡すことができます。

Nothingは古いバージョンのJuliaではVoidでした。そのため、呼び出しの説明でVoidを使っている場合がありますが、Julia 1.0以降ではNothingを使います。これは、関数の返り値の型です。

### 疎行列格納形式の注意

今回は疎行列を演算するFortranコードを呼び出していますので、Julia側の疎行列の中身をval,row,colと取り出しています。ここで注意しなければならないのは、FortranでのMKLの疎行列サブルーチンは行格納型（CSR）ですが、Juliaでは列格納型(CSC)であることです。しかし、これは特に大きな問題になりません。というのは、FortranのMKLのルーチンmkl_zcsrgemvは行列の転置の演算に対応しているからです。よって、mkl_zcsrgemvの引数のrowとcolの場所を入れ替えて"T"を引数にすれば、Juliaでの疎行列をそのまま入れることができます。


### 追記
cure_honeyさんに教えていただきましたが、ccallで呼び出すときのFortranのコードはFortran2003以降に対応していれば（最近のgfortranで使える事を確認しました）、

```fortran
subroutine mat(val,col,row,val_l,col_l,row_l,x,n,b) bind(c, name = 'mat')
```
とbindを使えば名前をつけられるようです。これを使えば、呼び出しの際に、`:__multi_MOD_mat`の代わりに`mat`を使って呼び出すことができるようです。
ハッシュ検索の中身の複雑さによる計算速度の違いについて

## やりたいこと
ハッシュ検索は計算オーダーがO(1)と言われているが，
hash検索が中身の複雑さ（例えば，単語やハッシュ値など）に応じて，計算速度が変化するのかを確認したい

### hashの中身がintの場合

```number.py
import time

if __name__ == '__main__':
    N = 100000
    dict = {i: None for i in range(N)}

    start = time.time()
    for i in range(N):
        if i in dict:
            pass

    elapsed_time = time.time() - start
    print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
# elapsed_time:0.010960102081298828[sec]
```



### hashの中身が複雑な場合

今回は中身を複雑にするために，hashで作成することする

```hash.py
import hashlib
import time

if __name__ == '__main__':
    N = 100000
    dict = {hashlib.md5(i.to_bytes(4, 'little')).hexdigest(): None for i in range(N)}

    list = [hashlib.md5(i.to_bytes(4, 'little')).hexdigest() for i in range(N)]
    start = time.time()
    for item in list:
        if item in dict:
            pass

    elapsed_time = time.time() - start
    print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")

# elapsed_time:0.023391008377075195[sec]
```

こうして比べてみると,同じhash検索でも，辞書の中身のデータタイプによって，大きく計算速度が変わることはないのではないかと思う．

###　もしhas検索でなかったら

もしhash検索でなかったらどうなるのだろうか？
ということで試してみた．

```list.py
import time

if __name__ == '__main__':
    N = 100000
    list = [hashlib.md5(i.to_bytes(4, 'little')).hexdigest() for i in range(N)]

    start = time.time()
    for i in range(N):
        if hashlib.md5(i.to_bytes(4, 'little')).hexdigest() in list:
            pass

    elapsed_time = time.time() - start
    print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")

# elapsed_time:85.36278200149536[sec]

```

listの中に特定の要素が存在するかを検索すると，かなりの時間がかかることがわかる．

なので，要素の検索をする際には，hash検索をするべきであることがわかる．
AtomにTypeScriptの設定をしよう!!

## TypeScriptって何?
言語の一種。
コンパイルすると、jsファイルになる。
最大の特徴は静的な型付け。
例えば、jsで`number`があったら、tsだと`number : value`みたいに、型を付けなくちゃならない。
コードが増えるっちゃ増えるけど、個人的には、tsファイルのままがわかりやすくて好き。
参考:[TypeScriptってどんなもの？ プロ生ちゃんと始めてみよう！](https://www.buildinsider.net/web/pronamatypescript/01)

## Packageのインストール
端末で

```
apm install atom-typescript
```

「環境設定からもできるんじゃない?」って思った人がいるかもしれないけれど･･･

![Screenshot from 2018-11-06 17-24-38.png](https://qiita-image-store.s3.amazonaws.com/0/218398/cdf77d81-ab38-144e-32cc-ab13d27c933d.png)

ご覧の通り、最新版はインストールできないっぽい。
問題なく動くと入っているけど、そりゃあ最新版を使いたいっすよ。
まぁ、あんまり気にしない人はここからでも良いかもしれないけれどね。

## 自動コンパイルをするために
今回インストールした`atom-typescript`は自動でjsファイルにコンパイルできるみたい。
その場合、プロジェクトのルートディレクトリに、[AtomでTypeScriptの環境を構築する](https://qiita.com/Sugima/items/113eb16f14ca1e9a6d0f)にあるような、`tsconfig.json`ファイルを作成する必要がある。

何もしなくてもシンタックスカラーと自動補完はあるし、個人的には別になくても良いような気はするけど、プロジェクトで開発する人からしたらそうも行かないか。

## 参考
[AtomでTypeScriptの環境を構築する](https://qiita.com/Sugima/items/113eb16f14ca1e9a6d0f)
[LINQ VB.NET] ToLookup() GroupBy() の違い。


LINQ の拡張メソッドに ToLookup() というものがあります。グループ化するものらしいです。ネット検索すると C# のサンプルばかりなので VB.NET のサンプルを作ってみますよ。

## ToLookup() を使った VB.NET のサンプル

早速サンプルです。

```vb:ToLookup()サンプル
' サンプルのためのデータを作成する
Dim lst As New List(Of Object)
With lst
    .Add(New With {.Type = "Fruits", .Name = "Apple"})
    .Add(New With {.Type = "Fruits", .Name = "Banana"})
    .Add(New With {.Type = "Fruits", .Name = "Citrus"})
    .Add(New With {.Type = "Fruits", .Name = "Dorian"})
    .Add(New With {.Type = "Vegitables", .Name = "Avocado"})
    .Add(New With {.Type = "Vegitables", .Name = "Broccoli"})
    .Add(New With {.Type = "Vegitables", .Name = "Carrot"})
    .Add(New With {.Type = "Vegitables", .Name = "Daikon"})
    .Add(New With {.Type = "Vegitables", .Name = "Endive"})
    .Add(New With {.Type = "Flowers", .Name = "Anemone"})
    .Add(New With {.Type = "Flowers", .Name = "Begonia"})
    .Add(New With {.Type = "Flowers", .Name = "Clematis"})
    .Add(New With {.Type = "Flowers", .Name = "Dahlia"})
    .Add(New With {.Type = "Flowers", .Name = "Echinacea"})
End With

' サンプルコードのキモ
Dim olinq = lst.ToLookup(Function(o) o.Type)

' 結果を表示する
For Each o As Object In olinq
    System.Diagnostics.Debug.Print("# " & o.key)
    For Each nm As Object In o
        System.Diagnostics.Debug.Print("    " & nm.Name)
    Next
Next
```

## 同じ結果になる処理を GroupBy() で書いてみる

一方、グループ化というと GroupBy() というメソッドもありますよ。上記サンプルコードの「キモ」の部分だけ書きます。

```vb:GroupBy()サンプル
Dim olinq = lst.GroupBy(Function(o) o.Type)
```

まったく同じ結果になりましたよ。何のために二つのメソッドがあるんでしょう。

## 使い分け

上のサンプルはいずれも LINQ to Object ですね。LINQ to Object に対する実行ではあまり差はないみたいです。LINQ to SQL で実行すると動作が違う。

ToLookup() は全部のデータを持ってきて走査、GroupBy() はデータベースに「グループ化して結果を返してね」とお願いして結果だけを返してもらう、という違いがあるということだと思います（[参考](https://stackoverflow.com/questions/10215428/why-are-tolookup-and-groupby-different)）。LINQ to SQL で ToLookup() を使って、もしデータが 10 億件もあったりしたら全部持ってきてたいへんなことになると。

## 評価の差

そのほかには GroupBy() は遅延評価、ToLookup() は即時評価。違いは [こちら](http://oxamarin.com/linq-lazy-evaluation/) を参照。たとえば二番目のサンプルで結果を表示するループ処理を二回行うとグループ化処理も二回行われてしまうということですね。

グループ化した結果をどのように使うかによる、と。