OmniAICreator/Qiita-1.07M huggingface dataset:
RxJS Observableの作成 (3) 　Observable.fromEvent の使い方

## 用途
Observable.fromEventは、DOMイベントから新しいObservableを作成します。

## 基本的な使い方

マウスクリックやマウスオーバー、入力フォーム等のイベントからObservableを作成します。
ユーザーの操作に対してObservableを作れるので使用頻度が高いオペレータになります。
fromEventから作られたObservableはcompleteを発火しません。

### クリックイベントからObservableを作成
```html:some.html
<button id="btn">click me</button>
```

```js:some.js
const btn = document.getElementById('btn');
Rx.Observable.fromEvent(btn, 'click').subscribe(e => {
  console.log(e.target.innerHTML);
})

// 結果
// click me
```
[ ES6 stackblitz ](https://stackblitz.com/edit/rxjs-fromevent-01-es6)
[ TypeScript stackblitz ](https://stackblitz.com/edit/rxjs-fromevent-01-ts)

### インプットイベントからObservableを作成

```html:some.html
<input type="text" id="input">
```

```js:some.js
const input = document.getElementById('input')
Rx.Observable.fromEvent(input, 'input').subscribe(e => {
  console.log(e.target.value);
})

// 結果 入力（hoge）
// h
// ho
// hog
// hoge
```
[ ES6 stackblitz ](https://stackblitz.com/edit/rxjs-fromevent-01-es6)
[ TypeScript stackblitz ](https://stackblitz.com/edit/rxjs-fromevent-01-ts)

## 他のオペレーターとの組み合わせ

Observable.fromEventは非常に多くのオペレーターとの組み合わせが考えられます。

### bufferTime、filterを使ったダブルクリック判定
```html:some.html
<button id="btn">click me</button>
```

```js:some.js
const btn = document.getElementById('btn');
Rx.Observable.fromEvent(btn, 'click')
  .bufferTime(500)
  .filter(arr => {
    return arr.length > 1
  })
  .subscribe(x => {
    console.log('ダブルクリック！');
  });
```

### window.resizeやmousemoveなどの連続するイベントで、リサイズやマウスマウスの移動を止めたときにイベントを流す。
```js:some.js
const input = document.getElementById('input')
Rx.Observable.fromEvent(window, 'resize')
  .debounceTime(100)
  .subscribe(e => {
    console.log('リサイズ終わり！');
  })
```

### bufferTime、filter、mapを使った押し順判定
2,3,1の順でボタンを押せば正解。

```html:some.html
<div>
  <button id="btn1">1</button>
  <button id="btn2">2</button>
  <button id="btn3">3</button>
</div>
```

```js:some.js
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');

const btn1Observable = Rx.Observable.fromEvent(btn1, 'click');
const btn2Observable = Rx.Observable.fromEvent(btn2, 'click');
const btn3Observable = Rx.Observable.fromEvent(btn3, 'click');

const checkList = ['2','3','1'];

Rx.Observable.merge(btn1Observable, btn2Observable, btn3Observable)
  .bufferTime(2000)
  .filter(arr => {
    return arr.length === 3
  })
  .map(arr => {
    return arr.map(x => {
      return x.target.innerHTML
    })
  }).subscribe(x => {
    if(JSON.stringify(x) === JSON.stringify(checkList)){
      console.log('正解！')
    }else{
      console.log('不正解！')
    }
  })
```
[ ES6 stackblitz ](https://stackblitz.com/edit/rxjs-fromevent-02-es6)
[ TypeScript stackblitz ](https://stackblitz.com/edit/rxjs-fromevent-02-ts)
スクロールでUINavigationBarを隠す

NavigationBarだけならこれだけでシュッと表示・非表示してくれる。
動きも滑らかなので割と良さそう。

```swift
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0 {
        navigationController?.setNavigationBarHidden(true, animated: true)
    } else {
        navigationController?.setNavigationBarHidden(false, animated: true)
    }
}
```
git jackとかいう便利チェックアウトコマンドを作ってみた

# 背景
複数のタスクを並行していて、
あっちのブランチに行ったりこっちのブランチに行ったりうろうろすることってあると思います

で、「gitあるある」かは知らんが、branchの移動って面倒ですよね。
branch名なんだっけ、となってgit branchして一覧確認して、branch名コピペしたり。

「branch名を補完すれば良かろう」という声は当然とし、
ただ結局そうしても、以下のような運用でブランチ作ってると、補完もろくに使えない。

（前方一致多すぎてtabキー押しても候補が多すぎてろくに省略できない（コピペの方が早い））

```
$git branch
develop
* feature/1129/modify_top_page
feature/1133/create_feature_summer_campaign
feature/1134/delete_test_code_in_mypage
・
・
・
```

もっというとbranch名の「modify_top_page」の方はわかっても「1129」のチケット番号の方は頭に浮かばん。

なんでこれを解決するために以下のようなコマンドを一個作って見た
まあ、作ったと行ってもエイリアスですが

# コマンド
```
git jack 
```

`git transfor`とか `git switch`とか考えたんすけど
`git jack`ってなんか短くてかっこいい（？）ということでこうなった。
乗っ取るという意味合いのhijackから持ってきたんだけど、長いしhiでもないので
まあ造語に近いですね。
もっといい名前ないかな・・・・


# 効果
ローカルブランチから特定の文字列を検索し、そいつにチェックアウトする

```
$git branch
develop
* feature/1129/modify_top_page
feature/1133/create_feature_summer_campaign
feature/1134/delete_test_code_in_mypage
・
・
・
```
の時

```
$git jack summer
```
と入力すると

```
$git checkout feature/1133/create_feature_summer_campaign
```

上記と同じ効果をもつ（例外もあるが）

# How do you
gitのエイリアス登録で実現した
具体的には「.gitconfig」に以下のような記述を追記した。

```
[alias]
    jack = "!f(){ git branch | grep $1 | head -n1 | tr -d '* ' | xargs -t git checkout;};f"

```

# 解説
```
jack = 
```
git jackってコマンドで実行される

```
"!f(){・・・・・・・;};f"
```
関数として定義し、紐付けるってことかな（よくわかってないけど、こうしないと動かなかった）

```
git branch | grep $1
```
git branchした結果を$1（シェルの引数）でgrepする


```
| head -n1 |
```
上の結果にパイプしてさらに先頭の一つだけ取得する（複数grepで引っかかった時のため）

```
| tr -d '* ' |
```
上の結果にパイプしてさらに'* 'といた文字列を削除する（現行のbranchには先頭に'* 'がつくため ）

```
| xargs -t git checkout |
```
上の結果で該当のブランチが引っかかるので、パイプしてさらにxargsで、git checkout に引数として渡してやる
（tオプションはコマンド確認用、なくても良い）

# 雑感
とりあえず自分には便利

問題点としては、
「複数引っかかった時に最初にhitしたものになる」ということだけど、
まあできるだけユニークな名前をつけておけばいいんでないかな。（運用で回避）
対話式で選択させたりしてもいいかもだけど、そこまでコストかける意味もなさそうなので今回はここまで
2018年 ArchLinuxで開発環境を作る完全版 (UEFI + GNOME3 + GRUB) 

## なぜArchLinuxのデスクトップを使ってるのか？
- webのエンジニアです。php、python、rubyとか
- ここ数年はwindows10上でコーディングして、vmware workstation上にcentosを構築しデバッグしていた。
- windows10の大型updateに嫌気が。
- macは無駄に高い。
- いい加減、dockerを使いたかった(高速な環境で)
- neovim使いたかった(過去形、今でも使いたいとは思うけど.nvimrcを育てるのが億劫で未だに手を出せていない)
- jetbrainsのIDEがあれば生きていける。
- ならwindows要らなくね？unix環境だけで全部出来るし。
- archlinuxのロゴかっこいい。響きがかっこいい。ジャケ買い的な発想。(manjaro、gentooも迷った)
- ローリングアップデートで常に最新でいられる
- 新しいもの好きなので、最新のツールが使える
- Arch Wiki読めば大抵のことが解決できる

## ArchLinuxをインストールしているPCの紹介
### HP Z820 Workstation(中古) x2 (家と会社)

| CPU | メモリー | GPU | SSD |
| ---- | ---- | ---- | ---- |
| Xeon E5-2643 3.30GHz x2 | 32GB | NVIDIA geforce 1060 3GB | Samsung 860EVO 500GB <br />Crucial BX300 240GB |

- ヤフオクで購入。安かった。
- 古いけどCPU2個だしメモリー大量だしSSDだしグラフィックカード最新だし、Core i7-7700と同じくらいのスコア出るし高速。
- 計2個のSSDを載せて、ArchlinuxとWindows10を別々にインストールしている。
- 1個のSSDへのデュアルブートは後々困ることがあったりするのでやらない。
- HHKB Pro2 のUSキーボードを愛用
- モニタはBenQ PD2700Q WQHD をデュアル。大領域でIDE広げまくりING

### Lenovo Thinkpad x250

| CPU | メモリー | GPU | SSD |
| ---- | ---- | ---- | ---- |
| i5-5300U 2.30GHz | 8GB | - | Crucial BX300 240GB |

特になし。サブPC。USキーボード付けたし。

## 2018年 ArchLinuxで開発環境を作る完全版 (UEFI + GNOME3 + GRUB) - インストール編
[https://qiita.com/bubbkis/items/a592c903ef6d5e445ffb](https://qiita.com/bubbkis/items/a592c903ef6d5e445ffb)

## 2018年 ArchLinuxで開発環境を作る完全版 (UEFI + GNOME3 + GRUB) - 開発環境構築編
[https://qiita.com/bubbkis/items/c5f1530151f52e997140](https://qiita.com/bubbkis/items/c5f1530151f52e997140)

## 2018年 モダンな開発環境構築方法 (PHP Ruby Python Node.js)
[https://qiita.com/bubbkis/items/f305bea7e2c1d95c791e](https://qiita.com/bubbkis/items/f305bea7e2c1d95c791e)

## おしまい
これで誰でもすぐにweb開発できます
larabelだってcakephpだってdjangoだってrailsだってreactだってvue.jsだって何でも来いですよ
さぁ、ガシガシ書き殴りましょう!!
BitriseでCarthageのビルド成果物をキャッシュする

## はじめに
BitriseでCarthageビルド，および成果物のキャッシュを行うようにしたので手順等をメモ

- 経緯
    - Carthageのビルド成果物をリポジトリに含めて運用していた
    - Xcode9.3(Swift4.1)に移行してビルドしたところ，100MBを超えるファイルが生成され，GitHubにpushできなくなった
    - もともとBitriseのワークフローは整備してあったので，その中でCarthageをビルド/キャッシュするようにした
        - 手順は基本的に[Bitrise Discussions](https://discuss.bitrise.io/t/how-to-cache-carthage-dependencies/197)に記載の通り．

## 設定方法
※ あらかじめ，基本的なiOSのビルド用Workflowは策定済みであるものとする

以下の３つのStepを追加
1. `Cache:pull`
2. `Carthage`
3. `Cache:push`

### `Cache:pull` の追加
- 挿入箇所： `Git clone` 以降
    - `Git clone` stepの直後でなくても問題はない
- オプション: 特にいじらなくてOK
  
### `Carthage` の追加
- 挿入箇所: `Cache:pull` 以降
- オプション:
    - Command: `bootstrap`を選択
        - `update`ではキャッシュがある場合にビルドできなかった
    - Options: 必要であれば以下のように設定
        - 設定例: `realm-cocoa --platform ios --no-use-binaries`
<img width="514" alt="スクリーンショット 2018-05-28 17.44.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/124121/9bfcc47a-d5b8-6f1d-004c-5a6b54348816.png">

:memo: `Carthage` Stepではなく `Script` StepでCarthageのビルドを行った場合は成果物をキャッシュできない模様  

### `Cache:push` の追加
- 挿入箇所: 全Stepの最後
    - キャッシュ対象がCarthageのビルド成果物だけなら`Carthage`の直後でもいいかも？(未確認)
- オプション:
    - Cache paths: `./Carthage -> ./Carthage/Cachefile`
        - Carthageディレクトリがリポジトリのルートにない場合は適宜パスを変更

## その他
### キャッシュファイルの参照・管理
- Project > Settings > Manage Build Cachesから参照可能．
<img width="1127" alt="スクリーンショット 2018-05-28 17.45.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/124121/04d38ec2-a978-776f-056b-25a143aafac0.png">
    - キャッシュの削除のほかダウンロードもできる．
    - キャッシュファイルはappごとに管理されており，別のWorkflowでキャッシュしたものがあればそれを利用可能(検証用のAdHocビルド時に生成されたキャッシュをAppStore用ビルドで使う，など)．


### ビルド時間への影響
キャッシュ(今回の計測時は1.35GB)を利用した場合，あらかじめリポジトリに含めておいたビルド成果物を利用した場合に比べ，ビルド時間は約２分増加．
DataFrame Mapper というPandasのコードを保守しやすくするライブラリを公開しました

DataFrame Mapper というライブラリを PyPI で公開したので、その理由と使い方を説明したいと思います。

## 作った理由

データ処理を Pandas を使って行うことは一般的だと思いますが、他の人が書いたコードがとても難しく感じ、保守しにくいなぁと思うことがありました。

自分の過去のコードもよくわからないことになっていたので、Pandas が原因の一端の少なくない部分を担っていると思ったので、原因を洗い出してみました。

* データ処理をスクラッチで書いていくことで意図を表現できない
* 設計・APIが古い気がする

これを解決するための一つの例としてオブジェクト指向っぽく記述できると、**処理に名前が付き、外側には泥臭いところを見せない**ようにできるのかなぁって思いライブラリを作ってみることにしました。

データ構造をマッピングできるクラスとして実装していて、継承することで

* 型定義をすることで、どのようなデータを扱っているかを表現している
* メソッドで処理内容を表現することができる

の2つのことが可能となり、読みやすくて保守しやすくなるのかなぁと思いました。

## 使い方

使い方は以下のような感じになるように実装しました。

```python
from dfmapper import DataFrameMapper, IntColumn, StrColumn

class UserDfm(DataFrameMapper):

    id = IntColumn(min=1, nullable=False)
    username = StrColumn(max_length=30, nullable=False)
    profile = StrColumn()

    def find_by_id(self, id):
        return self.df[self.df.id == id]

user_dfm = UserDfm({
    "id": [1, 2, 3],
    "username": ["Bessie Bennett", "Sandra Matthews", "Jessie Bates"],
    "profile": ["BLAH BLAH BLAH", "PITH PITH PITH", None]
})

user_dfm.validate()
#: True

user_dfm.find_by_id(1)
#:    id username       profile
#: 0  1  Bessie Bennett BLAH BLAH BLAH
```

* [PyPI](https://pypi.org/project/dataframe-mapper/)
* [Github](https://github.com/tokuda109/dataframe-mapper)

※ 機能的にこれで業務改善するのか検証はできていないので、実戦投入して改善していきたいと思っています。
Python3のビルトイン・ウェブ・サーバー（http.server）とCGIを使った簡易WEBサーバー作成してみた初心者メモ


# 作成したきっかけ
豊富なPythonのライブラリをブラウザから利用してみたいので作成してみた。

## pythonメモ
- コメントは#
- Python3は、print "Hello" ではなくprint("Hello")
- Python3は、'%d'とか'%+5.3lf'の記法は非推奨らしい

## 動作環境
- windows10
- Powershell
- Python3.6.3



## フォルダ構成とファイル置き場
PHPのビルトイン・ウェブ・サーバーのPHPファイルは、そのまま実行できますが、Pythonファイルは「cgi-bin」フォルダに入れないと動かないんですね。

```
cgi-bin
     ├test_cgi01.py
     ├test_cgi02.py
     ├test_cgi03.py
　　　└test_cgi04.py
```

## ビルトイン・ウェブ・サーバーをCGIを付与して起動させる。
通常実行する場合は

```shell
python -m http.server 8000
```
ですがポートの「8000」の部分を「--cgi」に変更する

```shell
python -m http.server --cgi
```

# pythonファイル
## その1（日本語が文字化け）

``` test_cgi01.py
# -*- coding: utf-8 -*-

print ('Content-type: text/html; charset=UTF-8\n')

print('abc123日本語１２３789xyz')
```

## その2（日本語対応）

``` test_cgi02.py
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

print ('Content-type: text/html; charset=UTF-8\n')

print('abc123日本語１２３789xyz')
```


## その3（HTML文をいれてみる）

``` test_cgi03.py
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

print ('Content-type: text/html; charset=UTF-8\n')

print ("""
<!DOCTYPE html>
<html lang='ja'>
<html>
<head>
<meta charset='UTF-8'>
<title>CGIスクリプト</title>
</head>
<body>
あいうえお<br>
</body></html>
""")
```

## その4（HTML内に呼び出し記法を入れてみた）

``` test_cgi04.py
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

kakikukeko ="かきくけこ"

import datetime
today = str(datetime.date.today())
print ('Content-type: text/html; charset=UTF-8\n')

print ("""
<!DOCTYPE html>
<html lang='ja'>
<html>
<head>
<meta charset='UTF-8'>
<title>CGIスクリプト</title>
</head>
<body>
{0}<br>
現在の時刻は「{1}」です<br>
</body></html>
""".format(kakikukeko,today)
)
```

## その4の結果
```
かきくけこ
現在の時刻は「2018-06-03」です
```
XFS上のスワップファイルが有効にならないとき

テスト用にUbuntu 18.04 Serverを新規インストールしてみた。

Ubuntu 18.04では以前のようにスワップパーティションは作成せず、
デフォルトでは`/swap.img`というスワップファイルを使用するようになる。

だが、どうもスワップファイルが有効になっていない。
起動時に`systemctl status swap.img.swap`を実行せよ、とメッセージが出ていたので見てみる。

~~~
$ sudo systemctl status swap.img.swap 
[sudo] password for foobar: 
● swap.img.swap - /swap.img
   Loaded: loaded (/etc/fstab; generated)
   Active: failed (Result: exit-code) since Mon 2018-05-28 08:34:52 UTC; 16min ago
     What: /swap.img
     Docs: man:fstab(5)
           man:systemd-fstab-generator(8)
  Process: 446 ExecActivate=/sbin/swapon -o sw /swap.img (code=exited, status=255)

May 28 08:34:52 dev001 systemd[1]: Activating swap /swap.img...
May 28 08:34:52 dev001 swapon[446]: swapon: /swap.img: swapon failed: Invalid argument
May 28 08:34:52 dev001 systemd[1]: swap.img.swap: Swap process exited, code=exited status=255
May 28 08:34:52 dev001 systemd[1]: swap.img.swap: Failed with result 'exit-code'.
May 28 08:34:52 dev001 systemd[1]: Failed to activate swap /swap.img.
~~~

ふむ、どういうことだろう？
とりあえずもう1個スワップファイルを作ってみる。

~~~
$ sudo fallocate -l 16G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile 
Setting up swapspace version 1, size = 16 GiB (17179865088 bytes)
no label, UUID=ab824d55-0f7b-4b1f-b2e5-50565fb5cbe9
$ sudo swapon /swapfile
swapon: /swapfile: swapon failed: Invalid argument
~~~

はて？
`Invalid argument`と言われても、たぶん合ってるよな・・・？

そういえば、気分で`/`をxfsでフォーマットしていたな・・・これが原因では？
もしかしたら`fallocate`では実際のディスク領域を確保してくれないのかも。

ということで、以下のようにしてみた。

~~~
$ sudo dd if=/dev/zero of=/swapfile count=4096 bs=4MiB
$ sudo mkswap /swapfile 
$ sudo swapon /swapfile
$ swapon -s
Filename                                Type            Size    Used    Priority
/swapfile                               file            16777212        1036    -2
~~~

できた。



ということで、xfsでフォーマットしたディスク上にスワップファイルを作るときは、ddを使いましょう。
Ignite UI for Angular リンク集

- 2018/05/28(Mon) 時点の情報に基づいています

## Ignite UI for Angular とは？
Infragistics が開発・販売する Angular ネイティブな UIコンポーネントです。
- 約50種類にもおよぶ Component, Direcive を収録
- Material Design に準拠
- 高機能・高パフォーマンス
が売りです。

---

## 非商用の場合はタダ
詳しくはこちら。
https://jp.infragistics.com/products/ignite-ui-angular#pricing

## デモ & API

https://jp.infragistics.com/products/ignite-ui-angular/angular

- オンラインでデモを試すことができます。デモのソースコードは `StackBlitz` 上で確認することができます。
- デモとあわせて API 一覧が掲載されています。 
- 例えばグリッドとチャートは以下のような感じです。

#### グリッド

![image.png](https://qiita-image-store.s3.amazonaws.com/0/70618/69deaa67-c4ff-ae40-aa1a-eec6c7160289.png)

#### チャート
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70618/5a8aa4fd-88fd-3ef0-62f9-072a99c4afdf.png)


## 今すぐ始める
https://jp.infragistics.com/products/ignite-ui-angular/getting-started

- [Ignite UI CLI](https://github.com/IgniteUI/igniteui-cli) というコマンドラインツールを使って、すぐに Ignite UI for Angular を始めることができます。


## GitHub
https://github.com/IgniteUI/igniteui-angular

- ソースコード
- Issue

- Wiki
  https://github.com/IgniteUI/igniteui-angular/wiki
  Ignite UI for Angular のコンポーネント・ディレクティブの各仕様が掲載されています。この仕様を満たすために日々開発が進められています。  


## VS Code 用 Extension
https://marketplace.visualstudio.com/items?itemName=Infragistics.igniteui-angular-tooltips

- テンプレート上でマウスオーバーするとツールチップを表示してくれる Extension です。
秀丸エディタで、矩形選択範囲を罫線で囲む秀丸マクロ

# 作ったきっかけ
秀丸で文章を書いている時、罫線で文字を囲いたい時があったので作成してみた。
┌────┐
│こんな　│
│イメージ│
└────┘┌──────┐
　　　　　　│じゃけんのー│
　　　　　　└──────┘

## 矩形選択のやり方
ctrl + マウスで選択


# 秀丸マクロの中身

```php5
$topc = str(seltopcolumn);
$endc = str(selendcolumn);

$topline = str(seltoplineno);
$endline = str(selendlineno);

#free_switch = 0;

if(selecting){
	if((seltoplineno > 1)&(seltopcolumn >1)){
	escape;
	#line = val($topline);

//┌─┐を追加：開始******************

if(!freecursor){
	#free_switch = 1;//もしカーソルモードがオフならスイッチオン
	freecursorswitch;
}
moveto val($topc)-2,#line-2;
overwrite "┌";

#i = val($topc);

while(#i < val($endc)){
	overwrite "─";
	#i = #i+2;
}
overwrite "┐";

//┌─┐を追加：終了******************

while(#line < val($endline)+1){
movetolineno val($endc)+1,#line;
overwrite "│";

movetolineno val($topc),#line;
overwrite "│";
#line = #line+1;
}

//└─┘を追加：開始******************
moveto val($topc)-2,#line-1;
overwrite "└";

#i = val($topc);

while(#i < val($endc)){
overwrite "─";
#i = #i+2;
}
overwrite "┘";
//┌─┐を追加：終了******************


//フリーカーソルモードをもとに戻す
if(#free_switch == 1){
freecursorswitch;
}

}else{escape "２文字目以上、２行目以上を選択して下さい";}
}else{
message "文字選択をして下さい";
}
```

## 作成サンプル

┌─────┐
│秀丸マクロ│
│で矩形選択│
└─────┘

　　　　　　　　　　　┌───────┐
　　　　　　　　　　　│よろしく　　　│
　　　　　　　　　　　│おねがいします│
　　　　　　　　　　　└───────┘


## 注意点
- 矩形選択の最終行がEOF【 End Of File 】 だと矩形罫線が崩壊します。（涙）
- 半角スペースができます。私は以下マクロで2半角空白を1全角空白にしています。

```
replaceallfast "  ","　";
```


## 参考本
- 秀丸マクロ ポケットリファレンス
 - 著者：西沢 直木
 - POCKET REFERENCE社
PhpStormにて多段sshで外部サーバにデプロイする方法

# 背景
PhpStorm導入したんだけどEC2上の開発環境で直接作業したい。（楽に）
でもそのEC2は踏み台サーバー経由しないとアクセスできない

ってことで[前回](https://qiita.com/SLEAZOIDS/items/1c07193b1e3cb4eeb7bf)書いたのだが

これだとソース管理できない。
というか、接続先の外部サーバにsshで繋いでソース管理しないといけない（面倒）

今回はその課題を解決する


# アプローチ方法
#### 前回
開発環境（外部サーバー）をプロジェクトとして登録すればいいんじゃね？

#### 今回
ローカルにプロジェクトを作成し、開発環境（外部サーバー）に自動デプロイすればいいんじゃね？

#### つまり方向を反対にした。


```
外部サーバー=>ローカル
```
```
ローカル=>外部サーバー
```


# 手法
以下、実際に行った手順を記載する。
※日本語環境で作業しています

## ssh configの設定

まずは、[前回](https://qiita.com/SLEAZOIDS/items/1c07193b1e3cb4eeb7bf)も書いたけど、ssh configを設定して踏み台経由で目的のサーバにアクセスできるようにしよう。
sftp(ssh)接続で使用するconfigファイルに多段ssh接続の設定を追記する
jumpが踏み台でmy_project_hostが真に接続したいサーバーである

```
Host jump
 Hostname jump-ip
 User jump-user_name
 IdentityFile ~/.ssh/jump-key

Host my_project_host
 Hostname my_project_host-ip
 User my_project_host-user_name
 IdentityFile ~/.ssh/my_project_host-key
 ProxyCommand ssh -W %h:%p jump

```
設定が間違っていないか、一度sshで接続できるか試しておこう。

## ローカルに該当プロジェクトを用意
- ローカルに該当プロジェクトを用意する（自分はgit cloneした）
- この辺は人によって違うので割愛

## PhpStormの設定

### プロジェクトの登録
- PhpStormを起動する 
- menu>ファイル>既存ファイルから新規プロジェクトを選択
- 「ソース・ファイルはローカル〜」を選択
<img width="858" alt="スクリーンショット 2018-05-24 19.17.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/105662/09557239-ed12-f7c1-bbab-3f5a8b33110b.png">


### デプロイサーバーの設定  
- 上記のローカルで作ったプロジェクトを選択する

- プロジェクトが開くと思うので、引き続きmenu>ツール>デプロイ>構成を選択する

- デプロイモーダルが開くので左上の「＋」を押しデプロイ先の設定を行う
- 適当な名前をつけ、sftpを選択する
<img width="891" alt="スクリーンショット 2018-05-24 19.24.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/105662/d9f1686e-3613-9c6d-384a-92edb262a02f.png">
- [前回](https://qiita.com/SLEAZOIDS/items/1c07193b1e3cb4eeb7bf)と同様に設定を行う
<img width="867" alt="スクリーンショット 2018-05-24 17.17.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/105662/59b859d8-e2d2-e63f-e3a8-4c2bb2f35c2d.png">

### 紐付け（マッピング）

- menu>ツール>デプロイ>自動アップロードを選択する
- デプロイ先を求められるので先ほど登録したサーバを選択する
- menu>ツール>デプロイ>構成>マッピングにてサーバにマッピング情報を設定する
- サーバのデプロイパスを入力する（アップロード先になる）
<img width="813" alt="スクリーンショット 2018-05-24 19.29.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/105662/c6463497-c43f-8f69-17c0-63cc8dc2dc2e.png">


- menu>ツール>デプロイ>オプションで自動アップロードを「明示的な保存アクション時」にする（好みだが）
<img width="792" alt="スクリーンショット 2018-05-24 19.34.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/105662/6c0e5521-dfd4-1289-7ef2-a8e3dc1f3c7b.png">

以上でローカルのファイルを保存すると自動的に対象サーバーにアップロード処理が走るようになった。

# 雑感
通信時に多少遅い時もあるが、概ね良好。
タスクランナー走らせて、PhpStorm以外でファイルを変更した時などには
設定から「サーバーへの自動アップロード」を「常時」にすればアップロードされるが、
一度PhpStormにフォーカスを持ってこないといけない現象がおきているのでちょっと面倒。
この辺の課題を今後解決していきたいと思う。
認証付き社内Proxyの落とし穴 in AndroidStudio 3.1 with gradle 4.4

# 何が起きたか？
Android Studio を認証プロキシ下の社内ネットワーク環境で使おうとすると、3箇所のプロキシ設定が必要になる。パスワードに記号が含まれる場合、そのパスワードをURIエンコードするかしないかに気をつける必要がある。忘れるとハマる。

|設定|場所|パスワードのURIエンコード|
|:---|:---|:----------------------|
|Android Studio|Settings|しない|
|gradle|~/.gradle/gradle.properties|しない|
|git|git config --global コマンドで設定|する|

# プロキシ設定方法
備忘録のため、以下に設定の詳細を書きます。

## Android Studio
Android Studio のメニューから [ Settings -> Appearance & Behavior -> System Settings -> HTTP Proxy ] で設定する。

## gradle
gradle.properties に記述する。

- Windows の場合 -> C:\Users\<username>\.gradle\gradleproperties 
- Linux/Mac の場合 -> ~/.gradle/gradle.properties

```text:gradle.properties
# HTTP Proxy --------------------------------
systemProp.http.proxyHost=myproxy
systemProp.http.proxyPort=8080
systemProp.http.nonProxyHosts=192.168.*
systemProp.http.proxyUser=username

# URIエンコードしない記述が正解
systemProp.http.proxyPassword=p@ssword

# 以下のようなURIエンコードした記述は不正解
systemProp.http.proxyPassword=p%40ssword
# --------------------------------------------

# HTTPS Proxy も同じ
systemProp.https.proxyHost=myproxy
systemProp.https.proxyPort=8080
systemProp.https.nonProxyHosts=192.168.*
systemProp.https.proxyUser=username
systemProp.https.proxyPassword=p@ssword
```

**補足**
Android Studio は プロジェクト直下に gradle.properties があると、そちらを優先している。混乱しやすいので ~/.gradle/gradle.properties に統一した方が良いだろう。

## Git
git コマンドで設定する。ここだけURIエンコードが必要。

```
git config --global http.proxy http://username:p%40ssword@myproxy:8080
git config --global https.proxy http://username:p%40ssword@myproxy:8080
```

確認も git コマンドで行う。

```
git config --list
```

間違った場合は削除できる。

```
git config --global --unset http.proxy
git config --global --unset https.proxy
```

## 反省
落とし穴にはまらないようにしたい。認証プロキシは辛み。撲滅したい。
固定ページのパーマリンクとタクソノミーの名前がかぶって固定ページ表示できず

Wordpressでとある固定ページが表示されない事案が発生した。

原因を調べるに、どうやら固定ページで利用しているパーマリンクの名称と、タクソノミーの名称がかぶってるせいで、該当URLがうまく固定ページまでたどり着けてない模様

* 固定ページのパーマリンク ... http://sample.com/hoge
* タクソノミー ... hoge

タクソノミーを定義している箇所で（おおよそfunction.php内）

```
register_taxonomy(
		'hoge',
		'post',
		array(
-			'rewrite' => array( 'slug' => 'hoge' )
+			'rewrite' => array( 'slug' => 'not_hoge' )
		)
	);
```

とすることで、タクソノミーのurlに使われるslugを変更することで解消できた。

WordPress難しい。。。
GCEのインスタンスにpython3.7環境を構築するメモ

# 目的
サラのGCEのインスタンス上に python3.7.0 で実行できる環境を pyenv を使って構築するメモです．

# 環境
ブートディスクイメージ : Debian GNU/Linux 9 (stretch)

# 手順

以下のコマンドで必要なライブラリをインストール

```
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
```

pyenv を ダウンロードしパスを通す

```
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init -)"' >> ~/.profile
source ~/.profile
```

```
$ pyenv install 3.7.0
```

インストールが完了したら以下のコマンドでバージョンの確認， 適用をする．

```
$ pyenv versions
$ pyenv global 3.7.0
```

最後に以下のコマンドを実行して `3.7.0` が出力されれば成功

```
python -V
```

# 参考にさせていただいた記事
- [pyenvのインストール、使い方、pythonのバージョン切り替えできない時の対処法](https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b)
- [Common build problems · pyenv/pyenv Wiki](https://github.com/pyenv/pyenv/wiki/common-build-problems#prerequisites)
Expressでtwigのキャッシュ設定が効かない

Expressでテンプレートのキャッシュを切りたい場合、`app.set('view cache', false)`としてやればよいが、[twig](https://github.com/twigjs/twig.js)ではなぜか設定が反映されない。
調べてみると、どうやら`twig.cache(false)`で別途設定する必要があるよう。

 [Disable view cache in express · Issue #312 · twigjs/twig.js · GitHub](https://github.com/twigjs/twig.js/issues/312)

```js
var twig = require('twig');

app.set('view engine', 'twig');
app.set('views', viewsDir);
app.set('cache', false);

// disable twig cache
twig.cache(false);
```
LinuxでMacのゴミ箱内のファイルを削除して見た

#やったこと
LPICの勉強中なので、とりあえずコマンドでなんでもやってしまおう活動をしております。
今回は単純にMacのゴミ箱を無性にコマンドで空にしたくなったので、やりました。

#ゴミ箱の場所
```ruby:terminal
$ find ~ -name "Trash"
$ ~/.Trash
```
とりあえずTrashっぽい名前だろうと思って調べたらビンゴした。

#移動してみる
```ruby:terminal
$ cd ~/.Trash
.Trash $ ls -la
total 48
drwx------   5 me  group    160  5 28 17:57 .
drwxr-xr-x+ 51 me  group   1632  5 28 17:34 ..
-rw-r--r--@  1 me  group  14340  5 28 17:57 .DS_Store
-rw-r--r--   1 me  group    229  5 22 10:16 myfunc.js
-rw-r--r--@  1 me  group   1087  5 24 16:40 ■アジェンダ
```
とりあえずGUIで確認した内容のファイルが確認できた。

#削除ぉ！
```ruby:terminal
.Trash $ rm ./*
.Trash $ ls -la
.Trash $ 
```

#最後に
慣れればこっちの方が早いし、GUIへのモヤモヤも解消されそう
MFクラウド経費データをExcel から操作する

#概要
経費申請から承認、管理までをクラウドで行うことができるマネーフォワード社の「MFクラウド経費」のデータをデスクトップ版のExcel から取得したり、Excel からデータを更新する方法を紹介します。マスターデータの一括管理や、Excel からのMFクラウド経費のデータクレンジングなどに便利です。

![MF-Excel.png](https://qiita-image-store.s3.amazonaws.com/0/116843/23eb85e0-f559-efe2-652d-60ca21874da0.png)


#必要なサービス
* MFクラウド経費のアカウント　[無償トライアル](https://expense.moneyforward.com/registration/new?from=ex_top&to=ex_reg_new)あり
* Excel デスクトップ（2017以降）
* CData Excel Add-in for MF クラウド経費　[無償トライアル](https://www.cdata.com/jp/drivers/moneyforwardexpense/excel/)


#MFクラウド経費のAPI キーの取得
[MFクラウド経費 API の使い方](https://qiita.com/jonathanh/items/9abde240db098338a5b0) を参照してAPI キーを取得してください。


#CData Excel Add-in for MF クラウド経費のインストールと接続の確立
1. [https://www.cdata.com/jp/drivers/moneyforwardexpense/excel/](https://www.cdata.com/jp/drivers/moneyforwardexpense/excel/) から製品をダウンロードします。
2. .exe ファイルを実行して、インストールを行います。
3. Excel を立ち上げます。上部に「CData」タブができているはずですので、これをクリック。
4. 出てきたリボンから「MF Expense」のアイコンをクリックして、CData の設定画面を開きます。
5. 右上のボタンで接続ウィザードを開きます。

* 接続名：任意の接続名
* 有効な操作：更新、挿入、削除までを許容するかをチェック
* Callback URL: https://localhost:33333
* OAuth Client Id: Your Client ID
* OAuth Client Secret: Your Client Secret

入力して、「接続のテスト」を押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/f1f2fc5e-360a-a47a-cf2c-9e3c2418c9c5.png)

入力情報が正しければ、ブラウザで認証画面が開くので、アクセスを承認します。
![mfexpense4.png](https://qiita-image-store.s3.amazonaws.com/0/116843/6739c153-b8a5-220b-6e36-17f6a822dd5c.png)

「OK」を押して接続を確立します。

#Excel へのMF クラウド経費データのロード
CData データ選択画面で、テーブルをドロップダウンリストから選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/f8dcd6ef-f6ac-bb39-b833-108287e68b93.png)

テーブルに格納されている項目が「列」としてスキーマ付きで表示されます。Excel に取得したい項目にチェックを入れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/10f784ed-6634-9af0-ebaa-d04744ea5ef0.png)


最大行数はデフォルトは100に設定されています。

「クエリー」ボックスにカスタムクエリを入力可能です。デフォルトは列の項目のチェックを入れた項目を100レコードを上限に取得するクエリです。Where 項目でフィルタリングや、並び替えなどのクエリが可能です。
使用可能なSQL はこちらを参照：[http://cdn.cdata.com/help/LYD/xls/pg_overview.htm](http://cdn.cdata.com/help/LYD/xls/pg_overview.htm)

「OK」ボタンを押すとクエリが実行され、MF クラウド経費のデータ（画像はTransaction ）がExcel のテーブルにロードされます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/0aaa6c34-f21b-68bb-aced-6364d0169c88.png)

#Excel からデータを編集
明細データで例えば、JR東日本を東日本旅客鉄道に変更します。
Excel 上で複数の明細をすべて修正します。置換などを使うことも可能です。
変更されたデータは字が赤く表示されます。
データが変更された行を選択して、リボンの「行の更新」を押すと、Excel 上で変更したデータがMF クラウドに反映されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/ed75f8e8-23f1-1c31-7315-46e982dbc8cf.png)

更新されるとデータの表示が黒色に戻ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/46cc9bd6-4189-b45e-2a37-b3d00bc7ee11.png)


同様にデータの削除、挿入もExcel から「行の削除」ボタンや「行の挿入」ボタンで可能です。

以上
Pythonで簡易Socket通信

##1.環境
クライアント・サーバ：CentOS7
##2.ソースコード
####サーバー側
```
# -*- coding: utf-8 -*-
import socket

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #指定したホスト(IP)とポートをソケットに設定する
    s.bind(("localhost", 50007)) 
    #1つの接続要求を待つ
    s.listen(1)
    #要求が来るまでブロック
    soc, addr = s.accept()
    #サーバ側の合図
    print("Connected by" + str(addr))
    hoge = "hello hoge"
    q = "q"

    while(1):
        #入力待機(サーバー側)
        data = input("server>")
        #ソケットにデータ送信
        soc.send(data)
        #データを受信(1024byteまで)
        data = soc.recv(1024)
        #サーバー側の書き込み表示
        print("client>", data)
        #qが押されたら終了
        if data == "q":
            soc.close()
            break

    main()
```
次にクライアント側のコードを書いていきます。
####クライアント側
```
# -*- coding: utf-8 -*-

import socket

def main():
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.connect(("localhost", 50007))
    hoge = "hello hoge"
    q = "q"

    while(1):
        data = soc.recv(1024)
        #サーバ側の書き込みを表示
        print("sever>", data)
        data = input("Client>")
        #ソケットに入力したデータ
        soc.send(data)

        if data == "q":
            soc.close()
            break

    main()
```
##3.実行
ターミナルを2つ開き、サーバー側とクライアント側とを分けます。
先にサーバー側のスクリプトを実行し、その後にクライアント側のスクリプトを実行します。
入力待ち状態になったら、hogeとお互いに入力し、qと入力すればプログラムが終了する。

##4.メモ
今回は簡易的なソケットしか書けなかったので、これからもっと高度なコードをかけるようになりたい！
Pythonはソースコードがシンプルなので書きやすいし、読みやすい。
ffmpegを使って映像と音声を結合する

ffmpegを使って映像と音声を結合して一つの動画ファイルにするには、次のようなコマンドを実行します。

```
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 output.mp4
```

ポイントは`-c:v copy`を指定して動画を再エンコードしないようにしていることと、`-map 0:v:0 -map 1:a:0`を指定して元の動画ファイルに音声トラックが含まれている場合でも確実に音声ファイルの音声トラックを利用するようにしているところです。
元の動画ファイルに音声が含まれていないのであれば、`-map`の指定はなくても良いです。
Python3で漢字の文字コードを取得する

漢字の文字コードが知りたくなる時、皆さんありますよね。文字コードなんてネットで検索すればもちろんいくらでも出てくる情報ですが、今回はPython3上で漢字の文字からUnicode, Shift_JIS, EUC-JP, JISコード (iso-2022-jp), Big5の各文字コードを取得する方法です。例として漢字の「一」に対応する文字コードを取り出します。

```python:Python3
print("Unicode: {}".format(
    hex(ord("一"))[2:].upper()
))
# Unicode: 4E00

print("Shift_JIS: {}".format(
    hex(int.from_bytes("一".encode("shift_jis"), "big"))[2:].upper()
))
# Shift_JIS: 88EA

print("EUC-JP: {}".format(
    hex(int.from_bytes("一".encode("euc-jp"), "big"))[2:].upper()
))
# EUC-JP: B0EC

print("JISコード (iso-2022-jp): {}".format(
    (hex("一".encode("iso-2022-jp")[3])[2:]+hex("一".encode("iso-2022-jp")[4])[2:]).upper()
))
# JISコード (iso-2022-jp): 306C

print("Big5: {}".format(
    "".join([hex(x)[2:] for x in "一".encode("big5")]).upper()
))
# Big5: A440
```

環境に依存する可能性がありますが、Ideone.comで正しく動くことを確認しました( https://ideone.com/PEeAdx )。
cadlab.ioを使って回路図のバージョン管理を行おう

# Eagleについて

EagleとはAutodeskの回路図設計ソフトです。
https://www.autodesk.co.jp/products/eagle/overview
http://www.picfun.com/Eagleframe.html

もともとはCadsoftというドイツの会社が提供していましたが、買収されAutodeskが提供しています。

# 回路図設計のバージョン管理

設計書のバージョン管理は難しいです。
私は10年以上前からEagleを使っていますが、これだと思えるベストな管理方法がなかったです。

## Zip管理

* 電源基板_20180520.zip
* 電源基板_20180520.zip

といったZipファイルで管理する方法です。
わかりやすい、誰でもできるというメリットがある反面、
Zipファイルのやり取りが上手く行かなくなり。部分的な先祖返りが発生するというデメリットがありました。

## git管理

gitで管理してGitHub上で変更差分を見れるようにするという方法です。
ソフトウェアならこれでもいいのですが、設計図だとうまくいかないです。

<img width="1531" alt="sch.png" src="https://qiita-image-store.s3.amazonaws.com/0/107013/81411f2d-f7be-2e0e-63ef-6baf3a6246ca.png">

SchematicファイルをGitHubでみると、このようなXMLの差分が出てきます。
これだと実際に何かわからないので、手元にpullしてきてEagleで開いて確認という少々めんどくさい方法を行ってレビューします。

Zip管理と比べて先祖返りは発生しないけども、git学習してまで回路図をgit管理するメリットがあるかと言われると微妙な気がしました。

# cadlab.io

 こういった問題点を解決してくれるのがcadlab.ioです。

https://cadlab.io/

gitで管理されたEagleプロジェクトの変更差分を視覚的に表示してくれます。


<img width="1478" alt="Tutorial_project_-_Circuits_diff___CADLAB_io.png" src="https://qiita-image-store.s3.amazonaws.com/0/107013/43c63bf8-50eb-cf3f-0533-8eff90e2ef4f.png">


* 素子の追加や削除がわかる
* 抵抗値、静電容量値などの値の変更がわかる
* ボード図の変更差分がわかる

といったようにこれ以外にもたくさんのメリットがあります。
gitを使った回路図管理の問題点を解決してくれます。

# 終わりに

ハードウェア設計を行っていてEagleをつかっている人は導入したほうが良いです。
gitがわからない人は、これを機に勉強してみるのもありだと思います。
Slackでじゃんけんを行う方法

# はじめに
何かを決めなければいけない時が人生にはあります。

- 2社から内定もらった、どちらにしよう
- emacsかvimか*
- gitかsvnか ~~Excelか~~
- MySQLかPostgreSQLか
- 今日の昼は何食べる？
- グリコ, チヨコレイト, パイナツプル

(* アルファベット順)

しかし、往々にしてなかなか結論が出ないものです。

そんなときのために、人類はじゃんけんを発明しました。
じゃんけんは非暴力であり平等に複数の選択肢から1つを選ぶことができます。しかも特別な道具を必要としません。
なんと素晴らしい問題解決手段でしょうか。


# チャットシステムにおけるじゃんけん
じゃんけんは極めて有能でありますが、チャット上では難しいのが現状です。
公平のため参加者が同時に手を出す必要があり、その確認ができないためです。

# Slackにおけるじゃんけん
しかしながら、Slackであればじゃんけんを行うことが可能です。
もちろんappなどは使わず標準の機能で実現できます。

## Slackにおける複数人でのじゃんけん
### 設定方法

Slackbot Responseの設定ページ(https://_workspace_.slack.com/customize/slackbot)で、以下のようにトリガーとレスポンスを定義します。

- トリガー
  - `じゃんけん`
  - `あいこで`

- レスポンス
  - `:fist:`
  - `:v:`
  - `:raised_hand_with_fingers_splayed:`

![slack-janken-setting.png](https://qiita-image-store.s3.amazonaws.com/0/118352/6569419b-918d-4efc-994c-a15ea290acd4.png)
図1. Slack上でのじゃんけん用設定

### 理論
参加者が `じゃんけん` および `あいこで` と発言することでSlackbotが出し手を選択して表示します。
出し手はランダムに選択されるため、参加者の発言タイミングが一致せずとも公平なじゃんけんが成立します。

### 実行例
![slack-janken-1.png](https://qiita-image-store.s3.amazonaws.com/0/118352/1fd5a671-9db9-b776-209c-2327edfea93d.png)
図2. Slack上での2ユーザのじゃんけん対戦例

## Slackにおける一人でのじゃんけん
### 設定方法
前節と同様です。

### 理論
参加者が `じゃんけん` および `あいこで` と発言し同時に出し手を入力することで、Slackbotが出し手を選択して表示します。
Slackbotの出し手はランダムに選択されるため、Slackbotが後から手を出しても公平なじゃんけんが成立します。

### 実行例
![slack-janken-2.png](https://qiita-image-store.s3.amazonaws.com/0/118352/62059221-1b15-c54b-478b-5e85c7f82082.png)
図3. Slack上での1ユーザとSlackbotとのじゃんけん対戦例


# まとめ・考察
本記事ではSlack上でじゃんけんを行う方法を示しました。
これによりSlack利用者の円滑な意思決定とじゃんけんの上達が見込まれます。
今後はじゃんけん以外のさらなる勝敗決定システムをSlack上で実現する方法を研究予定です。
Coroutineの使い方

今回ゲーム開発において、ある条件（Trigger)でイベントを発生するとき、時間の制限を置きたい場合Coroutineを使うと便利だというのを分かったので記述しておく。

##コルーチン（Coroutine）とは？
簡単にいうと、あるイベントを処理するとき、必要によって時間の間隙を置いてイベントを処理できるようにする関数形式。
>[Unityレファレンス](https://docs.unity3d.com/jp/530/Manual/Coroutines.html)
関数を呼び出すと戻り値を返す前に実行完了されます。

例として、最近作っているゲームのソースコードを持ってきた。

```c#:prisming
public class ButtonEvent : MonoBehaviour {

	public GameObject prism;
    GameObject player;

	void Awake ( ) {
        player = GameObject.FindGameObjectWithTag("Player");
	}

	void Start ( )
	{
		prism.gameObject.SetActive(false);
	}

	void OnTriggerEnter ( Collider other ) {
       if ( other.gameObject == player ) {
           prism.gameObject.SetActive ( true );
		}

	}
    void OnTriggerExit ( Collider other ) {
		if ( other.gameObject == player ) {
			prism.gameObject.SetActive ( false );	
		}

    }

}
```
このコードはprismという物体をTriggerのボタンに触れたら見えたり、見えなかったりするプログラムである。
作りたかったプログラムは、見えてから５秒たったら見えなくなる動作をするプログラムだったので、ここでコルーチンを使ってみる。

以下がコルーチンを使った実装である。

```c#:prismingcoroutine

public class ButtonEvent : MonoBehaviour {

	public GameObject prism;
    GameObject player;

	void Awake ( ) {
        player = GameObject.FindGameObjectWithTag("Player");
	}

	void Start ( )
	{
		prism.gameObject.SetActive( false );
	}

	void OnTriggerEnter ( Collider other ) {
       if ( other.gameObject == player ) {
			StartCoroutine( "DisappearPrism" );
		}

	}

	IEnumerator DisappearPrism ( ) {
		prism.gameObject.SetActive( true );
		yield return new WaitForSeconds( 5.0f );
		prism.gameObject.SetActive ( false );
	}
}

```

こんな簡単な方法で、時間をおいて見えなくすることができる。

便利な機能であるが、毎フレーム処理しないといけない作業はUpdateを利用するのがコルーチンより良い。
コルーチンは一定時間待ってという命令をして、待ってからイベントを起こす形式だが、アップデートは毎フレームイベントを起こすためにある関数なので適度な使い分けをした方がいいと思った。
MacBook Pro Retina (Late 2013) の内蔵SSDを交換した

MacBook Pro Retina, 13-inch, Late 2013 の内蔵SSDが死んだ。
駄目元でSSDを換装したが簡単に交換修理出来た。
同じ状況に陥った人の役に立てたら嬉しい。

#免責事項
- 本記事によって生じたいかなる損害も筆者は保証できません。
- 本記事で紹介している操作を行うかどうかは、ご自身の自己責任でご判断ください。
- コメント欄などで助けを求められても、力になれない可能性が高いです。ご了承下さい。

# TL;DR
* MacBook Pro Retina, 13-inch, Late 2013 に [Transcend JetDrive 820 240GB](https://amzn.to/2GXiRoW) を交換出来た。
* **[Transcend JetDrive 820](https://amzn.to/2GXiRoW) へのSSD交換はオススメ出来る。**

***

# 交換したSSD

* [Transcend JetDrive 820 240GB](https://amzn.to/2GXiRoW)
* 他のメーカーの物もあるようだが、Transcend の方が信頼出来るのでこれにした。
* 価格はAmazonが最安値だった。

# 注意点

* [JetDrive 825](https://amzn.to/2sjveGC)という、JetDrive 820とThunderbolt対応のアルミ筐体ケースのセットもあるが、今回は内蔵SSDが死んでいるためケースは要らないので [JetDrive 820](https://amzn.to/2GXiRoW) にした。
    * **ケースが必要な際は [JetDrive 825](https://amzn.to/2sjveGC)**
* 駄目元ということもあり、256GB の内蔵SSDから 240GB のSSDに容量を減らし交換した。
* 容量を下げると Time Macihne バックアップからの復元が出来無いらしい。
* **Time Macihne バックアップからの復元を考えている場合は故障したSSDよりも容量の大きいものに交換したほうが安全なようだ。**
    * 例えば，256GB の内蔵SSDの場合，480GB の [JetDrive 820](https://amzn.to/2QzvpZJ) が良い。


# 交換方法

1. 付属のドライバーで MacBook Pro の裏面のネジを外し、開ける。
2. バッテリーと基板の接続部を外す。
3. 付属のドライバーで内蔵SSDを固定しているネジを外し、交換してネジで固定。
4. バッテリーと基板を接続して、裏面のカバーをネジで固定

以上。**10分もかからない。**

不安な場合はこの[動画](https://youtu.be/l_cZlRjewdk)を見て欲しい。
この[動画](https://youtu.be/l_cZlRjewdk)と付属の取説を見れば誰でも簡単に出来るだろう。

この後に
1. 「[macOS 復元](https://support.apple.com/ja-jp/HT201314)」から「[ディスクユーティリティ](https://support.apple.com/ja-jp/guide/disk-utility/dskutl1029/mac)」でSSDを[フォーマット](https://support.apple.com/ja-jp/guide/disk-utility/dsku19ed921c/mac)
2. クリーンインストール
した。

***
ちなみに、下記がSSDを交換するに至る故障の背景。

## 故障の症状 

* 突然フリーズし、何も受け付けなくなったので強制終了し再起動する。
* 起動音はするものの、黒い画面に?が描かれた白いフォルダが点滅表示され続ける。

## 故障個所の特定過程

* 「[macOS 復元](https://support.apple.com/ja-jp/HT201314)」の「[ディスクユーティリティ](https://support.apple.com/ja-jp/guide/disk-utility/dskutl1029/mac)」を使い、修復を図る。(インターネット経由なのでユーティリティウインドウの表示まで時間がかかった)
* 「[ディスクユーティリティ](https://support.apple.com/ja-jp/guide/disk-utility/dskutl1029/mac)」に進むも、内蔵SSDが非表示だった。
* これで、内蔵SSDが逝ったことを悟る。

## 対策
* 保障切れなので駄目元でSSDを換装する。
* Apple の有償修理よりも安く治せそう。

***
# まとめ
* MacBook Pro Retina, 13-inch, Late 2013 に [Transcend JetDrive 820 240GB](https://amzn.to/2GXiRoW) を交換出来た。
* 新しく MacBook pro を買わずに済み、10万円は浮いた。
* 新しいコンピュータに買い換える場合も、数万円でサブのmacになる。
* **[Transcend JetDrive 820](https://amzn.to/2GXiRoW) へのSSD交換はオススメ出来る。**

***
みなさんのお役に立てたら嬉しいです:wink:

Please donate at [wish list](http://amzn.to/343JRQu) if you find this useful:thumbsup_tone1:
【Python】 【NumPy】上三角行列から下三角行列・正方行列を作成（復元）する方法

# 正方行列の作成

```python
>>> import numpy as np
>>> Z = np.ones((5,5))
>>> Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)
>>> Z
array([[0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0.]])
```

# 正方行列 → 上三角行列
```python
>>> triu = np.triu(Z)
>>> triu
array([[0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 0., 1., 1., 1., 1., 0.],
       [0., 0., 0., 1., 1., 1., 0.],
       [0., 0., 0., 0., 1., 1., 0.],
       [0., 0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0.]])

```

# 上三角行列 →　下三角行列
```python
>>> triu.T
array([[0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0.],
       [0., 1., 1., 0., 0., 0., 0.],
       [0., 1., 1., 1., 0., 0., 0.],
       [0., 1., 1., 1., 1., 0., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0.]])
```

# 上三角行列 →　正方行列
```python
>>> array = triu + triu.T - np.diag(np.diag(triu))
>>> array
array([[0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 1., 1., 1., 1., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0.]])
```

おわり。
松尾研のDeep Learning基礎講座演習コンテンツをやってみた(chap2-Scipy)

#はじめるScipy
キーワード：逆行列、固有値、固有ベクトル、最適化
...おぉ、もうなんというか
いちおう全部知ってはいるのでとりあえず突っ込んでみよう。

#準備
ライブラリはimportよー

```
# Scipyのモジュール
import scipy as sp

# 線形代数用のモジュール
import scipy.linalg as linalg

# 最適化計算（最小値）用のモジュール
from scipy.optimize import minimize_scalar
```

#determinant-行列式-
行列式求められるとかすごいなー。手計算で4×4やらされたこともあったしこういうのはありがたみが深いですね。
**linalg**が線形代数用なんですね。

```
test_array=np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
print(linalg.det(test_array))
出力
-4.0
```

#invertible matrix-逆行列-
こちらも便利でなかなか早い

```
print(linalg.inv(test_array))
出力
[[ 0.  -0.5 -0.5]
 [-0.5 -0.  -0.5]
 [-0.5 -0.5  0. ]]
```
積もnp.dotでラクチン、単位行列Ｉになることが確かめられます。

#eigenvalue&eigenvector-固有値・ベクトル-

```
eig_value,eig_vector=linalg.eig(test_array)

print("固有値")
print(eig_value)
print("固有ベクトル")
print(eig_vector)

出力

固有値
[-1.+0.j  2.+0.j  2.+0.j]
固有ベクトル
[[ 0.577 -0.816  0.428]
 [ 0.577  0.408 -0.816]
 [ 0.577  0.408  0.389]]
```

#ニュートン法で解く方程式
こんなことまでメソッドひとつでできる!!

```math
f(x)=x^3+1 \\\
f(x)=0を解く
```
まず関数の定義

```
def test_function
    return(x*2-1)

```

では解きましょう

```
#import文
from scipy.optimize import newton
#計算
print(newton(test_function,0))

出力
1.0
```

解を出してくれました
虚数解があると上手くいかないのかな？

$x^3+1=0$や$x^3-1=0$だと0.00010000169277201161
がかえってきました

#minimize_scalar-最小値求値-
scipyの最後にこんな機能も...

```
print(minimize_scalar(test_function,method="Brent"))
```
出力

```
     fun: -1.0
    nfev: 37
     nit: 36
 success: True
       x: 4.4020875904303335e-09
```
min:-1(x=0)に一致するような結果になってますね。

では機能紹介はここまで
のこるは練習問題！！

#練習問題

<details><summary>問題１</summary>
```
A=np.array([1,2,3,1,3,2,3,1,2]).reshape(3,3)
print(A)
print('det:{:}'.format(linalg.det(A)))
```

<details><summary>問題２</summary>
```
print('inv:{:}'.format(linalg.inv(A)))
eig_value, eig_vector = linalg.eig(A)
print('eig_value:{val} \n eig_vector:\n{vec}'.format(val=eig_value,vec=eig_vector))
```

<details><summary>問題３</summary>
```
from scipy.optimize import newton
def practice_function(x):
    return(x**3+2*x+1)
print(newton(practice_function,0))
print(practice_function(newton(practice_function,0)))
```


#最後に
scipy,非常に便利な計算ライブラリですね
ニュートン法については次のページがいいと思います

[1]ニュートン法とは何か？？ニュートン法で解く方程式の近似解　@PlanetMeron さん
https://qiita.com/PlanetMeron/items/09d7eb204868e1a49f49
MF クラウド経費データにTableau からアクセスしてビジュアライズ

#概要
経費申請から承認、管理までをクラウドで行うことができるマネーフォワード社の「MFクラウド経費」のデータをTableau  からビジュアライズする方法を紹介します。他のデータソースと併せた分析などにも便利です。

![MF-Tableau.png](https://qiita-image-store.s3.amazonaws.com/0/116843/b517e331-3ba7-35a8-4344-37e86c543f76.png)


#必要なサービス
* MFクラウド経費のアカウント　[無償トライアル](https://expense.moneyforward.com/registration/new?from=ex_top&to=ex_reg_new)あり
* Tableau デスクトップ
* CData ODBC Driver for MF クラウド経費　[無償トライアル](https://www.cdata.com/jp/drivers/moneyforwardexpense/odbc/)


#MFクラウド経費のAPI キーの取得
[MFクラウド経費 API の使い方](https://qiita.com/jonathanh/items/9abde240db098338a5b0) を参照してAPI キーを取得してください。


#CData ODBC Driver for MF クラウド経費のインストールと接続の確立
1. [https://www.cdata.com/jp/drivers/moneyforwardexpense/odbc/](https://www.cdata.com/jp/drivers/moneyforwardexpense/odbc/) から製品をダウンロードします。
2. .exe ファイルを実行して、インストールを行います。
3. インストールを完了するとODBC DSN 画面および製品ドキュメントが開きます。OAuth 認証情報を入力します。
* Callback URL: https://localhost:33333
* OAuth Client Id: Your Client ID
* OAuth Client Secret: Your Client Secret

入力して、「接続のテスト」を押します。
![スクリーンショット (856).png](https://qiita-image-store.s3.amazonaws.com/0/116843/ce40bfd1-d994-30bc-fa97-c0bbfa1d85b7.png)

入力情報が正しければ、ブラウザで認証画面が開くので、アクセスを承認します。
![mfexpense4.png](https://qiita-image-store.s3.amazonaws.com/0/116843/6739c153-b8a5-220b-6e36-17f6a822dd5c.png)

ODBC DSN 画面で「OK」を押して接続を確立します。

#Tableau からODBC 経由でMF クラウド経費データの取得からビジュアライズ
1. 「接続」から「その他のデータベース(ODBC)」を選択。![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/e9e17db5-126e-96c7-2146-725241c80ac4.png)

2. 作成済みの「CData MFExpense Source」を選択して、「OK」→「接続」→「サインイン」します。ユーザー名やパスワードなどは空欄で大丈夫です。
3. データソース画面で、データベースのドロップダウンで「CData」を選択。スキーマの🔍マークを押して、MF クラウド経費のデータをリストとして表示します。ここから分析するデータを選択して、ドラグします。![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/e41b2a13-4544-8bcf-650e-d4be3fd2e438.png)


4. あとは、通常のデータソースと同じようにTableau 上でビジュアライズを作ります。
![スクリーンショット (863).png](https://qiita-image-store.s3.amazonaws.com/0/116843/64306145-f61a-f989-f72c-db8d85b6b4cf.png)



以上
Unity と Mac で開発する Oculus Go アプリ #3 ブラウザをデバッグする

Oculus & Unity 初心者が開発するまでのメモ


まずは[開発者モードをON](https://qiita.com/Sam/items/699ab94a2ebca67da14c)にした状態のOculusとmacbookをUSBで接続する

Oculus側で標準ブラウザを立ち上げる
<img src="https://qiita-image-store.s3.amazonaws.com/0/33505/c83ae4ad-020d-0b0c-101b-386e347f48c6.jpeg" width=50%/>

chromeで次のURLにアクセスする
[chrome://inspect/#devices](chrome://inspect/#devices)

<img width="70%" src="https://qiita-image-store.s3.amazonaws.com/0/33505/aeadf2aa-4953-9ace-e109-a171a0328390.jpeg">
デバッグしたいブラウザの inspect を開く

すると、別ウィンドウで見れるようになります
<img width="70%" src="https://qiita-image-store.s3.amazonaws.com/0/33505/bb6c725d-af38-0b27-5e83-e80f8d654d3b.png">

同じタブ内の操作なら、これでchromeからできます
Node.jsでJSONを読み込んで加工して書き出す


input.jsonを読み込んでoutput.jsonの形に整形して書き出すスクリプトです。
頻度は高くありませんが、ファイルを読み込んで何かをしたり、ファイルに書き出したりする場面があるので備忘録として残しておきます。

```convert.js

const fs = require('fs');

const jsonObject = JSON.parse(fs.readFileSync('./input.json', 'utf8'));
const result = {};

jsonObject.list.forEach((obj) => {
    result[obj.id] = obj;
});

fs.writeFileSync('./output.json', JSON.stringify(result));
```

```input.json

{
  "list": [
    {
      "id": "hoge",
      "name": "ほげ"
    },
    {
      "id": "fuga",
      "name": "ふが"
    }
  ]
}

```

```output.json

{
  "hoge": {
    "id": "hoge",
    "name": "ほげ"
  },
  "fuga": {
    "id": "fuga",
    "name": "ふが"
  }
}
```
[Review] Bidirectional RNN/LSTM

## Introduction
This paper explains the basic concept of Bidirectional RNN by making the benefits of this new architecture clear and its implementation as well.
The reason why I wrote this article was that I had to understand bidirectional LSTM which is used in state-of-the-art language models and sometimes by combining with other models, the model can obtain significant representational capability of languages.

## Bidirectional RNN
The idea has initially appeared in the great paper published by Mike Schuter et al in 1999.
Link: https://pdfs.semanticscholar.org/4b80/89bc9b49f84de43acc2eb8900035f7d492b2.pdf

However, I couldn't find any mathematical reference about the architecture.
So I have decided to proceed my research further.


### Architecture
I have create this ppt! lol
- Legacy RNN/LSTM
<img width="1141" alt="Screen Shot 2018-05-29 at 9.02.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/32b78e6a-453d-8080-4a9f-f6d16c172b07.png">

- Bidirectional RNN/LSTM
<img width="1058" alt="Screen Shot 2018-05-29 at 9.03.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/2e1241b7-bbb3-873b-d035-b1dd90969ad1.png">
<img width="1064" alt="Screen Shot 2018-05-29 at 9.03.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/ddafec92-0232-22b9-46f7-56480caeb49c.png">


## Maths
Regarding to basic RNN, please refer to this my article.
https://qiita.com/Rowing0914/items/6803fbc0af9163788a0c

Based on this, the Bidirectional RNN only differentiates its input.
Input should look like this.

```math
h_1^{(t)} = \sigma(W_{in}X^{(t)} + W_{hh_1}h_1^{(t-1)})\\
h_2^{(t)} = \sigma(W_{in}X^{(t)} + W_{hh_2}h_2^{(t+1)})\\
o^{(t)} = softmax(W_{out,h_1}h_1^{(t)} + W_{out,h_2}h_2^{(t)})
```

I did Proof of concept mathematically.
![IMG_0100.JPG](https://qiita-image-store.s3.amazonaws.com/0/240801/3c68e5eb-e6e6-ac1d-2421-602fcc103db6.jpeg)

```python:imdb_bidirectional_lstm.py
from keras.layers import LSTM, Bidirectional, Dense, Dropout, Embedding
from keras.datasets import imdb
from keras.models import Sequential
from keras.preprocessing import sequence
import numpy as np

max_features = 20000
maxlen = 100
batch_size = 32

print('Loading data...')
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')

print('Pad sequences(samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape: ', x_train.shape)
print('x_test shape: ', x_test.shape)
y_train = np.array(y_train)
y_test = np.array(y_test)


model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(Bidirectional(LSTM(64)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])

print('Train...')
model.fit(x_train, y_train, batch_size=batch_size, epochs=4, validation_data=[x_test, y_test])
```
https://github.com/keras-team/keras/blob/master/examples/imdb_bidirectional_lstm.py
Hyperledger Fabric on Azure触ってみた

## Hyperledger Fabric on Azureとは

Hyperledger Fabric（以下 fabric）はLinux Foundationがホストするビジネス・ブロックチェーン・フレームワークで、
許可制のネットワークを採用し、より機密保持性の高い取引を実現した、エンタープライズ向けプライベートブロックチェーンです。

このfabricはOSSでコードが公開されてはいるものの自身で環境を構築しようした場合には多くの技術的なハードルがあります。
（公式には簡単なチュートリアルしかない、ドキュメントがすべて英語、dockerの知識が必要 etc...）
つまり、その環境の上にアプリケーションを載せて実行する（fabricを使って本当にやりたいこと）までには多くの手間がかかるというわけです。

その環境構築をGUI操作で簡単に実現し、本来のシナリオやアプリケーションの構築に集中できるように、時間のかかる作業を自動化させたものが、[Hyperledger Fabric on Azure](https://azuremarketplace.microsoft.com/ja-jp/marketplace/apps/microsoft-azure-blockchain.azure-blockchain-hyperledger-fabric?tab=Overview)です。

## 構築手順
※fabricについての説明、用語の解説は割愛させていただきます。[参考サイト](https://www.ibm.com/blockchain/jp-ja/hyperledger.html)

1. AzureポータルのMarketplaceから【Blockchain】→【Hyperledger Fabric】を選択し作成ボタンを押します。
※対応のfabricバージョンは1.0.1（2018年5月現在）

![Marketplace.PNG](https://qiita-image-store.s3.amazonaws.com/0/206219/3c4ad96e-d9f3-fc02-72a8-79bfa2d8cd04.png)


1. 【基本設定の構成】に必要事項を入力します。
    - この際リソースグループを新規作成してfabric関連のリソースをまとめておくと便利です。

1. 【Network Size and performance】で各ノード数やスペックを設定します。
    - Membership Node(ca)とOrderer Nodesは現在1ノードしか立てれないみたいです。
    - Peer Nodesは２～９台まで選択できます。今回は２台を選択しました。
    - その他スペックやレプリケーション（冗長構成）の設定はデフォルトを使用しました。

1. 【Fabric Settings】では初回にMembership Node(ca)に登録されるユーザーのID/PWを設定します。
    - このアカウントを使ってメンバーを追加したり、チェーンコードをデプロイしたりします。
    - （いわゆる管理者アカウントでサービスプロバイダのイメージ）

1. 構成の確認後、購入ボタンを押すことでデプロイが開始され、10～20分程度で環境が出来上がります。

## 出来上がった環境

出来上がったリソースグループを見ると沢山のリソースが出来上がっていることがわかります。
簡単に構成図にまとめるとこんな感じ、
![構成図.png](https://qiita-image-store.s3.amazonaws.com/0/206219/7787951a-0c09-1a95-72f1-41a47fcd20a6.png)


- 各ノードは別々のVMとして存在しており、各VM(ubuntu)上でfabricのdockerイメージからコンテナが展開されている。
- かつ、それぞれのVMが可用性セット（同一リージョン内の別ラック）で冗長構成されている。
- 各ノードへのアクセスはロードバランサー経由で行われ、それ以外のアクセスは基本NSG（ネットワークセキュリティグループ）で制限している。

## コスト感

課金は通常のコンピューティング、ストレージ、ネットワークのみ​の課金で、ソリューション自体への課金はなありません。
その上で今回の構成を見積もりツールにて計算した結果がこちら
![cost.png](https://qiita-image-store.s3.amazonaws.com/0/206219/4ca17952-996a-0424-df49-92fea35955a0.png)

約34,000円/月
約1,200円/日

本番運用を意識した構成（1VMに1コンテナで各ノードが分散）になっている、「少し触ってみたい」や「PoCで一時的に使う」のようなユースケースの場合、少し高額な印象を受けました。

## 課題

簡単にfabricの環境が手に入るAzureテンプレートですが、実際に触ってみて以下のような課題があると感じました。

- 現状、単一のorganizationしか作成できず、fabricの特性であるコンソーシアム型のネットワークが構築できない。
- fabricのCLIコンテナが用意されていないので直接コマンドを実行できず、開発環境には向かない。
- fabricのアプリケーション開発フレームワークであるfabric composerを導入するのが困難である。（公式FAQより）
- 上記Composer用のテンプレートは近日公開予定とのこと。（2018年5月現在）

## まとめ

基本的かつシンプルなfabric環境が簡単に構築できました。
今後、複数Membership Node(ca)への対応や、Composer用テンプレートのリリースなど期待の持てる改善が予定されていたりと、動向を注視する価値はあると感じました。

またアップデートがあれば投稿します！