OmniAICreator/Qiita-1.07M huggingface dataset:
Sass(scss) を自動ビルドしつつブラウザも自動リロードして開発速度を上げる

手早く html の LP とかカンプを作りたい時のための手順。Sass を使いつつ、ファイル変更でブラウザも自動リロードしたかった。

## TL;DR
- https://github.com/TsuyoshiNumano/simple-sass-build-and-reload をクローンして `npm i && npm run dev`
- それも面倒な人は以下を自身の package.json に書き加える(変更検知のフォルダは任意の場所を！)
 - `npm run dev`

```json:package.json
{
  "scripts": {
    "build-css": "node-sass --include-path scss scss/style.scss css/style.css",
    "watch-css": "nodemon -e scss -x \"npm run build-css\"",
    "sync": "browser-sync start --server --files \"**/*\" ",
    "dev": "concurrently --kill-others \"npm run watch-css\" \"npm run sync\""
  },
  "devDependencies": {
    "browser-sync": "^2.23.3",
    "concurrently": "^3.5.1",
    "node-sass": "^4.7.2",
    "nodemon": "^1.14.7"
  }
}
```

ファイル更新で sass をビルドしつつ、ブラウザも自動リロード|
---|
![recortde3.gif](https://qiita-image-store.s3.amazonaws.com/0/26095/e9c6bc43-ecc3-30a9-ffd8-1db369291aa2.gif)|


## 背景
「なんかサイトのモック作ってよ。」みたいなことを言われた時に、最近のフロントエンド環境に慣れすぎた結果

- １から html 環境を用意するのが面倒。
- かといって [html5-boilerplate](https://github.com/h5bp/html5-boilerplate) はフルスタック感がある。。。
- sass ファイルの変更検知で自動ビルド＆自動リロードしたいだけ

と思ったので、[オレオレボイラープレート](https://github.com/TsuyoshiNumano/simple-sass-build-and-reload)を作ってみました。



## 解説
1. [node-sass](https://github.com/sass/node-sass) で sass ファイルを css ファイルにビルドして変換
2. [nodemon](https://github.com/remy/nodemon) で変更を watch
3. [browser-sync](https://www.browsersync.io/) でファイルの変更を検知して自動リロード
4. nodemon と browser-sync のタスクをパラレルで実行するため [concurrently](https://github.com/kimmobrunfeldt/concurrently) を利用

ビルドに関しては [npmでミニマムに始めるSass](https://qiita.com/micchyboy/items/0074f002d8f1663577a2) を参考にさせていただきました:bow:(ありがたや〜）

ファイル変更後の自動リロードだけパッと使いたいだけなら browser-sync だけで十分。

```bash:browser-syncでお手軽自動リロード環境
$ npm i browser-sync -g
$ browser-sync start --server --files "**/*"
```

## 参考
- [npmでミニマムに始めるSass](https://qiita.com/micchyboy/items/0074f002d8f1663577a2)
- [nodemonをただのファイルウォッチャーとして使う](https://qiita.com/gcoka/items/b01eb0a26fdb2b0b86f4)
- [How can I run multiple npm scripts in parallel?
](https://stackoverflow.com/questions/30950032/how-can-i-run-multiple-npm-scripts-in-parallel)
- [これからはcssはSassで書こう。](https://qiita.com/m0nch1/items/b01c966dd2273e3f6abe)
- [HTML5のサイトが素早く作れるフレームワーク「HTML5 Boilerplate」をちゃんと触ってみた](http://webcre8.jp/use/howto-framework-html5boilerplate.html)

## 所感
- 2018 年なんだからもっと良い方法がありそう
- css grid system とか含めようか迷ったけど目的に対して too match なのでやめました
コードマスタを使う理由

# コードマスタとは？
|分類CD|コード|名称|ソート順 |
|:-:|---|---|---|
|'GENDER'|1|'男性'|1|
|'GENDER'|2|'女性'|2|
|'STATUS'|1|'未登録'|1|
|'STATUS'|2|'登録済み'|2|
|'STATUS'|3|'更新中'|3|
上記のようなコードを一まとめに定義したテーブルのことです。

# 書くきっかけ
社内でコードマスタを使う以外の方法は、ないのだろうか？　と必死に考え相談した結果
運用や保守、全体を考えると、コードマスタが一番よいという結果になりました。
それの備忘録として書きます。

## コードマスタを使う大きなメリット
- コードの名称変更や追加の場合、コードマスタの修正のみで対応できる
- テーブルの数を減らすことができ、ER図やテーブル設計書を簡単にできる。

## 問題点１: DB(コードマスタ)と実装内の2重管理
コードマスタで定義したコードで、分岐処理等を実装で書くと、DB(コードマスタ)と実装内の2重管理となってしまう。

解決策として、**実装内の列挙型Enumで定義**する方法があります。
でも下記のデメリットがあります。

- コードの変更や追加する際は、再デプロイが必要
- データベースしか見れない人は、性別コードの1が何か分からない。
- 性別名称も含めて出力したい時は、実装で加工する必要がある。(CSV, EXCEL出力等)

業務アプリケーションはデータありきのシステムであることが多く、データの定義が実装とDBに分かれるのは良くない。

参考: [Rails脱初心者のための基礎知識と実装Tipsまとめ(2) - 区分値管理編 - Qiita](https://qiita.com/hoshi-k/items/6b72980a19a39bb1f780)


コードマスタを使って下記のように対応。
⇒判定に必要なコードのみ定数クラスで定義して、その定数に修正が入った場合は実装も併せて修正する

## 問題点２: 複数コードをまとめて1テーブルに定義
- データ量が多くなると、パフォーマンスが悪い。
どんな値でも入るように、型を大きめに定義する必要がある。

- 分類CDのコピペミス等でもエラーにならず、バグに気づきにくい。
```SQL: コピペミスの例
SELECT * 
FROM X
LEFT JOIN CODE_MASTER CM1
ON CM1 = 'GENDER'
AND X.gender = CM1.CODE
LEFT JOIN CODE_MASTER CM2
ON CM2 = 'GENDER'
AND X.status = CM2.CODE
```

原則でいうと、一つのコードごとにテーブルを分けて定義するものだと思います。
上記のデメリットとコードマスタのメリットである、テーブル数を減らすことを比較すると
パフォーマンスに問題がある場合を除いて、メリットの方が大きい。

コードマスタを使って下記のように対応。
⇒コードマスタを起因とするバグは、単体テストで必ず発見する。
コードマスタでなんでも対応しようとせず、コードマスタ対応外の場合は別テーブルを作成する。
(データ量が多い、汎用カラム等は作らない。)

参考: [第3回　テーブル設計のグレーゾーン～毒と薬は紙一重　（1）単一参照テーブル～テーブルにポリモフィズムは必要か](http://gihyo.jp/dev/serial/01/sql_academy2/000301)

## まとめ
コードマスタのデメリットを無くそうすると、コードマスタの大きなメリットが失われてデメリットの方が大きくなる。だからコードマスタを使う。
Debianでesp32の環境構築をしてLチカするまで

##経緯
秋葉原に行ったときに友人に進められて買った[ESP32の開発ボード](http://akizukidenshi.com/catalog/g/gM-11819/)を使ってなかったのでそろそろ何かやろうと思ってとりあえず環境構築とLチカをしてみた話です。
ご察しの通り電子工作とか組み込み系とか初心者なので、間違っているところがあればご指摘いただけるとありがたいです。

##環境構築
基本的には[このサイト](http://tomono.eleho.net/2017/02/06/6337/)の通りにやったのですがところどころつまずいたとこがあったので書いて行こうと思います。


###arduinoIDE

[このサイト](https://www.arduino.cc/en/main/software)で最新のarduinoIDEをダウンロードしてきます、自分は1.8.5でした、寄付を求められますがJustDownloadを押せば無料で手に入れることができます。

ダウンロードできるファイルは圧縮されているので下記のコマンドで解凍します、バージョンのところはダウンロードしてきたものにあわせてください

```zsh

  xzcat Downloads/arduino-1.8.5-linux64.tar.xz | tar xvf -  
```
インストール、自分はなんとなくsudoで実行したのですがそのままでもいけるかも。

```zsh
  cd aruduino-1.8.5
  sudo ./install.sh
```

### arduino core for ESP32
[github](https://github.com/espressif/arduino-esp32)
インストールは[ここ](https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/debian_ubuntu.md)にあるコマンドを実行するだけです
{}で囲まれてる部分は自分であとから追加した部分です

```zsh
  sudo usermod -a -G dialout $USER && \
  sudo apt-get install git && \
  wget https://bootstrap.pypa.io/get-pip.py && \
  sudo python get-pip.py && \ 
  sudo pip install pyserial && \
  mkdir -p ~/Arduino{-1.8.5}/hardware/espressif && \
  cd ~/Arduino{-1.8.5}/hardware/espressif && \
  git clone https://github.com/espressif/arduino-esp32.git 
  esp32 && \
  cd esp32 && \
  git submodule update --init --recursive && \
  cd tools && \
  python{2} get.py
```
arduinoディレクトリではなくarduino{バージョン}ディレクトリでした、これはgithubに書いてありました。

私はpython = python3,とエイリアスを貼っているのですがそれでつまりましたubuntu,debianではデフォルトではpythonはpython2系がよばれてしまうんですよね...~~python2なんてなくなってしまえばいいのに~~

~~渋々~~python2で実行することで解決しました

###サンプル動かしてみた
[参考にしたサイト]()のとおりwifiscanを実行してみたのですがそこでもいくつかつまずくことがあたので書いておきます

~~GUIの説明ってめんどくさいから~~これは参考にしたサイトのとおりなのでまるまる引用します
>WiFiScanを動かしてみます。
「ファイル」→「スケッチ例」→ESP32 Dev Module用のスケッチ例の下の「WiFi」→「WiFiScan」選択すると、サンプルプログラムが表示されます。「ツール」⇒「シリアルポート」⇒「/dev/ttyUSB0（環境によって変わります）」でシリアルポートを選択した後、「ツール」⇒「シリアルモニタ」でシリアルモニタを起動しておきます。

>準備ができたら「⇒」ボタンをクリックして、書き込んでみます。「⇒」をクリックする際にはIO0に接続したタクトスイッチを押しながらクリックすることでダウンローダを起動します。「Wrting … 」という表示が出たら、タクトスイッチのボタンを離します。
[ESP32を動かしてみた @ ともの技術メモ](http://tomono.eleho.net/2017/02/06/6337/)

書き込むときにこんなエラー吐かれました
```シリアルポート「/dev/ttyUSB0」を開く際にエラーが発生しました。次のドキュメントを参考にしてください。http://playground.arduino.cc/Linux/All#Permission
```
リンク先に行って解決方法をやっていたのでやってみたのですがうまくいかず...
sudoでarduinoIDEを実行することで解決しました。

無事書き込めて動かしてみたのですがシリアルモニターが文字化けしてました、[ここ](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12154583922)にあるとおりビットレート(?)をプログラムとシリアルモニターで合わせることで文字化けしないようになりました

##Lチカ

マイコンとかラズパイとかってLチカから始めるイメージがあるのでとりあえずLチカやってみた

ファイル→新規ファイルから新しいファイルを作って

```c
   void setup() {
     pinMode(4, OUTPUT);
   }
   void loop() {
     digitalWrite(4, HIGH);
     delay(250);
     digitalWrite(4, LOW);
     delay(250);
   }
```

上と同じ手順で書き込む
io4 →　LED →　抵抗　→ GNDで繋げば


<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">とりあえず環境構築終わってLチカ <a href="https://t.co/dm5EHMs5Z8">pic.twitter.com/dm5EHMs5Z8</a></p>&mdash; yuto (@_yuto_py) <a href="https://twitter.com/_yuto_py/status/949501138751045632?ref_src=twsrc%5Etfw">2018年1月6日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
UnityでiOSとAndroidのバージョニングについてまとめた

各環境ごとに微妙に文言が統一されておらず、混乱したのでまとめました。
以下のキーワードを使うと検索しやすいと思います。

# キーワードの対応表

| 環境 | バージョン(表示用) | バージョン(内部用)  |
|:-----------|------------:|------------:|
| Unity(Android) | Version(`PlayerSettings.bundleVersion`) | Bundle Version Code (`PlayerSettings.Android.bundleVersionCode`) |
| Unity(iOS) | Version (`PlayerSettings.bundleVersion`) | Build (`PlayerSettings.iOS.buildNumber`) |
| Android | versionName | versionCode |
| iOS | Version (`CFBundleShortVersionString`)  | Build (`CFBundleVersion`) | 

前者がストアなどユーザーが見られるリリースバージョンとして使われ、後者がビルドの区別をするためのバージョン(ビルド番号)です。

# バージョニング管理

セマンティック バージョニング 2.0.0が一般的な考え方のベースになっているようです。
https://semver.org/lang/ja/

## リリースバージョン

一般に以下のフォーマットに則ります。

`x(major).y(minor).z(point)`

ファーストリリース時には`1.0.0`にするのが一般的です。

## ビルドバージョン

内部的な区別にのみ使われるので、ある程度自由です(重複しなければ)
Androidが整数で管理してるので、マルチプラットフォームの場合は合わせておくと良いです。(最大値は`2100000000`)

以下の方法がよく使われると思います。
 - 単調増加(jenkisnのビルド番号などを使う)
 - リリースバージョンを使う

# 参考

AndroidとiOSのアプリバージョン周りについてまとめてみた - Qiita
https://qiita.com/tarappo/items/6d20d2f4bc03135ed9c7

アプリのバージョニング | Android Studio
https://developer.android.com/studio/publish/versioning.html?hl=ja
アプリを作るために要件定義からやってみた(要件定義の準備)

# はじめに
リアルタイムでチャットができるアプリを作ろうと思い要件定義の準備からはじめました。

# 経緯
node.jsでアプリ作りたい
↓
backbone.jsも使ってアプリ作りたい
↓
上2つを使ってリアルタイムチャットアプリを作ってみよう
↓
どうせなら要件定義の方法も学びたい
↓
要件定義から実装まで一通りやってみよう**←今ここ**

# とは言ったものの
要件定義に関する書籍[^1]を読んだところ、どうやら要件定義にも準備が必要なようなので、まずは要件定義の準備から入りました。

# 要件定義の準備

## 要件定義に必要な要素
まず要件定義には以下の要素を決めておく必要があります。
- UI
- 機能
- データ

## 上記3点を決めるために必要な準備
### 企画を固める
まずは企画を具体的に明文化してみました。

```
【リアルタイムチャットツール】

[目的]
インターネットを介して様々な人とチャットを使いコミュニケーションをとることで、人のつながりを増やす

[目的達成のために製作するもの]
複数人で話すためのチャットルーム

[製作物の説明]
・主な機能
	→ ログイン機能
	→ カテゴリ毎のチャットルーム

[制作物の利用者]
・一般利用者

[利用する人が得られる便益]
・同じ趣味・嗜好の人達とのコミュニケーション

[作るための体制]
・個人開発

[制作物の期限]
・未定
```

## 全体像を描く
どういった利用者がいるのか、どういう機能を利用するのかを決めました。

```
[全体像]
~利用者~
・一般利用者
	→ 会員登録
	→ ログイン/ログアウト
	→ チャットルーム作成
	→ チャット
・システム管理者
	→ システムを監視する
	→ ログ確認する
	→ データのバックアップをとる
	→ 障害時に復旧を行う
```

## 実装技術を決める
どういった技術を使い実装を行うのかをまとめました。
**※赤いコメント枠は実力不足によりよく決めきれなかった部分です。**

![chat.jpg](https://qiita-image-store.s3.amazonaws.com/0/133772/9db01ce6-9f69-6390-eb96-100e24f573ba.jpeg)

## 要求を整理する
要件定義を円滑に進めるために、お客さんの要求（この場合自分）を一覧できるようにリスト化しました。

```
[要求一覧]
・不特定多数の人とチャットをしたい
・カテゴリ毎にチャットルームを作りたい
・ユーザーを判別したい
・チャットルームに誰がいるか可視化したい
・画像も表示できるようにしたい
```

## 行動シナリオを定義する
```
[行動シナリオ]
・一般利用者
	→会員登録する
	→ログイン/ログアウトする
	→チャットルームを作成する
	→チャットをする
```

## 概念データモデルを定義する
```
[概念データモデルの作成]
・会員
・メールアドレス
・チャットルーム
・チャット
```

# これで準備完了だが……
これで準備は完了です。
ここから要件定義に入りたいところですが、今回は時間がないためこのまま実装に入ります。（手抜き）
今後作りたいアプリができた時に改めて要件定義を行います。

# 参考書籍

[^1]: [はじめよう！要件定義](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86-%E8%A6%81%E4%BB%B6%E5%AE%9A%E7%BE%A9-%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E3%81%8B%E3%82%89%E3%83%99%E3%83%86%E3%83%A9%E3%83%B3%E3%81%BE%E3%81%A7-%E7%BE%BD%E7%94%9F-%E7%AB%A0%E6%B4%8B/dp/4774172286)
Dropboxの競合コピーのファイルを一括で削除する

Dropboxのディレクトリ配下にgitリポジトリを作成すると、`.git` の中にDropboxの競合コピーのファイルがたくさん作られてしまいました。

スペースを含むファイルをfindとxargsで一括で削除するのに少し手間取ったので、メモを残しておきます。

```bash
find . -name "*の競合コピー*" -type f -print0 | xargs -0 rm
```

#　参考記事

- [findとxargsコマンドで-print0オプションを使う理由(改)](https://qiita.com/maskedw/items/2dfdf6fa7eee991ddc45)
numpy.newaxis

```python
A = np.random.randint(0,5,(8,3))
B = np.random.randint(0,5,(2,2))
print(A.shape, B.shape)
X = A[..., np.newaxis, np.newaxis]
print(X)
print(X.shape)
print(A[np.newaxis, ..., np.newaxis].shape)
```
```
(8, 3) (2, 2)
[[[[4]]

  [[0]]

  [[2]]]


 [[[0]]

  [[1]]

  [[0]]]


 [[[2]]

  [[0]]

  [[0]]]


 [[[3]]

  [[3]]

  [[0]]]


 [[[4]]

  [[4]]

  [[3]]]


 [[[4]]

  [[0]]

  [[1]]]


 [[[2]]

  [[2]]

  [[1]]]


 [[[0]]

  [[0]]

  [[1]]]]
(8, 3, 1, 1)
(1, 8, 3, 1)
```
# Refs.
* [numpy.newaxisについて](https://qiita.com/tomoshi0809/items/a5ed38ad8db030650e7f)
* [numpy.newaxisで配列に次元(ndim)を追加する方法](https://deepage.net/features/numpy-newaxis.html)
自己学習 ~Apache~

#**Apache理解**
自己学習のアウトプット
ディレクトリの差分を確かめてみる

##**環境**
ubuntu 16.04 64bit(VertualBox)

##**apacheのインストール**
```
sudo apt-get install apache2
```

##**差分**
インストール前と，[/etc,/lib,/opt,/var,/usr/]ディレクトリを比較してみた。

一部抜粋
・/etc/apache2
・/etc/init.d/
・/var/www/
・/var/log/apache2

##**/etc/apache2**
apache2配下は以下の通り
・apache2.conf
・port.conf
・conf-enabled
・mods-enabled
・sites-enabled
・conf-available
・mods-available
・sites-available

###**apache2.conf**
apache2全体の設定ファイル
設定の有効範囲，設定内容を記載

インストール時は以下のコードが記載されている。

```
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
<Directory>

<Directory /usr/share>
AllowOverride None
Require all denied
<Directory>

<Directory /var/www>
Options Indexes FollowSymLinks
AllowOverride None
Require all denied
<Directory>
```

・< Directory [ディレクトリパス(/var/www/test)]>設定ディレクティブ< /Directory>
→指定したディレクトリ配下のファイルとサブディレクトリ全体に適応される
・< Files [ファイル名]>設定ディレクティブ< /Files>
→指定したファイルに適応される
・< Location [URL]>
→指定したURLとパスに適応される

**AllowOverrideディレクティブ**

```
AllowOverride All | None | directive-type 
```
All→.htaccessによる設定が有効になる
None→.htaccessファイルを完全に無視
directive-type
→[AuthConfig(認証に関するディレクティブの許可),FileInfo(ドキュメントタイプを制御するためのディレクティブの許可),Indexes(ディレクトリインデックスを制御するための許可),Limit(アクセス制限を制御するための許可),options]

.htaccess→各ディレクトリの設定ファイル。アクセス制限なども設定できる。ディレクトリの設定は同じディレクトリに置かれた.htaccessを優先的に適用


**Optionsディレクティブ**

```
Options All | None | Indexes | FollowSymLinks
```

All→MultiViews以外の全ての機能を有効にする
None→何も設定されない
Indexes→リクエストに対して、DirectoryIndexで指定したファイルが存在しない場合、ディレクトリ内のファイル一覧を表示する

**Requireディレクティブ**

```
Require
```
アクセス制御を行う
all granted→すべてのアクセスを許可
ipアドレス指定での許可設定も可能

###**port.conf**
ファイル内の説明
**httpの待受ポート番号**
　複数のポートを指定し、Listen状態にすること可能

```
Listen 80
Listen 55080
```

**httpsの待受ポート番号**
mod_guntls.cは単一のSSLセッションキャッシュを共有し．複数ドメインへの適用が可能らしい

```
<IfModule ssl_module>
Listen 443
</IfModule>
```


```
<IfModule mod_guntls.c>
Listen 443
</IfModule>
```


###**sites-available/000-default.conf**

```
<VirtualHost *:ポート番号>
Documentroot /var/www/html
</VirtualHost>
```
Portで指定したポートを指定する

DocumentRootでは、アクセスした際の、参照するパスを指定
上記の例では、http://ＵＲＬ/でアクセスした場合、/var/www/htmlのindex.htmlを参照する
styled-jsx 「妥協なしの完全な CSS in JSX」

React で CSS を使うには [styled-components](https://www.styled-components.com/) や CSS Modules などの方法があります。

僕は React は修行中の身で styled-components をちょっとかじったくらいなのですが、最近何かの記事で [styled-jsx](https://github.com/zeit/styled-jsx) というものを見て勉強中の今だからこそ試してみよう！と思いたちました。

ちょうど[パワポカラオケ用のWebアプリ](https://qiita.com/ygkn/items/0ce000e2128881a05dc1)で React を使っていたのでこのプロジェクトで試しました。

タイトルの「妥協なしの完全な CSS in JSX」は[リポジトリ](https://github.com/zeit/styled-jsx)の説明文「Full CSS support for JSX without compromises」の意訳です。

この記事は紹介程度のものなので詳しくは[README](https://github.com/zeit/styled-jsx#readme)をご覧ください。

# どんなの？
[Hyper](https://hyper.is/)、[Now](https://zeit.co/now) の [ZEIT](https://github.com/zeit) プロダクトです。

コードはREADMEより。英語は意訳してます。

```js
export default () => (
  <div>
    <p>この p タグはスタイルが適用されるよ :)</p>

    { /*子 <Component /> 内部の p タグには適用されない */ }

    <style jsx>{`
      p {
        color: red;
      }
    `}</style>
  </div>
)
```

コンポーネントの中の `jsx` 属性をつけた `style` タグにCSSを書いていく感じですね。
Vue や Shadow DOM の CSS の書き方に似てていいですね！
styled-components のようにスタイリングのために余計なコンポーネントを作る必要もなくなります。

# 機能
[READMEのFeatures](https://github.com/zeit/styled-jsx#features)より

- パフォーマンスに影響しない完全なCSSのサポート
- 実行時のサイズは**3kb** (gzipした状態で, 元は12kb)
- 完全なセレクタ、アニメーション、キーフレームの隔離
- 組み込みのCSSベンダープレフィックス
- 早く、最小限で効率的なCSSトランジション高性能ランタイム
- SSR以外の高パフォーマンスな実行時CSS注入
- ソースマップ
- 動的CSSとテーマのサポート
- プラグインを使ったCSSの処理

# 使い方
## インストール
```bash:npmの場合
npm i -S styled-jsx
```

```bash:yarnの場合
yarn add styled-jsx
```
## 設定
`.babelrc`に以下の設定を追記します。

```json:.babelrc
{
  "plugins": [
    "styled-jsx/babel"
  ]
}
```

完了です！

### 注：
 [Create React App](https://github.com/facebookincubator/create-react-app)を使用する場合は `eject` する必要があります。
`eject` すると `package.json`の`"babel"`フィールドに Babel の設定があるのでそこに追記してください。

```json:package.json（"babel"だけ抜粋）
  "babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      "styled-jsx/babel"
    ]
  },
```

# 仕組み
styled-jsx は Babel プラグインでJSX内のクラスを被らないものに変えて、CSSのセレクタもそれに合わせています。

```text:例
.wrapper → .wrapper.jsx-XXX (XXXはクラスごとに一意の数字)
img → img.jsx-XXX
```
# 使ってみた感想
- やはり`<style>`で書けるのはきれいで気持ちいい。
- サードパーティのコンポーネントを使うがちょい汚くなる
- `<style jsx>{` がリンターやフォーマッタに設定によっては引っかかる（自分はignoreしてる）
- 日本語の情報が全く無いのがつらかった。英語もまだ多いとは言えない……。
- [react-transition-group](https://github.com/reactjs/react-transition-group) の CSSTransition がうまく動かない？（自分の書き方が悪いだけ？　うまいやり方があればコメントやTwitterで教えてください！）


# 最後に
QiitaのJSXシンタックスハイライト……
OpenWrtのログサイズを変更する

OpenWrtではsyslogdに当たるものとしてlogdが動いている。デフォルトではログサイズは64K。

~~これを変更するにはuciコマンドを利用するしかない（と思う）。~~ LuCIの「System」「System」「Logging」からも設定できるらしいですが、以下はuciコマンドによる設定例です。

```
# uci set system.@system[0].log_size=1024
# uci commit
# reboot
```

実際にサイズが変わっていることは次のように確認できる。

```
# ps | grep logd
  650 root      2284 S    /sbin/logd -S 1024
 2006 root      1188 S    grep logd
```

`logread`で読み出せるログの量も増える。

```
# logread | wc
     1103     14081    121425
```

## 参考資料

- https://wiki.openwrt.org/doc/howto/log.essentials
googleのAIY Project VoiceKitを音声起動する

# 概要

年末帰省するとgoogleのAIYProject VoiceKitが導入されていた。
https://aiyprojects.withgoogle.com/voice#list-of-materials

自分で購入したわけではないので詳細は不明だが、
最近流行りのスマートスピーカーの派生製品で、
出来合いの製品とは異なりsdkによる実装で任意の動作をプログラムできるらしい。

家を出る直前だったが電気とかつけさせてほしいとのことだったので簡易なスクリプトを書いてみた。
ほぼデモアプリのまま、任意の日本語音声をトリガーに処理を実行できるところまでを実装した。

#実装

基本的にはcloud_speech_demo.pyのチュートリアルどおりに起動できるまでをやる。

日本語対応も下記サイトを参考に実装
https://kureuetan.com/web/iot/4638/

詰まったのがスクリプト起動時に ```ImportError: No module named 'google'``` でエラーになる。
voicekitにssh経由でログインしていたためvirtualenvに入れてないのが原因らしいので下記で解消。
https://azriton.github.io/2017/12/13/ラズパイの簡易スマート・スピーカーGoogle-AIYでVoice-Recognizerを作る/

日本語に反応するまではここまでで良いが、
デモで用意されているcloud_speech_demo.pyではvoicekitのボタンを押している間音声認識を働かせる実装になっている。
「OKgoogle」という音声をキックに指示を聞いてくれるようにしてほしいとのこと。

googleのapiとしてgoogleアシスタンスの機能とcloudspeechの機能は別物として用意されているらしく、（アシスタンスはOKgoogleに反応して天気とか聞くと答えてくれる、cloudspeehは単なる音声認識機能のみ）googleアシスタンスに任意の命令を紐付ける方法がよくわからず時間もなかったので、簡易にスクリプトを修正して実現してみた。

cloudspeechのapiに「OKgoogle」を聞かせるとlisten状態を制御しただけ。

```python3
#!/usr/bin/env python3
import aiy.audio
import aiy.cloudspeech
import aiy.voicehat
aiy.i18n.set_language_code('ja-JP')


def main():
    is_able_to_listening = False
    recognizer = aiy.cloudspeech.get_recognizer()
    recognizer.expect_phrase('電気をつけて')
    recognizer.expect_phrase('電気を消して')
    recognizer.expect_phrase('チカチカ')

    status_ui = aiy.voicehat.get_status_ui()
    status_ui.status('ready')

    led = aiy.voicehat.get_led()
    aiy.audio.get_recorder().start()

    while True:
        print('Press the button and speak')
        print('Listening...')
        text = recognizer.recognize()
        if text is None:
            print('Sorry, I did not hear you.')
        else:
            print('You said "', text, '"')
            if not is_able_to_listening and 'Ok Google' in text:
                print('change status to listening')
                status_ui.status('listening')
                is_able_to_listening = True
            elif is_able_to_listening:
                status_ui.status('ready')
                is_able_to_listening = False
                if '電気をつけて' in text:
                    led.set_state(aiy.voicehat.LED.ON)
                elif '電気を消して' in text:
                    led.set_state(aiy.voicehat.LED.OFF)
                elif 'チカチカ' in text:
                    led.set_state(aiy.voicehat.LED.BLINK)
                elif 'goodbye' in text:
                    break


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


#結果
実行するとコンソール上に結果を出力しながらvoicekitの頭が光ったり光らなかったりする。
<img width="1440" alt="スクリーンショット 2018-01-06 1.00.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/114040/266df32e-da9d-3094-d313-6fcaf14d6d5d.png">


#感想

簡易な文章であれば日本語でもapiで結構な精度で当てれれるのすごい。
全然公式ドキュメントとか見てないのでなんとも言えないが電気つける程度ならgoogleアシスタンス経由で実行できる気がする。
googleアシスタンス自体は無料？っぽいのでトリガーにするのはそっちが正しい気がするけど、googleアシスタンス経由にすると勝手に喋ったりするから邪魔な気がする。
この実装だと常にcloudspeechのapi叩き続けるのですごいお金かかるしなんか別にいい方法あるんでしょうね。
もう実家出て手元にないのでなんともしませんが、、、
NYAGOS で環境設定系バッチファイルが期待どおり動かない原因と対策

※2018.03.26記 4.2.5β で本件は過去の話になる予定です。詳しくは「[NYAGOS 4.2.5βが、いかにしてバッチファイルでの環境変数の変更取り込みを可能としたか](https://qiita.com/zetamatta/items/efff93d92ac2150192fb)」参照のこと
※2018.01.29記 sourceコマンドの不具合について追記あり（文末参照）

なぜバッチの環境設定が反映されないのか
===================================

CMD.EXE でバッチファイルを実行すると、バッチファイルの中での環境変数の変更が CMD.EXE にも反映されますが、NYAGOS では反映されません。

これは、NYAGOS の場合、**子プロセスとして呼び出した CMD.EXE でバッチファイルの読み込み・実行を行っているからです。一般に子プロセスから親プロセスに環境変数を反映するすべはありません**。

source コマンド
==============

これでは困るということで、**NYAGOS には source コマンドという内蔵コマンドがあります**。これを使えばバッチファイルでの環境変数やカレントディレクトリの変更を NYAGOS 側に取り込むことができます。

この source コマンド、いったいどうやって子プロセスの情報を取り込んでいるのでしょうか。その理由を知るには仕組みを理解する必要があります。コマンドラインで `source foo.cmd` と実行した場合、以下のような処理が行われます。

（１）以下のようなバッチファイルを `%TEMP%\nyagos-(プロセスID).cmd` という名前で作成

```batch:%TEMP%\nyagos-(プロセスID).cmd
@call foo.cmd
@set "ERRORLEVEL_=%ERRORLEVEL%"
@set > "C:\Users\（ユーザ名）\AppData\Local\Temp\nyagos-(プロセスID).tmp"
@cd > "C:\Users\（ユーザ名）\AppData\Local\Temp\nyagos_(プロセスID).tmp"
@exit /b "%ERRORLEVEL_%"
```

（２）このバッチファイルを CMD.EXE で実行する
（３）「`%TEMP%\nyagos-(プロセスID).tmp`」の内容を読み取って、NYAGOS.EXEプロセス本体の環境変数へ反映する
（４）「`%TEMP%\nyagos_(プロセスID).tmp`」の内容を読み取って、NYAGOS.EXEプロセス本体のカレントディレクトリへ反映する
（５）「`%TEMP%\nyagos-(プロセスID).tmp`」「`%TEMP%\nyagos_(プロセスID).tmp`」「`%TEMP%\nyagos-(プロセスID).cmd`」を削除する

これで理論上はバッチファイル上の環境変数やカレントディレクトリの変更を NYAGOS.EXE 側へ取り込むことができるはずです。

例：Visual Studio 2017 Community Edition
========================================

.nyagos に以下のような１文を足して、「`2017`」とタイプすると、Visual Studio 2017 の環境設定を行うようにします。

```lua:.nyagos
nyagos.alias["2017"]=[[pushd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\." ; source "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" $* ; popd]]
```

- `.nyagos` でいきなり source を実行してもよいのですが、nyagos の起動がいつも遅くなるのも嫌なので、ロードするコマンドを別途作成しました。
- `nyagos.alias["2017"]=` などとしているのは 2017 が数字で、Lua の識別子として使えないからです。`vs2017` などであれば、`nyagos.alias.vs2017=`と書けます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/29454/fe8c223e-26c1-ee0f-954c-38e051b8c321.png)

期待どおり動作しているようです。

だがしかし
=========

どうも自分の預かり知らぬところで、この仕組みがうまく動かないという噂を聞いています。

もし、そのような場合は「**`source -d バッチファイル名`**」とデバッグオプション（`-d`）付きで実行してみてください。そうすると上の（５）のテンポラリファイルの削除が行われなくなります。テンポラリファイルの結果からうまくゆかない原因が分かるかもしれません。

それをもって[issue を起案](https://github.com/zetamatta/nyagos/issues)していただければ、こちらも何らかの対応ができると思います。

余談
====
* `source` には `-d` オプションの他、`-v` オプションというものがあります。`-v` をつけると、テンポラリファイルの結果を画面にも出力します。
* `source` コマンドの前身は NYAOS-3000 の `cmdsource` という Lua で実装したコマンドです。NYAGOS では、これをネイティブな Go 言語で実装しています。
* `source` コマンドの別名として「`.`」（ピリオド一つ）も使えます。

2018.01.29追記：source コマンドの不具合
===================================
NYAGOS 4.2.3_2 までのsource コマンドでは、実行したバッチファイルの標準出力・標準エラー出力が画面に出ないという不具合がありました。

環境変数を読み取るという目的の機能には不備はありませんが、この不具合によって、環境変数バッチがちゃんと呼び出されているか分からないという問題がありました。

当不具合は [NYAGOS 4.2.3_3](https://github.com/zetamatta/nyagos/releases/tag/4.2.3_3)にて修正されました。

ぶっちゃけると
-------------
実は画面に何もでないのは**「そのバッチが元から何も出力しないバッチ」**だと思い込んでいて、**全く疑いもしなかった**んですね。こういう開発者の思い込みがあるから、ささいなことでも不具合報告いただけると、すごく助かるわけなんです。

今回は[tyochiaiさん](https://github.com/tyochiai)から報告だけでなく、[不具合を修正するプルリクエスト](https://github.com/zetamatta/nyagos/pull/276)をいただきました。ありがとうございました。

以上
Visual Studio Codeの背景を透過する(Windows版)

## 結論

拡張機能[GlassIt\-VSC](https://marketplace.visualstudio.com/items?itemName=s-nlf-fh.glassit)を使えばできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/50391/69bb7b1d-1209-1c1a-2c8f-d99494f46cc8.png)

## やりかた

1. Windowsを用意します。Macしか無いならばこの機会に買いましょう。
1. [VSCode](https://code.visualstudio.com/)をインストールします。
1. VSCodeの拡張機能[GlassIt\-VSC](https://marketplace.visualstudio.com/items?itemName=s-nlf-fh.glassit)をインストールします。

おわり。

### 環境

- VSCode 1.19.1 x64
- Windows 10 Pro Insider Preview 10.0.17025.0

Insider Previewである必要は特に無いと思いますが、GlassIt-VSCはWindows7以降でないと動作しないようです。

### 拡張機能のインストールと設定

VSCodeのコマンドパレットを起動(Ctrl+Shift+P)して`>Install Extensions`から`Glasslt-VSC`をインストールします。

コマンドパレットで`>Open User Settings`して、settings.jsonに`glassit.alpha`を設定すると、不透明度を調整できます。`>Reload Window`で反映されます。

```json:settings.json
{
  "glassit.alpha": 220
}
```

またCtrl+Alt+zで減少、Ctrl+Alt+cで上昇します。settings.jsonにも反映されます。

## 参考: Mac版について

[Make VSCode window transparent · Issue \#12578 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/12578)にて議論されていますが、Macにはまだこのような拡張機能は無いようです。
コード晒し：単語のカウント（PaizaランクC相当）

#はじめに
己に課したコード晒し修行（[参考](https://qiita.com/kakeijin/items/5e4e30219c9693f79937)）。
言語は Ruby です。
批判、コメント歓迎


#コードの内容
Paizaの練習問題「単語のカウント（Paiza Cランク相当）」
　『重複ありの英単語列を与えるので、数を数えて表示しなさい』
　　入力　　　　：半角スペースで区切られた長さNの文字列
　　期待する出力：単語、半角スペース、出現回数の順で１行に１単語で
　　　　　　　　　出現したすべての単語を、列に出現する順に出力
　　条件　　　　：全てのテストケースにおいて 1 ≦ N ≦ 1,000
　　例：
　　　入力例２：Nagato Yukikaze Akagi Kitakami Nagato Akagi Akagi Kitakami
　　　出力例２
　　　　　Nagato 2
　　　　　Yukikaze 1
　　　　　Akagi 3
　　　　　Kitakami 2
　　問題文の全文は[こちら](https://paiza.jp/learning/word-count)
Paizaスキルチェックは問題文、解答コード、解答のヒントをネット上に出すな、と警告されますが、練習問題はいいんじゃないかなぁ。公開の可否について以前にPaizaさんに問い合わせたのですが、解答がこないのですよね。

それはそれとして、Paizaさんの問題作成担当に提督がいることは明らか



#コーディング前の準備
Cランク相当なので、問題文は簡潔で読み込む必要などはありませんでした。
Ruby技術者認定試験の勉強中なので、おぼえたての標準クラスのメソッドをできる限り使うように心がけました。

#コード
```ruby:count_words.rb
input_words = gets.split
#  p input_words #=> ["red", "green", "blue", "blue", "green", "blue"]
uniq_words = input_words.uniq
#  p uniq_words #=> ["red", "green", "blue"]

uniq_words.each do | u_w |
    wnum = ( input_words.select { |i_w| i_w == u_w } ).size
    puts u_w + " " + wnum.to_s
end
```
テストケースは全てパス。各テストケースの実行時間は 0.10~0.11秒で、問題なさそうでした。
コーディングの所要時間は測っていませんでした。15分はかかってないんじゃないかと思いますが、もっとスラスラかけるようになりたい。


#見直し
名前づけがおざなり
　　uniq_words
　　　　input_words に uniq メソッドを適用したことから名づけたものの、
　　　　これだけを見ると意味が明瞭ではない。
　　u_w, i_w, wnum
　　　　スコープが短い変数なので短い名前をつけたが、省略形があるし、
　　　　これでよかったのか、という迷いがある。

uniq_word.each
　　脳直でやってしまいましたが、本当にこれが最適な処理なのか？
　　という自問自答をすべきでした。
　　とは言え、落ち着いて見直しても妙案は思いつかず。

単語数を数える部分がちょっと汚い
　　count_duplicate_word などのメソッドを作って隠ぺいした方がよかった？
　　というか、[逆引きRuby](http://www.namaraii.com/rubytips/)でざっと探して見つからなかったので
　　selectを使って実装しましたが、
　　Arrayは重複を数えるメソッドを持ってそうな気がします。
　　　　やることはuniqと処理上はほとんど変わらないわけだし
　
#まとめ
ん～読みやすいコードを書く修行のためにはもう少し複雑な問題を使った方がいいのでしょうか。もうしばらく試行錯誤して、修正するかもしれません。
[C#]ラムダ式の基礎まとめ

#はじめに
C#を基礎から見直しているときに、
ラムダ式をちゃんと理解できていないことに気づきました。
いまさら感はありますが忘れないように備忘録としてまとめておきます。


#開発環境
Visual Studio 2013 Ultimate
.NET Framework 4.7


#テストコード
```csharp:Main.cs
/// <summary>
///	メイン関数
/// </summary>
/// <param name="args">コマンドライン引数</param>
static void Main(string[] args)
{
	// テストケース
	var nameList = new List<string> {
		"Tokyo", "Osaka", "Aichi", "America", "London", "Australia",
	};

	//-----------------------------------------
	// リスト内から6文字以上の文字列を探す場合
	//-----------------------------------------

	// パターン１
	var nameBuf1 = nameList.Where(s => 6 <= s.Length);
	Print(nameBuf1);

	// パターン２
	Func<string, bool> func2 = (s) => 6 <= s.Length;
	var nameBuf2 = nameList.Where(func2);
	Print(nameBuf2);

	// パターン３
	Func<string, bool> func3 = (s) => { return 6 <= s.Length; };
	var nameBuf3 = nameList.Where(func3);
	Print(nameBuf3);

	// パターン４
	Func<string, bool> func4 = Judge;
	var nameBuf4 = nameList.Where(func4);
	Print(nameBuf4);
}

/// <summary>
/// パターン４確認用メソッド
/// </summary>
/// <param name="s">判定文字列</param>
/// <returns></returns>
static bool Judge(string s)
{
	return 6 <= s.Length;
}

/// <summary>
/// 結果確認
/// </summary>
/// <param name="v">出力対象</param>
static void Print(IEnumerable<string> v)
{
	foreach (var name in v)
	{
		Console.WriteLine(name);
	}
	Console.WriteLine("---");
}
```


#最後に
基礎が理解できていないと応用も難しいのでしっかり理解していこうと思います。
rsyncで作成日もコピーする

rsyncで普通に `rsync -avh` しても、作成日（ctimeではなくて、MacのFinderで「作成日」と出たり、Rubyで birthtimeと言ったりするもの）をコピーしてくれない。

Mac標準のrsync (High Sierra 時点）では対策が無いので、Homebrewでrsyncを入れて、
`rsync -avh -N`でOK。
`-N, --crtimes`   `preserve create times (newness)`

なぜか日本語情報が無いので書いてみた。
vagrant+virtualboxでubuntu/xenial64を使うときにvagrantユーザーを作る

`ubuntu/xenial64`のboxを使うとvagrantユーザーではなく、ubuntuユーザーが作成されています。`vagrant ssh`した時はこのubuntuユーザーでログインしているとおもいます。
ですが、ほかのsshクライアントからログインしたい場合にubuntuユーザーではログインパスワードが`vagrant`や`ubuntu`とはなっておらず、[探し出すのは難しい](https://qiita.com/TKR/items/f27271c963de0033f7ff)ようです。なので、provisionの時点で`vagrant`ユーザーを作っちゃいましょう。

## シェルスクリプトを準備
```bootstrap.sh
#!/bin/bash

if ! grep -sqE "^vagrant" /etc/passwd ; then
    PASSWORD=$(perl -e 'print crypt('vagrant', "\$6\$");')
    sudo useradd -p ${PASSWORD} -G sudo -m -s /bin/bash vagrant
fi

sudo sh -c "echo 'vagrant ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-cloud-init-users-vagrant"
```
[vagrantでubuntu/xenial64のユーザーとパスワード設定](https://qiita.com/koooge/items/55138be46f3922c0ab6f)を参考にさせていただきました。
元記事からの変更点は2つ。

* if文でvagrantユーザーが作成済みかどうかをチェックする
* vagrantユーザーでは`sudo`をパスワードなしで実行できるようにする

### if文でvagrantユーザーが作成済みかどうかをチェックする
provisionを複数回実行するハメになったとしてもエラーで止まることは無いはずです。
if文がないと `useradd: user 'vagrant' already exists` とかでエラーになってそれ以降のprovisionがあっても実行されなかったので、追加しました。

### vagrantユーザーでは`sudo`をパスワードなしで実行できるようにする
`sudo`グループに所属していてもsudoを実行するときにはパスワードを求められるので、従来と同じようにvagrantユーザーでのsudo実行時もパスワードなしで実行できるように追加しました。


## Vagrantfileにprovisionを追加
```Vagrantfile
config.vm.provision "shell", privileged: false, path: "bootstrap.sh"
```

この1行を`Enable provisioning with a shell script.` というコメントブロックのあたりに追加してください。

あとは `vagrant up` なり `vagrant provision` をしてみてください。
その後、SSHクライアントから`vagrant`ユーザーでパスワード`vagrant`を使ってログインできればOKです。
あとは `sudo su` とかしてパスワードを聞かれることなくrootになれるはずです。
長生きするための障害対応の三つの心得

# これは何
システムに障害が起こった時に電話がかかってくるようになった人のための心得。具体的な障害対応手順ではなくて、元気にSREエンジニアとして、そして人として生き残っていくための心得。

# 心得

### 1. 本当の優先事項は何かを考える
仕事の電話がかかってきた。（仮に）今は奥さんの誕生日食事会の途中だ。さあ電話に出て対応をするか？
そういう時には対応をしてはいけません。他の人に任せましょう。ほっておけば2番目の人が電話を受けてくれます。
人生で重要なことの優先順位をつけましょう。電話がかかってきたら必ず仕事、なんてことはやってはいけません。そういう風に考えていると２４時間いつでもかかってくる電話を所持していると精神が持ちません。気をつけましょう。
エンジニアとしても人としても長生きしましょう。
（補足：待機人員として拘束時間になっているならちゃんと出ましょう。しかし特に決まりもなく電話を持たされている場合には法的には何も拘束力がないと理解しています）

### 2. 最初にやることを意識する
まずは他の人も呼びましょう。
あまりにも軽微な障害なら一人で対応しても良いですが、すぐに問題原因が特定できない可能性があるもの、影響範囲が狭くないものの場合にはチームメンバーが気がつけるようにSlackで@channelしましょう。躊躇なく。
その目的としては以下のような人員を増やす目的があります

* 問題原因特定のための人員
* 原因特定後、手作業が発生した時に対応する手として
* 影響システムや社内一次報告、関係会社などに連絡する連絡人員として
* SREの知見は少なくてもユーザ目線で障害発生や復旧を確認できる動作確認人員として

なんにせよチームメンバならやれることはあるはずなので人を集めましょう。
上にはいろいろ理由は書きましたが、一人で対応するとテンパったりミスをしたりするのでオブザーバでもいてもらった方が良いです。

### 3. 障害対応は実況しよう
やったことは生のコンソールログを含めてSlackに貼っておこう。他のチームの状況なども可能なかぎり一つのチャンネルに集める。これの目的は以下のもの

* 途中から対応に参加した人が状況を把握できる
* 手分けして対応をしている場合に他の人の状況が把握できる
* ミスや考え違いをしていたら他の人が気がつくことができる
* 振り返りに使うことができる（後で見て情報ないと本当に困るので、やってみると効力がわかるはず）

実際にやったことだけでなく、障害原因の予想や、対応方針、ふわっとした違和感なども投げましょう。少しでも情報を表に出してみんなで考えることが大切です。書くことで自分の考えも整理されます。

# 終わりに
これらは電話をもらって頑張りすぎて死にそうになっている同期や後輩を見て考えたことです。

ストレスためすぎているなと思ったら電話をおいて海にでも出かけるのも良いです。この投稿で言いたいことはこれがほとんで全てです。
Jupyter > 外部コマンド実行 > !top > 出力がセルに逐次追加される > Kernel:Interruptで止める

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

## 前置き

2017年11月20日: 「デュアルモニタになり(27インチx2)、快適快適」
2018年01月06日: 「画面足りない(*1, *2)」

*1)[生産性を上げる。プログラマによる個人的健康管理術。> 机配置編](https://qiita.com/7of9/items/cfe0400c38c6b1d3d8f6)
の前面に二つのモニタ、机の左側にMacbook Airの状態

*2) Sublime Text(ADDA用bash scriptとPython scriptを実装)とJupyter(+Matplotlib)とChrome(QiitaとmindmupとGitHub)とYouTubeを開くと足りない。MATLAB開くとさらに足りない。

Jupyter Notebook実行ターミナルが占有されるので、Jupyter上でコマンドを実行することにした。

## Jupyterの外部コマンド実行

### 一回限りの外部コマンド

Sublime Textやgitなどの一回限りのコマンド実行

```txt:Jupyter
!subl res.qext_TMT_180106.txt
```

起動済のSublime Textにファイルが表示されるので問題ない。

lsやgitなども実行できる。

### 繰り返し処理の外部コマンド実行

```txt:Jupyter
!top
```

セル内に処理結果が逐次追記されていく。
Kernel > Interruptで止めないと困ったことになる。
ASP.NETブラウザの判定方法

HTTPリクエストに含まれるBrowserオブジェクトを利用する

````C#
public HttpBrowserCapabilities Browser { get; set; }
````


- 利用例

```C#:LogActionFilter.cs
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
    var request = filterContext.HttpContext.Request;
    Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
    StreamWriter writer = new StreamWriter(@"D:\WebSites\TEST1126\Log\Log.txt", true, sjisEnc);
    writer.WriteLine("テスト書き込みです。[{0}]", request.Browser.Browser);
    writer.Close();
}
```

- 結果

```
テスト書き込みです。[InternetExplorer]
テスト書き込みです。[Chrome]
```
Gtk+ 3アプリケーションがXSendEvent(3)による入力を受け付けない時は

# TL; DR

Gtk+ 3アプリケーションが`XSendEvent(3)`による入力を受け付けない時は環境変数`GDK_CORE_DEVICE_EVENTS=1`をセットすればよい。

# 詳細

`XSendEvent(3)`はXlibの関数で、X Window Systemのイベントメッセージを指定のウィンドウに送りつける関数です。これを使うとキーボード入力のエミュレーションを(ある程度)実現できます。例えば、[xvkbd](http://t-sato.in.coocan.jp/xvkbd/)や[xdotool](https://www.semicomplete.com/projects/xdotool)といったエミュレーションツールは裏でこの関数を使う場合があります[^1]。

[^1]: ただし、これらのツールは可能ならばXTest拡張の関数を使うようになっています。これは、`XSendEvent(3)`で送るイベントメッセージは人工的な(synthesized)イベントであることが分かるフラグが付けられており、アプリケーションによってはそれを無視する場合があるためです。XTestによる入力はアプリケーションからは物理デバイスからの入力と区別できず、エミュレーションとしてより信頼性が高いと考えられます。

が、Evinceなど一部のGtk+ 3アプリケーションでは`XSendEvent(3)`によるキーボード入力を受け付けません。

これはGtk+ 3の入力バックエンドがデフォルトでXInput2というX Window System拡張を使うからです。`GDK_CORE_DEVICE_EVENTS=1`環境変数をセットすると、イベントメッセージによる入力を受け付けるようになり、`XSendEvent(3)`も効くようになります。

# 参考

- [Using GTK+ on the X Window System: GTK+ 3 Reference Manual](https://developer.gnome.org/gtk3/stable/gtk-x11.html)
- [GTK3 and XINPUT_2](https://mail.gnome.org/archives/gtk-list/2012-May/msg00001.html)
- [gnome - xvkbd not working on GTK3 apps - Ask Ubuntu](https://askubuntu.com/questions/661609/xvkbd-not-working-on-gtk3-apps)
- [435742 – \[GTK3\] Some keybindings/shortcuts become unresponsive](https://bugs.eclipse.org/bugs/show_bug.cgi?id=435742)
EDGE IE11のfooter下部の隙間？白線？アウトライン？

# EDGE IE11のフッター下部にできる白線の応急処置
根本的な原因はわからず。

・Chrome,Firefoxには隙間はない
・clearfixを使っていない
・scriptで下部にimgを生成することもない

見た目の応急処置

```
footer{
  box-shadow: 0px 1px #{ページのフッターカラー};
}
```

でとりあえずは要望はクリアできるはず。。。
XcodeでiPhoneをワイヤレスでデバッグする

# はじめに

WindowsでXamarin.Forms開発を行う際、iOSのデバッグをワイヤレスでできないかと色々と試してみました。

結果として、WindowsのVisual Studio 2017からはワイヤレスでデバッグできませんでしたので
ワイヤレス接続が確認できたXcodeからのワイヤレス（WiFi）デバッグの手順を記載します。


以下の環境で確認しました。

**Mac側**

- masOS Sierra 10.12.6
- Xcode 9.2

**iPhone 6s**

- iOS 11.2.1

# 準備
デバッグするiPhoneをMacにLightningケーブル接続しておきます。

# Xcodeの設定

Xcodeのメニュー[window - Devices and Simulators]でデバイス画面を開きます。

![スクリーンショット 2018-01-05 11.32.04.png](https://qiita-image-store.s3.amazonaws.com/0/171118/cdce555a-a383-ee45-802c-881e693211f2.png)

自分の端末が表示されるので[Connect via network]にチェックを入れます。
すると左のデバイス名の横に地球マークが表示されます。

![スクリーンショット_2018-01-05_13_30_22.png](https://qiita-image-store.s3.amazonaws.com/0/171118/a6ddde89-c3e6-cb0b-5a77-594c1f9fccdd.png)


あとはLightningケーブルを抜いても大丈夫です。

> 私の場合、ここで地球マークがすんなりつきませんでした。そこで以下の確認を行いました。
> - iPhoneとMacが同一ネットワークにあるか？　→　ある
> - Devices and Simulators画面からUnpair Deviceをし再度ペアリング　→　変化なし
> - iPhone再起動　→　変化なし
> - Mac再起動 →　何故かこれで繋がるようになりました。
> 本設定を試すためxCodeを9.2にバージョンアップしてその後一度も再起動
> していなかったのが原因かもしれません。

これでLightningケーブルを接続していなくてもXcodeからデバッグできるようになりました。

# さいごに
この状態で、WindowsのVisual Studio 2017からMacに接続しデバッグしようとしたのですが
iPhoneは見えません。
iPhoneをケーブルでつなぐと見えます

Visual Studio 2017のiOSプロジェクトの設定で「WiFi経由でデバッグする」のチェックを
入れても認識されませんでした。

![スクリーンショット_2018-01-06_9_58_17.png](https://qiita-image-store.s3.amazonaws.com/0/171118/bce6b1a1-8e83-c704-984c-edea2748a07c.png)

[Xamarinのサイト](https://developer.xamarin.com/ja-jp/guides/ios/deployment,_testing,_and_metrics/debugging_in_xamarin_ios/)で以下の記載がありました。デバッグ中にケーブルを抜いてもセッションを継続することが可能なようです。
>アプリケーションの起動は引き続き USB ケーブルで行われます。そのため、最初の起動でケーブルを差し込んでいる必要
>があります。 ただし開始後は、ケーブルを安全に抜き、Wi-Fi によるデバッグ セッションを続行できます。

本来やりたかったWindowsからの完全ワイヤレスでのデバッグは現時点ではできないことが分かりました。
生のjavascriptで親要素は削除するけど子要素は残す（jQueryのunwrapっぽく）

あるdivがあって、子要素は残しつつそのdivだけを削除したいというとき、生のjavascriptでどうやるのか意外と情報が見当たらなかったのでメモします。 [jQueryのunwrap](https://api.jquery.com/unwrap/) と同じことを生のjavascriptでやろうという目的です。

## 準備

前提としてこういうHTMLがあるとして、ボタンをクリックすると div タグは消すけど p タグは残すという処理を、 jQuery の場合と生の javascript の場合とで実装してみます。

```html
<!-- jQueryの実験用 -->
<button id="button1">ボタン</button>
<div id="parent1">
  <p>child</p>
</div>

<!-- 生のjavascriptの実験用 -->
<button id="button2">ボタン</button>
<div id="parent2">
  <p>child</p>
</div>
```

上述のとおり jQuery には unwrap という便利なものがあるのですが、生の javascript にはそういうのはなさそうでしたので、これで代替できそうというのを以下でやってみました。 ES6 で書いています。

## jQuery の unwrap() を使う場合

```javascript:jQuery&nbsp;の場合
// jQuery で用意されている unwrap() を使う
$('#button1').click(() => $('#parent1 p').unwrap());
```

## 生の javascript でやるとこんな感じ。

```javascript:生の&nbsp;javascript&nbsp;で再現
/**
 * 指定したDOMは削除し、子要素を取り出して描画する関数。
 * jQuery の unwrap と同等の処理をおこないます。
 *
 * @param {HTMLElement} target 対象のDOMオブジェクト
 */
const unwrap = target => {
  while(target.firstChild) {
    target.parentNode.insertBefore(target.firstChild, target);
  }
  target.remove();
};

//使用例: ボタンをクリックしたらunwrapを実行します。
document.querySelector('#button2').onclick = () =>
  unwrap(document.querySelector('#parent2'));
```

[jsfiddleにサンプル置きましたのでご参考ください。](https://jsfiddle.net/snakada2/dexepr06/8)


(19/05/02: 文体等を調整しました。)
読みやすいコードを書くために今日からやろうと思ったこと（読後メモ：リーダブルコード）

#はじめに
きっかけはこの記事
　[新人プログラマ正月休み中を使って読んでみてほしい技術書をセレクトしてみた。](https://qiita.com/hirokidaichi/items/d30714f0698dcff1200f)
全部は無理そうだったので、よく見かける「[リーダブルコード](https://www.amazon.co.jp/gp/product/4873115655/ref=as_li_tf_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4873115655&linkCode=as2&tag=hirokidaichi-22)」を読んでみました。

#本の概要
書籍情報：
　　タイトル -- リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック 
　　著者　　-- Dustin Boswell,‎ Trevor Foucher
　　翻訳　　-- 角 征典
　　出版年　　　　-- 2012/6/23
　　紙の本の長さ　 -- 260 ページ
　　出版社　　　　 -- オライリージャパン
　　[Amazonのページ](https://www.amazon.co.jp/gp/product/4873115655/ref=as_li_tf_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4873115655&linkCode=as2&tag=hirokidaichi-22)
　　　　古典的名著のような印象でしたが、2010年代に出版されているんですね
　　　　（原著の出版年も2011年でした）

想定読者：「読みやすいコードを書きたいと思っているプログラマ」
　　新人プログラマ（未満）の自分でも読みやすかったです
　　（実践できるかどうかは別問題ですが）。

著者、訳者について
　　Dustin Boswell
　　　　ソフトウェアエンジニア、[HP](http://dustwell.com/)
　　Trevor Foucher
　　　　？
　　角 征典
　　　　ワイクル株式会社 代表取締役
　　　　東京工業大学環境・社会理工学院 特任講師

#学んだことまとめ
詳しいまとめは大勢の先達がいらっしゃいます。qiita では[こちら](https://qiita.com/AKB428/items/20e81ccc8d9998b5535d)の記事は網羅的にまとめてくださっています。なので、読み終えた時点での自分なりのまとめを三点だけあげます。

・コードにおいて最も大事な要素は読みやすさ
　　　読みやすさは他の要素とトレードオフ？「でも、やるんだよ」
・「他人が読みやすいか」を常に意識しながら書く
　　　大事なのは正確さ（誤解されにくさ）、簡潔さ、見映え
・読みやすくできないときは「やり方がマズいのでは」と考える
　　　処理自体の見直しにも他人の目が有効。ラバーダッキングでもよい

#今日からやろうと思ったこと：自分のコードを公開する
先輩プログラマにコードを見てもらえるのが一番ですが、残念ながら現状アテがありません。そこで、qiita上でコードを公開したいと思います。「これは他人の目に触れるコードなんだ」と思いながらコーディングする機会を定期的に作りつつ、「晒してるあのコード、こうしたらもっとよくなるのでは」という感じで見直しをしたくなる環境を強制します。
その際は
　　[リーダブルコード適用 チェックリスト](https://qiita.com/AKB428/items/574f94695de51fa1fa19)
を利用させていただきます。
Javaでコマンドを実行する(ping)




```
String cmd = "cmd.exe /c ping 8.8.8.8"; //実行するコマンド

Runtime runtime = Runtime.getRuntime();

Process p = runtime.exec(cmd);

InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "Shift-JIS");
BufferedReader reader = new BufferedReader(isr);

for (String line; (line = reader.readLine()) != null;) {
	System.out.println(line);
}
```

出力

```
8.8.8.8 に ping を送信しています 32 バイトのデータ:
﻿8.8.8.8 からの応答: バイト数 =32 時間 =15ms TTL=57﻿
﻿8.8.8.8 からの応答: バイト数 =32 時間 =13ms TTL=57﻿
﻿8.8.8.8 からの応答: バイト数 =32 時間 =12ms TTL=57
﻿8.8.8.8 からの応答: バイト数 =32 時間 =13ms TTL=57

8.8.8.8 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 12ms、最大 = 15ms、平均 = 13ms
```
bash > セットした変数を保持する > . ./some_bash_script

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

bashコードを実行時、その時の変数を後で参照したいと思った。

以下を見つけた。
[How to write a bash script to set global environment variable?](https://stackoverflow.com/questions/12351702/how-to-write-a-bash-script-to-set-global-environment-variable)
> answered May 29 '14 at 15:22
JDembinski
> 
> Just run your shell script preceded by "." (dot space).

```bash:keep_env_180106_exec
#!/usr/bin/env bash

addacfg="-grid 32 -eq_rad 4.24478229"

echo $addacfg
```

`chmod +x keep_env_180106_exec`で実行権限をつけておく。

```bash
$ . ./keep_env_180106_exec 
-grid 32 -eq_rad 4.24478229
$ echo $addacfg
-grid 32 -eq_rad 4.24478229
```

addacfgという変数を保持できた。

`bash keep_env_180106_exec`の形で実行する方法は未調査。
HOKUSAI > Python > わたしの中では料理はできているの

```txt:動作環境
ideone (Python3.5)
```

### 処理概要

@ ドラマ：ホクサイと飯さえあれば

> わたしの中では料理はできているの

どういう処理をするかは自明なのでここでは書かない。

### code

https://ideone.com/y6KIGW

```hokusai_180106.py
'''
v0.1 Jan. 06, 2018
  - replace keyword with text defined in the list
'''

# coding rule: PEP8

atxt = 'わたしの中では料理はできているの'

alist = ['コード', 'ソフト', 'ハード', '装置']
alist += ['アルゴリズム']
alist.remove('ハード')

for elem in alist:
    res = atxt.replace('料理', elem)
    print(res)

```

```txt:run
わたしの中ではコードはできているの
わたしの中ではソフトはできているの
わたしの中では装置はできているの
わたしの中ではアルゴリズムはできているの
```

### コードの学習内容

- list: 定義
- list: 追加
- list: 削除
- string: 置換
- iterator
- 標準出力
- (オプション) coding rule: PEP8

### 所感

「未完了のことは記憶に残る / 未完了の仕事は人の関心を奪い取る」

keijiroさんによる、かつて存在したRadium Software Development。
日々活動するエンジニアが様々な技法について検討する面白いブログだった。今はもう存在しない。

そのブログにおいて引用されていたフレーズ「未完了の仕事は人の関心を奪い取る」自体が頭に残っている。

ホクサイと飯さえあればのフレーズが未完了だったので、ここで完了とする。

### link

- [ズンドコキヨシまとめ](https://qiita.com/shunsugai@github/items/971a15461de29563bf90)
Elementary OSとwindowsのDual Boot PCを作った話 XPS13

忙し過ぎて書けなかった宿題などを消化中・・・

PCやPC部品も年末年始セールと言うことで、PCを新調しました。自宅のEndeavorにはUbuntu Budieを設定していますが、同じディストロ使うのもつまらないので、かっこいいという噂のElementary OSをインストールして新年早々色々ハマったため備忘録として書きます。Panteonデスクトップならもっといいのあるよという記事も見ましたが、Elementary OSよかったら、手を伸ばしてみようかなと思いました。

# 結論
UNetboootinを使ってElementary OSをFATフォーマットしたUSBにやき、

https://qiita.com/furu8ma/items/3af582658780c9679e3f

の手順を参考に設定をするのが最も安全です。

ハマった

Windowsから未割り当て領域のボリュームにパーティションを切っておく作業などもしますが、割愛。
この記事見る前に自分でいろいろ作業した結果、XPS13だとRAIDモードで起動することがデュアルブートを妨げる要因になっていたため、AHCIモードで起動することが必須みたいですね。

その前にRaidモードのままで起動すると、

![Image uploaded from iOS.jpg](https://qiita-image-store.s3.amazonaws.com/0/99145/cd20922e-eff9-754c-5194-84cb9f65defb.jpeg)

SSDが認識されなくてあれぇー？ってなったり、
セキュアブートをオフにしてレガシーモードで起動してインストール走らせると、

![Image uploaded from iOS (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/99145/5db2d8fd-ae6b-4abc-49f6-325a133dedfd.jpeg)

あれパーティション作ってインストールしたのにBootローダーどこにもない・・・。
っていうような現象が起きました。

AHCIモードで起動するとちゃんとUEFIブートローダーをインストールすることができるので、めでたしめでたし。Ubuntu Baseなので基本インストール設定の手順は一緒で

https://www.abten.net/2015/05/538/

を参考に設定。/bootに新規作成したパーティションを与えて、elementary OS用のブートローダー(GRUB2)をインストールさせます。その他のボリューム割り当てはよしなに。これでインストール完了後PC再起動でGRUBが実行されるようになりました。

めでたしめでたし。

スペックはMemory 8GB, CPU Core-i7 8550U,ssd256GBでセールのためMac book Pro 13 inch 128GBモデル第7世代Core-i5メモリ8GBと同じくらいの値段で買えたこと、OSの起動が一瞬で完了して感動するなど、とても満足度の高い買い物でした。。。

[このニュース](https://gigazine.net/news/20180104-meltdown-spectre/)を知るまでは・・・。

とても悲しい・・・。
Python > split > 二つのデリミタ(=と空白) > 実装: 'R1=0.5000D+01  R2=0.5000D+01  R12=0.1000D+02  LAM=0.6283D+01'から数値を取り出す

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

### 処理概要

```.py
IN_TXT = 'R1=0.5000D+01  R2=0.5000D+01  R12=0.1000D+02  LAM=0.6283D+01'
```

上記からそれぞれの値を取り出したい。

### code v0.1

```split_equal_space_180106.py
'''
v0.1 Jan. 06, 2018
  - add extract_value()
'''


def extract_value(atext, akey):
    # for a single delimiter
    txt = atext.replace('=', ' ')
    #
    found = False
    for elem in txt.split(' '):
        if found:
            return elem
        found = akey in elem
    return None

IN_TXT = 'R1=0.5000D+01  R2=0.5000D+01  R12=0.1000D+02  LAM=0.6283D+01'

val = extract_value(IN_TXT, 'R1')
print(val)
val = extract_value(IN_TXT, 'R2')
print(val)
val = extract_value(IN_TXT, 'R12')
print(val)
val = extract_value(IN_TXT, 'LAM')
print(val)
val = extract_value(IN_TXT, 'DELTAFLYER')
print(val)

```

```txt:run
$ python3 split_equal_space_180106.py 
0.5000D+01
0.5000D+01
0.1000D+02
0.6283D+01
None
```
【個人的】webpackでreactするときのCSS環境のベストプラクティス

個人的ですが。
## CSSModulesを使う
[CSSModules](https://github.com/css-modules/css-modules)を使います。これに関しては賛否あり、確かに微妙な点はありますが、とりあえずはこれで良い気がします。CSSModulesに限界を感じるようだったらRadium等のCSS in JSを試してみてください。僕が使うwebpack.config.jsの経過はこんな感じ。あとはお好きに設定を。

```javascript:webpack.config.js
{
  test: /\.css$/,
  include: __dirname + '/src',
  exclude: /node_modules/,
  use: [{
    loader: 'style-loader',
    options: { sourceMap: true }
  }, {
    loader: 'css-loader',
    options: {
      localIdentName: '[sha512:hash:base32]-[name]-[local]',
      modules: true,
      sourceMap: true
    }
  }
}
```
（追記: `localIdentName`は`localIdentName: '[sha512:hash:base32]-[name]-[local]'`みたいにしないとファイル名とクラス名を同じにした時に衝突が起きることにあとから気づいた。
## Stylusを使う）
[Stylus](https://github.com/stylus/stylus)を使います。CSSメタ言語のうちの１つで、変数定義やメソッド定義、子要素への簡潔なアクセス、シンプルな文法など便利な機能がたくさんあるので、オススメです。

```Stylus:index.styl
$header-color = #ffffff
$subtitle-color = #939395
.root
  h1
    color $header-color
  h2
    color $subtitle-color
```
webpack.config.jsはこんな感じになります。こちらもお好きに設定を。

```javascript:webpack.config.js
{
  test: /\.styl$/,
  include: __dirname + '/src',
  exclude: /node_modules/,
  use: [{
    loader: 'style-loader',
    options: { sourceMap: true }
  }, {
    loader: 'css-loader',
    options: {
      localIdentName: '[sha512:hash:base32]-[name]-[local]',
      modules: true,
      sourceMap: true
    }
  }, {
    loader: 'stylus-loader',
    options: { sourceMap: true }
  }]
}
```
少なくとも、CSSをそのまま書くよりは圧倒的に短くかけるしストレスが減ります。お気に入りのCSSメタ言語がある人はそれを使ってもいいと思います。
## nibを使う
[nib](https://github.com/tj/nib)を使います。これはStylus用のユーティリティやmixin機能等を提供してくれるライブラリです。詳しくは[ドキュメント](https://github.com/tj/nib/tree/master/docs)を見てください。これはwebpack2以降だとwebpack.config.jsでwebpack.LoaderOptionsPluginを使って設定します。

```javascript:webpack.config.js
plugins: [
     new webpack.LoaderOptionsPlugin({
       options: {
         stylus: {
           use: [require('nib')()],
           import: ['~nib/lib/nib/index.styl']
         }
       }
     })
   ]
```
ちなみに、importの所に任意のstylファイルを追加すれば、そこで定義した変数やメソッドを使えるようになります。色は全てそこで定義しておくとわかりやすくていいと思います。個人的ですが。
人工知能API「Wit.ai」で遊ぶ (2)

## はじめに
前回は、Wit.aiのサイトから実際にAppを登録し、インプットする文章を「インテント」と「エンティティ」に分けてWit.aiに認識させるところまで進めました。
今回は文章を外部サーバから送信し、Wit.aiからレスポンスを受信するところまで進めてみます。これができれば、後は受け取ったレスポンスの値によって、適切な外部APIと接続するなどして実際にサービスにしていくこともできそうです。

## node-wit
Wit.aiは様々な言語で開発していくことが可能な人工知能ですが、今回はNode.js SDKである、`node-wit`を利用してみます。

node-wit
https://github.com/wit-ai/node-wit

リポジトリをcloneしてきた後は、

```js
yarn --save node-wit
yarn
```
で必要なモジュールをインストールします。

## exampleを触ってみる
まずはReadMeにしたがってexampleにあるbasic.jsを実行してみます。

```js
node examples/basic.js <MY_TOKEN>
```

`MY_TOKEN`にはWit.aiのメニューにあるSetting画面からClient Access Tokenを取得し、指定します。
上記のコマンドをコンソールから実行すると、対話モードに入るので前回入力した「Turn on the TV」を入力してみましょう。

すると、以下のようにレスポンスが返却されました。
<img width="569" alt="スクリーンショット 2018-01-06 3.56.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/73643/4070e135-8f1f-859d-d30b-ed4e45c51314.png">

少し見辛いので整形します。

```json
{  
   "_text":"Turn on the TV",
   "entities":{  
      "state":[  
         {  
            "confidence":0.94501193062763,
            "value":"on",
            "type":"value"
         }
      ],
      "target":[  
         {  
            "confidence":0.94276322425952,
            "value":"TV",
            "type":"value"
         }
      ],
      "intent":[  
         {  
            "confidence":1,
            "value":"turn"
         }
      ]
   },
   "msg_id":"0TZTR7O1aHtRSwdJV"
}
```
なるほど。
前回学習させたインテントである「turn」とエンティティ「state」「target」がちゃんと認識されており、そのvalueが返却されています。
この中身を見つつ、ハンドリングしていく感じでしょうか。

## 内部処理を覗く
ちょっと気になるのでnode-witの中身を覗いてみましょう。
ざっとReadMeを読んだ感じだと、`DEPRECATED `なAPIばかり。[^注1]
まともに使えそうなものはmessage APIくらいでした。

message APIの実装箇所をみると、以下のようになっています。

```node-wit/lib/wit.js
this.message = (message, context, n, verbose, junk) => {
    let qs = 'q=' + encodeURIComponent(message);
    if (context) {
      qs += '&context=' + encodeURIComponent(JSON.stringify(context));
    }
    if (typeof n === 'number') {
      qs += '&n=' + encodeURIComponent(JSON.stringify(n));
    }
    if (verbose != null) {
      qs += '&verbose=' + encodeURIComponent(JSON.stringify(verbose));
    }
    if (junk != null) {
      qs += '&junk=true');
    }
    const method = 'GET';
    const fullURL = witURL + '/message?' + qs
    const handler = makeWitResponseHandler(logger, 'message');
    logger.debug(method, fullURL);
    return fetch(fullURL, {
      method,
      headers,
    })
    .then(response => Promise.all([response.json(), response.status]))
    .then(handler)
    ;
  };
```

やってることはとても単純。
Wit.aiが提供しているテキスト解読用のAPI(message API)の高レベルAPIになっており、適切なクエリパラメータを付与しているだけのようです。
https://wit.ai/docs/http/20170307#get--message-link

## おわりに
今回Wit.aiのほんの触りの部分だけ書いてみましたが、思ったより扱いやすく、1日もあれば簡単なBotサービスを作れそうな印象を受けました。
今後、時間を見つけて実際にサービス(Line Botなど)を作ってみたいと思います。

## 注釈
[^注1]: 以前、Wit.aiには`Stories`と呼ばれる機能があり、会話用のAPI（converse API）も用意され、複雑な会話のコンテキストを実現できるように実装されていたようですが、よりシンプルなmessage APIを推奨する方向に進んでいるようです。(https://wit.ai/blog/2017/07/27/sunsetting-stories)