OmniAICreator/Qiita-1.07M huggingface dataset:
Coursera のMachine Learningコースを走破しました！

CourseraのMachine Learning講座を終了しました。
リンク先： [Coursera](https://www.coursera.org/learn/machine-learning/home/welcome "Coursera")

## 受けてみた感想
非常にわかりやすかったです。

自分は高校・大学時代は数学のできが悪かったので、数学に対する苦手感が激しかったし、コーディング技術にもそこまで絶大な自信がなかった状態だったのですが、思い切って受講してみよう思い、このコースに挑みました。

そんな自分でも、なんとか最後まで走破できたので、もし自信がなくて足踏みしている方がいるなら、ぜひ挑戦した方がいいよ！と言いたいです。ここまでわかりやすい授業ができるAndrew Ng 先生は、本当にすごい。

## 受講すると、何がわかる？
機械学習の学習プロセス、学習メソッド、そのメリットやデメリットなどがわかります。

ただ、受けてて思ったのは、まだまだこれは入門なんだろうなという事。本格的にやるなら、論文読んだり、専門書読んだりという形になると思います。自分はプログラマなので、どこまで専門的な領域まで突っ込まないといけないかは謎ですが。

さて、肝心の当コースについてですが、すでに何名もの方が書かれているので、自分は概要だけ下にさらっと記述します。

### 教師あり学習
学習メソッド
- 線形回帰
- ロジステック回帰
- ニューラルネットワーク、誤差逆伝播法、SVM
  
　内容を少し説明すると、医療検査から得られた数値から、ガン患者を検知したり、購買する家屋の値段を家の大きさや、部屋の数から予想するケースを例にあげて話が進んでいきます。このタイプは、学習の際に答えを提示してあげる必要あり。

　予測値と実測値（教師データ）の差分を求める関数（損失関数といいます）を扱う。損失関数の値が少ないほど、学習が進んでいることになる。コストの収束ポイントの検知は上の導関数を繰り返し処理にて求める。といった話がメイン。

### 教師なし学習
学習メソッド
- K平均法
- 主成分分析
- 異常検知
  
　写像、カーネル関数などでの次元を落とす話などがメイン。あとは損失関数の収束パターンなどについてとか。上に記述した教師あり学習は、分類、予測値を出すために使われることが多いが、教師なし学習は記事のカテゴリ分けやクラスタリングに使われることが多いらしい。

### その他
bias/variance、標準化、学習データを集める際のポイント、などなど
あと、Octaveが少し使えるようになります。


### 今学んでいること
いまは、[ゼロから作るDeep-Learning](http://www.amazon.co.jp/exec/obidos/ASIN/4873117585//ref=nosim/)を読んでいます。また読み終えたら、記事にします！

![ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://images-fe.ssl-images-amazon.com/images/I/512ru2i5gyL._SL160_.jpg)

## 最後に
ゼロから作る～を終えた後は、NLP(Natural Language Process)を勉強しようと考えているのですが、もしお勧めの本ないしオンラインコースなどをご存知な方がいましたら、アドバイスいただければ幸いです。

とりあえずは、この辺りをやればよい？
[https://github.com/oxford-cs-deepnlp-2017/lectures](https://github.com/oxford-cs-deepnlp-2017/lectures
)
[言語処理100本ノック](http://www.cl.ecei.tohoku.ac.jp/nlp100/)

ではでは。
Windows Subsystem for Linux上にsshdを立ててlocalhost宛にsshしてbashを使う

掲題の通りです。
僕は以下の宗教上の理由からteraterm信者なので、どうしてもteratermからbashを使いたいのです。

- 右上「✕」(もしくは<kbd>Alt</kbd>+<kbd>F4</kbd>)で閉じる際、「切断しますか？」と確認してくれる。
- コンソールログにタイムスタンプを付与できる。
- コンソールログに制御文字が残らない。

なので Windows Subsystem for Linux 上に sshd 立てます。

https://github.com/koginoadm/wsl/blob/master/service/install-wsl-and-sshd.bat
https://github.com/koginoadm/wsl/blob/master/service/sshd.bat

立てました。

※注意
上記スクリプトはWindowsファイアウォールの22/tcpに穴を開けます。
「localhostでしか使わない！」という方は、お手数ですがファイアウォールルールを削除してください。

おわり。
ロジスティック方程式の数値計算 with Python

# 本日は

一番簡単なロジスティック方程式を数値計算して行きませう．

## 概要

```math
\frac{\mathrm{d}y}{\mathrm{d}x} = y(1-y)
```

この微分方程式には

```math
y=\sigma(x)=\frac{1}{1+\exp(-x)}
```

という形の厳密解を持ちます． 深層学習で出てくるシグモイド関数です．
実際，シグモイド関数の微分を計算するとロジスティック方程式の解となることがわかります．
数値計算であればEuler法でも解くことができますので実際に確かめてみましょう．

##　実装例

```py3
import numpy as np
from matplotlib import pyplot as plt


def get_integral_curve(f, init_xy, x_end, delta):
    """
    solve ode 'dy/dx=f(x,y)' with Euler method
    """
    (x, y) = init_xy
    xs, ys = [x], [y]
    for i in np.arange(init_xy[0], x_end, delta):
        y += delta*f(x, y)
        x += delta
        xs.append(x)
        ys.append(y)
    return xs, ys


def main():
    """
    solve logistic equation dy/dx=y(1-y)
    """
    # set parameters
    init_xy = (0, 0.5)
    x_end = 5
    delta = 0.1
    # calc integral curve of logistic equation
    f = lambda x, y: y*(1-y)
    xs, ys = get_integral_curve(f, init_xy, x_end, delta)
    # calc explicit solution
    sigmoid_xs = np.arange(-5, 5, delta)
    sigmoid_ys = 1/(1+np.exp(-sigmoid_xs))
    # plot
    fig, ax = plt.subplots()
    ax.plot(xs, ys, "x", color='blue', label="integral curve")
    ax.plot(sigmoid_xs, sigmoid_ys, "-", color='red', label='explicit curve')
    ax.legend()
    ax.set_xlim([-5, 5])
    ax.set_ylim([-0.5, 1.5])
    plt.show()

if __name__ == '__main__':
    main()
```

## 動作例
![logistic.png](https://qiita-image-store.s3.amazonaws.com/0/135978/a5272f57-af56-9b7c-0bb9-17e5bfb7b3bc.png)
ruby 2.4.0 CSV の liberal_parsing オプションについて調査してみた

# 概要

ruby 2.4.0 から、CSV に `liberal_parsing` オプションが追加された

- [リリースノート](https://docs.ruby-lang.org/ja/latest/doc/news=2f2_4_0.html)
- 当該PR → [#1160](https://github.com/ruby/ruby/pull/1160)

これによって、[RFC4180](https://www.ietf.org/rfc/rfc4180.txt)を無視してフィールド内に置かれた、エスケープされていないダブルクォートを読み込むことができるようになった

実用に足りるか細かい挙動を調査したので、それをメモ

# 調査した感想

- RFC4180に準拠しているフィールドと、そうでないフィールドが混在しているときに使うのを想定している様子
    - たとえば `"a""a""a",b"bb` みたいな
- そういう使い方ならばオススメ。 **ただし、ダブルクォートのとじ忘れは、今までと同様にパースに失敗する場合がある**
- 文中に改行も無く、ダブルクォートに囲まれたフィールドを期待していないのであれば、`String#split(',')` を使ったほうが速いし、上記のような問題も発生しない


# `liberal_parsing` オプションの挙動をざっくり説明

ruby 2.4.2 の挙動

- **ダブルクォートに囲まれたフィールドの場合、 `liberal_parsing` があってもなくても今までと同じ挙動**
- ダブルクォートに囲まれていないフィールドの場合、
    - フィールド内にあるダブルクォートに特別な意味を持たせずにパースする
        - `a,bb"b,c` ならば `["a", "bb\"b", "c"]`
    - **フィールドの先頭にダブルクォートがあって末尾にない場合、文中のダブルクォートの数が奇数だとパースに失敗する**
        - 例 `a,"b"b"b,c`
            - 既存のダブルクォートに囲まれた文字列のパースの実装とバッティングしている? バグと言ってよいのかな...?
        - フィールドの先頭にダブルクォートが無くて末尾にある場合は、ダブルクォートの偶数奇数に関わらずパースされる
            - 例 `a,b"b"b,c`


# 参考

色々なCSVを `liberal_parsing` オプションをつけてパースした結果


##ダブルクォートに囲まれたフィールドの場合

`liberal_parsing` オプションに関わらず、今までと同様の挙動

### 正しくエスケープされたダブルクォートの場合
```01.csv
a,"bb""b",c
```

RFC4180に合わせてダブルクォートが処理される

```.rb
CSV.parse(csv, liberal_parsing: true) #=> [["a", "bb\"b", "c"]]
```

### 文中にエスケープされていないダブルクォートがある場合
```01.csv
a,"bb"b",c
```

例外が発生する

```.rb
CSV.parse(csv, liberal_parsing: true) #=> Unclosed quoted field on line 1.
```

##ダブルクォートに囲まれていないフィールドの場合

### 途中にダブルクォートがある場合
```01.csv
a,bb"b,c
```

恐らく、こういうパターンを救いたいが為の `liberal_parsing` オプション
ダブルクォートに特別な意味を持たせずにパースされる

```.rb
CSV.parse(csv, liberal_parsing: true) #=> [["a", "bb\"b", "c"]]
```

### 途中にエスケープされたダブルクォートがある場合
```01.csv
a,bb""b,c
```

ダブルクォートに特別な意味を持たせないのでエスケープは無視される

```.rb
CSV.parse(csv, liberal_parsing: true) #=> [["a", "bb\"\"b", "c"]]
```

### 先頭にのみダブルクォートがある場合
```01.csv
a,"bbb,c
```

RFC4180に準拠したフィールドであるかどうか確認している途中で末尾に到着して、`MalformedCSVError` が発生
これを救いたければ、CSVライブラリは使わずに、`split(',')` した方が良さそう

```.rb
CSV.parse(csv, liberal_parsing: true) #=> Unclosed quoted field on line 1.
```

### 先頭と途中にダブルクォートがあって、ダブルクォートの合計が偶数の場合
```01.csv
a,"bb"b,c
```

この場合は救われる
実装を斜め読みする限り、既存のダブルクォートをパースする処理との共存のためにそうなっている

```.rb
CSV.parse(csv, liberal_parsing: true) #=> [["a", "\"bb\"b", "c"]]
```

### 先頭と途中にダブルクォートがあって、ダブルクォートの合計が奇数の場合
```01.csv
a,"b"b"b,c
```

奇数の場合は例外になる
この辺を救いたければ(ry

```.rb
CSV.parse(csv, liberal_parsing: true) #=> Unclosed quoted field on line 1.
```

### 末尾と途中にダブルクォートがある場合
```01.csv
a,bb"b",c
```

この場合は、フィールド内のダブルクォートが奇数だろうが、偶数だろうが例外は発生しない

```.rb
CSV.parse(csv, liberal_parsing: true) #=> [["a", "bb\"b\"", "c"]]
```
EC2でプロビジョニングしたインスタンスをAMIにする

# 目的

ケチなのでEC2でこまめにGPUノードを作ったり消したりしたい。毎回ファイルをインストールし直すのは時間がもったいないし、既存のAMIは一長一短でどうも気に入らない。自分でインスタンスをプロビジョニングして、AMIを作る。

# 手順

1. プロビジョニング対象のインスタンスを用意する。"Ubuntu Server 16.04 LTS (HVM), SSD Volume Type - ami-6e1a0117"を"g2.2xlarge"[^1]でスポットインスタンスを要求する[^2]。なお、インストール容量が必要なため、"EBS volumes"にて"Root"は20GBとした。

[^1]: GPUをプロビジョンするのにGPUノードである必要があったかは不明。
[^2]: "EBS volumes"で"Root"の"Delete"オプションをオフにしたほうがよかった。後述。

2. [Ansible playbook](https://github.com/koreyou/ec2-provision-playbook)を使ってインスタンスをプロビジョンニングする。なお、上記AMIには `python`がインストールされていないので、事前にsshで入ってインストールする。

3. インスタンスを止める[^3]。ボリューム選びスナップショットを作成する。

[^3]: 今回は"EBS volumes"で"Delete"を入れ忘れたので、とめずにやってしまった。

4. スナップショットを選び"Create Image"でイメージを作成する。 "Virtualization type"を"Hardware-assisted virualization"にすること (GPUを使うために必要）。

以上
【私的メモ】チャットボットに関するリンク集【圧倒的情報不足により随時更新】

PHPの勉強のためにチャットボットを作ることになり、情報収集しました。
下記はそのリンク集です

此ノ木よしるの今日も更新しません
http://konogi.sub.jp/blog/?cat=9

下ネタのチャットボットっていいですねｗ

チャットボット（Chatbot）とは【人工知能との関係、開発の方法】
https://hitobo.io/blog/overview-of-the-chatbot/

APIの紹介もあって嬉しいｗ

Botブームに乗り遅れた人たち用】Chat Bot（チャットボット）についてまとめてみたよ。
http://qiita.com/kanottyan/items/2783bf91c8ea6a8a4ce8

概論見たな話です
APPTVRepeater (ESP8266) > ハードウェアの準備 > 赤外線送信基板の実装 (x2)と動作確認

```txt:動作確認
- ESP-WROOM-02 (以下、ESP8266)
- ユニーバサル基板実装
- Arduino IDE 1.6.6
- Canon IXY 3
```

[ESP8266 > 検討 > APPTVRepeater > 英語リスニング補助ツール (定数時間の巻き戻し機能)](https://qiita.com/7of9/items/5f20327af0574f80cd6b)
の続き。

今後の検索用にキーワードとして「APPTVRepeater」とした。

この記事では、赤外線送信基板を実装した。

### 基本回路

[macsbugさんの記事](https://macsbug.wordpress.com/2015/11/29/%E8%B5%A4%E5%A4%96%E7%B7%9Aled%E3%83%AA%E3%83%A2%E3%82%B3%E3%83%B3%E3%81%AE%E5%88%B6%E4%BD%9C/)を参考にしました。
情報感謝です。

今回はESP8266で使うため、R2を接続している+5.0Vを+3.3Vにした。

R2V = 3.3 - (1.2 + 0.5) = 1.6V
R2 = 1.6V/500mA = 3.3Ω
となった。

### ベース基板

ESP8266を搭載するベース基板。
[こちらの回路図](https://qiita.com/7of9/items/bc96d1cf17d4d87e1fcd#%E5%9B%9E%E8%B7%AF%E5%9B%B3)を基本とし、下図の「３」の上にピンを出している。

![IMG_0964.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/149232f8-43ec-92d4-072a-407d33f49e12.jpeg)

| 位置 | ピン |
|:-:|:-:|
| -  | GND |
| -  | IO5 |
| -  | IO4 |
| -  | VCC (3V3) |

このピンに接続する赤外線送信基板を実装する。
GND, IO4, VCCを使う。

電池はCR123Aを使う (写真左上のXHPケーブルの先にCR123A用ケースがついている)。

### 関連ICの入手

シリコンハウスからネコポスを利用して購入した。
土曜日の10時に発注して、投函されたのは木曜日。
送料280円。

急ぎの時は休みの日に買いに行く方がよさそう。

購入したのは以下

- 2SC2655-Y
- OSI5LA5111A
- L-53F3BT
    - 以前、[こちら](https://qiita.com/7of9/items/8d7c6e5407ca31ed6080)や[こちら](https://qiita.com/7of9/items/7c031af2f629f288bf66)で使用
- 酸金抵抗 2W 10Ω
    - 間違って購入。
    - **実際に使ったのは手持ちのカーボン抵抗3.3Ω。**
- 酸金抵抗 2W 680Ω

酸金抵抗というのは中電力向けのようだ。P=VIの計算でどれくらいになるかに合わせてカーボン、金被、酸金から選択する。

### 実装基板

部品面
![IMG_0965.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/49e72514-e4a3-f81c-f065-bb82d77a91b7.jpeg)

左はOSI5LA5111A使用、右はL-53F3BT
左の基板はDAISENの基板。右は両面TH丸型ユニバーサル基板 27mm(ペットボトル基板)
(参照: https://qiita.com/7of9/items/ce8df84d6133336de7c6)
右の基板は2017年9月現在廃版のよう？

はんだ面
![IMG_0966.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/ab281873-9b49-9e01-f8a6-1ba28344a770.jpeg)

### 動作確認ソフト

```c:esp8266_170923_APPTVrepeater
#include <ESP8266WiFi.h>

/*
 * v0.1 Sep. 23, 2017
 *   - turn on/off the IR pin to check the device
 */

static const int kPinIR = 4;

void setup() {
  WiFi.disconnect(); // watch dog reset対処
  Serial.begin(115200);
  pinMode(kPinIR, OUTPUT);
}

void loop() {
  Serial.println(F("ON")); // F() to reduce RAM usage
  digitalWrite(kPinIR, HIGH);
  delay(1000); // msec

  Serial.println(F("OFF")); // F() to reduce RAM usage
  digitalWrite(kPinIR, LOW);
  delay(1000); // msec
}
```

### 動作確認

それぞれの基板で動作させて、デジカメ(IXY3)でのぞき込む。

1枚目OK。
![IMG_0962.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/525fab30-c92a-4e35-b12a-d04a634b7d67.jpeg)

2枚目OK。
![IMG_0963.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/4c9c3a88-0436-d110-7942-b86f5a1575b9.jpeg)
【速報：2017/09/23】Reactのライセンスから特許条項が外れて真のオープンソース・ライセンスになる

# 背景
Facebookが開発し、JavaScriptライブラリーとして人気を誇るReactですが、これまでBSD + Patentsライセンスのもとでリリースされていました。
これはFacebookが特許関連の問題で訴えられた場合にReactを利用できなくするための防御的な意味を持っていたのですが、Reactを利用していた製品やオープンソース・プロジェクトから「Reactを排除するべきだ」ということで、最近騒ぎになっていました。
（詳細はこちらの記事[『React死亡?React終了?～Facebookの特許事項付きライセンスの問題～』Qiita](https://qiita.com/exli3141/items/a36b9bc88d818efb3331)を参照）

# Reactライセンスの変更
上記の騒動を受けてReactの開発チームは、もうすぐリリースされる次期バージョン（React v16）から、関連するいくつかのソフトウェアを含めてライセンスを変更し、特許条項を外すことにしました。
具体的には、これまでBSD + Patentsだったものを普通のMITライセンスに変更することで、他のオープンソース・ソフトウェアのプロジェクトで安心して利用できるようにしたのです。ちなみに対象のソフトウェアもReact本体をはじめ、Jest、Flow、immutable.jsとReact関連のものは一式含まれています。（ReduxはもとからMITライセンスなので心配ありません）
詳しくは下記の記事を参照してください。

参考：[Facebook Engineering Blogの記事](https://code.facebook.com/posts/300798627056246/relicensing-react-jest-flow-and-immutable-js/)

# おわりに
何はともあれ、Reactが安心して使えるようになってよかったです。（最新版へのアップデートが必要ですが）
Reactから他のライブラリーやフレームワークに乗り換えを検討していた方も結構いるようなので、このことを早めに知っていただければ幸いです。（もう、乗り換えてしまった方には残念なニュースですが・・・）
Mackerelを別サーバへ引っ越す


## Mackerel-agentを停止する

```
sudo /etc/init.d/mackerel-agent stop
```

## サーバ起動時設定からMackerelをはずす
サーバ起動時に自動で上がるサービスの一覧を確認する

```
$ chkconfig --list
（略）
mackrel-agent   	0:off	1:off	2:off	3:off	4:off	5:off	6:off
```

該当する設定をはずす

```
$  chkconfig --del mackrel-agent
```

## サーバ発行のIDファイルを削除
```
rm /var/lib/mackerel-agent/id
```

## 移行する先のMackerelのAPI KEYを取得
DashboardのOverview＞詳細にあります。
![APIKEY](https://qiita-image-store.s3.amazonaws.com/0/1593/4aff7fe5-00b5-6a4f-b9e0-777b6a16d2b4.png)

## 移行先にMackerel-agentをインストール
Hostの設定からエージェントのインストール方法が出ています（下図参照）。GCPのRedhatサーバだと以下の通り。

![新規ホストの登録](https://qiita-image-store.s3.amazonaws.com/0/1593/7c49646f-fa1b-b17f-cc2c-7665116c2c83.png)

```
curl -fsSL https://mackerel.io/file/script/setup-all-yum.sh | MACKEREL_APIKEY='xxx' sh
```
必要に応じてプラグインをインストールします（以下参照）。
https://qiita.com/hardreggaecafe/items/f7af6a5d98028bda13c8

## （プラグインインストール後）mackerel-agent.confのapikeyより下をコピーして書き換え

```
apikey = "xxx" # エージェントインストールで勝手に追加される
# pidfile = "/var/run/mackerel-agent.pid"
# root = "/var/lib/mackerel-agent"
# verbose = false
（略）
[plugin.checks.check_httpd]
command = "check-procs --pattern httpd"
[plugin.checks.mysql_connection]
command = "check-mysql connection --host=xxx --port=3306 --user=xxx --password=xxx --warning=250 -- critical=280"
```

## Mackerel-agentを再起動

```
sudo /etc/init.d/mackerel-agent restart
```

## 移行完了
うまくいくとホストが登録されて以下のように各種メトリクスが計測できるようになります。
![mackerel.png](https://qiita-image-store.s3.amazonaws.com/0/1593/69557e0d-0971-6c03-d837-c5940d1edd0c.png)
sitemap_generatorの使い方

## sitemap_generatorとは
sitemap_generatorはサイトマップを作成してクローラに送信するしてくれるgemです
[公式Github](https://github.com/kjvarga/sitemap_generator)

## 環境
sitemap_generator：5.1.0
Rails：4.2.2

## ① Google Search Consoleにドメインを登録
[Google Search Console](http://g.co/SearchConsole)へドメインを登録します

## ② インストール

```rb:gemfile
gem 'sitemap_generator'
```

## ③ プログラムから送信
ソースのサンプルです
ブログを例にすると記事投稿時に以下のような処理を入れる

```rb:controller
def hoge

  # 本番のみ送信
  if Rails.env == 'production'

    # サイトのホスト名
    SitemapGenerator::Sitemap.default_host = 'http://hogefuga.com'
    SitemapGenerator::Sitemap.create do
      SitemapGenerator::Sitemap.add '/', :changefreq => 'daily', :priority => 0.9

      Article.all.each do | value |
        SitemapGenerator::Sitemap.add "/contents/#{value.id}", :lastmod => value.updated_at
      end
    end

    # サイトマップを送信
    SitemapGenerator::Sitemap.ping_search_engines
  end
end
```

プログラムから送信するだけなら設定ファイルはなくても問題なさそう

## その他オプション・コンフィグ
下記リンクが参考になると思います
コンフィグを設定し、crontabで動かすのがメジャーみたいです

[[Rails 4.1] sitemap-generator を使って Sitemap を作成する。](http://qiita.com/satomyumi/items/0864a082a0cee7bfaf93)
[【Ruby on Rails】sitemap-generator の超簡単な使用方法](http://qiita.com/andeight/items/72b599410171037ef840)
gitのタグを一括削除する

## タグ一覧を取得
```bash:terminal
git tag --list
```


## grepでマッチしたリモートのタグを全て削除する
```bash:terminal
git tag | grep "hotfix_" | awk {'print ":" $1'} | xargs git push origin
```

## 例）「hoge」タグ以外のリモートのタグを全て削除する
```bash:terminal
git tag | grep -v "hoge" | awk {'print ":" $1'} | xargs git push origin
```

リモートのタグを削除しても、だれかがローカルのタグをPUSHしてしまうと
タグが復活してしまうので


「みなさんフェッチしてくださ～い！！」
と声をかける必要がある。（なんとめんどくさい...）

<br>

![fetch.png](https://qiita-image-store.s3.amazonaws.com/377/40799/7267535e-8cd9-1af0-e643-bf6b0016deac.png)


<br>

なにか他にいい方法あるんですかね。



----------
cifsでmount error(22): Invalid argumentの場合、ver2.1を付ける

* windows機側のレジストリ値を修正すれば治る、という情報もあったが、レジストリ変更不要の方法を発見。
* [networking - Why am I getting Mount Error (121), Remote I/O Error? - Ask Ubuntu](https://askubuntu.com/questions/808712/why-am-i-getting-mount-error-121-remote-i-o-error)


```sh:失敗例
$ sudo mount -t cifs -o username="user1",password="pass1",rw,uid=1000,gid=1000 \
    //192.168.100.2/share /mnt/share
mount error(22): Invalid argument
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
```

```sh:ver2.1を付ければ成功した
$ sudo mount -t cifs -o username="user1",password="pass1",rw,uid=1000,gid=1000,vers=2.1 \
    //192.168.100.2/share /mnt/share
```
ちょっとずつ読むドメイン駆動設計 第ニ部 モデル駆動設計の構成要素 第四章 ドメインを隔離する4

# レイヤ化アーキテクチャの難点
![レイヤ化アーキテクチャ.png](https://qiita-image-store.s3.amazonaws.com/0/150455/b5db10cf-2934-16ca-1a2e-73b815535238.png)

[先日](https://qiita.com/YasuhiroKimesawa/items/22a36fd340075396d064)DDD本で紹介されているレイヤ化アーキテクチャは、上図の通り、モデルがインフラストラクチャに依存してしまっていると書きました。

たとえばどんな時にそうなるかというと、あるオブジェクトがアプリケーション全体で一意であることを確認するために、モデルがインフラストラクチャに問い合わせて、DB内のテーブルを検索する、などなど。。。

では、どうするか。いくつかの候補が「[実践ドメイン駆動設計](www.amazon.co.jp/dp/479813161X)」で紹介されているので、暫くの間こっちを読んで行こうと思います。

## 他の選択肢 DIを使う
![DI (2).png](https://qiita-image-store.s3.amazonaws.com/0/150455/b83001be-0dae-b3f6-5e10-f5f55192764d.png)



> 上位モジュールは下位モジュールに依存してはならない。どちらのモジュールも、抽象に依存すべきである。抽象は、実装の詳細に依存すべきではない。実装の詳細が、抽象に依存すべきである。(実装ドメイン駆動設計 4.2レイヤより)

先ほどの例
> あるオブジェクトがアプリケーション全体で一意であることを確認するために、モデルがインフラストラクチャに問い合わせて、DB内のテーブルを検索する

で言えば、モデルはインターフェイスであるRepositoryを呼び出し、その実装はインフラストラクチャでされているが、DIを使用してインフラストラクチャの実装自体はモデルから隠蔽させます。

以下ソースコード例です

(DI使用前)

```java:SomeModel.java
// domain層
public SomeModel{
  // infrastractureに依存している
  Repository repository = new SomeInfrastracture();

  public isExist(){
    repository.find();
  }
}

interface Repository{
  find();
}

public SomeInfrastracture implements Repository{
  @override
  find(){・・・｝
}

```
(DI使用後)

```java:SomeModel.java
// domain層
public SomeModel{
　　　// 依存性注入によりinfrastractureの依存が隠蔽された
  @Autowired
  Repository repository

　　　　public isExist(){
    repository.find();
  }
}

interface Repository{
  find();
}

// infrastracure層
@Repository
public SomeInfrastracture implements Repository{
  @override
  find(){・・・｝
}

```


また、上記図ですが、書籍で示されている図よりもっとシンプルにしました。
自分のこれまでの経験では、インフラストラクチャがユーザーインターフェイスを使うことはなかったし、アプリケーションを利用することもなかったです。

また、書籍ではユーザーインターフェイスはドメインを利用しないような図になっていましたが、ユーザーインターフェイスからのデータをモデルに変換する責務をアプリケーションレイヤが負っているのですかね。。。

自分が利用してきたSpringFrameworkではユーザーインターフェイス(SpringFrameworkではController)で自動的にモデルに変換してくれるので、ユーザーインターフェイスがモデルを使用している図になっています。

いずれにしても大事なことは**モデルがどこにも依存していない**こと、です。
最近便利だと思ったshellテクニック

# 最近便利だと思ったshellコマンド

いきなり全然関係ないですが、すごい投稿がすごい久しぶりだ。。。（ってか2投稿目）。もっと頑張ろうと思いました。（無理）
ここではshellのコマンドやテクニックで便利だ！思ったけど、少し期間が空くとすぐ忘れちゃうので備忘目的でつらつらと書きます。

最近、システム構築の案件で触ることが多いので、
ここで見つけた良いと思うテクニックは忘れないようにしたいです。

## paste [files,...]

文字列の水平結合、ある結果をExcelにまとめたいけど手でコピペとかめんどい！ってなったときに便利だった。
デリミタも指定できる

```shell-session
$ cat file1
aaa
bbb
ccc

$ cat file2
AAA
BBB
CCC

$ paste file1 file2
aaa AAA
bbb BBB
ccc CCC
```

## diff <(command1) <(command2)

shellの中で似たcurl結果同士を比較したいんだけど、わざわざファイルにするのイヤな時に便利だった。

```
CURL1=`curl http://localhost/rest/hoge1`
CURL2=`curl http://localhost/rest/hoge2`

# echo -e "$VAR"　で複数行で出力
RET=`diff <(echo -e "$CURL1") <(echo -e "$CURL2")`

if [ ! "$RET" = "" ]
  echo "find difference"
fi
```

いきなりたくさんやると、また疲れてしまうから今日はこれまで
ジェネリクスがないPHPでも配列中身のタイプヒントを可能にする「Splat Operator」

PHP7現在ではジェネリクスっぽいタイプヒントが書けない。したがって、配列の中身の型が決まっている関数でも、タイプヒントには`array`を受け取ることを明示するのが最大限だ。

ジェネリクスに対応している言語であれば、`doSomething(array<DateTime> $dates): void`のように配列の中の型まで固められる。このおかげで、事前条件チェックが効いて期待しない型の混入にも気づきやすいが、PHPではそうもいかない。なかなか歯がゆいものがある。

```php
<?php

/**
 * @param DateTime[] $dates
 */
function doSomething(array $dates): void
{
}

$dates = [
    new DateTime('today'),
    new DateTime('tomorrow'),
    new DateTime('yesterday'),
    null, // 🔥DateTimeじゃないものが紛れている🔥
];

doSomething($dates);
```

このコードは実行してもエラーにならない。

phpdoc(関数の上のコメント)に`DateTime[]`と書いてあるが、IDEや静的解析ツールではこれを見て検査してくれるかもしれないが、PHP実行時には何の拘束力にもならない。

PHP7.1では`string`などのタイプヒントも実装され、いよいよphpdocでのドキュメントなしでも、関数に何を渡したら良いかを伝えられるコードが書きやすくなった。一方で、配列を受け取る関数ではまだまだphpdocを書かないとユーザやIDEに関数の仕様を伝えにくいという別の問題もある。

## 配列の中身をタイプヒントする裏ワザ

極めて限定的な局面になるが、配列の中身の型を明示する方法がPHPにもある。Splat Operatorを使う方法だ。`...`がそれだ。これは可変個引数の関数を実装するためのものだが、タイプヒントとも組み合わせることができる。

先程のコードをSplat Operatorで実装しなおすと次のようなコードになる。

```php
<?php

function doSomething(DateTime... $dates): void
{
}

$dates = [
    new DateTime('today'),
    new DateTime('tomorrow'),
    new DateTime('yesterday'),
    null, // 🔥DateTimeじゃないものが紛れている🔥
];

doSomething(...$dates);
```

コレを実行すると関数呼出し時にエラーになる。

> PHP Fatal error:  Uncaught TypeError: __Argument 4__ passed to doSomething() must be an instance of __DateTime__, __null__ given

Splat Operatorはあくまで可変個引数関数を実装するための機構なので限界はある。まず、配列を複数受け取る関数ではこの裏ワザは使えない。`f(array $a)`は`f(A... $a)`に書き換えできるが、`f(array $a, array $b)`は`f(A... $a, B... $b)`とはできない。

また、Splat Operatorは最後の引数にしか使えない。`f(string $a, array $b)`は`f(string $a, A... $b)`に書き換えできるが、引数が逆の`f(array $a, string $b)`は`f(A... $a, string $b)`と書くことはできない。

限定的な場面でしか使えないが、`array`とだけタイプヒントに書くよりは固いコードが書けそうではある。
Androidの拡張ファイル(.obb)の罠

Androidアプリのサイズが100MBを超えるとapkとobbに分割する必要がある。
しかし一部の端末でobbが読み込めずアプリが正常動作しないというバグがある。
再現条件や対処法について書く。

# TL;DR

- 根本的な解決策はなさそう:innocent: 
    - 何かご存じの方いらっしゃいましたらぜひコメント等で教えて下さい！:bow:
- 端末を再起動すると何故か読めるようになる:confused:
- Samsung製:milky_way:端末全般、ZTE製MO-01Jで再現した
- 結論
    - 100MB超えないようにする:arrow_double_down: 
    - それができない場合はREAD_EXTERNAL_STORAGEパーミッションを付加することで回避:disappointed_relieved:

# 対象読者

Androidアプリ開発者

# 問題にぶち当たった経緯

Unityで大きな動画ファイルを内包したアプリを開発していた。
いよいよ公開準備という段になり、念のためPlayストアからクローズドβテストを行った。
するとあるSamsung製端末で最初のシーン以降が動作しない（最初のシーンから次のシーンに遷移できない）という現象が発覚した。
テスト時はうまく行っていたのに…:sob:

違いといえばストアに公開するためapkを分割したことくらいである。
（それまでは巨大なapk1つでインストールしていた）

# 調査開始

## ログを見る
特にエラーは出ていない。
シーン切り替え部分で処理が進まなくなっているように見える。

## obbが無いのでは？
ちょうど2つ目のシーンから先に進めないので、obbが無いと考えると辻褄が合う。
（※apkには1つ目のシーンだけが含まれ、obbにはその他が含まれる）
ファイラーアプリで`Android/obb/[package name]`を見てみると、obbは確かに存在している。
バイト数も一致しているし、ファイルが無い・壊れているということではなさそう。

## obb無しでインストール
apk+obbに分割ビルドしたものを、apkファイルだけでインストールしてみた。
すると最初のシーンは正常に動作し、2つ目のシーンから先に進めない。
今回の事象と同じ挙動になった。
ますますobbがあやしい。

## obbを手動でインストール
このあたりを参考にapk+obbを手動でインストール。
https://www.quora.com/How-can-I-install-OBB-data-file-on-an-Android/answer/Gangani-Roshan
しかし再現しない。2つ目のシーンも正常に動作する。
（apk+obbを手動でインストールする方法については後でまとめたい）

## いろいろ試す
タスクキル→動作せず:neutral_face:
再インストール→動作せず:frowning2:
端末再起動→正常動作！:open_mouth:

## ググる
色々なキーワードでググッた結果、シンプルに「android obb bug」でそれらしい結果がヒット！
[APK with expansion file (OBB) fails to load the second scene until the phone has been restarted](https://forum.unity.com/threads/apk-with-expansion-file-obb-fails-to-load-the-second-scene-until-the-phone-has-been-restarted.465714/)
タイトルがまさに今回の事象にジャストフィット。

>a regression (bug) appeared and Android apps now requires again the "WRITE_EXTERNAL_STORAGE" permission if they use obb files ([source](https://issuetracker.google.com/issues/37075181), that was very difficult to find...). Unity did not patch this as this is more of an undocumented android bug, but there we are... Now, the fix that made the trick for us is the following: in your custom Assets/Plugins/Android/AndroidManifest.xml, make sure you require WRITE_EXTERNAL_STORAGE permission on all versions of android and not up to maxSdk 18:
>`<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18" />`

Androidのバグ…？

https://issuetracker.google.com/issues/37544273#comment11
インストール時と再起動後でオーナーが違うらしい…度し難い…


# やってみる
`<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">`
を追加すれば良いらしい。ということでやってみた。

…動いた！

# 参考

- Unityフォーラムのバグ報告 
    - [APK with expansion file (OBB) fails to load the second scene until the phone has been restarted](https://forum.unity.com/threads/apk-with-expansion-file-obb-fails-to-load-the-second-scene-until-the-phone-has-been-restarted.465714/)
- Googleグループのバグ報告 
    - [Wrong owner/permission of APK Expansion files and directory ?](https://issuetracker.google.com/issues/37075181)
    - [App downloaded from Google Play with required OBB files only work after device restart](https://issuetracker.google.com/issues/37544273)

# あとがき

Samsung製端末といえばBluetoothスピーカーの音量が小さすぎるバグがあったなぁ…
Androidで部分的なViewをぼかす


## build.gradle

```
defaultConfig {
  // for blurview
  renderscriptTargetApi 25
  renderscriptSupportModeEnabled true
}

dependencies {
  compile 'com.eightbitlab:blurview:1.3.0'
}
```

## activity_main.xml

```
<eightbitlab.com.blurview.BlurView
  android:id="@+id/blurview"
  android:layout_width="match_parent"
  app:blurOverlayColor="@android:color/transparent">
</eightbitlab.com.blurview.BlurView>
```

`blurOverlayColor` は標準の `transparent` を指定。

## MainActivity.java

```
final float radius = 16;
final View decorView = getWindow().getDecorView();
final ViewGroup rootView = (ViewGroup) decorView.findViewById(R.id.activity_main);
final Drawable windowBackground = decorView.getBackground();

BlurView blurView = (BlurView) findViewById(R.id.blurview);
blurView.setupWith(rootView)
        .windowBackground(windowBackground)
        .blurAlgorithm(new RenderScriptBlur(this, true))
        .blurRadius(radius);
```

## 検討したもの
- [android - dim/blur a parent layout background - Stack Overflow](http://stackoverflow.com/questions/34632728/dim-blur-a-parent-layout-background)
- [GitHub - Dimezis/BlurView: Dynamic iOS-like blur of underlying Views for Android](https://github.com/Dimezis/BlurView)
- [GitHub - wl9739/BlurredView: Dynamic blur of image views for Android](https://github.com/wl9739/BlurredView)
- [GitHub - wonderkiln/blurkit-android: The missing Android blurring library. Fast blur-behind layout that parallels iOS.](https://github.com/wonderkiln/blurkit-android)
CSSの種類

CSSはHTMLやXMLで記述された文書の体裁、見栄えを表現するためのスタイルシート言語です。
CSSを学んでいるとSassやSASS、SCSSなどが出てきて混乱したため、まとめます。
要するに、CSSを書き易く、見栄え良くするための拡張です。

#SassにはSASS記法とSCSS記法がある
ナンノコッチャ(´･ω･`)となりますよね。
主流はSCSS記法。これは簡単に言うと、入れ子ルールや&が使えるCSS。これを使うにはコンパイルが必要です。。Railsで書く場合にはGem入れてあげればおけ。
それに対し、SASS記法は{}のない記法です。
記述はこんな感じに変わります。

```hoge.css
.hoge {
     width: 200px;
     padding: 10px;
}
.hoge .fuga {
     background: #000;
}
a {
     color: #ccc;
}
a:hover {
     text-decoration: none;
}
```

```hoge.scss
.hoge {
     width: 200px;
     padding: 10px;
     .fuga {
     background: #000;
     }
}
a {
     color: #ccc;
     &:hover {
          text-decoration: none;
     }
}
```

```hoge.sass
.hoge 
     width: 200px
     padding: 10px
     .fuga 
        background: #000
a
     color: #ccc
     &:hover
          text-decoration: none
```
Squareの在庫を外部システムと連携させる

Squareは元々カフェや美容院、雑貨屋などの小さな店舗で使えるレジを提供していたこともあり、リアル店舗とEコマースを連動させるオムニチャンネルが得意分野となっています。つまり店舗とWebサイトで在庫を調整し合わなければなりません。

それを可能にするのがWeb APIになります。今回はRubyを使ってSquareの在庫データを調整する方法を紹介します。

## 初期設定

利用するのはSquare Connectになります。RubyであればRubygemsでインストールできます。

```
$ gem install square_connect
```

そして初期化します。YOUR_ACCESS_TOKENは自分のものに読み替えてください。

```
require 'square_connect'

access_token = 'YOUR_ACCESS_TOKEN'

SquareConnect.configure do |config|
  config.access_token = access_token
end
```

## 在庫データの表示

まず在庫データを表示する方法です。これはv1のAPIを使う必要があります。店舗ID、商品IDがそれぞれ分かっていることとします。

```
location_id = 'YOUR_LOCATION_ID'

api = SquareConnect::V1ItemsApi.new

# 商品情報
item_response = api.retrieve_item(location_id, 'YOUR_ITEM_ID')

# 在庫情報
inventory_response = api.list_inventory(location_id)

# 引き合わせ
inventory_response.each {|i|
  item_response.variations.each {|v|
    next if v.id != i.variation_id
    puts "#{v.name} => #{i.quantity_on_hand}"
  }
}
```

このようなスクリプトで以下のような結果が返ってきます。それぞれのバリエーションに対する在庫数です。

```
バリエーション名 => 20.0
黒 => 20.0
白 => 20.0
```

## 在庫を調整する

そしてこの内の一つのバリエーションIDを指定して在庫調整を実行します。売れた場合はマイナスの数字で指定する（在庫を減らすという意味で）のがコツです。

```
response = api.adjust_inventory(location_id, 'YOUR_VALIATION_ID', {
  quantity_delta: -2,
  adjustment_type: 'SALE',
  memo: '他のシステムで販売'
})
```

この結果のレスポンスは次のようになります。quantity_on_handは新しい在庫数です。

```
{
  :variation_id=>"YOUR_VALIATION_ID",
  :quantity_on_hand=>18.0
}
```

あらかじめ外部システムにおける商品ID（またはSKUのID）とバリエーションIDを紐付けておかないといけないので注意してください。adjustment_typeはSALE（売れた場合）の他、RECEIVE_STOCK（在庫追加）、MANUAL_ADJUST（マニュアル調整）が用意されています。

----

このような操作で在庫数を調整できます。システム連携される際の参考にしてください。

[Square Connect API Documentation](https://docs.connect.squareup.com/api/connect/v1/#post-inventory-variationid)
何となく分かった気になる共変・反変

Scalaを勉強していて出てきた言葉、共変と反変。
共変は直感的に理解しやすかったですが、反変は最初よく分かりませんでした。
それが、以下の様な例えを考えたら何となく分かってきました。

# はじめに、型パラメータとなるクラス

こんな2つのクラスがあるとします。

```scala
class Food

class Sushi extends Food
```

これらのクラスを型パラメータとするクラスを、これから考えていきます。

# わりと理解しやすい共変

共変の例として、こんなクラスがあるとします。

```scala
class Restaurant[+T] {
  def serve(): T = // 何かしらT型を返す実装...
}
```

そうすると、こんな変数を定義できます。

```scala
val familyRestaurant: Restaurant[Food] = ...
// familyRestaurant.serve()はFoodを返す。

val sushiya: Restaurant[Sushi] = ...
// sushiya.serve()はSushiを返す。
```

型パラメータTが共変ということは、Restraurant[Food]型の変数にRestaurant[Sushi]型の変数を代入できる、つまり以下の様に考えられます。

```scala
val restaurant1: Restaurant[Food] = familyRestaurant
// とりあえずこれはOK。restaurant1.serve()はFoodを返す。

val restaurant2: Restaurant[Food] = sushiya
// 型パラメータが共変だからこれもOK! restaurant2.serve()はFoodを返す。
// restaurant2の実体は寿司屋だけど、寿司屋が返すSushiはFoodの一種だから問題なし。

val restaurant3: Restaurant[Sushi] = familyRestaurant
// これはコンパイルエラー。restaurant3.serve()はSushiを返さないといけない。
// だけどrestaurant3の実体はファミレス。
// ファミレスが返すのは大まかな括りであるFoodであり、Sushiとは限らないのでコンパイルエラー。
```

こんな風に考えて、共変が分かった気になりました。
共変は直感的にも理解しやすいですよね。

# そして反変

いよいよ小難しそうな反変を考えてみます。
例として、こんなクラスがあるとします。

```scala
class Eater[-T] {
  def eat(menu: T) = // T型の引数を受け取ってモグモグする実装...
}
```

そうすると、さっきと同じようにこんな変数を定義できます。

```scala
val kuishinbo: Eater[Food]
// 食いしん坊は何でも食べられる。
// kuishinbo.eat(new Food)とすることもできるし、
// kuishinbo.eat(new Sushi)でもよい。

val edokko: Eater[Sushi]
// 江戸っ子は寿司しか食べない。
// edokko.eat(new Sushi)はいいけど、
// edokko.eat(new Food)はコンパイルエラーになってしまう。
```

型パラメータTが反変ということはえーと、[...]の中身の関係が共変と逆だから、Eater[Sushi]型の変数にEater[Food]型の変数を代入できる、つまり以下の様に考えられます。


```scala
val customer1: Eater[Food] = kuishinbo
// とりあえずこれはOK。customer1.eat()はFoodを受け取れる。

val customer2: Eater[Sushi] = kuishinbo
// 型パラメータが反変だからこれもOK! customer2.eat()はSushiを受け取れないといけない。
// customer2の実体は食いしん坊だから、喜んでSushiを食べられる。

val customer3: Eater[Food] = edokko
// これはコンパイルエラー。 customer3.eat()はFoodを受け取れないといけない。
// だけどcustomer3の実体は江戸っ子。Sushiならいいけど、Food全般となると無理。
```

いやー、これで反変も分かった気になりました。

さらっと流しましたが、共変の型パラメータの使い所はメソッドの返り値（例でいうとserve()）、反変の型パラメータの使い所はメソッドの引数（例でいうとeat()）、というのが基本になります。
NTFSのファイルやフォルダーに設定されているアクセス権の一覧をPowerShellで取得する

## PowerShellコマンド

```
$path = "C:\My\Projects\"
(Get-Item $path).GetAccessControl().Access | Select-Object FileSystemRights, AccessControlType, IdentityReference
```

## 実行結果の例

```
           FileSystemRights AccessControlType IdentityReference
           ---------------- ----------------- -----------------
                FullControl             Allow BUILTIN\Administrators
                FullControl             Allow NT AUTHORITY\SYSTEM
ReadAndExecute, Synchronize             Allow BUILTIN\Users
        Modify, Synchronize             Allow NT AUTHORITY\Authenticated Users
                 -536805376             Allow NT AUTHORITY\Authenticated Users
```
AngularJS・JavaScriptのデバッグ方法まとめ＆使い分け

##デバッグ方法
今回はお作法や概念ではなく、私が普段デバッグをする時に使用している方法をメモ書き程度にまとめてみました。
私は大きく分けて3個のデバッグ方法を用いてます。
下記から一つづつ紹介し、最後に私の使い分け方を記述してあります。

###console.log
これは一般的なデバッグ方法だと思います。
JSファイル内の特定行に下記のコードを記述すると、開発者ツールのConsoleタブに
**ログの結果**とconsole.logを書いた**ファイル名**、**行数**が表示されます。
私はログの結果と行数を見ながらバグ原因を探ります。

```basicDebug.js
console.log({{デバッグしたい変数}});
```

console.logは下記のように**,**を途中で記述すると一つのconsole.logに複数の値が表示できるので
何箇所もconsole.logを表示したい場合は先に関数名を書き、後ろに表示したい変数を記述しています。

```pluralDebug.js
console.log('debug', 'test');
console.log({{変数A}}, {{変数B}});

console.log('functionName', {{変数}}); //先に関数名など位置が特定できる名前をつけておくと、いちいち行数等を見なくて済む
```

AngularJsでconsole.logを使用する際にひとつ注意点があります。
下記のコードでデバッグをするとどうなるでしょうか？

```angularErrorDebug.js
var test = 'test';
console.log('1', test);
test = 'Z';
console.log('2', test);
test = 'ZZ';
console.log('3', test);
```

実は結果は1,2,3の変数**test**は全て**'ZZ'**になってしまいます。
ですので、回避方法として以下のように記述すると各行時の変数の値が出力してくれます。

```angularDebug.js
console.log(angular.copy({{デバッグしたい変数}})); //AngularJsの特殊ケース
```

###Request, Response
こちらは開発者ツールのNetworkタブ内の機能を利用してデバックをする方法です。※開発者ツールはchromeだと「F12」
送受信したオブジェクトの構造を確認できます。以下が見る方法。

- 送信したオブジェクトの内容確認をしたい場合：上から順にNetworkタブ、**Headers**タブ内の**Request Headers**
- 受信したオブジェクトの内容確認をしたい場合：上から順にNetworkタブ、**Response**タブ

console.logでも代用は出来ますが、送受信した実際のデータが確認出来るので
「もしconsole.logを記述した行が間違って～」などのケアレスミスを回避することが出来ます。

###preタグ
こちらは画面上にオブジェクトをJSON形式で表示して、デバッグを行う方法です。
htmlに直接書いているので上記の2つと違い、**動的**に値が変更できます。
以下のように記述すると画面に対象のデータが表示されます。

```debug.html
<pre>{{表示したいdata属性・form属性など | json}}</pre>
<pre>{{data|json}}</pre> //具体例
```

またRequest, Responseでもオブジェクトは見れるのですが、階層が深いと見たい値を探すのに苦労します。
ですが、JSON形式だとすぐに見つけられるので便利です。

##使い分け
個人的に上記３つのデバッグ方法の使い分け方を書いてみました。
※絶対にこれが正解という事では無いので、使いながら自分の使い分け方を見つけて下さい。

- console.log：処理途中のデータ確認
- Request, Response：APIに送受信したオブジェクトの内容確認
- preタグ：構造が複雑な連想配列の内容確認・input系のエラーチェック
Amazon S3のリダイレクトルールを手軽に更新できるようにする

# 始めに
[この記事](https://qiita.com/yamatok/items/eeb962813d826d080b36)の続きです。
なんでこんなことをしてしまったのかはこの記事を読んでください。

# やりたいこと
Amazon S3のリダイレクトルールに新しいルールを追加したい。
でもリダイレクトルールいちいち編集して保存したくない。
そもそもMFAが面倒なのでリダイレクトルールを追加するためだけに毎回AWSコンソールを開きたくない。

# やったこと

- Amazon S3の新しいリダイレクトルールを、AWS CLI一行で更新できるようにした
    - リダイレクトルールはDynamoDBに保存する
    - リダイレクトルールは、DynamoDBの更新をトリガーにしてAWS Lambdaが自動で更新する

# 構築手順
## DynamoDB
`任意のテーブル名`で作ってください。
[前の記事](https://qiita.com/yamatok/items/eeb962813d826d080b36)にリダイレクトルールの完成形があります、これに必要な属性を定義します。

- url
- host
- name

デフォルトページを先に定義しておきましょう。

- {"url":"twitter.com"}
- {"host":"you"}
- {"name":"default"}

## AWS Lambda
Python3.6で書きます。

```
#! /user/local/bin/python
# -*- coding:utf-8 -*-
import boto3
from boto3.dynamodb.conditions import Attr

def lambda_handler(event, context):
    # init
    table = boto3.resource('dynamodb').Table('任意のテーブル名')
    # scan table
    res = table.scan(FilterExpression=Attr('url').begins_with('clouddrive'))
    row_def = table.scan(FilterExpression=Attr('name').eq('default'))['Items'][0]
    # template
    conf = {"IndexDocument": {"Suffix": "tekitou"}, "RoutingRules":[]}
    # add routing rules
    for row in res['Items']:
        conf['RoutingRules'].append({"Condition": {"KeyPrefixEquals": row['name']},"Redirect": {"HostName" : row['host'],"ReplaceKeyWith" : row['url']}})
    # add default rule
    conf['RoutingRules'].append({"Redirect":{"HostName" : row_def['host'],"ReplaceKeyWith" : row_def['url']}})
    # put routing rules
    s3client = boto3.client('s3')
    s3client.put_bucket_website(Bucket='任意のBucket',WebsiteConfiguration=conf)

    return 'ok'
```
必要なロールは

- "dynamodb:GetItem"
- "dynamodb:Scan"
- "s3:GetBucketWebsite"
- "s3:PutBucketWebsite"

とAWSLambdaDynamoDBExecutionRole（AWS 管理ポリシー）なので作ったLambdaさんにつけてあげてください。

Lambdaのトリガーは、先ほど作ったDynamoDBの`任意のテーブル`を選択してください。
これで、AWS CLIからレコードを追加したらあとはLambdaさんが頑張ってくれます。

## IAM
AWS CLIからDynamoDBにレコードを追加するので、DynamoDBに書き込み権限のあるIAMユーザを作成してアクセスキーを取得してお使いのPCのawsコマンドに設定しておきます。

# 最後に
ローカルで

```
aws dynamodb put-item --table-name 任意のテーブル名 --item '{"host": {"S":"www.amazon.co.jp"},"name": {"S":"comiket_20170813"},"url": {"S":"clouddrive/share/aaabbbccc"}}'
```
を叩いたら、新しいルーティングが設定されます。

# おわり
簡単でしたね。（吐血）
DynamoDBとか、あまり詳しくなかったので良い勉強になりました。boto3.dynamodbのドキュメント・サンプルの少なさよ

# おことわり
今回実装したのはルーティングの追加のみです。
使わなくなったルーティングの削除の実装は読者の課題としようと思います。
ruby unless文にelsifはないよ。。。


とても単純なことですが、自分がアルゴリズム問題を解いていてはまってしまったので一応。
# 対象読者
・ruby初心者
# 内容
タイトルの通りなのですが、rubyのunless文にelsifは使えません。

例えば

```ruby:unless.rb
hoge = "動物名"
unless hoge == "猫"
  puts "猫ではありません"
elsif hoge == "犬"
  puts "犬ではありません"
end
```

みたいな処理はできません。
こういった処理をしたい場合

```ruby:if.rb
hoge = "動物名"
if hoge != "猫"
  puts "猫ではありません"
elsif hoge != "犬"
  puts "犬ではありません"
end
```


```ruby:if2.rb
hoge = "動物名"
if !hoge == "猫"
  puts "猫ではありません"
elsif !hoge == "犬"
  puts "犬ではありません"
end
```

```ruby:unless.rb
hoge = "動物名"
if not hoge == "猫"
  puts "猫ではありません"
elsif not hoge == "犬"
  puts "犬ではありません"
end
```

とかいう感じに変えてあげましょう。
ってかそもそも、unlessってぱっと見どっちだっけとか、わかりづらいからあんま使わないほうがいいのかもね
gitのinit 〜 git commit までの流れ

初めてgit commitまでやったのでメモ
このメモでは以下の流れについて記述します
1.[gitの初期化](#init)
2.[git add](#add)
3.[git commit](#commit)

使ったコマンドは以下の通り
・git init
・git status
・git add
・git commit
・git log

<a name="init"></a>
##1.gitの初期化

**git initでカレントディレクトリをGit管理対象にする**

```sh:git_init
~/workspace $ mkdir git_test
~/workspace $ cd git_test/
~/workspace/git_test $ ls
~/workspace/git_test $ git init
Initialized empty Git repository in /home/ubuntu/workspace/git_test/.git/
~/workspace/git_test (master) $ 
```


**git statusで現在のリポジトリの状態を確認**

```sh:git_status
#何もファイルの編集作成をしていないのでこの結果
~/workspace/git_test (master) $ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)
~/workspace/git_test (master) $ 
```

<a name="add"></a>
##2.git add で対象のファイルをステージングエリアに追加

**git addで対象のファイルを指定**
git add ファイル名(ファイルパス) で実行

```sh:git_add
#README.mdを作成
~/workspace/git_test (master) $ touch README.md
~/workspace/git_test (master) $ ls
README.md
~/workspace/git_test (master) $ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
		 #新たにREADME.mdが存在していることを確認
        README.md

nothing added to commit but untracked files present (use "git add" to track)
~/workspace/git_test (master) $ git add README.md
```

**git statusで状況を確認**

```sh:git_status
~/workspace/git_test (master) $ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
		 #README.mdがステージングエリアに追加
        new file:   README.md

~/workspace/git_test (master) $ 
```

<a name="commit"></a>
##3.git commitでリポジトリに追加
git commit -m "コメント"　で実行
・もし-m を入れ忘れ、コメントが入らなかったら、Control+xで終了し、再度git commit -m "first commit"でコミットする
・またはnanoエディタで編集する

```sh:git_commit
#コメント付きでステージングエリアにあるものをリポジトリにコミット
~/workspace/git_test (master) $ git commit -m "my fiirst commit"
[master (root-commit) 0ccf01d] my fiirst commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
~/workspace/git_test (master) $ git status
On branch master
nothing to commit, working tree clean
~/workspace/git_test (master) $ 
```

**git logでコミット履歴を確認できる**

```sh:git_log
~/workspace/git_test (master) $ git log
commit 0ccf01d20dd8526ffd8d400c07956e7f45febae4 (HEAD -> master)
Author: <Cloud9ユーザー名> <Cloud9登録アカウント> #いつgmailの情報を取得した？ →Cloud9の情報から取得したようだ
Date:   Fri Sep 22 13:00:50 2017 +0000
	#-m　で指定したコメントが表示されている
    my fiirst commit
~/workspace/git_test (master) $ 
```
Amazon S3のリダイレクトルールを駆使してPrime Photoのリンクを管理する

# 動機
最近、いろいろな機会で写真を撮ってはアルバムにまとめて、そのリンクを知人や被写体に共有することが多くなってきました。

みなさんもそういうことありますよね？

でも、URLにランダム文字列が入ってていやだなあ、とか、URLを見ても何のリンクか分からないなあ、とか、思うじゃないですか。

思いますよね？

そこで、できるだけ任意のURLを付ける方法があるんです。
そう、AWSならね。

# 準備するもの
AWSアカウント
リンクしたいサイト

# 手順
## S3 Bucket作成
Amazon S3で `任意のBucket名` のBucketを作成します。
完成するエンドポイントが
`http://[任意のBucket名].s3-website-[Region].amazonaws.com`
になりますので、ここで自分のHNなどを入れて存在感をアピールします。

## リダイレクトルールの設定
先ほど作成したBucketのプロパティの[Static website hosting]を編集します。

[このバケットを使用してウェブサイトをホストする]を選択して以下のように設定します。

- インデックスドキュメント：使いませんが必須項目なので、適当な値（ `a` とか）を入れます
- リダイレクトルール (任意)：以下のように設定します

```
<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>event_20170701</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <HostName>www.amazon.co.jp</HostName>
      <ReplaceKeyWith>clouddrive/share/aaabbbccc</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>comiket_daredare_20170813</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <HostName>www.amazon.co.jp</HostName>
      <ReplaceKeyWith>clouddrive/share/abcdefghi</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Redirect>
      <HostName>twitter.com</HostName>
      <ReplaceKeyWith>you</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>
```
上記のように設定すると、
`http://[任意のBucket名].s3-website-[Region].amazonaws.com/event_20170701`
⇒ `http://www.amazon.co.jp/clouddrive/share/aaabbbccc`
のようにリダイレクトすることができます。

## 簡単な解説

```
<RoutingRule>
  <Condition>
    <KeyPrefixEquals>event_20170701</KeyPrefixEquals>
  </Condition>
  <Redirect>
    <HostName>www.amazon.co.jp</HostName>
    <ReplaceKeyWith>clouddrive/share/aaabbbccc</ReplaceKeyWith>
  </Redirect>
</RoutingRule>
```

Conditionに該当したらリダイレクト先に繋がります。
上の例なら、
`http://[任意のBucket名].s3-website-[Region].amazonaws.com/event_20170701`
にアクセスすると、
`http://[任意のBucket名].s3-website-[Region].amazonaws.com` 以下の `event_20170701` が
上のRoutingRuleのConditionに一致するので、Redirectに指定した `http://<HostName>/<ReplaceKeyWith>` にリダイレクトしてくれるというわけです。

```
<RoutingRule>
  <Redirect>
    <HostName>twitter.com</HostName>
    <ReplaceKeyWith>you</ReplaceKeyWith>
  </Redirect>
</RoutingRule>
```

一番下のこのConditionのないルーティングは、ルールが設定されていなかったら遷移するデフォルトページとして機能します。
これを一番上に書いてしまうとデフォルトページにしか遷移しないので気をつけてくださいね。

# おわり
もうできちゃいましたね。
エンドポイントはおいそれと変更できませんが、`KeyPrefixEquals`は自在に設定できますので、ここに撮影日やイベント名・写っている人や送りたい人の名前を入れましょう。

# おことわり
お金がかかりそうなので試してもいないのですが、長ったらしいエンドポイントはRoute53を使えば短くできると思います。試していないので責任は取れません。

# ところで…
S3のプロパティの設定次第で自由にリンクを作れるようになりましたが、
毎回S3のコンソールを開くの、面倒臭いですよね…？コマンドで一発で新しいRoutingRuleを設定したいですよね…？

続く（書いたらここに続きの記事を貼ります）
[続きの記事](https://qiita.com/yamatok/items/219fc55294f355f2df0e)書きました。
Xcode9 ipaファイルをターミナルのコマンド操作で実機にインストールする方法

こんにちは。iosフリーランスエンジニアの永田です。

今回は、ipaファイルをターミナルのコマンド操作で実機にインストールする方法のご紹介です。
最新のiTunesではXcodeから生成するipaファイルを実機にインストールできなくなっています。Windows環境でもこの方法なら、ipaファイルからiphoneの実機に保存できます。それと、iTunesは必要です。(実際には使用はしない)


sdkのダウンロード
http://www.adobe.com/devnet/air/air-sdk-download.html

インストール先のPATH設定 　ターミナルで起動

  ```vi ~/.bash_profile```

PATHの操作

```export PATH=$PATH:/Users/nagatadaisuke/adt/bin```


PATHの操作の設定

```export PATH=$PATH:```


ディレクトリーのPATHの設定
ここは各オリジナルで、vimはshift zzでもターミナルは閉じます。
```/nagatadaisuke/adt/bin```


### ちなみにインストールしたSDKのファイルのPATHをそのまま通そうとしたら、何か認識できなかったので、adtという名前でファイルを作りました。



.bash_profileの保存　
```source ~/.bash_profile```
ターミナルを再度開き直す

PATHの確認
```echo $PATH```

-versionの確認
```adt -version```

実機にipaファイルをインストール
```adt -installApp -platform ios -package /Users/nagatadaisuke/Desktop/slotNumber.ipa```

２年前に作ったアプリケーションslotNumberをインストールしました！！

<img width="329" alt="スクリーンショット 2017-09-22 22.10.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/ba595684-9e92-5c8d-f8df-f3a530f416d8.png">

#参考サイト

http://help.adobe.com/ja_JP/air/build/WSfffb011ac560372f-71994050128cca87097-8000.html


貴重なお時間お読みくださいまして、ありがとうございます。
WindowsでNode.jsアプリをデプロイ

Linux系と違ってシステムユーザーじゃないとWindowsでNode.jsアプリをデプロイして、ログオフしたらアプリもダウンされてしまいます。
[システムユーザー権限で`Cmd`](https://blogs.technet.microsoft.com/askds/2008/10/22/getting-a-cmd-prompt-as-system-in-windows-vista-and-windows-server-2008/)を使用できますが、やり方が複雑すぎてめんどくさい　:punch:

多分、一番簡単な方法はシステムサービスを使うことだと思います。
システムサービスにアプリサービスを登録できたらシステムユーザーがコントロールしてくれます。つまり、通常のユーザーがログオフしてもアプリが立ち上げっぱなしできます。

このノートで[NSSM](https://nssm.cc/)を使用してNode.jsアプリをサービスとしてシステムサービスを登録し、
作業する`.bat`ファイルを投稿します。

### 1. システムサービスにアプリサービスを登録し開始する。
```shell-session
@echo off
echo サービスをアンインストール...
nssm stop <SERVICE_NAME>
nssm remove <SERVICE_NAME>

echo サービスをインストール...
nssm install <SERVICE_NAME> "node"

echo 引数を設定...
nssm set <SERVICE_NAME> AppDirectory "path\to\app"
nssm set <SERVICE_NAME> AppParameters "index.js"
nssm set <SERVICE_NAME> AppEnvironmentExtra "NODE_ENV=production"
nssm set <SERVICE_NAME> AppStdout "path\to\logs\nssm_out.log"
nssm set <SERVICE_NAME> AppStderr "path\to\logs\nssm_err.log"

echo サービスを開始...
nssm start <SERVICE_NAME>

timeout 10
```

### 2. サービスを停止し、システムサービスから削除する。
```shell-session
@echo off
echo サービスをアンインストール...
nssm stop <SERVICE_NAME>
nssm remove <SERVICE_NAME>

timeout 10
```

NSSMのコマンドラインの詳しくは[HP](https://nssm.cc/commands)にご参考ください。
LaravelでFacadeのエイリアスをconfig/app.phpに設定したけれどクラスが見つからない場合の対処法

## 2017/09/24 追記

開発環境ではconfig:cacheではなく、config:clear するのが通常です。
config:cacheと記載していた箇所を修正しました:bow:

------

自前で作成したクラスを簡単に呼び出したいのでFacadeのエイリアスをconfig/app.phpに設定したのはいいものの、クラスがnot foundのエラーが出てしまう場合の対処法です。

```config/app.php
'aliases' => [
    // 省略
    'Example' => App\Facades\Example::class,
],
```

ここでaliasesに登録したExampleをControllerなどで`\Example::methodName();`と呼び出したところ
クラスが見つからないというエラーになってしまう…

## 環境

|名前|バージョン|
|---| -------- |
|PHP | 7.1.8    |
|Laravel| 5.5.5 |

## 対処法

```
$ php artisan config:clear
```

これを実行するだけでOK。
`php artisan cache:clear` でやっていて
「あれおかしいなー反映されないなー」てたらcache:clearだとダメだったという…

~~configファイルを編集したら `config:cache` すること。~~
**開発環境でconfigファイルを編集したら `config:clear` すること。**
知っている人からすれば当たり前なんでしょうけど…
【PlayCanvas】画面のサイズを指定する

Editor > Settings > RENDERING のプロパティ

- Fill mode
- Resolution

を変更する。

>## フィルモード
>
>フィルモードはキャンバスがそのようにブラウザのウィンドウを埋めるかを定めます。
>
> - Keep aspect ratio - キャンバスは画面一杯に拡大しますが正しいアスペクト比を維持します。
> - Fill window - キャンバスは拡大して画面を完全に埋めます。
> - None - キャンバスは解像度の幅と高さのサイズを保ちます。

>## 解像度モード

>解像度モードはキャンバスの解像度がリサイズ時に変更されるかを定めます。

> - Fixed - 解像度は必ず幅 x 高さになります。
> - Auto - 解像度は必ずキャンバスと同じサイズになります。

[マニュアル](https://developer.playcanvas.com/ja/user-manual/dashboard/settings/)

スマホで公開する場合は
- フィルモード　- Keep aspect ratio
- 解像度 - 対応予定のスマホの一番小さい解像度(iPhone5なら1132,640)

FixedとAutoの違いはよくわからないのでご存知の方は教えてください。
zip()で合成したリストを再び分割する

機械学習や、その他、何かしらのデータセットを扱うときに、データが二つのリストに分かれていることがあります。

そんなときに、二つのリストをくっつけるのに、zip()関数を使います。

```python:zip-test.py
a = [1, 2, 3, 4, 5]
b = ['a', 'b', 'c', 'd', 'e']
print(list(zip(a, b)))
# [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')]
```

しかし、くっつけた後、何かしらの処理をした後に、再び分割するには、どうしたらよいのでしょう。

そんなときには、zip(*リスト)のように書くと、合成したリストを分離することができます。以下は、二つのリストを合成して、シャッフルした後に、再び分割する例です。

```python:zip-unzip.py
import random

a = [1, 2, 3, 4, 5]
b = ['a', 'b', 'c', 'd', 'e']

# 二つのリストを合成
c = list(zip(a, b))

# シャッフル
random.shuffle(c)

# 合成したリストを分離する
a, b = zip(*c)

print(a) # (5, 2, 3, 1, 4)
print(b) # ('e', 'b', 'c', 'a', 'd')
```
Xcode β と Xcode をスイッチするコマンド

iOS 11 対応のために、Xcode β をインストールしたら、β を使ってビルドするためには switch する必要がある。

## βにスイッチ

```
sudo code-select --switch /Applications/Xcode-beta.app
```

## Xcode にスイッチ

```
sudo xcode-select --switch /Applications/Xcode.app
```
【PlayCanvas】canvasのサイズを取得する

canvasのサイズを取得します。
Settings > RENDERING のResolutionで指定したサイズとは違うので注意が必要です。

```js:

var canvas = this.app.graphicsDevice.
var canvasWidth = parseInt(canvas.clientWidth, 10);
var canvasHeight = parseInt(canvas.clientHeight, 10);

```

もしくは

```js:

canvas.offsetWidth
canvas.offsetHeight

```
jsdoでlovefield

#概要
jsdoでlovefieldでcrudやってみた。
ちなみに、crudは、こんな感じ。

Create	生成	INSERT
Read	読み取り	SELECT
Update	更新	UPDATE
Delete	削除	DELETE

#成果物

http://jsdo.it/ohisama1/Cgn9

#サンプルコード

```
var bsc = lf.schema.create('test0', 3);
var red;
bsc.createTable('red')
    .addColumn('name', lf.Type.STRING)
    .addColumn('createTime', lf.Type.DATE_TIME)
    .addIndex('idxCreateTime', ['createTime'], false, lf.Order.DESC);
bsc.connect().then(function(db) {
    window.db = db;
    red = db.getSchema().table('red');
});
function Create() {       
    var row = red.createRow({
        'name': "ore",
        'createTime': new Date()
    });
    db.insert().into(red).values([row]).exec();
    alert("ok");
}
function Read() {   
    db.select().from(red).exec().then(function(rows) {
        rows.forEach(function(row) {
            document.getElementById('out').value += row['name'];
        });
    });
}
function Update() {   
    db.update(red).set(red.name, 'ore2').where(red.name.eq('ore')).exec(); 
    alert("ok");
}
function Delete() {   
    db.delete().from(red).where(red.name.eq('ore2')).exec();
    alert("ok");
}


```
Python で Domo のデータセットの一覧を取得する

access_token の取得は
[Python で Domo の アクセストークンを取得する](https://qiita.com/ekzemplaro/items/91ddb8a19f3ec861666f)

```py3
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	main_list_dataset.py
#
#					Sep/22/2017
#
# ------------------------------------------------------------------
import	sys
import	requests
#
from domo_config import domo_config_proc
from get_access_token import get_access_token_proc
from list_dataset import list_dataset_proc
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
config = domo_config_proc()
#
access_token = get_access_token_proc(config)
#
json_str = list_dataset_proc(access_token)
#
print(json_str)
#
sys.stderr.write("*** 終了 ***\n")
#
# ------------------------------------------------------------------
```

```py3:list_dataset.py
# -*- coding: utf-8 -*-
#
#	list_dataset.py
#
#					Sep/22/2017
#
# ------------------------------------------------------------------
import	sys
import	requests
#
# ------------------------------------------------------------------
def list_dataset_proc(access_token):
	sys.stderr.write("*** list_dataset_proc *** start ***\n")
	headers = {"Authorization": "Bearer " + access_token
		}
	params = {
		"includeHeader": "true",
		"sort": "name",
		"offset": 0,
		"limit": 50
		}
#
	url_datasets="https://api.domo.com/v1/datasets"
#
	try:
		rr=requests.get(url_datasets,params=params,headers=headers)
		print(rr.status_code)
	except Exception as ee:
		sys.stderr.write(str(ee) + "\n")
#
	sys.stderr.write("*** list_dataset_proc *** end ***\n")
#
	return rr.text
# ------------------------------------------------------------------
```

API の仕様はこちら
[List DataSets](https://developer.domo.com/docs/dataset-api-reference/dataset#List%20DataSets)