OmniAICreator/Qiita-1.07M huggingface dataset:
さくらレンタルサーバ(共用)に CakePHP2 で作ったアプリをデプロイしようとしてはまった話


## やりたかったこと
* ドキュメントルート以外にアプリをインストール
* ドキュメントルートからはシンボリックリンクをはる

## 実際にシンボリックリンクを貼ってみる
SSH でログインし、おなじみの `ln -s source dest` を叩く。
css や js といったディレクトリ系は問題なくリンクが貼れている。
しかし index.php や .htaccess といったファイル系はなぜか作成後にディレクトリアイコンになる。
この状態でアクセスするとエラーメッセージがでる。

オプションの s を外したハードリンクでは貼ることができたし、ちゃんとアクセスすることができた。

原因を検索してみたところ、そもそも共有サーバではシンボリックリンクが貼れない仕様らしい。
ナンテコッタ。

## www 配下にデプロイして、ドキュメントルートを変えよう
仕方がないので www 配下にファイルをまるっと移動させる。
このままの状態だとライブラリとかのソースコードがノーガードなので、ドキュメントルートを変更してみる。

「マルチドメインとして使用する」にチェックが入っていても、初期ドメイン状態ではドキュメントルートを変更できないらしい！
ナンテコッタ。

## もう普通に構築する
しかしここにも罠が。
`.htaccess` をデフォルトから手を加えないといけないらしい。

以下のファイルの2行目をそれぞれ加筆する。
* /www/.htaccess
* /www/app/.htaccess
* /www/app/webroot/.htaccess

```/www/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
```

```/www/app/.htaccess
<IfModule mod_rewrite.c>
	RewriteEngine on
	RewriteBase /app
	RewriteRule ^$ webroot/ [L]
	RewriteRule (.*) webroot/$1 [L]
</IfModule>
```

```/www/app/webroot/.htaccess
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteBase /app/webroot
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^ index.php [L]
</IfModule>
```

git などで clone してくると、サブフォルダが作られたりするので、そういう場合は、それぞれのファイルで `/` を `/sub/` に変更する。

## 終わってみて
共有サーバだからいろいろ制限あるのは仕方がないんだろうなぁ。
.htaccess の改変は割とよくあるので気にならないけど、シンボリックリンク禁止はセキュリティ的な観点からなのかな。
もし開発前からさくらの共有サーバを使うことが分かっていれば、あらかじめ webroot を分離した状態で構築するのが良いと思う。
分離させた開発はさくら以外にも使い道はあるだろうし。

分離させる際は app/webroot/index.php あたりをごにょごにょ書き換えれば良い。
マウスイベントで取得されるカーソル座標パラメータの整理(offset, page, screen, client)

# はじめに

もはや何番煎じかわかりませんが，jsのマウスイベントにて取得されるカーソル位置パラメータを図とサンプルを見ながら整理します．なぜ今さらこんな記事を書くかというとoffsetX,Yにて取得される値について長年勘違いしていたことが発覚したためです（恥ずかしい...）．そちらについては，[こちらの記事](http://qiita.com/yukiB/items/cc533fbbf3bb8372a924)を御覧ください，

# 図解でわかるカーソル座標パラメータ

例として，ページ中にあるid=containerの要素に対してマウスのイベントを付与した時を考えます．コードで書くなら例えば

```js

var el = document.getElementById("container");
el.onmousemove = function(event){
   event.offsetX;
};

```

のような感じです．

得られるパラメータがそれぞれ表している値の意味を下図にのせました．

![offset2.png](https://qiita-image-store.s3.amazonaws.com/0/59864/797e6560-8c37-3946-fe0d-1d42db1be797.png)
![offset3.png](https://qiita-image-store.s3.amazonaws.com/0/59864/5242e6d8-09b7-02ec-0645-34c6294f948f.png)


### event.offsetX / Y
要素内でのカーソル座標(マウスが載っているDOMの左上を原点とした座標)を取得．

### event.clientX / Y
ブラウザウィンドウ内でのカーソル座標を取得．ウィンドウの左上が常に (0, 0) の座標となる．

### event.pageX / Y
ページ全体でのマウスの位置座標を取得．ページの左上が常に (0, 0) 座標となる．そのため，ページをスクロールさせた場合，図のように原点がウィンドウよりも上に移動し，pageX/YとclientX/Yの値がずれるようになる．

### event.screenX / Y
スクリーン（モニタ・ディスプレイ）全体でのカーソル座標を取得．ディスプレイの左上が常に (0, 0) 座標となる．

offsetX / Yについては，FireFoxが対応しておらず，かわりにlayerX / Yという値が利用されていましたが，ver.39からは対応するようになっているので，ややこしいことはないはずです．これでもうこの値はどこを原点にした値だっけ...と悩むことはないでしょう．jQueryで得られる値も同様です．

## それでもややこしいevent.offsetX / Y

上のパラメータで気をつけなければならないのがevent.offsetX / Yで，　idがcontainerの要素に付与したイベントであっても，なかで取得されるoffsetX / Yの値は，その内部にあるid=boxの要素の左上を原点とした値となっています．

つまり，**event.offsetX / Yで取得される座標値は，そのイベントが付与されている要素の左上を原点としたもの*****ではない*** ということです．気になる方は[こちら](http://qiita.com/yukiB/items/cc533fbbf3bb8372a924)を御覧ください．

# サンプルで確かめる

[code.pen](http://codepen.io)に上記の値の違いが確かめられる[サンプル](http://codepen.io/yukiB/pen/gwGjrw)を置きました．気になる方は色々値をいじって確かめてみてください

![image](https://qiita-image-store.s3.amazonaws.com/0/59864/2dcec115-26be-ec08-7ce6-087648331c92.png)

# 参考文献

- EasyRamble 「jQuery(JavaScript)でマウス座標やウィンドウサイズを取得して確認するツール」([http://easyramble.com/js-check-positions-and-sizes.html](http://easyramble.com/js-check-positions-and-sizes.html)
Sublime Text3のDefinitionsを消す

#### Definitionsが出るようになりました

Build 3116から新しい機能としてマウスオーバーすると、
定義元をパネルで出してくれるようになりました。

![スクリーンショット 2016-10-03 19.34.47.png](https://qiita-image-store.s3.amazonaws.com/0/11564/85e55c41-df82-6cf8-1e2e-7f26f6d9b3a7.png)

**??????????**

仮のphpファイルを用意し、$thisでマウスオーバーすると
なぜかjqueryのプラグインが定義元になります。
ST3は今までも定義を辿る（Goto Definition）時、文脈を理解してないようだったので、
まあ当然の動きですね。

#### Goodbye

邪魔なので消しましょう。

* ユーザ設定のメニューを開きます。
```SublimeText > Preferences > Settings```

* ユーザ用の設定ファイルに下記を追加します。
```"show_definitions": true```

これで消せます。

#### 定義元が見たいんじゃあって場合
* ST3は単なる豪華なテキストエディタなので、あまり過度な期待を抱かない
* どうしても見たい人はphpstorm(有料)がオススメ
* ST3とphpstormは使い分けましょう。どちらも便利です。
特定のタグが付いているawsのインスタンスのNameとIPをpecoで一覧しながらsshする


ただのshell芸です
key:app, value:qiitaというタグが付いているやつを一覧してsshできます。
表示されるのは、nameとipアドレス

#### 事前準備
## aws-cliの設定
1. aws consoleに入りIAMから、アクセスキーを作成します。
1. aws-cliの設定を行います。

```
aws configure
```
先程作成して表示された`AWS Access Key ID`および`AWS Secret Access Key`を入力します

#### Script

```bash
#!/bin/bash

ssh_user="qiita"
aws_result=$(aws ec2 describe-instances --filters "Name=tag:app,Values=qiita" --query "Reservations[].Instances[].{Name:Tags[?Key=='Name'].Value|[0], Ip:PublicIpAddress}")
selected_ip=$(echo ${aws_result} | jq -r '.[] | [.Name, .Ip] | join("\t")' | peco --query "$1" --prompt '>' | cut -f 2)
if [ -n "${selected_ip}" ]; then
    exec ssh ${ssh_user}@${selected_ip}
fi
```

別にタグとか入らないから、インスタンス全て出してよって方は以下でいけます。

```bash

#!/bin/bash

ssh_user="qiita"
aws_result=$(aws ec2 describe-instances --query "Reservations[].Instances[].{Name:Tags[?Key=='Name'].Value|[0], Ip:PublicIpAddress}")
selected_ip=$(echo ${aws_result} | jq -r '.[] | [.Name, .Ip] | join("\t")' | peco --query "$1" --prompt '>' | cut -f 2)
if [ -n "${selected_ip}" ]; then
    exec ssh ${ssh_user}@${selected_ip}
fi
```
MFA 設定手順

(これは、非エンジニアの方に MFA 設定手順を説明するための文書です。)

## MFA とは

MFA は Multi Factor Authentication の略で、日本語では二段階認証・多要素認証などと呼ばれています。

通常の ID とパスワードに加えて、スマホに表示される6桁の番号で認証します。スマホを持っていることが、その人本人であることの証明になります。

### MFA のメリット

パスワードを盗まれても、アカウントを勝手に使われる心配がありません。

### MFA のデメリット

スマホを買い換えたり、無くしたり、壊したりした場合、そのアカウントにログインする方法がなくなってしまいます。これを避けるため、通常は各サービスで復旧用のコード(リカバリコード)が発行されます。リカバリコードは印刷するなどして、大切に保管しておいてください。

## 手順1. スマホに Authy をインストールする

MFA 用のアプリを入れます。基本的には Authy を使ってください。

 * https://www.authy.com/
 * http://dev.classmethod.jp/cloud/aws/authy/
 * http://www.appbank.net/2014/02/13/iphone-application/750689.php
 * http://nya-0.hatenablog.com/entry/2015/05/30/080000

Authy は Authy 用のパスワードと電話番号から、設定のリカバリができます。上で説明したリカバリコードが無くても設定を引き継げるので、携帯を変えた時に非常にラクです。(Authy 用のパスワードを忘れると困るので、時々忘れていないかどうかダイアログで聞かれます)

Authy 以外のアプリを使う場合は、リカバリになにが必要かを把握しておいてください。

## 手順2. 各サービスで MFA の設定を行う

お使いのサービスによって、手順が異なります。

### AWS

AWS はリカバリコードを発行しません。AWS (IAM) アカウントの MFA は、管理者側で再設定できるので、それほど心配する必要はありません。

以下の手順で設定をお願いします。

#### 1. AWS にログインして IAM を選択

IAM (Identity & Access Management) の設定画面を開きます。

![shot(17).png](https://qiita-image-store.s3.amazonaws.com/0/2596/a07e390b-eda2-023a-e1c8-690f989cb532.png)

#### 2. 自分のユーザ設定画面を開く

`ユーザ > 自分のユーザ名`と進みます。

![shot(18).png](https://qiita-image-store.s3.amazonaws.com/0/2596/a222f028-e618-7bd0-13f6-b9874b1b0ab1.png)

#### 3. MFA デバイスの管理画面を開く

`認証情報 > MFAデバイスの管理 > 仮想MFAデバイス` と進みます。

![shot(68).png](https://qiita-image-store.s3.amazonaws.com/0/2596/e6386418-5439-bd8d-80c3-db105663d87e.png)


#### 4. QR コードを読み込んで数字を2つ入力する

Authy で表示された QR コードを読み込み、表示された数字を認証コード1に入力します。

数秒待つと Authy の数字が変わるので、次の数字を認証コード2に入力します。

![shot(20).png](https://qiita-image-store.s3.amazonaws.com/0/2596/beb4b98c-858e-5df1-1ca1-d17fa7790690.png)


#### 5. 一旦サインアウトして、再度サインインできるか確認する

一度サインアウトします。
サインインの画面で ID とパスワードを入力し、次の画面で Authy に表示された番号を入力します。

サインインできたら、設定完了です。


### GitHub

GitHub はリカバリコードを発行します。Authy で復旧できず、リカバリコードもなくした場合、GitHub に別のアカウントを作成しなければならなくなります。アカウントが2つあると、他の開発メンバーにとっても不便な状態になります。

**リカバリコードが手元にあるかどうかを確認してください。**見つからない場合は、いますぐダウンロード or 印刷をお願いします。

https://github.com/settings/security からダウンロードできます。

## Google アカウントの2段階認証

リカバリコードが手元にあるか、確認してください。

## Slack の2段階認証

リカバリコードが手元にあるか、確認してください。

 * http://qiita.com/kohatan811/items/35cd8eed83d5df33dbc3
GAE/GoをDocekrで動かす

macOS SierraでGAE/GoのSDK（1.9.40）がエラーになってビルドやデプロイができない。

回避方法としては、VMでやったり、Dockerでやったり Google Cloud Shellでやったりが考えられる。

このページでは Dockerでやってみる。
といっても、すでにDockerfileを公開している人がいるのでコマンド一発でOKである。

- Dockerのセットアップは完了している前提
- DockerやるならAlpine

#### A. 開発環境サーバーを立ち上げる

    PROJECT_NAME=sample-project
    cd ~/google-appengine-sdk/src/$PROJECT_NAME/default
    docker run -it -v ~/google-appengine-sdk/src/$PROJECT_NAME/default/:/app \
      -v ~/go/src:/go/src \
      -p 8080:8080 -w /app \
      zadki3l/gae-go-alpine goapp serve --host=0.0.0.0

0. プロジェクト名（sample-project）を自分のプロジェクト名にする
0. ~/google-appengine-sdk/src/$PROJECT_NAME/default/の部分はローカルサーバーのapp.yamlが含まれているディレクトリを指定する
0. ~/go/src の部分はローカルサーバーで echo $GOPATH の結果に /src を追加する  

（追記） 上記だとadmin serverにアクセスできないようです。admin serverを使用する場合は、下記のようにdev_appserver.pyを使用します。

    PROJECT_NAME=sample-project
    cd ~/google-appengine-sdk/src/$PROJECT_NAME/default
    docker run -it -v ~/google-appengine-sdk/src/$PROJECT_NAME/default/:/app \
      -v ~/go/src:/go/src \
      -p 8080:8080 -w /app \
      zadki3l/gae-go-alpine dev_appserver.py \
      --host 0.0.0.0 --admin_host 0.0.0.0 \
      --skip_sdk_update_check true app.yaml


#### B. デプロイする

    PROJECT_NAME=sample-project
    cd ~/google-appengine-sdk/src/$PROJECT_NAME/default
    docker run -it -v ~/google-appengine-sdk/src/$PROJECT_NAME/default/:/app \
      -v ~/go/src:/go/src \
      -w /app zadki3l/gae-go-alpine goapp deploy


#### C. docker環境にログインして設定を確認する

万が一エラーになるときは docker環境にログインして調べる

    PROJECT_NAME=sample-project
    cd ~/google-appengine-sdk/src/$PROJECT_NAME/default
    docker run -it -v ~/google-appengine-sdk/src/$PROJECT_NAME/default/:/app \
      -v ~/go/src:/go/src \
      -w /app zadki3l/gae-go-alpine /bin/sh
Android RXJavaでキャッシュ的な処理

# RXJavaとは
非同期処理を行うためのライブラリ。AsyncTaskやAsyncTaskLoaderの代わりに利用できる。これらよりイケてるので騙されたと思って一回使ってみると良い。Java8との相性が良いので、併用すべし。

# Androidへの導入方法
Gradleに以下の依存関係を追加する<code>
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
</code>

# 本編
データが本体になければネットから拾う、キャッシュ的な処理を実装する。
loadFromStroage()は本体からデータを取得するメソッドで、ない場合はnullが帰る。doInBackGround(callback:Callback)はダウンロードをする関数。Callbackは終了時にresultを引数とし呼ばれる。<code>
Observer.create(f->loadFromStroage())
.flatMap(res->(res!=null)?
　　Observable.just(res): //ローカルにあった
　　Observable.create(f->{ // ネットへ拾いに行く
　　　　// 終わったらonNextに結果を渡して終了
　　　　doInBackGround(result->f.onNext(result))
 })
.subscribe(//書き出す処理)
</code>


# 種明かし
逐次処理を次のように定義する。
ObservableA->ObservableBかつ、BはAの結果を利用する場合。Observable=Taskと考えてよい。
前の値を利用するようなものはmapかflatMapにする。両者の違いはObservableを戻り値にするか否か。

これを実現するには次のように行う。

```java
ObservableA
.flatMap(res->ObservableB(res))
.subscribe(//Bの結果を表示)
```
EC2 + IAM Role で供給されたクレデンシャルを環境変数として使う

## 2016-12-09 14:15 追記

EC2 上の Docker コンテナ内からでも、`AWS_` 環境変数を設定することなくインスタンスプロファイルが使えました。

AWS SDK は `AWS_*` 環境変数設定されてなかったら自動で `http://169.254.169.254/latest/meta-data/...` を叩いてクレデンシャルを取りに行きます。で、ホスト直実行でもコンテナ挟むのでもつなぎに行くネットワークは同じ AWS なので問題なくインスタンスプロファイルを取れるのでした。

したがって、この記事に書いてあるような手間をかける必要はありません…

## tl;dr

~~`AWS_SECURITY_TOKEN`~~ `AWS_SESSION_TOKEN` を忘れるな

### 2019-03-11 追記

awscli は `AWS_SECURITY_TOKEN` で実行できますが、 AWS SDK は `AWS_SESSION_TOKEN` でないと動作しないものがあるようです。
ログイン画面から発行されるワンタイムパスワードも現在は `AWS_SESSION_TOKEN` であるため、そちらに統一する方が良さそうです。

## 時代は IAM Role

EC2 上で AWS リソースにアクセスする場合、専用の IAM ユーザを作ってクレデンシャルを発行してもいいのですが、[IAM Role を EC2 に紐付ける](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)と便利です。クレデンシャルをアプリケーションコードやスクリプトに埋め込む必要がなくなるからです。

しかし awscli や AWS SDK を埋め込んだコードを__ホスト上で直に__実行する場合は彼らがよしなにクレデンシャルを取得するのでいいのですが、Docker コンテナ上で実行する場合は少々面倒です。`-e AWS_ACCESS_KEY_ID=` でクレデンシャルを渡したいのですが値はどこから取ればいいのか。

※ 今回は ECS 上ではなく[^1]、直接インスタンス上で `docker run` する場合の話です。

## metadata からクレデンシャルを取り出す

EC2 インスタンス内部から `http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>` を叩くと、いま現在有効なクレデンシャルが得られます。これを `jq` なりでパースして値だけ抜き出せばそのまま使えます。`Expiration` の時刻になったらクレデンシャルは入れ替わります。

```bash
core@ip-10-0-2-126 ~ $ curl -w '\n' http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>
{
  "Code" : "Success",
  "LastUpdated" : "2016-10-03T09:13:16Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "awsaccesskeyid",
  "SecretAccessKey" : "awssecretaccesskey",
  "Token" : "SecretToken",
  "Expiration" : "2016-10-03T15:26:54Z"
}
```

ただ、このクレデンシャルを使うには `AccessKeyId` (= `AWS_ACCESS_KEY_ID`) と `SecretAccessKey` (= `AWS_SECRET_ACCESS_KEY`) だけ抜き出すのでは足りません :cry: __`Token` (= `AWS_SECURITY_TOKEN`)__ も一緒にアプリケーション / スクリプトへ渡してあげる必要があります。

シェルスクリプトにするとこういう感じです (curl, jq 前提)。

```bash
#!/bin/bash

metadata=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>/)
export AWS_ACCESS_KEY_ID=$(echo $metadata | jq -r .AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $metadata | jq -r .SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $metadata | jq -r .Token)

docker run \
  --rm \
  -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
  -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
  -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \
  awesome:latest
```

自分はこれで数時間ハマったので、今後同じことをする人の助けになれば幸いです。

[^1]: ECS は [Task 単位で IAM Role を紐付けられる](http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-iam-roles.html)ので便利

## REF
- [一時的なセキュリティ認証情報を使用して AWS リソースへのアクセスをリクエストする - AWS Identity and Access Management](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_use-resources.html#using-temp-creds-sdk-cli)
Windows ホストの Docker コンテナにホストのディレクトリをマウント

## 環境
- windows7
- Docker Toolbox
- Docker Quickstart Tarminal

## やり方
`docker run`時のオプションとして`-v /c/Users/[host directory]:/[container directory]`を入れる．

すると，ホストの`C:Users/[host directory]`が，コンテナの`/[container directory]`にマウントされる．

### 例

```
# docker run -v /c/Users/[host directory]:/[container directory] [container]
```

## 注意
- ディレクトリ指定時，`/c/Users`の部分の c が大文字になっていたりするとマウントできない（エラーメッセージは出ない）．
- デフォルトでは`Users/`以下のディレクトリしかマウントできない．
kubernetes: 特定のコンテナ(Pod)だけ特定のホストで

kuberenetsで複数のコンテナを複数クラスタ上で運用すると、リソースの関係などで特定のコンテナ（Pod）だけ特定のホストで実行したいケースがある。

label機能を使うことで実現できる。

参照） Constraining pods to run on particular nodes
http://kubernetes.io/docs/user-guide/node-selection/


#host(minion node)にlabelを付ける

初期状態として以下のworker(minion) nodeとする

```
$ kubectl get nodes
NAME              LABELS                                   STATUS    AGE
ip-172-31-25-70   kubernetes.io/hostname=ip-172-31-25-70   Ready     1m
ip-172-31-25-72   kubernetes.io/hostname=ip-172-31-25-72   Ready     1m
```

それぞれのホストにlabelを付与する

```
kubectl label nodes ip-172-31-25-70 type=app1
kubectl label nodes ip-172-31-25-72 type=app2
```

※上書きするときは--overwrite オプションを付ければ良い。

任意のkey=value形式で、例ではtype=app1、app2とそれぞれ付与した。

以下のようにlabelが付与されていることが確認できる。

```
$ kubectl get nodes
NAME              LABELS                                             STATUS    AGE
ip-172-31-25-70   kubernetes.io/hostname=ip-172-31-25-70,type=app1   Ready     31m
ip-172-31-25-72   kubernetes.io/hostname=ip-172-31-25-72,type=app2   Ready     31m
```
※バージョンによっては `kubectl get node -L type` で確認


#Pod/RC(or Replica Set/Deployment)にlabelを付与する

yamlファイルのspecにて nodeSelectorを追記。
以下はReplication Controllerのyaml設定例。

```
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
      nodeSelector:
        type: app2
```

上記ではtype=app2のlabelを付与したホスト（ip-172-31-25-72）に限定することを意味する。

#動作確認

RCを起動して、Podが指定したホストのみで起動されることを確認。

```
$ kubectl create -f test.yaml
```

以下の通り、type=app2のlabelを付与したホスト（ip-172-31-25-72）へのみアサインされていることがわかる。

```
$ kubectl get pod -o wide
NAME          READY     STATUS    RESTARTS   AGE       NODE
nginx-5w09v   1/1       Running   0          17m       ip-172-31-25-72
nginx-mf4l7   1/1       Running   0          20m       ip-172-31-25-72
nginx-p79e9   1/1       Running   0          17m       ip-172-31-25-72
```

試しにyamlファイルのreplicasを3から5に変更してapplyすると、新たに2つのPodが追加され、かつtype=app2のlabelを付与したホスト（ip-172-31-25-72）へのみアサインされていることがわかる。

```
$ kubectl get pod -o wide
NAME          READY     STATUS    RESTARTS   AGE       NODE
nginx-5w09v   1/1       Running   0          17m       ip-172-31-25-72
nginx-mf4l7   1/1       Running   0          20m       ip-172-31-25-72
nginx-p79e9   1/1       Running   0          17m       ip-172-31-25-72
nginx-r7dmc   1/1       Running   0          20m       ip-172-31-25-72
nginx-yu0r3   1/1       Running   0          20m       ip-172-31-25-72
```
>/dev/null 2>&1は順序が逆だとダメ

# はじめに
標準出力、標準エラー出力をどちらも破棄したい場合、よく`>/dev/null 2>&1`という書き方をすると思います。これを間違えて`2>&1 >/dev/null`と書いてうまく動かなかったのですが、いまいち腑に落ちなかったので記法を詳しく調べてみました。

## まず前提知識
ハマったポイントに進む前に、いくつか前提知識を整理します。下記のサイトを参考にさせていただきました。

- [ファイルディスクリプタについて理解する](http://qiita.com/toshihirock/items/78286fccf07dbe6df38f)
- [リダイレクト コマンドの出力をファイルや別のコマンドに振り分ける (リダイレクション) ](http://x68000.q-e-d.net/~68user/unix/pickup?%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8)
- [紛らわしいけど重大な違いを引き起こすリダイレクトAdd Starblp1526](http://d.hatena.ne.jp/zariganitosh/20110623/redirect_command)
- [いい加減、>/dev/null 2>&1と書くのをやめたらどうか　(追記あり)](http://dqn.sakusakutto.jp/2012/06/shell_dev_null_2_1_crontab.html)

## ファイルディスクリプタ
まず`2>`や`2>&1`の数字について。これらの数字は、入出力インターフェースにつけられた識別番号で、ファイルディスクリプタというそうです。それぞれ下記のようになっています。

| インタフェース | ファイルディスクリプタ |
|:-------------:|:---------------------:|
| 標準入力       | 0                     |
| 標準出力       | 1                     |
| 標準エラー出力 | 2                     |

## リダイレクト
次に、`>`の記号について。`>`に続けてパスを指定することをリダイレクトといい、`>`以左のコマンドの実行結果の出力先を任意のパスに設定することができます。記法としては下記の通り。

```bash
command N>path
```

ただし、`N`は上述のファイルディスクリプタ、`command`は任意のコマンド、`path`は出力先のパス。ファイルディスクリプタで指定したインターフェースの出力を、`path`に指定したファイルに出力することができます。

ちなみに、`>`とは`1>`の省略形とみなされるため、冒頭の`>/dev/null`は標準出力を`/dev/null`に設定することを意味します。

### ※`/dev/null`について
リダイレクト時に、どのファイルにも書き出さず、画面にも表示せず、破棄したいときに指定する特殊なパス。`/dev/null`というファイルが存在しているわけではありません。

## 標準出力と標準エラー出力を同じに設定する
最後に、`&`の記号について。ファイルディスクリプタの前に`&`をつけると、「ファイルディスクリプタで指定したインターフェースに現在設定されている出力先」を表すようになります。たとえば、`&1`とすると標準出力(1)に設定されている出力先を表すようになります。

たとえば、`command 2>&1`のように指定することで、標準エラー出力(2)の出力先を標準出力(1)の出力先に設定することができます。

# ハマりポイント
## 勘違いの原因
今回`2>&1 >/dev/null`と記載して問題に気づけなかった原因は、`>`記号が矢印のように見えるためか、`command > file`の記載に対し、「`command`の出力を`file`につなげる」というイメージを持っていたためでした（パイプ`|`と同じような動きをすると勘違いしていた）。また、`&1`の表記についても、リダイレクト先に記載するときは`&`をつけなきゃいけないんだなーくらいの認識でした。


このイメージをもって、下記の記載（誤りです）を見てみると、確かに、「`command`の出力について、標準エラー出力を標準出力につなげ、さらにまとめて`/dev/null`に捨てる」...なんだかよさそうに見えてしまいます。

```bash
command 2>&1 >/dev/null
```

しかし実際のところ、`N>file`は「`N`の出力先を`file`に設定する」という意味合いですし、「`&N`は現在`N`に設定されている出力先」のことです。ここまで理解したうえで、再度上記の誤った記載を見直してみると、下記のように、まったくトンチンカンなことをしていることに気づきます。`2>&1`の時点では、まだ標準出力の出力先は画面なので、`2>&1`をしても何も起きません。

- 標準エラー出力の出力先を、標準出力に設定されているパス（ここではまだ画面）に設定する（`2>&1`）
- さらに、標準出力の出力先を、`/dev/null`に設定する（`>/dev/null`）


## 正しい表記

```bash
command >/dev/null 2>&1
```

正しい記法の場合についても、処理の流れを見直してみると、以下のようになります。

- 標準出力の出力先を、`/dev/null`に設定する。
- 標準エラー出力の出力先を、標準出力に設定されているパス（ここでは`/dev/null`）に設定する（`2>&1`）

# おわりに
と、ここまで書いたうえで、[いい加減、>/dev/null 2>&1と書くのをやめたらどうか　(追記あり)](http://dqn.sakusakutto.jp/2012/06/shell_dev_null_2_1_crontab.html)内の、下記記載を読んで再度混乱しています。

> a.txt 2>&1 と 1> a.txt 2> a.txt は意味が違う

`2>&1`は「`2`の出力先として`&1`（1の出力先と同じもの）を設定する」という理解では、上記の２つに差分ができる理由が説明できません。すんなり説明がいったような気がしていましたが、もしかしたら重大な勘違い
をしている可能性が出てきました。

今後理解が進んだ場合に、追って訂正します。
d3.js Force Simulation の世界


```javascript
var simulation = d3.forceSimulation();
```

とは、

![d3js_force_simulation.png](https://qiita-image-store.s3.amazonaws.com/0/63210/898b7b82-6695-4492-28cf-946a162799b0.png "d3js_force_simulation.png")

http://bl.ocks.org/mbostock/4062045

のような、グラフ可視化ができるシステム。リンク先を見ればコードの書き方はだいたい分かるけれども、実際に自分のデータでやってみると、いい感じになるパラメータの調整が意外と難しいので、この世界を簡単に解説する。詳しい説明は、
https://github.com/d3/d3-force

## 力あれ

### 1. 摩擦力
この世界には摩擦力があるので、動いているものはやがて止まる。

```
simulation.velocityDecay(0.01)
```

で摩擦係数を指定できる。いい感じになる前に止まってしまう場合は小さく、ふらふら動き続けて困る場合は大きくする。デフォルトは 0.4.

### 2. 重力

アリストテレスの重力よろしく、世界の中心に落ちていく力 `d3.forceCenter`。

```javascript
simulation.force("center", d3.forceCenter(width / 2, height / 2))
```

一点ではなくて一直線上に落ちていくようにしたい場合は `d3.forceX(x)` `d3.forceY(y)` がある。

### 3. バネ

いわゆるフックの法則。グラフの edge/link/枝が `distance` よりも長い場合はその伸びに比例して引っ張られ、短い場合は押し合う。力は `strength` で指定できるが、2より大きい値を入れるとなぜか爆発する。


```javascript
simulation.force("link", d3.forceLink().id(function(d) { return d.id; }))

simulation.force("link")
          .links(graph.links)
          .distance(function(){ return 10;})
          .strength(function(){ return 2; })
```

### 4. クーロン力／万有引力

```javascript
simulation.force("charge", d3.forceManyBody())

simulation.force("charge")
          .strength(function() { return -0.1; })
```

`strength` に負の数を入れると互いに反発して、正の数だと引かれ合う。

### 5. 接触力

```javascript
d3.forceCollide([radius])
```

グラフの vertex/node/頂点 が半径 `radius` の球のようにぶつかるようになる。

## 固定

```javascript
node0 = simulation.nodes()[0]
node0.fx = x;
node0.fy = y;
```

`node0` を (x,y) に固定する。

## alpha

`alpha` というのは砂時計のようなもので、時間とともに減っていって、何ステップ世界が動くかを司る。

```javascript
simulation.alpha([alpha])  // = 1
simulation.alphaMin([min]) // = 0.001
simulation.alphaDecay([decay]) // = 0.0228 = 1 - pow(0.001, 1/300)
simulation.alphaTarget([target]) // = 0
```

１ステップで（単位時間あたり）速度が摩擦力で

```R
velocity <- velocity * velocityDecay
```

だけ減少して、alpha が、

```R
alpha <- alpha + (alphaTarget - alpha) * alphaDecay
```

になる。`alpha` が `alphaMin` を下回ると止まり、デフォルトのパラメタでは300ステップに相当する。なぜこんなパラメタなのかわからないけれども:

* `alpha` は `alphaTarget` に漸近する。
* よって、`alphaTarget` が `alphaMin` 以上だと止まらない。
* alphaDecay が大きければ少ないステップでalphaTargetに近づいて止まる。


# 例
将棋の序盤をグラフしてみたけれども、はみだしたりしてなかなか思うようにいかない...
https://junkoda.github.io/kyokumen/graph/2016_1.html
unlessの評価がいつとまるのか慣れてないので苦戦すると思って冷静に試してみると...

## `全部OR`なら`true`が来たら評価がとまって実行されない

```rb
def hoge
  puts :hoge
  false
end

def foo
  puts :foo
  true
end

def bar
  puts :bar
  true
end

unless hoge || foo || bar
  puts :a
end
```

結果：

```
hoge
foo
```

## `全部AND`なら`false`が来たら評価がとまって実行される

```rb
def hoge
  puts :hoge
  true
end

def foo
  puts :foo
  false
end

def bar
  puts :bar
  true
end

unless hoge && foo && bar
  puts :a
end
```

結果：

```
hoge
foo
a
```

よくよく見ると評価がとまるの`if`のときと同じか。。。

とはいえ、ややこしいので ベストプラクティスとしては、 `unless`で`&&`や`||`を使ってはいけない。混乱しやすい。
プロデルで今日も1日がんばるぞい！

[プロデル](http://rdr.utopiat.net/)で今日も1日がんばるぞい！
日本語プログラミング言語でネタプログラムを作ってみました。
普通に書くと面白くないので、変数名に作品に登場するキャラクタ名を使っています。~~シュールです。~~

```プロデル:今日も1日がんばるぞい！.rdr
コウちゃんは、{{「今日」,「ぞい」},{「も」},{「1」,「ぞい」},{「日」,「ぞい」},{「がん」,「ぞい」},{「ばる」,「ぞい」},{「ぞい！」}}
りんちゃんを増やしながら『
	青葉ちゃんは、{}
	ねねちゃんを1から7まで増やしながら『
		青葉ちゃんにコウちゃん(ねねちゃん,1から2までの乱数)を加える
	』ことを繰り返す
	青葉ちゃんを繋げたものを出力する
	改行を出力する
	もし青葉ちゃんを繋げたものが「今日も1日がんばるぞい！」なら繰り返しから抜け出す
』ことを繰り返す
「☆がんばるまで [りんちゃん] zoiでした☆」を出力する
改行を出力する
```

目的の文字列が生成されるまで、文字列を生成し、ループします。
可変長配列に、ランダムに選んだ文字列を挿入して「繋げる」ことで目的の文字列を作ります。
日本語で書くプログラムの雰囲気を楽しんで頂けたら嬉しいです。

##実行結果
[Web版プロデル](http://rdr.utopiat.net/play/)または[デスクトップ版](http://rdr.utopiat.net/files/index.html)で動かせます。

![qiitazoi.png](https://qiita-image-store.s3.amazonaws.com/0/101225/8dfdbe9f-4d18-f59c-d9d3-706ff58694da.png)

##元ネタ
[今日も1日がんばるぞい！](http://qiita.com/giiko_/items/8c3442e8e7a83cc0b91a)
[atom] テキストが合字(リガチャ)されてコードのインデントが崩れる問題

動機
--
atomが合字(リガチャ)をサポートしたことにともなって, `fi`, `ft`のような文字を入力した場合に1文字幅で扱われる.
そのため, それ以降の同じ行の文字がリガチャをサポートしない環境でみたときに, エディタ上での表示から1文字分ずれた状態になる.
これにより, 複数行のコードで, コードの整形を行った場合などに, コードが意図したとおりに整形されないことがおきた.

解決方
--
リガチャのサポートを無効にすることで, 問題を回避することができる. <https://github.com/atom/atom/issues/3821#issuecomment-249427387>

```less:~/.atom/styles.less
atom-text-editor {
  -webkit-font-feature-settings: "liga" off, "calt" off;
}
```
angular-cliでfont-awesomeを使う方法

angular-cliでfont-awesomeを使ったときのメモ

# 事前準備
angular-cliでプロジェクトを作成する。(angular-cliのインストールとかは省略)
```
$ ng new fontawesome-example --skip-git
$ cd fontawesome-example
```

# font-awesomeのインストール
```
$ npm install -save font-awesome
```

# angular-cli.jsonの編集
``` diff:angular-cli.json
{
  ...
  "apps": [
    {
      ...
      "styles": [
+       "../node_modules/font-awesome/css/font-awesome.css",
        "styles.css"
      ],
      ...
    }
  ],
  "addons": [
+   "../node_modules/font-awesome/fonts/*.+(otf|eot|svg|ttf|woff|woff2)"
  ],
  ...
}
```

# 使ってみる
```diff:src/app/app.component.html
<h1>
+ <i class="fa fa-user" aria-hidden="true"></i>
  {{title}}
</h1>
```

# 起動
```
$ ng serve
```
localhost:4200にアクセスしてみる。

![20161003_162147_0000.png](https://qiita-image-store.s3.amazonaws.com/0/83747/048e6352-d312-cffa-534f-9716392eeb42.png)

以上！
Talendを1から使ってみるサイトまとめ


#Talendサイトまとめ
実行環境やら、インストール方法やら、メリット・デメリットは、以下参照しました。

インストール方法から、基本、応用編まで一通りそろっている
[ETLツール「Talend Open Studio」を使ってみる　紹介編](http://recipe.kc-cloud.jp/archives/6934)

こちらもインストール方法から、一通りまとまっている
[Talend Open Studio によるビッグデータ分析](http://www.gixo.jp/blog/4859)

Talendのスキーマに、日本語が使えなかったので、使えるようにする
[Talend Open Studio スキーマのカラム名に日本語を使用する ](http://talend-jp.jinaka.com/talend-open-studio-metadata-creation/post-468.html)

かゆい時に手が届きます。実体験の例が貴重。
[【Talend】使い方メモ](http://qiita.com/kazu56/items/b089ded9af884426f008)

Talendで避けて通れない、コンポーネントの紐付けについて
[[Talend] Flow, Iterate, Trigger についてのまとめ](http://dev.classmethod.jp/talend/flow-iterate-trigger/)

Talendは有償版、OSS無料版がある。ライセンスが気になる時に
[よくある質問](https://www.air.co.jp/tal/faq/02-2/)

トランザクション処理、夜間バッチの参考
[DB間のデータコピーを2つのコンポーネントだけで行う](http://www.gixo.jp/blog/4874)

Talendの活用シーン
[Talendの活用シーン](http://www.air.co.jp/tal/)

[Talendでディレクトリの中にある一番最新ファイルを取得する方法](http://dev.classmethod.jp/talend/get_most_recent_file/)

開発環境、実環境でファイルパスなどを変えたい時に
[[Talend] 実行時にコンテクストパラメータを変更する方法](http://dev.classmethod.jp/talend/talend-change-context-parameters/)

#その他
SQLServerに繋げる時、インスタンスがSQLEXPRESSの場合、追加パラメータを記述する必要あり。
instance=sqlexpress
iOS 10で追加されたAVPlayerLooperを使ってシームレスにビデオをループ再生

# iOS 10 でAvPlayerLooperが追加
iOS 10からAVPlayerLooperが追加されて、ループ再生をかんたんに実現することができるようになりました。

試してみる前に、まずはWWDC 2016のビデオを観るのがおすすめです。ループ関連の説明は13:00からはじまります。

- [Advances in AVFoundation Playback - WWDC 2016 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2016/503/)

iOS 9でも、AVQueuePlayerを工夫して使えばシームレスなループ再生ができましたが、いろいろと面倒でした。iOS 10からはAVPlayerLooperを使えば、シンプルな実装でシームレスなループ再生を実現できます。

試しに、Appleが提供しているサンプルプログラムを動かしてみるのが分かりやすいです。AVPlayerLooperと、AVQueuePlayerを使った場合のそれぞれの実装を比較することができます。

- [AVFoundation Looping Player: Using AVQueuePlayer and AVPlayerLooper to demonstrate loop playback ](https://developer.apple.com/library/prerelease/content/samplecode/avloopplayer/Introduction/Intro.html)

AVPlayerLooperを使うと、startTime秒からendTime秒までループしたい場合は、以下のようなコードを書くだけでOK。

```swift
let asset = // AVAsset with its 'duration' property value loaded
let playerItem = AVPlayerItem(asset: asset)
 
// Create a new player looper with the queue player and template item
playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem)

let timescale = playerItem.duration.timescale
let start = CMTime(seconds: startTime, preferredTimescale: timescale)
let end = CMTime(seconds: endTime, preferredTimescale: timescale)
let timeRange = CMTimeRange(start: start, end: end)

// Create a new player looper with the queue player, template item, and time range     
playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem, timeRange: timeRange)
 
// Begin looping playback
queuePlayer.play()
```

# ちょっと困ること

1つ気をつけないといけないのが、ループ範囲を設定すると、再生位置が自動的にループの開始位置にシークされてしまうこと。

- [init(player:templateItem:timeRange:) - AVPlayerLooper | Apple Developer Documentation]( https://developer.apple.com/reference/avfoundation/avplayerlooper/1643626-init)

> Time range looping will be accomplished by seeking to the time range’s start time and setting player item’s forwardPlaybackEndTime property on the looping item replicas.

この仕様、場合によっては困ります。例えば、曲のA-B区間をループ再生中に、ループ区間を解除してそのまま通常再生を続けたい場合、この仕様だと、ループを解除すると、曲の先頭に勝手にシークされてしまいます。

回避策として、ループ解除前に、現在の再生位置を保存しておいて、ループ区間を解除した後に、保存しておいた再生位置にシークし直せばいいのですが、どうしても不連続になるので、ビデオとオーディオが途切れてしまいます。

この点について、Apple Bug Reporter経由で問い合わせてみたのですが、AVQueuePlayerをベースにしているため現状の仕様とのこと。改善を検討します、とは言っていましたが、まぁきっとすぐには実現されないでしょう。

# 実装例

私が開発しているPlaySectionsのバージョン2.0.0でビデオ再生機能を追加したのですが、その際にAVPlayerLooperを使ってループ機能を実装しました。興味ある方はお試しください。

- [PlaySections](https://itunes.apple.com/jp/app/id1032204861)
[macOS] 超速！10分間で、テキストエディタを作る。Storyboard版。

###**前置き**###
前回、テキストエディタをサンプルとして、Document Based Applicationを作成する話をしましたが、それの**Storyboard版**です。私は、アプリケーション開発の目標として、日本語専門の、縦書きワードプロセッサを考えています。その第一のコンセプトは、フルスクリーンモードで、Macのディスプレイサイズが大きかろうが小さかろうが、一画面に表示する文字数とレイアウトは、常に同じにしたいと考えています。なので、編集モード、ドラフトモード、環境設定ダイアログなどは、別ウインドウを開くのではなく、画面遷移で実装することになるでしょう。ならば、Storyboardによる編集は、必然になると思われます。
###**Xcodeで編集開始**（ここから10分間）###
(1) Xcode 8で、新規プロジェクトを作成します。テンプレートは、macOSのCocoa Applicationです。
(2) プロジェクト設定で、**Use Storyboards**と、**Create Document-Based Application**にチェックを入れます。今回は、プレーンテキストを保存するテキストエディタを作成するので、Document Extension（拡張子）をtxtとします。

<img width="267" alt="option.png" src="https://qiita-image-store.s3.amazonaws.com/0/140894/1d618ddf-7475-68cc-6086-5f6c99df9fa3.png">

(3) **Main.storyboard**を開きます。View ControllerにText Viewを貼り付けます。Text Viewを、**ViewController.swift**の**@IBOutlet var textView: NSTextView!**にコネクトします。
(4) **Document.swift**を開きます。下のように編集します。テンプレートに対して、新規に追加したコードを、`// ↓↓↓↓↓↓`と`// ↑↑↑↑↑↑`で挟んで、示しています。

```swift:Document.swift
import Cocoa

class Document: NSDocument {
    
    // ↓↓↓↓↓↓
    var viewController: ViewController?
    var text: String?
    // ↑↑↑↑↑↑

    override init() {
        super.init()
    }

    override class func autosavesInPlace() -> Bool {
        return true
    }

    override func makeWindowControllers() {
        let storyboard = NSStoryboard(name: "Main", bundle: nil)
        let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as! NSWindowController
        self.addWindowController(windowController)
        
        // ↓↓↓↓↓↓
        viewController = windowController.contentViewController as? ViewController
        if let viewController = self.viewController, let text = self.text {
            viewController.textView.string = text
        }
        // ↑↑↑↑↑↑
    }

    override func data(ofType typeName: String) throws -> Data {
        // ↓↓↓↓↓↓
        text = viewController?.textView.string
        if let data = text?.data(using: .utf8) {
            return data
        }
        // ↑↑↑↑↑↑        

        throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
    }

    override func read(from data: Data, ofType typeName: String) throws {
        // ↓↓↓↓↓↓
        if let text = String(data: data, encoding: .utf8) {
            self.text = text
            return
        }
        // ↑↑↑↑↑↑
        
        throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
    }

}
```

前回は、コードに対する説明を省きましたが、すこしだけ説明をつけておこうと思います。
Text Viewのテキストを、ファイル保存するのは、`data(ofType typeName: String) throws -> Data`で行いますが、逆にファイルを開いて、Text Viewのテキストに入力するのは、ファイル読み込みのメソッド`read(from data: Data, ofType typeName: String) throws`で行うわけではないことに、注目してください。このメソッドが実行された時点では、まだウインドウが開いていないので、Text Viewのテキストに代入しようがないのです。そこで、いったんプロパティ`text: String?`に代入しておいて、ウインドウを開くメソッド`makeWindowControllers()`にて、Text Viewのテキストに代入します。
プログラミングするように文章を書く

#きっかけ
文章を書く能力ない。
簡単なメール作成に、３０分かかる。
誤字脱字がある。
結局、何が言いたいかわからない。

こんなことを指摘される事がある。

正しい文章を書けるようになりたい。こんな理由から、
[大人のための書く全技術](https://www.amazon.co.jp/%E5%A4%A7%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E6%9B%B8%E3%81%8F%E5%85%A8%E6%8A%80%E8%A1%93-%E9%BD%8B%E8%97%A4-%E5%AD%9D/dp/4046012331)
を読みました。
この本の中にあるセンテンスで、
「最初に最後の文章を決めて、次にタイトルを決めよう」
というセンテンスがありました。

あぁこれって、プログラミングと同じかも
と思い、この記事を書くことにしました。

#プログラミングのように文章を書く
プログラミングにおいて、関数を作成する場合、
関数が "何をするもの" かを決めてから、
”関数名” を決めて、
"内容" を書いていきますよね。

例えば、
この関数は、"存在するかどうかを戻り値として返す" を作成すると決めてから、
関数名 "IsExist" を決めて、"内容"を書いていきます。

関数の"内容"を書き終わってから、
さて関数名を何にしようか、、、存在チェックしてるから、"IsExist"にしようっと。
と書く人は少ないと思います。

つまり、
プログラミングが出来る人は、
文章を書くコツの１つとして、
プログラミングするように文章を書いてみてはどうだろうか。

#文書作成とプログラミングの相関関係
この段階に至って、調べてみると同じように感じている人は多いようだ。
[国語力とプログラミング力の関係](http://www.atmarkit.co.jp/ait/articles/0903/18/news121.html)
[プログラミングと文章を書くこと](http://gothedistance.hatenadiary.jp/entry/20081203/1228295950)

"あなたは、たった1つの短い文を正しく書けるか？"

#国語力、プログラミング力
「どちらも並行して、伸ばしていこう。」

説得力に欠ける文章になってしまった。。。ただ、
この一文を言いたくて書き始めましたよｗ
[Cloud102]#0-1 (補足)環境準備: Bash on Windows

本コンテンツは、以下の補足資料です。

[Cloud102]#0 環境準備
http://qiita.com/nagahisa/items/c6bd92992eef42dbe53a

なお、設定手順・キャプチャはすべてWindows10 1607用です。

#AGENDA

0.はじめに
1.WindowsからのSSHアクセス
2.Bash On Windows環境作成
3.SSHアクセス確認
4.Bash on Windowsのおまけ

#0. はじめに

Macbook持っていなくても、iPad(4G)使ったSSHアクセスが確認できます。
ただ操作性を考えるとBT Keyboardを用意するか、キーボード付きPCでSSHアクセスできないとかな〜り厳しいです。
ここでは持っている人が多い Windows NotePCでのSSHアクセス方法をいくつか紹介し、その中の１つを少しだけ深堀します。

#1.WindowsからのSSHアクセス

##(1)SSHアプリケーション

・Windows環境からのSSHは、TeraTermやPutty(HOL標準)などのアプリケーションを使うやり方が旧来からの方法です。
・鍵ファイルの扱い方がアプリによって異なるので留意してください。

参考：http://dev.classmethod.jp/cloud/aws/aws-beginner-ec2-ssh/

##(2)SSHコマンド

・WindowsでもSSHコマンドが使えるようになっています。
これは、[Cloud101]#3 1.(2)でも取り上げました。
http://qiita.com/nagahisa/items/d20c267cbd0d7dea7676

こちらが元ネタです。
http://dev.classmethod.jp/cloud/aws/win32-openssh-was-released/

##(3)Bash on Windows

・Windows10 1607から利用可能になった Bash on Windowsはまだベータ版ながら非常便利です。
・"Bash on Windows"は、WSL(Windows Subsystem for Linux)という環境で動くLinux(Ubuntu)なので、一部制約はあるもののUbuntuバイナリがうごく「本物のLinux環境」です。
・今後のCloud102コースで行うハンズオンを AWS VM使わなくても実習できます。(個人Windows PCをネットに繋げられない社内環境でも勉強できます :smile: ）

#2.Bash On Windows環境作成

この環境作成は自宅など安定したネット環境で行ってください。テザリング環境なんかでやるとすぐにパケ死します。

##(1)CoEmu導入（オプション）

・"Bash on Windows"は cmd.exe (Windowsコマンドプロンプト）経由で利用しますが、cmd.exeに問題が多いので使いやすくするアプリケーションです。
cmd.exeでも動きますが、日本語画面表示がずれるなど、ちょっとイケテナイです。

・以下参考に導入します。
https://github.com/Maximus5/ConEmu


##(2)Bash on Windows導入

たくさんのネット情報がありますが、信頼できるClassMethodさんのブログにも記述あります。
この記事は "Bash on Windows"でAWSCLIを使う例ですので、Macbook持ってない方も、「Cloud102 #0-2 (補足)環境準備: AWS CLI」がそのまま試せます。

http://dev.classmethod.jp/cloud/windows-10-bash-aws-cli/

##(3)Bash on Windowsの起動

・cmd.exeの代わりにConEmuを起動します

![001.PNG](http://qiita-image-store.s3.amazonaws.com/0/79389/24773469-9ed8-08a2-d6a8-5b4d7a45feb1.png)

・ConEmu操作はcmd.exeと同じです。
![002.PNG](http://qiita-image-store.s3.amazonaws.com/0/79389/d2e4cdf7-48a6-2b2d-d96f-25c1cf278895.png)

・bashコマンドでUbuntu環境に入れればOKです。
![003.PNG](http://qiita-image-store.s3.amazonaws.com/0/79389/3e831efb-45a9-fb3a-d1f3-e0e785c8b409.png)

#3.SSHアクセス確認

環境ができたら、本編で作成したAWS VMに SSHアクセスしてみましょう。

・ここではWindowsの"kenzo"ユーザのDownloadフォルダにある秘密キーを ~/.sshディレクトに格納しています。
・SSHコマンドで秘密キーを指定してAWS VMにSSHアクセスします。
![005-edit.png](http://qiita-image-store.s3.amazonaws.com/0/79389/6714f688-724b-4927-c001-8f9c216f749c.png)

#4.Bash on Windowsのおまけ

AWS VMアクセスが確認できたら、Bash on Windowsに戻ってちょっと触ってみましょう。

##(1) Python/perlはあります。他はapt-getで。
Python2.7.6が入ってます。当面これで十分です :smile: 
![006.PNG](http://qiita-image-store.s3.amazonaws.com/0/79389/1e29b7ff-ebe6-041d-b4b2-abff77d74abb.png)
その他のツールもLinuxのお作法(Ubuntu apt-getとか）で簡単に導入できます。

##(2)pingなどはできません。でもネットワーク関連ツールは使えます。
2016/10/2時点でまだ pingなどは使えません。でもちゃんとネットワーク関連ツールは使えます。
![007.PNG](http://qiita-image-store.s3.amazonaws.com/0/79389/f3004ff9-abff-30ef-5abd-fd03f1440395.png)

##(3)python ワンライナーWebサーバ
いつも動作確認に使っている、pythonワンライナーWebサーバもちゃんと動きます。

![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/79389/4339dc92-6573-348e-e2dc-54a5548b0e5e.png)

Enjoy! :tada:
[Swift] UIViewから親のViewControllerを取得するためのExtension

# Problem

- UIViewから、自分を配置しているViewControllerを取得する

# Solution

以下のようにUIViewのprotocol extensionを作成する

```UIView+Extension.swift

extension UIView {
    var parentViewController: UIViewController? {
        get {
            var parentResponder: UIResponder? = self
            while true {
                guard let nextResponder = parentResponder?.next else { return nil }
                if let viewController = nextResponder as? UIViewController {
                    return viewController
                }
                parentResponder = nextResponder
            }
        }
    }
}
```



# Reference

- [How do you access a UIViewController function from within a UICollectionCell?](http://stackoverflow.com/questions/26965691/how-do-you-access-a-uiviewcontroller-function-from-within-a-uicollectioncell)
NotNull宣言したプロパティは文字列リテラルの中でOptionalになる

まずは普通に

```swift

class Model {
  var value: Int
  init(value: Int) {
    self.value = value
  }
}

let model = Model(value: 0)
print("\(model.value)")

```

結果は
`0`

ではプロパティを明示的にNotNullと宣言する

```swift

class Model2 {
  var value: Int!
  init(value: Int) {
    self.value = value
  }
}


let model = Model2(value: 0)
print("\(model.value)")

```

結果は

`Optional(0)`

#追記


```
Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38)
Target: x86_64-apple-macosx10.9
/Applications/Xcode8.app/Contents/Developer/usr/bin/lldb "--repl=-target x86_64-apple-macosx10.9 -enable-objc-interop -sdk /Applications/Xcode8.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -color-diagnostics"
Welcome to Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38). Type :help for assistance.
  1> class Model2 {
  2.   var value: Int!
  3.   init(value: Int) {
  4.     self.value = value
  5.   }
  6. }
  7.
  8.
  9. let model = Model2(value: 0)
 10. print("\(model.value)")
Optional(0)
```

```
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
Target: x86_64-apple-macosx10.9
/Applications/Xcode.app/Contents/Developer/usr/bin/lldb "--repl=-target x86_64-apple-macosx10.9 -enable-objc-interop -sdk /Applications/Xcode8.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -color-diagnostics"
Welcome to Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29). Type :help for assistance.
  1> class Model2 {
  2.   var value: Int!
  3.   init(value: Int) {
  4.     self.value = value
  5.   }
  6. }
  7.
  8.
  9. let model = Model2(value: 0)
 10. print("\(model.value)")
0
```


Swift3からみたい
QString で long double を扱う

# 概要

QString は int, double 等に対応する変換のメソッドがあります(number,setNum,arg,toInt,...)。
しかし、long double はプリミティブ型にも関わらず変換メソッドが用意されていません。
こういった場合は、std::string を経由することで変換できます。

# 例

## long double → QString

```cpp

#include <sstream>
#include <QString>

QString to_qstring(const long double value)
{
  std::stringstream ss;
  ss << value;

  return QString::fromStdString(ss.str());
}
```

## QString → long double


```cpp

#include <sstream>
#include <QString>

long double to_long_double(const QString & str)
{
  std::stringstream ss(str.toStdString());
  long double value;
  ss >> value;

  return value;
}
```

# 補足：C++11以降の場合

C++11 以降であれば、std::stringとの変換メソッドがあります(std::to_string, std::stold)。
そのため、std::stringstream なしに変換できます。

## long double → QString

```cpp

#include <string>
#include <QString>

QString to_qstring(const long double value)
{
  return QString::fromStdString(std::to_string(value));
}
```

## QString → long double


```cpp

#include <string>
#include <QString>

long double to_long_double(const QString & str)
{
  return std::stold(str.toStdString());
}
```


# 参考資料

1. [c++ - long double to string - Stack Overflow](http://stackoverflow.com/questions/2326850/long-double-to-string)
1. [C++11メモ @ std::to_stringで数値から文字列に変換 - ラーメンは味噌汁](http://ramemiso.hateblo.jp/entry/2013/09/05/205206)
1. [C++11メモ @ 文字列から浮動小数点値への変換 - ラーメンは味噌汁](http://ramemiso.hateblo.jp/entry/2013/09/05/221123)
1. [stringstream - C++ Reference](http://www.cplusplus.com/reference/sstream/stringstream/)
忘れないでね、railsでアプリの作成方法

```
rails _4.2.2_ new ohgiri_app
```
rails newの間でバージョン指定できる。便利って誰かが言ってた。
どれぐらい便利なのかはまだ体感していない。
便利だなと感じたその時、俺は成長したということなのだろう。
【論文シリーズ】3Dの像を畳み込みNNで学習する

## 原文
[人間の行動認識のための3次元CNN (3D Convolutional Neural Networks for Human Action Recognition)](http://goo.gl/SlrkES)
Shuiwang Ji (2013)


## 1. 要約／背景
* CNNの3Dの人間の動きを学習させた点がこの論文の差別化の点である。これまでは、2Dの特徴抽出がある程度コントロールされたデータの使用が関の山だった。


## 2. 骨子の理論
### (1)3DCNNの畳込み層の一般的な定式化
m番目のフィルタリングによって、$(i-1)$層のフィルタポジション$(p,q,r)$が$i$層の映像$(x,y,z)$に与える影響を一般的に表現すると、次のようになる。

```math
v_{i,j}^{xyz} = \tanh \Big( b_{ij} + \sum_{m}\sum_{p=0}^{P_i-1}\sum_{q=0}^{Q_i-1}\sum_{r=0}^{R_i-1}w_{ijm}^{pqr}v_{(i-1)m}^{(x+p)(y+q)(z+r)} \Big)
```


3Dの畳み込みの方法にも、特徴がある。
2Dでは、1方面の情報のみ畳み込んでいたが、3Dでは、様々な角度から捉えた情報を系列的に取り込んで、それを次の層に抽出していく（下図）。

![151207223622_2.JPG](https://qiita-image-store.s3.amazonaws.com/0/127228/dcde1312-3b3f-e1fe-42a3-6b72ed660cb8.jpeg)




## 3. モデル適用例
**HMAX**という動画サンプルの分類を行った。
6種類の人間の動きを分類するものだが、識別率はトップレベルに拮抗するものの目覚ましい違いが出る感じではなかった。

![151207223623_3.JPG](https://qiita-image-store.s3.amazonaws.com/0/127228/aa96780a-7aef-da5f-946c-a8d3ed2e0f3d.jpeg)
【論文シリーズ】貪欲法による事前学習で深層学習の精度を上げる

## 原文
[教師なし多段特徴学習による学習歩行者検知 (Pedestrian Detection with Unsupervised Multi-Stage Feature Learning)](http://goo.gl/pDztX4)
Pierre Sermanet (2013)

## 1. 骨子の理論
(1)教師なし学習
学習の骨子は畳み込みニューラル・ネットワーク（CNN）である。
ただし、事前に教師なし学習で、層を積み上げている点に特徴がある。
このような事前学習の方法を**貪欲法** (Greedy Method) という。
単層の学習器には、スパース正則化自己符号化器を用いる。

これらを合わせて、**畳込み予測スパース分解モデル**(Convolutional Predictive Sparse Decomposition; CPSD)と総称される。

パラメータの更新は、誤差項と正則化項の重ねあわせで評価される。

```math
f(x;g,k,b) = \tilde z = \{ \tilde z_j \}_{j = 1..n} \\
\tilde z_j　 = g_j \times \tanh(x \otimes k_j + b_j)
```

CPSD誤差関数は、畳込み項と予測項の重ねあわせである。

```math
\mathbb{E}_{CPSD} = \mathbb{E}_{ConvSC} + \beta\mathbb{E}_{Pred} \\
\mathbb{E}_{ConvSC} = \big\| x - \sum_{j} D_j \big\|_{2}^2 + \lambda \| z\|_1 \\
\mathbb{E}_{Pred} = \| z^{*} - f(x;g,k,b) \|_{2}^2 
```


自己符号化器の出力は、元の入力項との誤差で評価される。

```math
\mathbb{E}_{ConvSC} = \sum_{i}\big\| x_i - \sum_{j \in \bar P _i} D_{i,j} \otimes z_j\big\|_{2}^2 + \lambda \| z\|_1 \\
```
※サンプリング法にブートストラップ法を用いる。負の項目も満遍なく付加して、学習効率を高めるためである。


## 3. モデル適用例
**INRIA**という歩行者のデータセットを用いて誤差率を測定した。
教師ありのみ、かつ単層の学習では、誤差率23.4％、に対して、教師なしかつ多層の学習では、誤差率10.6％に改善した。
RubyでECHONET Lite家電を制御する

# はじめに
ECHONET Lite は家電製品をネットワークで制御するプロトコルです。
今回はRubyでシンプルなECHONET Liteの制御プログラムを載せます。
※ECHONET Lite（ISO/IEC 14543-4-3）国際規格

やりたいことは
1. 家電製品のON,OFF制御
2. 家電機器の動作状態の取得

対象者は
「ECHONET Liteって何ができるの？」「とりあえず動かしてみたい」って人向けです。
※もちろん規格書みたいな堅苦しいことは書きません

# 環境
●　空気清浄機（ECHONET Lite対応）
　　　⇒　[Sharp KI-EX100](http://www.sharp.co.jp/kuusei/products/kiex100.html)
●　Windows
●　Ruby v2.2.4

#1. 家電製品のON,OFF制御
上記の空気清浄機のON, OFF制御を行うサンプルコードです。
「[ECHONET Lite入門 スマートハウスの通信技術を学ぼう!](https://www.amazon.co.jp/ECHONET-Lite%E5%85%A5%E9%96%80-%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%8F%E3%82%A6%E3%82%B9%E3%81%AE%E9%80%9A%E4%BF%A1%E6%8A%80%E8%A1%93%E3%82%92%E5%AD%A6%E3%81%BC%E3%81%86-%E6%9D%89%E6%9D%91-%E5%8D%9A/dp/4274506320)」 を参考にしています。

ip = "192.168..." のところはご自身の環境に合せて記入してください。
## 動作状態をONにする

```ruby:send.rb
require "socket"

#空気清浄機のIPアドレス
ip="192.168.2.166"

msg=[
0x10,0x81,
0x00,0x00,
0x05,0xFF,0x01,
0x01,0x35,0x01,
0x61,0x01,
0x80,0x01,
0x30
].pack("C*")

u = UDPSocket.new()
u.connect(ip,3610)
u.send(msg,0)
u.close

```

##動作状態をOFFにする


```ruby:send.rb
require "socket"

//空気清浄機のIPアドレス
ip="192.168.2.166"

msg=[
0x10,0x81,
0x00,0x00,
0x05,0xFF,0x01,
0x01,0x35,0x01,
0x61,0x01,
0x80,0x01,
0x31
].pack("C*")

u = UDPSocket.new()
u.connect(ip,3610)
u.send(msg,0)
u.close
```

変わったのは　msgの配列の中身で(13行目)
*0x30*   ⇒　　*0x31*
になっただけです。

## 空気清浄機以外の家電を動かしたかった場合
今回は例として空気清浄機を上げましたが、
エアコンや照明をON,OFF制御したい。。。
って場合があると思います。

そんな時は以下のところを変更してください

```
#空気清浄機のOFF制御
msg=[
0x10,0x81,
0x00,0x00,
0x05,0xFF,0x01,
0x01,0x35,0x01,
0x61,0x01,
0x80,0x01,
0x31
].pack("C*")

```

```
#エアコンのOFF制御
msg=[
0x10,0x81,
0x00,0x00,
0x05,0xFF,0x01,
0x01,0x30,0x01,
0x61,0x01,
0x80,0x01,
0x31
].pack("C*")
```

```
照明のOFF制御
msg=[
0x10,0x81,
0x00,0x00,
0x05,0xFF,0x01,
0x02,0x90,0x01,
0x61,0x01,
0x80,0x01,
0x31
].pack("C*")

```
変わったのは10行目の

空気清浄機の場合
*0x01,0x35,0x01,*　
       ↓
エアコン
*0x01,0x30,0x01,*
照明
*0x02,0x90,0x01,*

だけです。

# 2. 家電機器の動作状態の取得
空気清浄機の動作状態を取得したいと思います。
今回の場合はわかりやすいように、
*状態取得のリクエストを送信するプログラム*と
*受信プログラム*
に分けたいと思います。

##送信プログラム
※先ほどのコードと少し変わっています！

```ruby:send.rb
require "socket"

#空気清浄機のIP
ip="192.168.2.166"

msg=[
0x10,0x81,
0x00,0x00,
0x05,0xFF,0x01,
0x01,0x35,0x01,
0x62,0x01,
0x80,0x00
].pack("C*")

u = UDPSocket.new()
u.connect(ip,3610)
u.send(msg,0)
u.close
```

##受信プログラム
```ruby:receive.rb
require 'socket'
udps = UDPSocket.open()
port = 3610

udps.bind('0.0.0.0',port)
loop do
  data = udps.recv(65535).chomp
  puts data.unpack("H*")
end
udps.close
```
うまいこといけば以下の文字列が表示されるはず!!

ONの時
1081000001350105ff017201800130
OFFの時
1081000001350105ff017201800131

##受信できなかったときの原因
1. 空気清浄機以外の家電でやろうとしている
⇒　上記のサンプルコードは空気清浄機を対象にしています。1の制御プログラムの時にやったmsg内を変更する要領やってくだい
2. ファイアーウォールの設定　　
⇒　ECHONET Liteはポート3610　を使用してます。
ファイアーウォールで3610ポートをブロックしていると機器からのパケットが受信できないのでポートの開放をしてください。


# 参考資料
1.  [ECHONET Lite入門 スマートハウスの通信技術を学ぼう!](https://www.amazon.co.jp/ECHONET-Lite%E5%85%A5%E9%96%80-%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%8F%E3%82%A6%E3%82%B9%E3%81%AE%E9%80%9A%E4%BF%A1%E6%8A%80%E8%A1%93%E3%82%92%E5%AD%A6%E3%81%BC%E3%81%86-%E6%9D%89%E6%9D%91-%E5%8D%9A/dp/4274506320)
2.  [HEMS(ECHONET Lite)認証支援センター](http://sh-center.org/)
Rubocopで設定に違反するコードを直してhubでプルリクエストを出す

Rubocopは`--auto-fix`というオプションがあって、これを使うと違反を自動で直してくれます。Rubocopが警告できる違反の全てが直るわけではないですが、結構直ります。

これを自動化して定期実行すると一定レベルのコードの治安が担保され、より心穏やかに開発できます。弊社では下記のようなシェルスクリプトをJenkinsから実行して、定期的にプルリクエストを出しています。

```bash
bundle exec rubocop --auto-correct $(git ls-files | grep -E -v "^(db|bin)" | grep "\.rb$") || true
git diff --exit-code && exit 0
git add .
timestamp=`date +'%Y%m%d%H%M'`
commit_comment="rubocop --auto-correct $timestamp"
git commit -m "$commit_comment"
git checkout -b rubocop-auto-correct-$timestamp
branch_name=`git name-rev --name-only HEAD`
git push -u origin $branch_name
hub pull-request -m "$commit_comment" -h your-company:$branch_name
```

いきなり導入すると大量の自動修正が出てしまうので不安です。Rubocopはバージョンによって誤審することもあるので[^g]、油断なりません。なので、導入時はディレクトリを指定するなどして、少しずつ修正していくのがよいかと思います。一度全体に自動修正がかかった状態になるとそれ以降の差分は小さくなり（当たり前ですが…）、レビューも簡単になります。

継続的にコードの品質を維持する仕組みとして大変便利なので、是非試してみてください。

[^g]: https://github.com/bbatsov/rubocop/issues/3510
考察 > 構造体メンバ変数へ値代入する場所


- 多数の結果を格納するメンバ変数を持つ構造体があるとする

そのメンバ変数への結果の格納方法を検討してみた。

- 案1
  - 様々なサブ関数の中で構造体のメンバ変数に代入をする
  - 欠点: どこで値を代入したかソースリーディングしにくい
  - 欠点: 代入漏れが発生する可能性あり
- 案2
  - それぞれの計算結果を戻り値とする関数郡を用意する
  - 1つのサブ関数において、`構造体のメンバ変数 = 対応関数()`という形のコール文を列挙する
  - 利点: 代入している処理が見やすい
  - 利点: 代入漏れの防止などしやすい

案1のような実装は「技術的負債」と思う。
http.Response.Bodyちゃん行方不明事件

適当なエンドポイントにアクセスして、レスポンスボディを読んで、更に他にも利用しようとします。

```go
func badFunc() {
	// httpRequestは、http.Client.GetのWrapper
	resp, err := httpRequest("https://httpbin.org/")
	if err != nil {
		log.Fatal(err.Error())
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	// 中略

	// スクレイピング
	data, err := scrap(resp.Body)
	// 以下、省略
}
```

一見問題なさそうにみえますが、実はこれは正常に動きません。
`ioutil.ReadAll(resp.Body)`が動いた段階で、`resp.Body` の中が空になってしまうからです。これによって、後続のスクレイピングの処理は空データをスクレイピングしようとするのでエラー扱いになります。
（というか、独自処理なので、エラー扱いにしますといったほうが正しいかも）


結論から先にいうと、下記のようにしてしまえば解決します。
違いは、`ioutil.ReadAll(resp.Body)`の後に、`resp.Body`にレスポンス入れ直しているところ。これで、後続処理も正しく動くようになります。

```go
func goodFunc() {
	// httpRequestは、http.Client.GetのWrapper
	resp, err := httpRequest("https://httpbin.org/")
	if err != nil {
		log.Fatal(err.Error())
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	// 中略

	// ioutil.ReadAllの時点で消失してしまうので
	resp.Body = ioutil.NopCloser(bytes.NewBuffer(body))

	// スクレイピング
	data, err := scrap(resp.Body)
	// 以下、省略
}
```

メモリリークしたりするとこの現象が起こるらしいですが、そんなことが起きているわけでもなさそうなので、原因はよくわかりません。ソース読んでも、Stackoverflowとか見ても解決方法は書いてても、この現象の原因みたいなのはわかりませんでした。
（わかったら追記します）

とりあえず、http.Response.Bodyちゃんはきちんとお家に帰ってきましたとさ。
めでたしめでたし
ビットコインのトランザクションを作成

# ビットコインのトランザクションを作成

前提条件としてトランザクションを作って署名するには以下の条件が必要

* ビットコインアドレスにUTXOが入っていること(入金済みアドレス)
* ビットコインアドレスの秘密鍵を知っていること

## トランザクションの流れ

* UTXOに入金済みのトランザクションのID(TXID)とアウトプット(VOUT)を指定する（複数可）
* 送金先と金額を指定する（複数可）
* お釣りのアドレスを指定する
* 手数料を計算する
* 生成したトランザクションにビットコインアドレスに対応した秘密鍵で署名する
* ビットコインネットワークにトランザクションを送信する

## tips

* P2PKHとP2SHという方式があるがここではP2PKHを指定
* トランザクションには閉じるという概念がある
* 閉じていない場合には展開して追記ができる
* マルチシグで時間軸が異なるタイミングで複数の署名をする時などに使われる
* ビットコインのネットワークに流すには閉じていることが必要

## 送金トランザクションの作成

```
var bitcore = require('bitcore-lib');
var address = "1xx";//入金済みビットコインアドレス
var privateKey = "xxxxxxxx";//入金済みビットコインアドレスの秘密鍵
var a_address = "1xxx";//お釣りビットコインアドレス
var b_address = "1xxxx";//送金先ビットコインアドレス
var amount = 100000;
var fee = 10000;
var utxo = {
    txId: '0000',
    vout: 0,
    script: bitcore.Script.buildPublicKeyHashOut(address).toString(),//アドレスの方式(P2PKHの場合)
    satoshis: 1000000,//入金済み金額(satoshi)
};
var transaction = new bitcore.Transaction().fee(fee)//手数料
  .from(utxo) //前のトランザクションの参照
  .to(b_address, amount) //送り先と金額(satoshi)の設定
  .change(a_address) //おつり（自分のアドレスへ）
  .sign(privateKey)//プライベートキーの設定

var rawtx = transaction.toString();
console.log(rawtx)// ここで表示される文字列をビットコインネットワークに送信することで送金が完了する
```

※　rawtxはinsightであれば /insight-api/tx/send へPOSTする
Cloud Shellを使いまくると死ぬ


> Your session was detached because it was attached in another browser tab. Since you have tmux enabled, your session context will be transfered between tabs, but can only be open in one browser tab at a time. To disable tmux, select the "Tmux Settings" option from the Cloud Shell settings menu.

ファッ！？

GCPを使ってる皆さん、Cloud Shellという超絶便利機能を活用していると思われますが、タイトルの通り以下のようなことをしてるとCloud Shellが使えなくなるので注意しましょう、という話
まあ使えなくなるというか、おお？ってなるだけなんだけど

1. 複数ブラウザで同一アカウントのCloud Shellを開く
2. MAX4タブ以上開いてる状態になるとヤバイ
	- 4タブ開いた状態で別ブラウザでCloud Shell開くと起きます
3. Reconnectすると生きてる方のセッションを奪って横取りできる

あんまりやらないと思うけど、これ別の人が同一アカウント共有して使ってるとセッション横取りされてビビるんじゃないかな…
一人で使う分には起きないでしょう。たぶん。

## ちなみに…

ちょっと前は`reconnect`がなくてしばらくしてからアクセスしてね、って言われてました。
またそのうち変わるかもしれませんね。