OmniAICreator/Qiita-1.07M huggingface dataset:
個人的React周りベストプラクティス⑦ - 運用編

#前の記事
前回：[個人的React周りベストプラクティス⑥ - 開発編](https://qiita.com/enshi/items/289e579620ca95f3adab)
一番始め：[個人的React周りベストプラクティス① - 構成編](https://qiita.com/enshi/items/e6ad8c91168cfe8a88da)

#テスト
##フロントサイド起動
package.jsonが置いてあるディレクトリで`npm start`を実行する

```shell-session
$ cd redux_hoge
$ npm start
```
起動中はブラウザで`http://[自分のIP or localhost]:3000`で表示できるようになる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/156086/5f3fdf11-3de6-6d36-ac99-8a6e494ff7ad.png)


##サーバーサイド起動
serverless.ymlが置いてあるディレクトリで`sls offline`を実行する

```shell-session
$ cd lambda_hoge
$ sls offline
```
起動中は`http://[自分のIP or localhost]:[serverless.ymlで指定したポート]`で関数を実行できるようになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/156086/7213321f-ca88-386a-77f4-a54bcaa463d9.png)


#本番運用
##lambda関数デプロイ
serverless.ymlが置いてあるディレクトリで`sls deploy`を実行する

```shell-session
$ cd lambda_hoge
$ sls deploy
```
###ステージング環境と本番環境の使い分け
`sls deploy`のみだとステージが「dev」になる

ステージング環境にデプロイしたいときは`sls deploy`のみ
本番環境にデプロイしたいときには`sls deploy -s prod`としてステージを「prod」にしている

###デプロイする関数を指定する
`sls deploy`のみだとserverless.ymlに書かれている全関数がデプロイされてしまう
`sls deploy function -f [関数名]`で関数を指定したデプロイができる

ただし、上記はすでに存在する関数を更新する場合のみの話で、
新規に作った関数の場合は`sls deploy`として全関数をデプロイしなければならない模様

##S3初期設定
reactのデータをビルドで静的ファイルにした上で、S3上でWEB公開している
S3でWEB公開をするためにいくつか設定する必要がある

※コマンドに関しては[こちら](https://qiita.com/tsukapah/items/96e8402181609518fd3d)を参考にさせてもらいました


###:one: バケットを作成する
```shell-session
$ BUCKET_NAME=hogefuga-backet
$ aws s3 mb s3://${BUCKET_NAME}
```

###:two: ウェブホスティングを有効にする
react-routerでルーティングする際、下層ファイル付きでアクセスするとファイルが存在しないためエラーになってしまう
そのため --error-document で index.html を指定することでエラーにならないようにしている

```shell-session
$ aws s3 website s3://${BUCKET_NAME} --index-document index.html --error-document index.html
```

###:three: バケットポリシー設定
```shell-session
$ PUBLIC_POLICY=public.json
$ cat << EOF > ${PUBLIC_POLICY}
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::${BUCKET_NAME}/*"
		}
	]
}
EOF
$ aws s3api put-bucket-policy --bucket ${BUCKET_NAME} --policy file://${PUBLIC_POLICY}
$ rm -f ${PUBLIC_POLICY}
```

社内で使う等IPを制限した運用にしたい場合は以下のように書く

```shell-session
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::${BUCKET_NAME}/*",
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": [
						"111.111.111.111/32",
						"222.222.222.222/32"
					]
				}
			} 
		}
	]
}
```

###:four: Route 53を使用しドメインと紐付ける
ここまで実行すると`http://hogefuga-backet.s3-website-ap-northeast-1.amazonaws.com`というURLでアクセスできるようになる

ここからRoute 53を使用することによってドメインで運用出来るようになるらしい
[設定方法（公式）](http://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/RoutingToS3Bucket.html)


##フロントサイドアップロード

###:one: 静的ファイルを作成する
```shell-session
$ cd redux_hoge
$ npm run build
```

###:two: S3にアップロードする
```shell-session
$ BUCKET_NAME=hogefuga-backet
$ aws s3 cp --recursive build/ s3://${BUCKET_NAME}
```

#おわりに
7回に渡ってReactによる開発指針や考え方を書いてきましたが、この記事で終了です。

私自身まだ勉強中ですし、使ってみたいパッケージもいくつかあります。
使えそうなものがあれば記事に追記していきます。

また、念入りに調べたつもりですが、間違っている箇所もあるかもしれません。
その場合はコメント等で訂正していただければうれしいです。
docker swarm でホットデプロイを試してみよう


## 背景
個人のサービスをdockerで本番運用を行うにあたって

- コンテナアップデート時のダウンタイムは無くしたい
- １つのサーバーで完結したい(別途ロードバランサーを用意したくない)

みたいなことを考えていたのですが、docker swarmを利用すると、とても簡単に実現できたので共有したいと思います。

## 検証環境
Docker version 17.10.0-ce, build f4ffd25

## docker swarm の作成
managerのnodeが１つだけある環境を用意します。

```bash:swarmの作成
$ docker swarm init --advertise-addr="リモートのIPアドレス"
```
```bash:nodeの起動を確認
$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
qjdzkq17bxva02am04rou51dw *   digitalocean        Ready               Active              Leader
```

## Serviceの作成
１つのサービスを２つのコンテナ(レプリカ)で作成します。

```bash:Serviceの作成
$ docker service create --name demo --replicas 2 --update-delay 10s -p 8080:8080 hashicorp/http-echo -listen=:8080 -text="demo-1"
```

今回の検証には`hashicorp/http-echo`のイメージを使用しています。
これは起動時に引数で渡した文字列を表示してくれるWebサーバーのコンテナです。
https://hub.docker.com/r/hashicorp/http-echo/

### Service起動の確認
`--replicas 2`を指定したのでコンテナが２つ作成できています。

```bash:コンテナの確認
$ docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                    NAMES
a0dcff10b6c8        hashicorp/http-echo:latest   "/http-echo -text=..."   10 hours ago        Up 10 hours         5678/tcp                 demo.3.9zba9ygmdnjo764rt8fgprcip
baffe41b305d        hashicorp/http-echo:latest   "/http-echo -text=..."   24 hours ago        Up 24 hours         5678/tcp                 demo.2.ydki5edzc2r1henjtw343el6f
```
```bash:動作の確認
$ curl http://サーバーIPアドレス:8080/
demo-1
```

## Serviceのアップデート
`docker service update`コマンドを利用すると、各コンテナを順にローリングアップデートしてくれます。アップデート中も一方のコンテナが起動しているので、サービスを継続しながらのアップデートが可能です。

起動時とは引数を変えてイメージをアップデートします。

```bash:Serviceのアップデート
$ docker service update --image hashicorp/http-echo --args  "-text="demo-2" -listen=:8080" demo
demo
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged
```

外部からウォッチしながらアップデートをすると次のようなログになります。

```
$ while true; do curl http://サーバーIPアドレス:8080/; sleep 1s; done
demo-1
demo-1
demo-1
demo-2 ←片方のコンテナがアップデート完了
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-2 ←両方のコンテナがアップデート完了
demo-2
demo-2
```

※今回はService作成時に`--update-delay 10s`を指定しているので、各コンテナのアップデートには10秒の間隔が空きます。

## アップデートのロールバック
`docker swarm rollback`コマンドを使えば、デプロイ後に問題が見つかった場合も、サービスを１世代前に戻すことができます。

```bash:ロールバック
$ docker service rollback demo
rollback: manually requested rollback
overall progress: rolling back update: 2 out of 2 tasks
1/2: running   [>                                                  ]
2/2: running   [>                                                  ]
verify: Service converged
```
```bash:動作の確認
$ curl http://サーバーIPアドレス:8080/
demo-1
```

rollbackコマンドは、Docker 17.09.0-ce以降で利用できます
https://docs.docker.com/release-notes/docker-ce/

## 参考
Apply rolling updates to a service
https://docs.docker.com/engine/swarm/swarm-tutorial/rolling-update/
Cesium で３D三次メッシュ棒グラフ表示

# ３D棒グラフ表現を実現する関数の作成

Cesiumでは、rectangle（矩形）というオブジェクト描画がありますので、メッシュコードからrectangleを定義する関数を作成しました。

## 成果物イメージと公開先
http://jsdo.it/tkama/kQnc

<img width="466" alt="スクリーンショット 2017-12-06 13.17.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/5f28f197-269b-c677-0214-02e699c0c471.png">


## 3次メッシュ３D棒グラフ出力関数

```js:getJapan3rdmeshRectangle.js
/**
 * 3次メッシュ３D棒グラフオブジェクト作成関数
 * @param  <Number>  meshcode3rd (required) 3次メッシュコード
 * @param  <Number>  h (required) 高さ（単位メートル）
 * @param  <string>　　　　color_abgr (required) 　色
 * @param  <string> description_text (required) オブジェクトの説明文
 * @retrun <object> ans_entities rectangleオブジェクト
 **/
function getJapan3rdmeshRectangle( meshcode3rd , h, color_abgr , description_text　){

    var strMeshcoe = String(meshcode3rd);
    var p = parseInt(strMeshcoe.slice(0,2));
    var u = parseInt(strMeshcoe.slice(2,4));
    var q = parseInt(strMeshcoe.slice(4,5));
    var v = parseInt(strMeshcoe.slice(5,6));
    var r = parseInt(strMeshcoe.slice(6,7));
    var w = parseInt(strMeshcoe.slice(7,8));
    var lat = p / 1.5 + q / 12 + r / 120;
    var lon = u + 100 + v * 0.125 + w * 0.0125;

    console.log(lon +":"+ lat) ;

    var ans_entities = {
            id:meshcode3rd ,
            description : "<p>"+description_text+"</p>",
            rectangle : {
                coordinates : Cesium.Rectangle.fromDegrees( lon , lat , lon+0.0125 , lat+0.008333333 ),
                height : 0,
                extrudedHeight : h,
                material : Cesium.Color.fromRgba( color_abgr )
            }
        };
    return ans_entities ;

}
```

# まとめ

日本の多くの空間統計が標準メッシュをベースとしたものが多く、3次元表示が簡単にできればデータ活用が促進できればと思います。
コピペでそれっぽいFlexboxなヘッダー

## メモ書き程度の記事です。
`display: flex;`とちょっとのCSSでできるそれっぽいヘッダー

## 用意するもの
* HTMLファイル
* CSSファイル
* エディタ

## コピペ本文

```header.html
<header>
  <nav>
    <ul>
      <li><a href="/">ロゴ</a></li>
      <li><a href="#">メニューA</a></li>
      <li><a href="#">メニューB</a></li>
      <li><a href="#">メニューC</a></li>
    </ul>
  </nav>
</header>
```

これに

```header.css
ul {
  display: flex;
}

ul li {
  padding: 10px 20px;
}

ul li:first-child {
  margin-right: auto;
}

```

おしまい。
`display: flex;`はすごい！！
jqueryを使って `<input type="file">` に入れられた画像データをリアルタイムでサンプル表示する

formの処理の課題はよくもらうんだけど、いつもどうだったか忘れてしまう。  
担当しているサイトがjqueryを使っているので、画像をfileで取り込んでサンプル表示するメモしておく。

* InternetExplorer 9 以前では、対応していません。  
* Safari 5 以前では、対応していません。
* 対応表はこちら[MDN ウェブドキュメント](https://developer.mozilla.org/ja/docs/Web/API/FileReader#Browser_compatibility)


```js
    //fileを変更したら
    $('#image').on('change', function() {
    
        //fileの値は空ではなくなるはず
        if ($('#image').val() !== '') { 
        
            //propを使って、file[0]にアクセスする
            var image_ = $('#image').prop('files')[0]; 
            
            //添付されたのが本当に画像かどうか、ファイル名と、ファイルタイプを正規表現で検証する
            if (!/\.(jpg|jpeg|png|gif|JPG|JPEG|PNG|GIF)$/.test(image_.name) || !/(jpg|jpeg|png|gif)$/.test(image_.type)) {
                alert('JPG、GIF、PNGファイルの画像を添付してください。');
            //添付された画像ファイルが１M以下か検証する
            } else if (1048576 < image_.size) {
                alert('1MB以下の画像を添付してください。');
            } else {
                //window.FileReaderに対応しているブラウザどうか
                if (window.FileReader) {
                    //FileReaderをインスタンス化
                    var reader_ = new FileReader();
                    //添付ファイルの読み込みが成功したときに実行されるイベント（成功時のみ）
                    //一旦飛ばしてreader_ .readAsDataURLが先に動く
                    reader_.onload = function() {
                        //Data URI Schemeをimgタグのsrcにいれてリアルタイムに添付画像を描画する
                        $('#preview').attr('src', reader_.result);
                    }
                    //Data URI Schemeを取得する 
                    reader_.readAsDataURL(image_);
                }
                return false;
            }
        }
        //ダメだったら値をクリアする
        $('#image').val('');
    });
```

* 参考：<http://hakuhin.jp/js/data_uri_scheme.html>

データの送信はformData_ を使うことを想定している。

```js
var formData_ = new FormData($sendForm.get(0));
```
あなたがまだ読んでないredux docsを探しやすくしたい[2017/12/06時点]

# モチベ
ひさしぶりにredux docs眺めたら「ん？増えてね？」ってなったので、いつどのDocsが追加されたのかをまとめてみました。
自分がDocs読んだ時期と照らし合わせると、何を読んでないか分かりやすいかと思います。

# 謝罪会見
以下はファイルが追加された日の時系列なので、「重要な記述が追加された」とかまでは分からんっす。
:bow_tone1: :bow_tone1: :bow_tone1: :bow_tone1: :bow_tone1: 

# 時系列

### 2015/08
- [Read Me](https://redux.js.org/)
  - Docとして追加されたのはこのタイミング
- [introduction/*](https://redux.js.org/docs/introduction/)
  - [introduction/CoreConcepts](https://redux.js.org/docs/introduction/CoreConcepts.html)を除く
- [basics/*](https://redux.js.org/docs/basics/)
- [advanced/*](https://redux.js.org/docs/advanced/)
  - [basics/UsageWithReact](https://redux.js.org/docs/basics/UsageWithReact.html)を除く
- [recipes/MigratingToRedux](https://redux.js.org/docs/recipes/MigratingToRedux.html)
- [recipes/ReducingBoilerplate](https://redux.js.org/docs/recipes/ReducingBoilerplate.html)
- [recipes/ServerRendering](https://redux.js.org/docs/recipes/ServerRendering.html)
- [recipes/WritingTests](https://redux.js.org/docs/recipes/WritingTests.html)
- [recipes/ComputingDerivedData](https://redux.js.org/docs/recipes/ComputingDerivedData.html)
- [Troubleshooting](https://redux.js.org/docs/Troubleshooting.html)
- [Glossary](https://redux.js.org/docs/Glossary.html)
- [api/*](https://redux.js.org/docs/api/)

### 2015/09
- [recipes/ImplementingUndoHistory](https://redux.js.org/docs/recipes/ImplementingUndoHistory.html)

### 2016/02
- [recipes/UsingObjectSpreadOperator](https://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html)

### 2016/07
- [recipes/IsolatingSubapps](https://redux.js.org/docs/recipes/IsolatingSubapps.html)

### 2016/09
- [basics/UsageWithReact](https://redux.js.org/docs/basics/UsageWithReact.html)
- [recipes/reducers/*](https://redux.js.org/docs/recipes/StructuringReducers.html)

### 2016/10
- [faq/*](https://redux.js.org/docs/FAQ.html)
  - [faq/ImmutableData](https://redux.js.org/docs/faq/ImmutableData.html),[faq/DesignDecisions](https://redux.js.org/docs/faq/DesignDecisions.html)を除く

### 2016/11
- [introduction/CoreConcepts](https://redux.js.org/docs/introduction/CoreConcepts.html)
- [faq/ImmutableData](https://redux.js.org/docs/faq/ImmutableData.html)

### 2016/12
- [recipes/UsingImmutableJS](https://redux.js.org/docs/recipes/UsingImmutableJS.html)

### 2017/07
- [faq/DesignDecisions](https://redux.js.org/docs/faq/DesignDecisions.html)

# おすすめ
- [recipes/IsolatingSubapps](https://redux.js.org/docs/recipes/IsolatingSubapps.html)
    - 言われてみれば確かにreduxでstore分割するの難しくないね！ってなる
- [recipes/reducers/*](https://redux.js.org/docs/recipes/StructuringReducers.html)
- [recipes/UsingImmutableJS](https://redux.js.org/docs/recipes/UsingImmutableJS.html)
    - immutablejsのデメリットも書いてあるので読んどいた方が良いと思う
    - [dot-prop-immutable](https://github.com/debitoor/dot-prop-immutable)とか[object-path-immutable](https://github.com/mariocasciaro/object-path-immutable)とか[mori](https://github.com/swannodette/mori)とか[seamless-immutable](https://github.com/rtfeldman/seamless-immutable)とか、選択肢あるよ！
    - [seamless-immutable](https://github.com/rtfeldman/seamless-immutable)あるよ！！！！
High Sierra + Xcode 9な環境で2年ぐらい前のRubyがコンパイルできなかったので調べた

## Issue

諸事情あって `2.3.0-preview1` が欲しかった。

```
rbenv install 2.3.0-preview1
ruby-build: use openssl from homebrew
Downloading ruby-2.3.0-preview1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.0-preview1.tar.bz2
Installing ruby-2.3.0-preview1...
ruby-build: use readline from homebrew

BUILD FAILED (OS X 10.13.1 using ruby-build 20170914)

Inspect or clean up the working tree at /var/folders/yq/w8rq9kfj30l8_h1k281dbtk80000gn/T/ruby-build.20171206123148.82787
Results logged to /var/folders/yq/w8rq9kfj30l8_h1k281dbtk80000gn/T/ruby-build.20171206123148.82787.log

Last 10 log lines:
compiling vm_trace.c
compiling thread.c
compiling cont.c
thread.c:1077:27: error: implicit conversion loses integer precision: 'long' to '__darwin_suseconds_t' (aka 'int') [-Werror,-Wshorten-64-to-32]
        tp->tv_usec = ts.tv_nsec / 1000;
                    ~ ~~~~~~~~~~~^~~~~~
1 error generated.
compiling ./missing/setproctitle.c
make: *** [thread.o] Error 1
make: *** Waiting for unfinished jobs....
```

エラー箇所としてはthread内の時間計算をしているあたりのここらしい

>thread.c:1077:27: error: implicit conversion loses integer precision: 'long' to '__darwin_suseconds_t' (aka 'int')
> tp->tv_usec = ts.tv_nsec / 1000;

intな値にlong入れてるとコンパイラが怒ってくれる機能だと理解しました。

## Solution

この警告を無効にするために`--disable-werror` フラグを付けてビルドした。

```
RUBY_CONFIGURE_OPTS=--disable-werror rbenv install 2.3.0-preview1
ruby-build: use openssl from homebrew
Downloading ruby-2.3.0-preview1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.0-preview1.tar.bz2
Installing ruby-2.3.0-preview1...
ruby-build: use readline from homebrew
llInstalled ruby-2.3.0-preview1 to /Users/kstg/.rbenv/versions/2.3.0-preview1
```

`shorten-64-to-32` だけを無視しないと他の潜在的な問題を見逃していそうだけど、今回は全部無効にした。
SketchのシンボルをAtomicDesignで設計する。

# 概要

デザイン界隈でよく聞くAtomicDesignですが、
普段エンジニアの僕はReactのコンポーネント設計時にAtomicDesignに出会いました。

ReactやCSS(SCSS)側でも、AtomiDesignを採用しているのですが、
Sketchでも徐々にAtomicDesignを採用しています。

AtomicDesignは賛否両論あると思いますが、
賛成派の意見でAtomicDesignでのシンボル切り分けについて書きます。


# AtomicDesignとは

AtomicDesignとは、様々なパーツを合体させて、繰り返し可能なエレメントやテンプレートが作成できるシステムを構築することをいいます。

![1_j1P0pjQtl36QJavv8lHdyw.png](https://qiita-image-store.s3.amazonaws.com/0/129216/ac3bf667-97f7-2042-041f-240862cc3b90.png)

# AtomicDesignのメリット

Sketch/CSS/React全てで言える事だと思いますが、以下の様なメリットがあります。

* 保守性の高いUIを作る事ができる。
    * デザイン仕様の変更に強くなる。
    * コンポーネントの再利用性が高まる。(無駄な作業軽減)
* コンポーネントの粒度を論理的に説明できる。
    * コンポーネントの粒度を決定する基準が個人の感覚に依存しにくくなる。

# Sketchのシンボル設計

よくあるパターンですが、弊社では以下の切り分けでシンボルを設計しています

```
デバイスの名称 / レベル / コンポーネントの種類 / コンポーネントの名称 (または属しているコンポーネントの名称) _ 状態
```

## デバイス名称

デバイス毎の切り分けです。

| **名称** | **用途** |
| :--- | :--- |
| pc | PC |
| mobile | モバイル |
| common | PCもモバイルも共通 |

## レベルとコンポーネント

### lv1

ATOMSです。
それ以上分割のできないシンボルたちの集まりです。

| **名称** | **用途** |
| :--- | :--- |
| icon | アイコン |
| txt | テキスト |
| fill | 塗り(色) |
| img | 画像 |

### lv2

MOLECULESです。
ATOMSを組み合わせて作っています。
主にボタンが多いです。

| **名称** | **用途** |
| :--- | :--- |
| btn | ボタン類 |
| form | フォーム類 (インプット・ラジオ・チェックボックス) |

### lv3

ORGANISMSです。
lv1とlv2を組み合わせてできる、ブロックやリストです。

| **名称** | **用途** |
| :--- | :--- |
| list | リスト |
| block | ブロック |
| header | ヘッダー |
| footer | フッター |
| aside | アサイド |
| nav | ナビデーション |
| card | カード |

### lv4

TEMPLATESです。
lv3が組み合わさってできたコンポーネント ※シンボル化は基本しない
(lowレベルのワイヤー)

### lv5

PAGESです。
より具体的な姿となったTEMPLATES ※シンボル化は基本しない
(highレベルのワイヤー)

## 状態

クリックした状態などのイメージです。
コンポーネント名に_区切りで記載します。

| **名称** | **用途** |
| :--- | :--- |
| hover | ホバー状態 |
| selected | 選択されている状態 |
| click | クリック状態 |
| small | 小サイズ |
| big | 大サイズ |
| red, green, blue etc... | テキストや背景色 |

## 例

* パソコン画面のカードのタイトルテキスト

```
pc/lv1/txt/card_title
```

* モバイル画面のアサイドの項目のボタン

```
mobile/lv2/btn/aside_item
```

* 検索フォームのボタンをホバーした時

```
pc/lv2/btn/searchform_hover
```

* PC画面のヘッダー

```
pc/lv3/header
```

# 最後に

SketchでのAtomicDesignは発展途上ですが、
React側ではリファクタリングも進み可読性も上がり、
AtomicDesignを導入した事でかなり柔軟にUIの変更が可能になりました。

今後もAtomicDesignを意識して、保守性の高いUIを設計したいと思います。

# AtomicDesignでよく参考にする記事

* http://postd.cc/the-unicorn-workflow-design-to-code-with-atomic-design-principles-and-sketch/
gzipの読み方あってる？！

※お忙しい方のために、結論「ジージップ」でした。

最近、Qiitaでもよく爆速なサイト（[https://dev.to](https://dev.to)）が話題に上がり、そこで採用された技術に対する記事をよくみるようになった気がします。

その中でも、`gzip`というデータ圧縮方法でCSSやJSなどの転送量を減らす方法が注目を集めています。

ところで、この`gzip`、当たり前のように「ジージップ」と読んでいましたが、「g」はこれまで

- gifの「ジフ」「ギフ」
- gitの「ジット」「ギット」
- gunzipの「ジーアンジップ」「ガンジップ」

と戦争を巻き起こしたり、勘違いを引き起こしています。
※新たな火種「グジップ」などではないことを確認しておきたい！

ということで万が一のために調べましたが、wikipediaによると「ジー・ジップ」でよいそうです。
海外動画での発音も調べました。このサイト便利！！
https://youglish.com/search/gzip


## ちなみに「g」にまつわる発音
|単語|発音|参考|
|:--|:--|:--|
|gif|ジフ|https://www.gizmodo.jp/2013/05/gifgif.html|
|git|ギット|https://www.youtube.com/watch?time_continue=10&v=4XpnKHJAok8|
|gunzip|ジーアンジップ|https://youglish.com/search/gunzip|

## 番外編
たまに発音に違和感があったり、自信をもっていえない単語もこれを機に。
#### png
日本では「ピング」ないしは「ピン」と呼ぶらしいのですが、海外のどの動画をみても「ピーエヌジー」でした。
https://time-space.kddi.com/ict-keywords/kaisetsu/20160627/
https://youglish.com/search/png

#### maven
これはカタカナの問題でしょうが、メイヴン、メイヴェン、メイビン、メイバンなどがある中、「メイヴン」、「メイヴェン」のようです。
https://youglish.com/search/maven

## 調べるにあたって
このサイトは会話の中で発音している動画がちゃんとあって、とても便利でした
https://youglish.com/

gunzipに関しては、以下で「ガンジップ」といっていますが、コマンドをさして言っているのかは定かではなく。。
https://www.youtube.com/watch?v=UdBMgCxdFUg
gitで誤ったメールアドレスでpushしてしまった時の対処法

誤ったメールアドレスでもユーザー名とパスワードがあっていればpushできてしまいます。

gitはユーザーを特定できないのでUnrecognized authorとして、?マークがついた状態になります。

これに後から気付いて、修正する方法がないか探したらありました。

##### 1. 該当するレポジトリにcdして、以下のコードをコマンドラインに貼り付けてpush

名前やメールアドレスなどは自分で変える必要があります。

```
git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
```

##### 2. git push

```
git push --force --tags origin 'refs/heads/*'
```

終わりです！

---
参考
https://stackoverflow.com/questions/18561831/unrecognized-author
ちょこっとJulia言語を紹介する

この記事では、科学計算とか数値計算を全くしない人間が、何故か気に入っているプログラミング言語であるJuliaについてちょこっと紹介します。
# Juliaとは
Juliaは2012年に公開された、科学計算処理、数値計算向けのプログラミング言語で、MITの学生や教授によって作られました。
なぜJuliaを作ろうとしたか、ということについては[公式ブログ](https://julialang.org/blog/2012/02/why-we-created-julia)で語られています。
記述しやすさ、高速さがウリで、LLVMベースのコンパイラを搭載することで実現しています。
for文で単純な計算するだけでも速いです。感動します。
# プログラミング環境について
Juliaのインストールについては割愛し、ツールなどを紹介します。
## JuliaPro
[JuliaPro](https://juliacomputing.com/products/juliapro)はJulia Computingが提供するIDEです。
JuliaのインストールとAtomのインターフェイスであるJuno IDE、デバッガ、その他グラフ描写などの有用なパッケージが同梱されています。
## JuliaBOX
[JuliaBOX](https://auth.juliacomputing.io/dex/auth?response_type=code&client_id=dev-juliabox&state=f9f9c4629ff103b0fd524bd520397d07&redirect_uri=https%3A%2F%2Fnext.juliabox.com%2Fauth%2Flogin&nonce=3a5f0715f48c7f8e2d9d789d9522f6d5&scope=openid%20email%20profile%20offline_access)は同じくJulia Computingが提供するツールです。Jupyter Notebookを利用しているのでブラウザ上でJuliaを試すことができます。
## VSCode
Visual Studio Code上で公開されているJuliaの拡張機能をインストールすることで、Juno IDEのようなIDEとして利用することができます。補完も効きます。

#ちょっとした文法とか
文法については公式ドキュメントに詳しく書かれています。ここではほんのちょっとだけ紹介します。
###乗算記号がいらない

```jl
x=32     
32

y=3x+1   
97

z=2x^2+2x+1   
2113
```
###行列は「'」で転置

```jl
a=[1 2 3;4 5 6;7 8 9]
3×3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9 

a=[1 2 3;4 5 6;7 8 9]
3×3 Array{Int64,2}:
 1  4  7
 2  5  8
 3  6  9
```

###既約分数が求まる

```jl
t=2//4
1//2
```
# パッケージについて
Webフレームワークや機械学習関連をサポートするパッケージなど、Juliaには現在1686のパッケージが公開されています。
[ページ](https://pkg.julialang.org/)ではバージョンごとによってテストがpassしたかfailだったかが表示されていますが、半分くらいしかpassしていません…。

# その他
- JuliaConと呼ばれるカンファレンスがあり、2018年はロンドンで開催されます。プレゼンテーションはYoutubeで公開されています。
- Julia公式ページで書籍やチュートリアルのサイトなどが紹介されています。
- 東北大学の某教授も使っています。
- [どうすればPythonをJuliaと同じくらい速く動かせるのか？ : 様々なやり方で計算の高速化を図る](http://postd.cc/python_meets_julia_micro_performance/)みたいな記事も読んで面白いと思います。(Pythonだけど)
”人工知能”について学習してみたので書いてみます。

##まずはじめに
この記事を書いているのは高校数学（このあたりも少し怪しいです）程度の知識しかない現役SEです。
「最近話題になっている”人工知能”とはなんぞ？」と思い学習した内容を書いてみたました。

##「最近話題になっている”人工知能”とはなんぞや？」
まず「最近話題になっている”人工知能”とはなんぞや？」というところから書いていきます。

ざっくりいうと
「***”人間っぽくいい感じに判断してくれるプログラム”***ってことだわな」
くらいでしょうか。

ここを厳密に言い出すと
データをたくさん集めて学習したものだとか
ディープラーニングくらいやってないと人工知能とはいえないでしょうとか
論争が起きそうなんですが…

今のところ***”人工知能”っていうものの定義が決まっていない***ので混乱の元になっているんですよね。

なので、ざっくりと***”人間っぽくいい感じに判断してくれるプログラム”***ということにしておきます。

ここをなんで、こういうことにしておくかというと
人工知能について調べ始めた頃に大混乱したのですが…

・昔の人工知能を研究していた時代の話
・最近の人工知能の性能の話
・未来の人工知能はここまでできるはず！
・単純な人工知能の話
・高度な数学的な人工知能の話

みたいなものがゴチャゴチャしているような解説が非常に多くて

***「で、一体なにがすごくて、どういうプログラム書けばいいのよ？」***

というのが見えてこなかったという自分の経験に則しています。

##で、人工知能ってなんなの？
まずは、一口に人工知能って言われてるけど
実はいろいろなものがあるんだよねって話です。

具体的には
低レベルな人工知能（センサーとIF文で制御しているだけじゃんみたいなもの）
高レベルな人工知能（ものすごい量のデータから自分で傾向を判断しちゃうようなもの）
っていうのがあって
人工知能の４つのレベルなんて言われているようです。

この例についてわかりやすく書いてあったのがこちらの記事。

わかりやすい「人工知能4つのレベル」のたとえ話
https://tatoebablog.blogspot.jp/2016/06/4_20.html

何でもかんでも大規模なデータを使うのが人工知能ってわけでもないのよね
ってわかると学習の際の敷居が下がるような気がします。

ざっくりいうと
簡単なIF文数個で制御しているだけでもある意味人工知能だし
IF文をものすごいたくさん用意して分岐するような物も人工知能だし
沢山のデータを人間が解析して法則みたいなものを見つけ出して、その条件に沿ったものを判定するようなものも人工知能だし
沢山のデータを機械に読み込ませて法則みたいなものを見つけ出して、その条件に沿ったものを判定するようなものも人工知能だし
ってことっぽいです。

なんだか言葉の定義が曖昧だからすごくざっくりしてますね。

##人類を支配する人工知能はやってくるのか？
そして、もう一個”人工知能”って聞くと必ず
「感情を持っていて、成長すると人類を抹殺するターミネーターみたいなものを生み出すんじゃないか」
っていうような話が出てくるんですが

「今のところ、そういうのは存在しません」という話。

今話題になっている”人工知能”っていうのは
人間ができることのごく一部を代行できる程度にはなったねって言うくらいのもので
***得意なことがものすごく限定されている＝「弱い人工知能」***というものです。

これの「弱い人工知能」がようやく実用的になってきたんじゃね？ってくらいが最近の人工知能の動向らしいです。

人間にできることをなんでもできるようにしようぜ！っていうのは「強い人工知能」と言われているもので、こちらは現在まだまだ研究段階にあるようです。

***なのでターミネーターが未来からやって来るは、まだまだ遠そうですね！***

##【まとめ】
・人工知能の定義って定まってないよ。
・人工知能を実装するレベルもいろいろあるよ。
・ターミネーターはまだまだ来そうもない。
C++勉強メモ

# 1. std::min_elementとstd::max_element
配列、vectorの最小値、最大値のイテレータを返してくれる
```std::min_element(vec.begin(), vec.end());
```

# 2. volatile
C++ではコンパイラの最適化を無効にするために使われているそうです。
```volatile int a;
```
ちなみに、調べたところ、C#では、「同時に実行されている複数のスレッドによって、フィールドが変更される可能性があることを示す」の違いがあるそうで、覚えておきます。

# 3. emplace_backとpush_back
std::vectorに要素を追加する時、emplace_backを使った方がいい
参考Link: http://qiita.com/brackss1/items/e92da6458172397f7225

# 4. マルチスレッド(c++ 11)
```
std::thread t([](){
     // ここで別threadの処理

     Director::getInstance()->getScheduler()->performFunctionInCocosThread([]()
     {
            // cocosを使う場合、この中はメインスレッド
     });
    });
//スレッドの管理を手放す
t.detach(); 
//または、t.join()
```
join():子スレッドが完了するまで、メインスレッドがブロックされる
detach():メインスドットと切り離す。完了後自動リソース開放

---

スレッド内で一定時間を待つ処理の場合は、sleep使います。
注意点： windowsでは、大文字のSleepがあって、単位が違う
Linux： 　unsigned int sleep(unsigned int seconds);　　秒
Windows: void Sleep(DWORD dwMilliseconds);　ミリ秒

---
サブスレッドでcocos2d::Refをベースクラスに持つオブジェクトを生成するとクラッシュする恐れがあるので注意する必要がある。

# 5. std::enable_if
定義:
template< bool B, class T = void >
struct enable_if;
```
template <typename EnumType, 
typename std::enable_if<std::is_enum<EnumType>::value, std::nullptr_t>::type = nullptr>
```
Tはデフォルトでvoid、std::nullptr_tはnullptrのタイプでポインターなので、省略した書き方は↓
```
template <typename EnumType, typename std::enable_if<std::is_enum<EnumType>::value>::type* = nullptr>
```

# 6. std::find_if
vector、mapなど、条件を満たすオブジェクトを検索する

```
namespace std {
  template <class InputIterator, class Predicate>
  InputIterator find_if(InputIterator first,
                        InputIterator last,
                        Predicate pred);
}
```

三番目の引数は関数やラムダ渡して、boolを返す
Alpine Linux に node-gyp のビルドが必要な npm モジュールを入れる

node-gyp に依存しているモジュール (例: [mdns](https://www.npmjs.com/package/mdns) ) を Alpine Linux 上でインストールすると、ビルドに必要なパッケージが足りななくてインストールに失敗する。

``` Dockerfile:Dockerfile
FROM node:alpine

RUN npm install mdns
```

``` console
$ docker build .
(略)
mdns@2.3.4 install /node_modules/mdns
node-gyp rebuild
(略)
gyp ERR! configure error
gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.
(略)
```

ビルドに必要な python / make / g++ を入れれば良いのだが、せっかく軽量な Alpine を使ってるのに Docker イメージが重くなってしまう。

そこで apk の `--virtual NAME` オプションを指定しておくことで、ビルドのためだけに入れたパッケージをビルド後にまとめて削除する。

``` Dockerfile:Dockerfile
FROM node:alpine

RUN apk add --no-cache --virtual .gyp python make g++ \
    && apk --no-cache add avahi-dev \
    && npm install mdns \
    && apk del .gyp
```

※ `avahi-dev` は `mdns` が依存しているパッケージ

削除することでイメージサイズを 310MB → 165MB まで減らすことができた。

参考： [Alpine Linux で軽量な Docker イメージを作る \- Qiita](https://qiita.com/pottava/items/970d7b5cda565b995fe7)
PlayFramework で IllegalStateException が出たときの対処法


普段Javaを書くことはないのですが、ヘルプ要員として案件が舞い込んできたのでその時のエラーメモです。

## 問題
さっきまで動いていたローカル環境が以下のエラーにより動かなくなりました！

```
[error] application - java.lang.IllegalStateException: JSR-303 validated property 'hogeCode' does not have a corresponding accessor for data binding - check your DataBinder's configuration (bean property versus direct field access)
```

## 対処
下記コマンドを実行します！

```
$ activator clean
$ activator compile
```

## 原因
間違えてFW内のbin以下のファイルをいじっていたようでコンパイルエラーが出ていました。
そのため、一度`activator clean`で中間ファイルをクリアし、`activator compile`で再コンパイルすると上手く動くようになりました。
Mac上でのターミナル環境構築

昨年12月に転職して、まあこれまでも家ではiMacを使ってはいたんですが、Terminal環境が落ち着いてきたので、現時点の構成を纏めておきます

- iTerm2
- zsh
    - oh-my-zsh
        - git
        - aws
        - brew
        - python
        - golang
        - cp
        - emacs
        - gnu-utils
        - zsh-autosuggestions
        - node
        - npm 
    - pyenv
    - ls
    - ghq
    - chrome
    - emacs
    - emacsclient
    - awsenv
- byobu

---
shellはzshにしています
一時期fishにしていましたが、pyenvの設定shellが上手く動かない&&fish shellへの変換が上手くいかないので、zshに戻ってきました

zshの自動補完として [auto-fu.zsh](https://github.com/hchbaw/auto-fu.zsh)を使おうとしましたが、2013年から更新されていなかったので、oh-my-zshとzsh-autosuggestionsにしています

転職前はPHPerでしたが、転職してからは、pythonとgolangがメインのプログラミング言語になりました
pythonのバージョン管理ツールとして、pyenvを使っています

lsは上手く色が付かったので、`alias ls='gls -al --color=auto'`で使っています

ghqは 
> alias g='cd `ghq root`/`ghq list | peco`'

でリポジトリをインクリメンタルサーチしています(バッククオートが...)

chromeはヘッダレスブラウザの実行用にaliasを作っています

emacs関連は`
alias emacs="/Applications/Emacs.app/Contents/MacOS/Emacs -nw"
alias emacsclient='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'
alias e='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -nw -a ""'`
で e + ファイルで快適に使えるようになりました
emacsはspacemacsにしています
昔は、`alias m='micro'`で使っていたのですが、Macのキーバインドが効かなかったので止めてしまいました
色分けは綺麗で良かったのですが...

awsenvは色んなアカウントを使い分けるためのツールです

byobuを使っているのは、tmuxだとterminalのcopy&pasteが出来なかったためです
色んな設定やツールを試してみましたが、結局出来ませんでした

これらの設定は、あちらこちらの先達達から~~パクった~~インスパイアされたものです
ありがとうございます
platform.jsで特定のブラウザを弾く

普段はClojureScriptでフロントエンドの開発をしているIkuruと申します。
JavaScriptは普段書きません(汗

最初はClojureScriptの宣伝の記事を書かせていただこうと思っていたのですが、
最近生JavaScriptを初め使った出来事があってタイムリーだったので趣旨を変更しました。

## 問題：reactベースのアプリケーションが動かないブラウザーがあるので、ブラウザを検知して警告を出したい

ClojureScriptで開発していたreactベースのSPAで、FirefoxとChromeでしかテストしていなかった
→リリース直後にユーザーからIE11だと動かないというフィードバック
→UXのためにIEだったらアプリケーションを起動せずに即別のブラウザ使って下さい的メッセージを表示しよう!
→生JSで数行で済む事をClojureScriptでやるのは無駄だよね

という経緯で初めて仕事でJavaScriptを使う事になったのでした。

## ソリューション: platform.js で検知→domをゴニョゴニョ

軽くググって一番上に出てきた[platform.js](https://github.com/bestiejs/platform.js/)というライブラリを使いました。

[cdnjsに登録](https://cdnjs.com/libraries/platform)されている物をscriptタグから読み込み、プラットフォームのチェックと表示の切り替えのdom操作を以下のように書きました。

```clojure
[:body
 [:div [:div#app "Hello world"] 
       [:div#warn "Please use a supported browser"]]
 [:script {:type "text/javascript",
           :src "https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.4/platform.min.js"
           :async false}]
 [:script
    ；； valid browsers
    "if (!(platform.name == 'Chrome') &&
         !(platform.name == 'Safari') &&
         !(platform.name == 'Firefox') &&
         !(platform.name == 'Opera') &&
         !(platform.name == 'Microsoft Edge')){
       //hide the loading
       document.getElementById('app').setAttribute('style', 'display: none;');
       //change the id so that reagent loses the target to mount                                                                       
       document.getElementById('app').id = null;
 
       //make the warning element visible
       document.getElementById('warn').setAttribute('style', 'display: block;');
     }"]
```

### 解説

#### `[:body...` とか `[:scrips...` ?

ClojureではメジャーなHiccup記法と呼ばれる物でClojureのデータ構造でHTMLのマークアップを表現しています

#### platform.jsは`aync=false`で読み込む

platform.jsが読み込まれる前にアプリケーション本体のjsが動いてしまわないようにする為に指定しています。

#### scriptタグ内の処理

今回はInternet Exploerer を弾きたかったため

- IE以外の主要ブラウザだった場合は何もしない → アプリが起動する
- IEだった場合は
    - #app のdivにdisplay: noneを設定して非表示
    - #app のidを変更してアプリケーションがマウントされないようにする
    - 注意文が入っている #warn のdivのdisplayを設定して表示されるようにする

上記のようにしました。

#### その他の宣伝

普段はClojure/ClojureScriptを書いてて、今年のClojureアドベントカレンダーにも記事を書きました。
よろしけばこちらもチェックしていただけると嬉しいです!
https://qiita.com/iku000888/items/2f047d7c5eaa0235b61c
vagrant up時にmkdir -p /vagrantが失敗する

Vagrantfileに `config.ssh.username = 'root'` と追記してrootでSSHするように設定したのですが、
vagrant upすると `mkdir -p /vagrant` でエラーを吐くようになりました。

```
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mkdir -p /vagrant

Stdout from the command:



Stderr from the command:
```

これが起きても、`config.vm.synced_folder`で指定したディレクトリが共有されない以外は普通に使えている感じでした。
ただ、共有フォルダが使えないと不便なので`vagrant up --debug`したりして調べましたが有益な情報が出力されず困っていたのですが、[こちらのサイト](http://d.hatena.ne.jp/nekonokataomoi/20130525/1369458950
)によりrequirettyが有効になっていると該当のエラーが発生することが分かりました。

```config:/etc/sudoers
Defaults    requiretty
Defaults:vagrant        !requiretty

# この行を追加
Defaults:root   !requiretty
```

結果、`/etc/sudoers`にrootのrequirettyを解除する記述を追加することで問題のエラーが出なくなりました
既存のMVCWebアプリにWebAPIを追加する。

主題ママ。現行稼働している俗にいう「普通の」Webサービスの機能に
WebApiを追加したい場合の手順。

#1) ASP.NET Web APIの登録
ツール→NuGet パッケージマネージャ → パッケージマネージャコンソール
表示されたパッケージマネージャに以下を入力。

```
Install-Package Microsoft.AspNet.WebApi
```

#2) ルート設定追加
追加と修正を1か所ずつ。

[新規追加]

```WebApiConfig.cs
using System.Web.Http;

namespace TweetPvService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}
```

[修正]

```Global.asax.cs
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();            
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    // 以下を追加
    GlobalConfiguration.Configure({{クラス名}}.Controllers.WebApiConfig.Register); 

    Initializer.Init();
}
```
#3)新規コントローラ追加
ソリューションエクスプローラーにてプロジェクト名を右クリック、
コンテキストメニュー→追加→新しい項目

Web API コントローラー クラス(v2.1)を選択、
名前を適当につけて(testController.cs等)で追加ボタンを押下。

#4)動作確認
デバッグ起動。起動後URLに「api/{{クラス名}}※」を打ち込み、
処理結果がブラウザに表示されればOK。

※3)で作成したコントローラ名が"testController"なら
"http://localhost:XXXXX/api/test/"等。

割と簡単。
AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第1話]

# 概要
エヌシーアイ総合システムのtaguchyです。
普段は主にBtoCのWEBシステムや、BtoB向けWEB APIの開発などをしています。

最近はIoT関連でもお仕事させていただいていて、IoTセンサーを机の上に置いてごにょごにょいじる。
みたいなことが増えてきました。
普段仕様書やプログラミングとにらめっこしながら仕事をしている私としては、実物のセンサーを触るだけでも新鮮で。
新たな発見をする毎日です。

**IoT楽しい**

というわけで。
今回は本業のための勉強も兼ねて、IoTセンサーを使って会社の会議室の利用状況を可視化してみます。
（本当はトイレの利用状況可視化をしたかったのですが、自社ビルではないのであえなく断念・・）
まだ企画段階なので、「どんな風にデータを見せようか」とかは考えながらやっていきます。

## 利用デバイス
センサーはレンジャーシステムズ株式会社様の「monoコネクト」を利用して調達します。
※「monoコネクト」はゲートウェイ(GW)・デバイスの提供、GW死活監視やファームウェア(FW)更新を可能とするWEBコンソールの提供を行う「IoTコネクティングサービス」です。

以下のデバイスを調達します。
* BLE/WiFiゲートウェイ：１台
* 人感センサー：３台

センサーはとても軽くて小さいので、ガムテープ輪っかにして貼りつけるとかでいける感じです。

## システム構成(予定)
![会議室可視化システム構成.png](https://qiita-image-store.s3.amazonaws.com/0/197194/f569c922-861e-d133-2d59-f096fa59f935.png)
いたってシンプルですが、まずはこんな感じですかね。
作っていくうちにちょくちょく修正するかもしれませんが、まずはこの形で進めていきます。

## 課題
以下を課題として、調査しつつ記事を更新していきます。

1. デバイスまわり
    1. 送信データの形式（そもそもどんなデータが取れるのか）
    2. WEBコンソールの使用感（つまずきポイントなどあれば）
2. システムまわり
    1. Kibanaでどんな風でデータを見せるか（デバイスでどんなデータが取れるか次第ですが・・）
    2. どのくらいのAWS料金となるか（実測）

## 記事一覧
[AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第1話]](https://qiita.com/taguchy/items/a137c54d88cf605b4093 "AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第1話]")
[AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第2話]](https://qiita.com/taguchy/items/8bd153b91105cc11a04e "AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第2話]")
[AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第3話]](https://qiita.com/taguchy/items/179362a33413a3816c05 "AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第3話]")
[AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第4話]](https://qiita.com/taguchy/items/2766d29fe54266c7becc "AWSとBLE人感センサーで会議室の利用状況を可視化してみる[第4話]")
snowflake系ID生成器katsubushiのご紹介

この記事は[OSS紹介 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/favorite-oss)の6日目の記事です。OSS紹介 Advent Calendar　2017では、使っている便利なOSSを紹介したい方や、自分のOSSを広めたいという方の投稿をお待ちしております。

---

本日は、Unique ID生成器が流行っているので現在使っているOSSである、katsubushiを紹介します。

https://github.com/kayac/go-katsubushi

## 特徴

* ビットごとに時間, `worker-id`, `sequence`が割り振られたsnowflake系のID生成器です
 * 以下は上位からのビットの中身です

| ビット範囲 | 中身 |
|:-------|:----|
| 42ビット | `2015-01-01 00:00:00` からの積算ミリ秒 |
| 10ビット | `worker-id` |
| 12ビット | `sequence` |

ID生成器の実装に関してはこちらを参照するとよいでしょう。

https://github.com/kayac/go-katsubushi/blob/master/generator.go#L13-L21

* katsubushiは他のプログラムから独立したデーモンとして動作します
    * 言語を問わず利用できます
    * [sonyflake](github.com/sony/sonyflake)も同様のライブラリですが、本体はGoから使うライブラリです。[example](https://github.com/sony/sonyflake/tree/master/example)にHTTPサーバでIDを返す実装があります
* memcachedプロトコル(テキストプロトコル)で動作します
    * クライアントライブラリが豊富です
    * HTTPよりもオーバーヘッドが少ないです

## 使い方

### インストール

releaseバイナリがあるので、そこからダウンロードするのが良いでしょう。

https://github.com/kayac/go-katsubushi/releases

[ghg](http://www.songmu.jp/riji/entry/2016-07-06-ghg.html)を利用するとプラットフォームにあったバイナリを簡単にダウンロードすることが出来ます。

```shell-session
$ ghg get kayac/go-katsubushi
```

起動するには、`-worker-id`を指定します。`-worker-id`は複数のkatsubushi同士が発行するIDが被らないように設定する識別子です。範囲は0-1023までです。

```shell-session
$ katsubushi -worker-id=1
```

`v1.2.0`からはredisを使った`worker-id`の自動発番も利用することが出来ます。

```shell-session
$ katsubushi -redis='redis://localhost:6379/1?ns=katsubushi'
```

デフォルトでは`11212`番ポートで立ち上がります。

### 発番

前述したように、memcachedプロトコルを用いているので、簡単に発番することが出来ます。複数個のIDを一気に発行することも出来ます。

```shell-session
$ telnet localhost 11212
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET a
VALUE a 0 18
387779837193895936
END
GET a b c
VALUE a 0 18
387779862779150336
VALUE b 0 18
387779862779150337
VALUE c 0 18
387779862779150338
END
```

プログラムから使うには、例えばPerlであれば`Cache::Memcached::Fast`を使って、

```perl
use Cache::Memcached::Fast;
my $memd = Cache::Memcached::Fast->new({
    servers => ["localhost:11211"],
});
$memd->get("a"); # => 387782075148681216
$memd->get_multi(1..10); # => { 1 => 387782207940345856, 2 => 387782207940345857, ... }
```

という風にIDを発番することが出来ます。

好きな言語を使ったアプリケーションに簡単に組み込めるため、ORMなどに組み込んで、手軽にユニークなIDに利用することが出来ます。また、複数個を一度に発行できるメリットを活かして、RDBMSへbulk insertを行う場合でも利用できます。

## 使用事例

* [分散環境でユニークなidを発番するGo製プロダクト「katsubushi」のご紹介](http://techblog.kayac.com/katsubushi-introduction.html)

* [分散ユニークID採番機 katsubushi と Web アプリケーションへの応用例](https://speakerdeck.com/fujiwara3/katsubushi)

* [ソーシャルゲームのカスタマーサポートを支える行動ログとredash](http://techblog.kayac.com/2016/12/21/160000)
  * ユーザ行動ログのtrace idの発番に利用しています

## 参考記事

* [ID生成大全](https://qiita.com/kawasima/items/6b0f47a60c9cb5ffb5c4)
* [Go製のUnique ID Generator「xid」について](https://qiita.com/mura-s/items/8914f34696a3502d82da)
WKWebViewでアプリ領域に保存したコンテンツを表示

## はじめに
タイトルの通り、
WKWebViewを使い、アプリ領域(いわゆるローカルファイル)をWebView上に表示してみた。
問題点などを情報共有として残しておく。

## アプリ領域について
iOSアプリでアプリ毎に用意されるディレクトリ。

```text
/
|-- Documents/
|-- Library/
|-- tmp/
```
今回、WebViewで表示するコンテンツは上記の場所に保存する。

## 実装

```objc:ViewController

// WebViewの初期化
CGRect rect = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
self.webView = [[WKWebView alloc] initWithFrame:rect];
[self.view addSubview:self.webView];

```

```objc:Load

NSString *path = [[[NSURL fileURLWithPath:NSHomeDirectory()] URLByAppendingPathComponent:@"tmp/index.html"] path];
NSURL *url = [NSURL fileURLWithPath:path];
[self.webView loadFileURL:url allowingReadAccessToURL:url];

```
URLは下記の様なパスとなる。

```
file:///var/mobile/Containers/Data/Application/123456789-1234-55AB-8765-1234ABCDEFGH/tmp/html/index.html
```

## 問題点
コンテンツの置き場所で、**tmp/** ディレクトリ以外は、HTMLをWebViewに表示出来たが、
参照される、css/javascript等のファイルが読込めていなかった。

また、シミュレータと実機では読込み結果の挙動が変わったので、下記の表で纏めておく。

|ディレクトリ|実機|シミュレータ|
|:-----------------|:-----------------:|:------------------:|
|Documents/|×|○|
|Library/|×|×|
|tmp/|○|○|
○：読込み成功
×：読込み失敗

**読込み失敗時**
![ng.png](https://qiita-image-store.s3.amazonaws.com/0/112186/f6fea32e-5e24-8761-e83a-3b2d90b4b57e.png)

**読込み成功時**
![ok.png](https://qiita-image-store.s3.amazonaws.com/0/112186/97d88e72-1eac-8bb9-ccf0-d7e8f20330e0.png)

表示に利用したコンテンツは、bootstrapのサンプルを使用。
https://getbootstrap.com/
ansibleのメモ帳

## エラーの対処

* The authenticity of host 'XXXX' can't be established

```
/etc/ansible/ansible.cfg あるいは ~/.ansible.cfg に
[defaults]
host_key_checking = False
```

もしくは

```
export ANSIBLE_HOST_KEY_CHECKING=False
```

## 設定メモ

* localhostへの実行

```
localhost ansible_connection=local
```
[参考: Running ansible playbook in localhost](http://ansible.pickle.io/post/86598332429/running-ansible-playbook-in-localhost)

* コマンドラインからパラメータを渡す

```
---

- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'

  tasks:
     - ...

ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"
```
PaizaCloud試してみました。

# はじめに

paizaは転職サイトなのですが、スキルチェックとかいろいろと楽しいことがあるのでいつも使わせてもらっています。
[ITプログラマ・エンジニア向け転職・就活・学習サービスのpaiza](https://paiza.jp/)

ちょっとしたプログラムの確認とかは、paiza.ioが便利でした。
[ブラウザでプログラミング・実行ができる「オンライン実行環境」| paiza.IO](https://paiza.io/)

そのpaizaがオンラインIDEを発表したので、試してみました。
[PaizaCloud IDE - 環境構築で挫折しない！3秒で起動するブラウザだけで使えるウェブ開発環境・クラウドIDE](https://paiza.cloud/)

なお、普段使いは[cloud9](https://c9.io)なので、そちらとの比較も少しだけ。

## プラン内容

一番最初によく理解できなかったので、プラン内容について補足します。

|プラン名|無料プラン|ライトプラン|ベーシックプラン|
|:--|:-:|:-:|:-:|
|利用時間|24時間|制限なし|制限なし|
|連続起動時間|ブラウザが開いている間（最大4時間）|ブラウザが開いている間（最大4時間）|常時起動|
|サービス公開制限|公開不可|公開不可|公開可|
|利用可能サーバ数|1サーバ（起動時間制限あり）|3サーバ（起動時間制限あり）|常時起動1サーバ + 3サーバ（起動時間制限あり）|

+ 無料プランの利用時間が２４時間とのことですが、これは24時間たつとサーバー（コンテナ）が削除されるという意味のようでした。
+ サービス公開は、無料プランだと不可になっていますが、「https://ホスト名.paiza-user.cloud」で外部からアクセスできました。（ホスト名については後述）

※ 昨日作ったサーバが今朝みたらなくなっていました。まあ、無料だし、、、

## 環境

github連携でアカウントを作ったため、public profileのNameからユーザ名が自動生成されるようです。
ホスト名は「ユーザ名-1」たぶん自動連番になるかと思います。
プランによっては自由に名前が付けられるかもしれません。

OSのバージョンはこちら

```
~$ uname -a
Linux ホスト名 4.13.0-16-generic #19~16.04.3-Ubuntu SMP Mon Oct 16 18:59:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
```

Ubuntu 16.04ですね。無難な選択かと思います。

個別の環境はdockerで作成されているようです。

/.dockerenvのファイルのありなしでわかります。

ちなみにdockerのバージョンはこちら

```
~$ docker --version
Docker version 17.05.0-ce, build 89658be
```

## IDEについて

IDEはマルチウィンドウです。
エディタはpaiza.ioのエディタとよく似ています。
置換や検索はなさそうです。
ただし、マルチカーソルには対応していました。

# おわり

海外のオンラインIDEが消えていく中、国内産のオンラインIDEがでてきたのは非常に喜ばしい限りですね。
これからもがんばってほしいです。

余力があれば、他のオンライン環境との比較もしてみたいと思います。
Javaでの変数名の付け方

# 随所にあるまとめ記事

中でも簡潔にまとまった良記事があります。

Java言語の命名指針
https://qiita.com/rkonno/items/1b30daf83854fecbb814

私はここに書かれていることには賛成で、そうあるべきだと思います。ただ、いい名前が思い浮かばなかったら、どうしたらいいでしょうか？

# 基本ルール

プロジェクトでのコーディング規約に従うのは前提として、以下が望ましいと思います。

* 名詞、もしくは名詞句
    * 動詞や動詞句はメソッドに使う
* 省略しない
    * 読みやすく、誤解がないようにする
    * プロジェクト内で確実に通じる略語はOK
* スペルミスに気をつける
    * 有名どころで言うと→ [REGIST という英語は無い](http://developer.cybozu.co.jp/akky/2005/07/regist/)

# 具体例

## `FileOutputStream`

たとえば、何らかの処理結果を出力するために使用する `FileOutputStream` を格納する変数の名前を考えてみます。

* `fos` --- フォス……?? なんだかサッパリわかりません。（懺悔すると大昔私はこれを使っていました）
* `fileOutputStream` --- 型はわかりますが。長さの割に情報量としては少ないと思います。
* `output` --- 間違いではありませんが、漠然としています。

とここまでで。賢明なる読者の方はお気づきになったと思いますが、 **型を変数名に入れるというのはあまり意味がない** のです。最近はIDEで変数の型が何であるかはすぐわかりますし、私のようにIDEを使わない人でも、 **宣言場所が簡単に見通せるほどシンプルなクラスやメソッド** にしていれば問題ありません。メソッドの引数は当然ながら **APIドキュメント** に説明があるので型の名前を引数の名前に入れることは不要です。


ではどういう名前がよりよい名前でしょうか。上記記事にもありますが、 **名前を見るとデータの中身が想像できる** 名称がよいと考えます。私なりに言い換えると、 **それが何者かを表す名前をつける** のです。

たとえば、

* `resultCsv` --- ああ、結果が記録されたCSVファイルなんだな
* `saleInThisYear` --- ああ、今年の売上なんだな
* `commandOutput` --- ああ、コマンド実行結果なんだな

のような感じです。

## `XxxxService`

* `XxxxController` に1対1で対応する `XxxxService` であれば、単に `service` としても差し支えないでしょう。

```java:例
public class XxxxController {
    /**
     * Xxxxの実務を担うサービス。
     * コンストラクタインジェクションで代入する実装方針なのでここで {@code @Autowired} はつけない。
     */
    private final XxxxService service;
```

# いい名前をつけた自慢が聞きたい

どういうクラスのどういうフィールド、どういうメソッドのどういうローカル変数に、こんないい名前をつけた（あるいはついていてすごいと思った）ものをコメントで紹介していただけると嬉しいです。
hako で Parameter Store を用いて環境変数を設定する

ECS 環境への docker image の deploy には個人的には [hako]( https://github.com/eagletmt/hako) を用いることが多いのですが、docker container に設定する環境変数について設定ファイルの yaml にべた書きではなく、何かしらのシステムで管理されている値をしようしたいなと思っています。

AWS だと SSM に [Parameter Store](http://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-paramstore.html) という機能があり、これを使うことで各種変数の AWS に任せることができます。

ただし、標準の hako の機能では　Parameter Store から値を取得することができないので、追加でプラグイン的な実装を書きました。

# hako-parameterstore
https://github.com/moaikids/hako-parameterstore

hako の env_provider として、AWS Parameter Store から値を取得する実装を書いたプラグイン的な拡張です。
こちらを用いると、Parameter Store に設定されている値を、ECS container の環境変数として割り当てることができます。

## install
```
$ gem install hako
$ gem install hako-parameterstore
```

実際は Gemfile にまとめて bundle install で入れることを推奨します。


## set value using AWS Parameter Store
Parameter Store に情報を追加します。

Parameter Store には [Web Console](https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Parameters:sort=Name) から情報を登録することも出来ますが、ここでは　aws-cli 経由でコマンドラインで登録してみます。

Parameter　Store には以下３種のデータ型でデータを登録できます。ここでは一応それぞれ処理内容を例示します。

- String
- SecureString
- StringList

### String
普通の文字列です。

```
$ aws ssm put-parameter --name sada.masashi --value 'masshi sada' --type Secure

$ aws ssm get-parameter --name sada.masashi
{
    "Parameter": {
        "Type": "String", 
        "Name": "sada.masashi", 
        "Value": "masashi sada"
    }
}
```

### SecureString
KMS で暗号化済みの文字列を保存できます。

```
$ aws ssm put-parameter --name sada.masashi --value 'masshi sada' --type SecureString

$ aws ssm get-parameter --name sada.masashi
{
    "Parameter": {
        "Type": "SecureString", 
        "Name": "sada.masashi", 
        "Value": "AQICAHh0pImsl6eTbd8xlEj3ruViUrXuAkUnpBDSqSJq+H7pTAGWLSDIh+iJACc5U+1008sJAAAAajBoBgkqhkiG9w0BBwagWzBZAgEAMFQGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMCSetmq0nwh6EU0i7AgEQgCdEyE2IywQMY3uF/SEiKgrU8y0LSdZU+Cs1KR+LOgGdSN3OM6B64iQ="
    }
}
```

SecureString は普通に取得すると上記のように暗号化された情報が返却されます。get-parameter 時に情報を復号化したい場合は `--with-decryption` を指定します。

```
$ aws ssm get-parameter --name sada.masashi --with-decryption
{
    "Parameter": {
        "Type": "SecureString", 
        "Name": "sada.masashi", 
        "Value": "masashi sada"
    }
}

```

### StringList
文字列配列を保存できます。

```
$ aws ssm put-parameter --name sada.masashi --value ['sada','masashi'] --type StringList

$ aws ssm get-parameter --name sada.masashi
{
    "Parameter": {
        "Type": "StringList", 
        "Name": "sada.masashi", 
        "Value": "[sada,masashi]"
    }
}
```

## config hako
AWS Paramete Store に保存された値を hako で使う場合は、env_provider で parameterstore を指定すれば OK です。
あとは、使用したい値を保持している key 文字列を以下のように #{.......} という形で指定すれば、その値が Parameter Store から取得され、環境変数として使われます。

```
env:
    $providers:
      - type: parameterstore
    SADA_MASASHI: ‘#{sada.masashi}'
```

## deploy using hako
あとは、通常の hako の使い方と同じです。

# まとめにかえて
AWS ECS を便利に使うことができる hako について、より便利に使えるように AWS Parameter Store に対応をした実装を行ってみました。
ユースケースを見ながら実装を洗練させようと思っていて今のところ実装は結構荒いですが、ご容赦ください。
RubyOnRailsで建てたlocalserverにhttps接続する場合

#railsで建てたlocalhostにhttps接続する簡単な方法

今回開発でRailsで作ったアプリにスマホからhttps接続する必要があったので色々探しました。

-https://github.com/jugyo/tunnels
↑を使います。

使用OS:mac sierra
Railsver:4系,5系

```
$ gem install tunnels
```
gem installします

```
$ sudo tunnels 443 3000 #pcでhttpsしたい時

$ sudo tunnels 10.☓.☓.☓:443 127.0.0.1:3000 #スマホでhttpsしたい時。☓の部分は自分のIPを調べよう
```

接続する時


```
https://localhost:443 #PC
https://10.x.x.x:443 #スマホ
```

で接続できます。

ブラウザの警告が出ますが、無視して開いてOKです。


これで接続すればオレオレ証明書系を使わなくて簡単に出来る方法です。
Project Euler Q38 【パンデジタル倍数】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
$192$ に $1, 2, 3$ を掛けてみよう.
$192 × 1 = 192$
$192 × 2 = 384$
$192 × 3 = 576$

積を連結することで$1$から$9$の パンデジタル数 $192384576$ が得られる. $192384576$ を $192$ と $(1,2,3)$ の連結積と呼ぶ.

同じようにして, $9$ を $1,2,3,4,5$ と掛け連結することでパンデジタル数 $918273645$ が得られる. これは $9$ と $(1,2,3,4,5)$ との連結積である.

整数と $(1,2,...,n) (n > 1)$ との連結積として得られる$9$桁のパンデジタル数の中で最大のものはいくつか?

## 解答

整数が$5$桁の場合は$9$桁のパンデジタル数を得られない。よって、整数は最大でも$4$桁。
かつ結果がパンデジタルなので、整数は最大でも$9876$である。

```bash
seq 9876 |
awk '{L=0;i=1;while(L<9){printf $1*i" ";L+=length($1*i);i++};print ""}' |
grep -v "0" |
tr -d ' ' |
awk 'length($1)==9' |
awk -v FS= '{for(i=1;i<=NF;i++){a[NR,$i]+=1};printf $0" ";for(i=1;i<=9;i++){printf a[NR,i]};print ""}' |
awk 'length($1)==length($2){print $1}' |
sort -n |
tail -1
932718654
```

## 答え合わせ
こちらのサイト様と一致していればOKとした。
http://kingyojima.net/pje/038.html
phina.jsでブラウザ風タッチスクロール

## やりたいこと
・クリックやタップに反応させて、レイヤー全体をスクロールさせる
・今回はy方向のみ
・ブラウザのスクロールのように指が離れた後も緩やかにスクロール

[サンプルコード](http://runstant.com/Keith_K/projects/ccfd9147)

## 準備

・レイヤーを準備
・スクロール領域用にRectangleShapeを追加
・スクロール領域に連動して動かしたい要素をレイヤーに追加

```js
// MainScene クラスを定義
phina.define('MainScene', {
  superClass: 'DisplayScene',
  init: function() {
    
    var self = this;
    
    this.superInit();
    
    // レイヤー
    this.uiLayer = DisplayElement().addChildTo(self);

    // スクロールできる領域
    var uiBase = RectangleShape({
      width: 500,
      height: 3000,
      x: self.gridX.center(),
      y: self.gridY.center(),
    }).addChildTo(this.uiLayer);
    
    uiBase.setInteractive(true);
    
    // 領域上に要素を置く
    var tomapiko = Sprite('tomapiko').addChildTo(uiBase);
  },
});
```

## スクロール処理　
・pointstartでスクロール開始を検知
・pointmoveで動いた量を拾ってレイヤーを移動させる
・pointend時に加速量を保持しておく
・updateを用いて減速しながら移動させる

```js
// MainScene クラスを定義
phina.define('MainScene', {
  superClass: 'DisplayScene',
  init: function() {
    
    var self = this;
    
    this.superInit();
    
    // レイヤー
    this.uiLayer = DisplayElement().addChildTo(self);

    // スクロールできる領域
    var uiBase = RectangleShape({
      width: 500,
      height: 3000,
      x: self.gridX.center(),
      y: self.gridY.center(),
    }).addChildTo(this.uiLayer);
    
    uiBase.setInteractive(true);
    
    // 領域上に要素を置く
    var tomapiko = Sprite('tomapiko').addChildTo(uiBase);
    
    // スクロール用処理
    uiBase.on('pointstart', function(pointed){
      this.pointing = true;
    });
    uiBase.on('pointmove', function(pointed){
      self.uiLayer.y += pointed.pointer.dy;
    });
    uiBase.on('pointend', function(pointed){
      this.pointing = false;
      this.vy = pointed.pointer.fy;
    });
    uiBase.update = function() {
      if(this.pointing === false){
        this.vy = this.vy * 0.8;
        if(Math.round(this.vy * 0.8) === 0){
          this.vy = 0;
        }
        self.uiLayer.y += this.vy;
      }
    }

  },
});
```

## fpsと減速量について
ぬるぬる動かしたければfpsを60にするとよいと思います。
30だと若干カクカクした感じになります

減速量に0.8という数値を用いていますが、もう少し大きい数値を使ったほうがスムーズに動く感じを出せます。
お好みで。

## 課題

本当は、ポップアップダイアログ内でスクロールみたいのを作りたかったのですが、表示領域を限定する方法が分からず、実現できていません。
⇒解決しました。コメント欄参照

## 終わりに

phinajsは、動きのあるゲームに強いのは言うまでもありませんが、
結構何でもできちゃうので、2Dであれば作れないゲームはほとんどないのではないでしょうか。

UI部分を独自に実装していけば、今風のソーシャルゲームとかも作れるんじゃないかな。

★よろしければtwitterでも絡んでください
[twitter](https://twitter.com/Keith19880912)