OmniAICreator/Qiita-1.07M huggingface dataset:
TwitterKit for Android で Callback URL not approved してしまう

See also, iOS での対応方法はこちらを参照: https://qiita.com/nwatabou/items/6a0c891ff3f206cdb8e9

## ことのはじまり

先月にアナウンスがあり、つい先日正式に Callback URL のホワイトリスト化が強制となりました。
これに伴って、今まで適当に Callback URL を設定していたり何も設定せずにいても動いていたものが動かなくなります。

https://twitter.com/TwitterAPI/status/1006635008692350977

## 正しく設定しないとどうなるか

正しく設定していないアプリで TwitterKit for Android を使うと、Twitter 公式アプリがない状態で認証・認可のフローにはいると`Callback URL not approved`というようなエラーが403で返ってきます(Twitter 公式アプリがインストールされている場合はそちらが認証・認可のフローを担うため問題なく動作します)。
ただし TwitterKit for Android では特に Callback URL をクライアント側から指定する必要はないため、うっかりしていると「急に Twitter にログインできなくなった」というような状態になってしまいます。
公式のドキュメントにもとくに言及がないため、TwitterKit for Androidを使った場合の「正しい Callback URL」とは何か不明瞭な状態です。

## 正しい値

結論から言うと、[Twitter アプリの設定画面](https://apps.twitter.com/)で次の値を Callback URL に設定するのが正しいです。

```
twittersdk://
```

iOS やその他 Web アプリ向けの Callback URL の設定とは異なることに注意してください。Callback URL は複数登録ができるので、他のプラットフォーム向けの Callback URL と一緒に Android 用の設定も追加してください。

TwitterKit for Android のクライアント側がコード上で Callback URL を特に指定する必要はないとはいえ、実際にはライブラリ内で定数として使われています。

https://github.com/twitter/twitter-kit-android/blob/d71efe38404b5233e312f2531efbf72e5ce5d7bc/twitter-core/src/main/java/com/twitter/sdk/android/core/internal/oauth/OAuth1aService.java#L59

TwitterKit for Android の wiki にも適当な Callback URL を設定すれば良い旨の記述がありますが、先日のホワイトリスト化の強制に伴って、`twittersdk://`でなければなくなったということです。

## 参考

https://github.com/twitter/twitter-kit-android/issues/135
`brew upgrade` で MySQL バージョンアップ後に起動しなくなった場合の対応

開発用の Mac にて、`brew upgrade` したらローカルの MySQL が起動しなくなったので共有。

1. `brew upgrade` 実行
2. mysql のバージョンが 5.7 から 8.0 に上がる。
3. `mysql.server start` で `The server quit without updating PID file` エラーになる。

    ```
    yamadar-mac:~ yamadar$ mysql.server start
    Starting MySQL
    . ERROR! The server quit without updating PID file (/usr/local/var/mysql/yamadar-mac.pid).
    ```

4. `cat /usr/local/var/mysql/yamadar-mac.err` でエラーログを確認

    ```
    [ERROR] [MY-012526] [InnoDB] InnoDB: Upgrade after a crash is not supported. This redo log was created with MySQL 5.7.17. Please follow the instructions at http://dev.mysql.com/doc/refman/8.0/en/upgrading.html
    [ERROR] [MY-012930] [InnoDB] InnoDB: Plugin initialization aborted with error Generic error.
    [ERROR] [MY-011013] [Server] Failed to initialize DD Storage Engine.
    [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
    [ERROR] [MY-010119] [Server] Aborting
    ```
    クラッシュ後のアップグレードはサポートしてないとの事。つまり前回 MySQL はクラッシュして止まっていた模様。`brew upgrade` 前のバージョンのMySQLで、クラッシュせずに停止させれば良さそう。

5. 前のバージョンで起動してから停止。

    ```bash
    # クラッシュして停止したバージョンのMySQLをインストール
    brew install mysql@5.7
    # インストールしたバージョンのMySQLで起動と停止
    /usr/local/opt/mysql@5.7/bin/mysql.server start
    /usr/local/opt/mysql@5.7/bin/mysql.server stop
    ```
    これで「クラッシュせずに停止」した事になる。

6. `mysql.server start` で起動するようになった。

    ```
    yamadar-mac:~ yamadar$ mysql.server start
    Starting MySQL
    ...... SUCCESS!
    ```

エラー後に MySQL 8.0 で起動するまでの手順は以上。

## おまけ : MySQL8.0 から MySQL5.7 へのダウングレード手順

自分の環境では一度 MySQL8.0 で起動/停止した後は、そのままでは MySQL 5.7 では起動できなくなった。もしダウングレードしたい場合は、MySQL8.0で起動して `mysqldump` する必要がありそう。

MySQL8.0 から MySQL5.7 にダウングレードした手順

1. MySQL8.0 で `mysql.server start`
2. ダンプファイル作成 （自分は Sequel Pro を使った）
3. MySQL8.0 停止とアンインストール

    ```sh
    mysql.server stop
    # アンインストール前のデータをバックアップ(念の為)
    mv /usr/local/var/mysql/ /usr/local/var/mysql_bk20180615
    brew uninstall mysql
    ```
4. MySQL5.7 インストールと起動

    ```sh
    brew install mysql@5.7
    /usr/local/opt/mysql@5.7/bin/mysql.server start
    ```
5. データベース作成してダンプファイルを戻す
6. `/usr/local/opt/mysql@5.7/bin/` にパスを通す
7. `mysql.server stop` / `mysql.server start` などで動作確認

これで MySQL 5.7 に戻った。

以上。
Electronでレンダラプロセス同士のIPC

### ズバリ

```javascript:Renderer1
const ipcRenderer= require("electron").ipcRenderer;
ipcRenderer.send("message", body);
```
```javascript:Renderer2
const ipcMain = require("electron").remote.ipcMain;
ipcMain.on("message", (event, body)=>{...});
```

`レンダラプロセス => メインプロセス`
`メインプロセス => レンダラプロセス`
これはよくやるのですが。

`レンダラプロセス => レンダラプロセス`
をやろうとして躓いたので備忘録。

### NG集

```javascript:Renderer1
const ipcRenderer= require("electron").ipcRenderer;
ipcRenderer.send("message", body);
```
```javascript:Renderer2
const ipcRenderer= require("electron").ipcRenderer;
ipcRenderer.on("message", (event, body)=>{...});
```
チャネルが同じなら`ipcRenderer`同士でもワンチャン...
しかし世の中そんなに甘くは無かった。

```javascript:Renderer1
const ipcRenderer= require("electron").ipcRenderer;
ipcRenderer.send("message-to-main", body);
```
```javascript:Main
const ipcRenderer= require("electron").ipcMain;
ipcMain.on("message-to-main", (event, body)=>{
    event.sender.send("message-to-renderer2", body);
});
```
```javascript:Renderer2
const ipcRenderer= require("electron").ipcrenderer;
ipcRenderer.on("message-to-renderer2", (event, body)=>{...});
```
メインプロセスをリレーさせる暴挙に出るも、折り返せず失敗。

```javascript:Renderer1
const ipcRenderer= require("electron").ipcRenderer;
ipcRenderer.send("message", body);
```
```javascript:Renderer2
const ipcRenderer= require("electron").ipcMain;
ipcMain.on("message", (event, body)=>{...});
```
Electron「`ipcMain`?そんなモジュールねーよ」


ここで`BrowserWindow`の存在を思い出して、受信側を`remote`経由で`ipcMain`にしたら行けましたとさ。
Mozcのソースを読むとわかる、IMEの工夫

## まえおき

絶賛バズり中の [Macで矢印「↑」を「うえ」とかで変換している人へ。←↓↑→](https://qiita.com/Kohei_Kishimoto0214/items/38a7fefb355b36671462) の記事。

私は、MacのIME事情はそんなに詳しくないのだけど、「これ実はMozcのソースみたら書いてあるよ！」「他にもこんなのがあるよ！」という、非常にしょうもない情報はたまたま知っているので、いちおう発信をしておこうと思う。

あくまでMozcのソースなので、ATOKとかMS-IMEで動かないものもたくさんあるとおもう。
Android版Google IMEではきっと動くと思う。

　


## 矢印キーが zh, zj, zk, zl

まずは本家 [Macで矢印「↑」を「うえ」とかで変換している人へ。←↓↑→](https://qiita.com/Kohei_Kishimoto0214/items/38a7fefb355b36671462) で言われてたやつ。

https://github.com/google/mozc/blob/afb03ddfe72dde4cf2409863a3bfea160f7a66d8/src/data/preedit/qwerty_mobile-hiragana.tsv#L7-L10

　


## wwwwwwwwwwwwが打てる！

これ自然に使いすぎてて意識してない人がほとんどだと思う。

ttttttttって打つと 「っっっっっっっっっっっｔ」　ってなるけど
wwwwwwwwwwwwって打っても　「っっっっっっっっっっっw」　にはならないですよね？

https://github.com/google/mozc/blob/afb03ddfe72dde4cf2409863a3bfea160f7a66d8/src/data/preedit/qwerty_mobile-hiragana.tsv#L43

　


## 知ってたら意外と便利な　`z.` → `...` (三点リーダー) 　`z-` → `〜`

https://github.com/google/mozc/blob/afb03ddfe72dde4cf2409863a3bfea160f7a66d8/src/data/preedit/qwerty_mobile-hiragana.tsv#L5

　

## 地味に便利な　 `z[` → `『` 　　 `z]` → `』` 

もう　「かっこ」　とか　「かぎかっこ」　とか変換しなくていい

https://github.com/google/mozc/blob/afb03ddfe72dde4cf2409863a3bfea160f7a66d8/src/data/preedit/qwerty_mobile-hiragana.tsv#L12-L13

　


## まとめ

とりあえずソース読んでみよう！
https://github.com/google/mozc/commits/master/src/data/preedit/qwerty_mobile-hiragana.tsv

＃ これ2012年から変わってないんだね・・・


　

「あれ？ wwwwwwwwww打てないじゃん？」っていう人は、とりあえずGoogle日本語入力に乗り換えてみましょう（違ｗ
Emscriptenでwasmじゃなくてwastが欲しいとき

# 背景

[Fortran実装のゼータ関数をWASMにして動かしたかった件](https://abrakatabura.hatenablog.com/entry/2018/06/13/204136)

というブログ記事で取り組んだ
FortranからのwastとEmscriptenからのwastを合せて動かそうと
試みていた際に必要になった。

# Emscriptenでwastを吐かせるには

```shell-session
emcc -s BINARYEN_METHOD='interpret-s-expr' -o foo.js foo.c
```

と「-s」オプションで 「BINARYEN_METHOD='interpret-s-expr'」を
指定するとwastを吐いてもらえる。

# 関連記事

- [SLコマンドをEmscriptenでWeb化する 2014年秋編](https://abrakatabura.hatenablog.com/entry/2014/11/01/170855)
- [libiconvをemscriptenでjs化し、node.jsで使った](https://abrakatabura.hatenablog.com/entry/2015/04/18/115323)
- [公式のOpenCVでWASM版のOpenCV.jsがビルドできたのnode.jsで動かそうとした件](https://abrakatabura.hatenablog.com/entry/2017/11/29/063247)
小型LCDをRaspberry Pi 3からPythonで制御する

# 概要
- 2.2インチのディスプレイをRaspberry Pi 3からPythonで制御したので、そのメモです

# 使用ハードウェア
- [Raspberry Pi 3]( https://www.amazon.co.jp/gp/product/B01NAHBSUD/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1)
- [サインスマート 2.2インチ serial LCD モジュール 240*320 SPI TFT ディスプレイ](https://www.amazon.co.jp/gp/product/B00QV2WDJM/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1)

# 手順
## ハードウェアの接続
![connection_diagram.png](https://qiita-image-store.s3.amazonaws.com/0/228317/13ae8ffe-4f06-8476-a1f0-9dc74b4ef031.png)


- 対応関係を以下の表にまとめました

|  Raspberry Pi 3 Pin  |  LCD  |
| ---- | ---- |
|  -  |  SDO/MISO(未接続)  |
| 3.3V   |  LED  |
|  GPIO11  |  SCK  |
|  GPIO10/MOSI   |   SDI/MOSI |
|  GPIO25 |   DC/RS |
|  GPIO23 |  RESET  |
|  GPIO8/SPI_CE0_N  |  CS  |
|  GND  |  GND  |
|  3.3V |   VCC |

## ソフトウェアの準備

- 任意のディレクトリに以下コマンドでソースコードをダウンロードします（本家のAdafruit社ではありませんが、こちらだと今回使用する2.2inchi TFTディスプレイを使えます。)

```zsh
git clone https://github.com/Funkrusha/Adafruit_Python_ILI9340
```

- ディレクトリを移動します

```zsh
cd Adafruit_Python_ILI9340
```

- 必要なツールをインストールします

```zsh
sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus python-pip python-imaging python-numpy
```

- 必要なPythonライブラリをインストールします

```zsh
sudo pip install RPi.GPIO
sudo pip install Adafruit_BBIO
sudo python setup.py install
```

- サンプルディレクトリへ移動します

```zsh
cd examples
```

- image.pyの30行目を書き換えます（デフォルトだと2.8インチディスプレイになっています）

```python:image.py30行目
CURRENT_PITFT = PITFT_2_2  # 2.2インチディスプレイ用に設定を変更します
```

- image.pyを実行します

```python
python image.py
```

- 実行後、猫の画が出たら成功です

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228317/a53d30a5-08bb-d0d5-02e4-6ae55208702a.png)


### **以下のようなエラーが出た場合の対処法**

```zsh:エラーログ
Traceback (most recent call last):
  File "image.py", line 21, in <module>
    import Image
ImportError: No module named Image
```

- Adafruit_Python_ILI9340/Adafruit_ILI9341/ILI9341.pyの25,を以下のように変更します

```python3:Adafruit_ILI9341/ILI9341.pyの25,26行目
from PIL import Image  # PILからimportするようにします
from PIL import ImageDraw  # PILからimportするようにします
```

- 再度インストールします

```
sudo python setup.py install
```

- サンプルの実行ファイル（Adafruit_Python_ILI9340/examples/image.py）の21行目も以下のように書き換えます

```python:image.py21行目
from PIL import Image  # PILからimportするようにします
```

# 参考サイト
- [Raspberry Pi 3 GPIO(公式)](https://www.raspberrypi.org/documentation/usage/gpio/README.md)
- [2.2" 18-BIT COLOR TFT LCD DISPLAY WITH MICROSD CARD BREAKOUT](https://www.adafruit.com/product/1480)
CycleGANに自分のデータセットを用いて学習させる

# 0. 概要
ドメインの異なる画像を学習できるCycleGANを動かす。
このネットワークは何ができるかというと、「馬」と「しまうま」の画像両方を学習させると、どうしたら互いの画像を相互変換可能かを学習でき、最終的に馬の画像を入れると形はそのままで色合いをしまうまに変換してしまうなんてことができるそう。

他にも線分のみのキャラクターを入れると、2次元のかわいらしい絵に変換してくれたりだとか、使い道は多そう！


![image.png](https://qiita-image-store.s3.amazonaws.com/0/95636/4d0806b8-6053-de11-2d84-5df519a955c2.png)

このようにテクスチャーの変更が得意なネットワークです。一方、形の変換までは苦手だそう。

以下、実装
https://github.com/xhujoy/CycleGAN-tensorflow


# 1. 動作環境

```
GeForce GTX 1080 Ti
TensorFlow 1.8
CUDA 9.0
CUDNN 7.5
Python 3.6
```

# 2. デフォルトで動かしてみる

<b> 学習: </b>

まずはソースコードを持ってくる

```
git clone https://github.com/xhujoy/CycleGAN-tensorflow
cd CycleGAN-tensorflow
```

次に学習データを持ってくる。とりあえず王道の馬としまうまのデータセット。

```
bash ./download_dataset.sh horse2zebra
```

学習開始:

```
python main.py --dataset_dir=horse2zebra
```

使うGPUを選択するときは:

```
$ nvidia-smi -L
→ GPU一覧を確認

# GPUを指定
export CUDA_VISIBLE_DEVICES="0"
```


学習の可視化

```
tensorboard --logdir=./logs
```

ネットワーク構造が表示された後に、スムーズに学習が始まっていった。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95636/c93c73ae-c89b-34ea-c9b8-ea7b765e62cc.png)

<b> テスト: </b>

まずは馬からしまうまへ。

```
python main.py --dataset_dir=horse2zebra --phase=test --which_direction=AtoB
```

`--which_direction=AtoB`こいつを`BtoA`にしてあげれば逆も可能。

実行したら`main.py`直下のフォルダ`test/`に結果が格納される。

これが入力画像
![n02381460_20.jpg](https://qiita-image-store.s3.amazonaws.com/0/95636/39186373-8c73-74dd-979f-b02c276091b8.jpeg)

そしてこちらが出力画像
![AtoB_n02381460_20.jpg](https://qiita-image-store.s3.amazonaws.com/0/95636/79cefb0f-15c7-ba79-607c-34d5ec0dfdb7.jpeg)

3分学習させた程度なので、上手く変換できていない・・・
（追伸: 1日ほど学習させたら上手く変換できました）

# 3. オリジナル画像で学習させる
まずデータ構造を理解する。

学習データ及びテストデータは`main.py`直下のフォルダ`datasets/`に保存する。
`datasets/`以下に例えば`car`というフォルダを作る。

内部のフォルダ構成は以下のようになる。

```
*datasets
 + horse2zebra
 + car
   - trainA
   - trainB
   - testA
   - testB
```

ここで各学習データには以下を入れる。

`trainA`には普通乗用車の画像を入れる
`trainB`にはタクシーの画像を入れる
`testA`には普通乗用車のテスト画像を入れる
`testB`にはタクシーのテスト画像を入れる


このように画像を配置したら以下で学習を実行できる。

```
python main.py --dataset_dir=car
```

ものすごく簡単である。

なお、細かいが画像サイズは256 x 256が初期設定である。
このため、サイズを変更する場合はソースコードを変えましょう。

以上！
jQuery超初心者向けメモ

#jQuery超初心者向けメモ

###jQueryの基本的な書き方 

##jQueryとは？？
JavaScriptのwrapper的なライブラリ。
もっとかみ砕いていうと、JavaScript書くの難しいよ…めんどくさいよ…って人が簡単に使えるようになるもの。
CSSで言うBootstrapみたいなもの。

##導入方法
[初歩的なjQueryプラグインの設置方法](http://web-pc.net/jquery001)

・ダウンロードしてきた場合
jsのファイルと同じように、Scriptタグで**他のjsファイルより前に**読み込む。


##簡単な使い方

```index.html
!DOCTYPE html>

<html>

 <head>
   <meta charset="utf-8" />

   <meta http-equiv="Content-Style-Type" content="text/css" />
   <meta http-equiv="Content-Script-Type" content="text/javascript" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

   <title>sample</title>

   <link rel="stylesheet" href="./css/index.css" /><!-- css -->
      <!-- script -->
   <script src="./js/jquery-1.12.3.min.js"></script><!-- j-query -->
   <script src="./js/index.js"></script>


 </head>

 <body>
   <p id="text">Hello jQuery World!</p>
 </body>

</html>

```

```./js/index.js

$(document).ready(function(){
  $("#text").text("ハローjQueryワールド！");
});

```

##解説

$ ← jQueryライブラリを使うよっていう宣言だと思えばいい
("#text") ← CSSと同じセレクタを使って、要素を指定
.text("ハローjQueryワールド！") ← .textメソッドを使って中身のテキストを書き換え

メソッドについてはここで検索すればだいたいわかる。
[js STUDIO](http://js.studio-kingdom.com/jquery/)

$(document).ready();　は、ページが読み込まれたらっていう意味
window.onload = function(){} と同じ
WordPress ContactForm7で　チェックボックスなどにスタイルをあてる方法

とりあえず忘れないうちにコピペ！

SASS↓

```Sass
  input
    &[type=checkbox]
      display: none
  .wpcf7-list-item-label
    margin-top: 15px
    margin-right: 40px
    margin-bottom: 20px
    padding-left: 40px
    position: relative
    display: block
    height: 28px
    font-size: 18px
    font-family: $font_go
    line-height: 28px
    &::before
      content: ""
      display: block
      position: absolute
      top: 0
      left: 0
      width: 28px
      height: 28px
      background: #fff
      box-shadow: 0 0 5.34px 0.66px rgba(#000, .06)
  input[type=checkbox]:checked + .wpcf7-list-item-label
    &::after
      content: ""
      display: block
      position: absolute
      top: 0
      left: 0
      width: 28px
      height: 28px
      background: url("../img/icon_check.png") center center no-repeat
```
ペアプロ／モブプロをやってみて

昨年冬からチーム内でペアプロ／モブプロを取り入れています。
半年経ってどんな感じかざっと書いてみました。

## きっかけ

- 所属するチームで業務の属人化が問題となっていた
    - このシステムこの機能はhogeさんしか改修できない、など
    - メンバーの退職や異動により、開発を担当できる/障害対応ができる人が一人だけの機能、システムが複数...つらい

## どうなりたかったか

ペアプログラミング、モブプログラミングの効果には様々がありますが、私達のチームでは、ペアプロ／モブプロの高い教育効果で少しでも属人化問題を改善したい、ということで始めた
まずは1人から2人へ...

## 参考にしたもの
※ペアプロ、モブプロの詳細はこの投稿では割愛

- [WEB+DB PRESS Vol.102](http://gihyo.jp/magazine/wdpress/archive/2018/vol102)の記事「はじめてのペアプロ／モブプロ メキメキと人が育ち，プロダクトの質を高める」を主に参考にしてやってみた 
- [TAKAKING22氏のプレゼンテーション](https://speakerdeck.com/takaking22)

## 企画部門から突っ込まれたりした

「予定とか遅延したりしないの、工数が余計にかかっちゃうじゃん」とか言われたが、このままだとまずい現状やペアプロの効果を伝えて了承を得た

## どんな感じでやっているか

まずは[WEB+DB PRESS Vol.102](http://gihyo.jp/magazine/wdpress/archive/2018/vol102)の記事「はじめてのペアプロ／モブプロ メキメキと人が育ち，プロダクトの質を高める」を使用してペアプロ／モブプロについてチーム内で情報を共有した

### できるだけペアプロで

- 「チーム全体への知の共有より」も、「まずは目下起きている属人化問題を改善したい」ということで、モブプロではなくペアプロから始めた
- 毎日必ず、ではなく、ゆるく
    - 午後のxx時～xx時で場所はどこどこで、とか固定はしない
    - デイリースタンドアップで皆でタスクを共有するとき、やれそうなものを見つけては開催
        - 特に属人化を解消したい機能、システムを優先して
    - やらない日もある

### 週一モブプロ枠

- 毎週金曜に90分ほど場所と時間を確保
- ネタをメンバーから持ち寄り
- 実装や設計などのネタがない場合
    - GCPでstackdriverの設定をいじる作業だったり
    - ペアプロ／モブプロのふりかえりをやったり

## 半年やってみた感想

- 早期に高い教育効果を出た
    - 属人化問題がだいぶ解消された
- コミュニケーションにクセのある人にはペアプロをアサインしづらいかも
    - 今やっているメンバーは皆人当たりがいいので、彼らの人柄に恵まれている、救われている部分もあり
    - 辛辣な物の言い方をする人間にムカついちゃうので
- 暗黙的な知識の共有がいい
    - 参考にした記事にもあったが、他人のPCの操作を見るのはとてもおもしろい。「あ！こういうコマンド使っているんだ！」とか学び、気付きがたくさんある
    - 個人的にはこれがけっこう良いと思っている
- チームメンバー同士の交流につながった
    - いつもは別々の機能、システムを担当しているメンバー同士がコミュニケーション取るようになったり
- コードレビューが開発のボトルネックにならなくなった
    - WEB+DB PRESSの和田卓人氏の記事の通りだが「github(gitlab)のおかげで複数の機能の並行開発を行なえるようになった結果、プルリクエストのレビューがシステム開発の在庫問題となった」ということで...
    - 今後はそこを意識して継続して取り組んでいきたい
- 上長や企画部門の理解、了承が得られるなら、ぜひやったほうがいいと思う
- やってよかったペアプロ／モブプロ

### メンバーから挙げてもらった感想(ちゃんとまとまってないですがざっと以下に)

- 仕様説明する際、コードレベルで説明できるのがいい
- 実装する際、レビューの効率もいい
- 定数の定義をどこにしたらいいとかすぐ気づける
- タイポ減った
- マージリクエストをみてレビューするより、集中してレビューできる
- もっとコード量が多い開発でやれば、プルリクエストという在庫低減には役立つだろう
    - コードレビューの時間が一切かからない
- 知識量に差がある機能でドライバーをやって、かなり勉強になった
- もっと経験を積んで知識をつけたうえでペアプロをやったらもっと効率良く進められそう
- 教えることで自分の持っている内容が整理される
- 設計書を見ながらコードを見るのがちょっと大変だった
- 進め方決めるのが最初困った
    - プログラムのイメージが湧いてなかった
- 普段使ってないPCでやったときはちょっとつらかった...
- ナビゲータが指示しすぎると、ドライバーがただただ消化してしまうことに
書いたはずのことを忘れる！
- ナビゲータを信頼して安心しすぎていると...？ → コメントで意図が伝わるように
- リファクタリングするときは事前にソースを共有しておいて、別のタイミングでモブプログラミングする、など一度書いて直したいなと思う時、みんなで直せたらうれしい
- 眠くなる
    - 自分がぜんぜん知らないものだと
- 疲れる！
    - 終わったあとの倦怠感
    - 二時間くらいが最長
    - やっているときは気にならないが、終わったあとにどっと疲れる
    - 半強制的に、時間を通知して休んだほうがいい
        - ドライバーは集中するので、タイムキーパーはナビゲーターの役割か？
- vscode live shareとか使ってリモートでもやりたい
- 正対したほうがいい
    - 大きいテーブルで大きなディスプレイを斜めで見てやるのもちょっとつらい
- 目的を事前に参加者で共有しておくと、より有意義になりそう
    - 仕様共有なのか、品質上げるためなのか

## 他のチームもやり始めた

- 自分たちのチームのシマに大きなディスプレイを確保できなかった、ということもあるが「うちはペアプロ／モブプロやっているぜ！」アピールもしたく、フリースペースの大型ディスプレイ使ってやったり、敢えて目立つ場所でやっていた
    - ちょいちょい別のチームのメンバーが参加してくれるたりした(そのときだけペアプロがモブプロになる)
    - 3ヶ月以上経った頃、他のチームもモブプロやっているところが出てきた！

## これから

- ベトナム オフショア開発メンバー／北海道 ニアショア開発メンバーがチームに所属しているので、リモートでもペアプロ／モブプロやりたい
- ペアローテーションしていきたい

## その他

楽天のモブプログラミング見学してみたい
axiosでGETリクエストのパラメータにObjectを含める方法

以下のブログに移行しました。

[axiosでGETリクエストのクエリパラメータにObject型を含める方法 | TOMILOG](https://blog.ryou103.com/post/axios-send-object-query/)

<!--
axios
https://github.com/axios/axios

## 問題

axiosでGETリクエストのパラメータにObjectを含めたい。

以下のようなリクエストを送りたいが、これだと上手くいかない。

```js
const url = 'http://localhost/api/posts/search';

const params = {
  word: 'hoge',
  category: {
    $in: ['interview', 'column'],
  },
};

axios.get(url, { params });
```

結果はこうなる。

```js
GET /api/posts/search?word=hoge&category=%7B%22$in%22:[%22interview%22,%22column%22]%7D

> console.log(req.query);
  {
     word: 'hoge',
     category: '{"$in":["interview","column"]}'
  }
```

ObjectがStringになってしまう。



## 解決

オプション`paramsSerializer`を使えば、Objectも含めることができる

```js
# 
import qs from 'qs';


const url = 'http://localhost/api/posts/search';

const params = {
  word: 'hoge',
  category: {
    $in: ['interview', 'column'],
  },
};
const paramsSerializer = (params) => qs.stringify(params);

axios.get(url, { params, paramsSerializer });
```



```js
GET /api/posts/search?word=hoge&category%5B%24in%5D%5B0%5D=interview&category%5B%24in%5D%5B1%5D=column

> console.log(req.query);
  { word: 'hoge',
    category: { '$in': [ 'interview', 'column' ] }
  }

```
-->
php7: 関数, メソッドの返り値の型を取得する

# はじめに
メタプログラミングやフォーマット・仕様自動生成などの時に欲しい関数、メソッドの型を取得します。
`ReflectionFunctionAbstract` クラスの `getReturnType` を利用します。
自分用メモ

# 関数
```php
$functionReflection = new ReflectionFunction('メソッド名');
(string) $functionReflection->getReturnType();
```
`ReflectionFunction` 関数用のリフレクションクラスを利用します。 `ReflectionFunctionAbstract` を継承しているため、`getReturnType`が利用できます。
`getReturnType` は、タイプが特定できれば `ReflectionType` 、 それ以外は`null`を返します。
組み込みにも利用できますが、`null`なことが多いです。

```php:利用例
function foo(): string
{
    return "foo";
}

$functionReflection = new ReflectionFunction('foo');
echo (string) $functionReflection->getReturnType();
// "string"

$functionReflection2 = new ReflectionFunction('array_merge'); // 組み込み
echo (string) $functionReflection2->getReturnType();
// ""
```

参考 [php.net: The ReflectionFunction class](http://php.net/manual/en/class.reflectionfunction.php) および関連項目

# クラスメソッド
```php
$methodReflection = new ReflectionMethod('クラスの型', 'メソッド名');
(string) $methodReflection->getReturnType();
```

メソッドの場合も `ReflectionFunctionAbstract`を継承している`ReflectionMethod`を利用すればOKです。

```php:利用例
class Bar()
{
    public bar(): int
    {
        return "1";
    }

    private bar2() // 返り値宣言なし
    {
        return "1";
    }

    public bar3(): Foo
    {
        return new Foo();
    }
}

class Foo()
{
}

$methodReflection = new ReflectionMethod(Bar::class, 'bar');
echo (string) $methodReflection->getReturnType();
// "int"

$methodReflection2 = new ReflectionMethod(Bar::class, 'bar2');
echo (string) $methodReflection2->getReturnType();
// ""

$methodReflection3 = new ReflectionMethod(Bar::class, 'bar3');
echo (string) $methodReflection3->getReturnType();
// "Foo"
```

参考 [php.net: The ReflectionMethod class](http://php.net/manual/en/class.reflectionmethod.php) あたり参照
ビジネスサイドという言葉を使っているエンジニアたちへ

**そんな言葉使ってて恥ずかしくないの？** と言いたい。

案に、自分はビジネスしてませんよって言ってるのと一緒です。
エンジニアはシステムを作るものではなく、ビジネスを作るものでしょう？


（ビジネスサイドというのをエンジニアを含めて使っている場合はOKです）
特定のコミットでの差分を見るときのgitコマンド

gitで作業している時に「このコミットでのdiffなんだっけ？」と確認したい時があります。
そんなとき、コマンドベースで確認するための方法です。


## 前提
以下のようなコミットログがあるとする。


```
commit abcdefg (HEAD -> feature/test)
Merge: xxxxxx
Author: nishina555
Date:   Fri Jun 15 15:34:05 2018 +0900

    Merge branch 'master' of https://github.com/xxxx into feature/test

commit hijklmn (origin/master, master)
Author: nishina555
Date:   Fri Jun 15 13:34:14 2018 +0900

    test
```

このコミットログは直前のコミットは`abcdefg`、その前のコミットは`hijklmn`ということを意味している。

## diffの見方

### `abcdefg`(直前のコミット)でのdiffを見るには以下のようにする

```zsh

git show abcdefg
```

もしくは以下でもOK

```
git diff HEAD
```

### `hijklmn`でのdiffを見るには以下のようになる

```
git show hijklmn
```

もしくは以下でもOK

```
git diff HEAD^2
```

by <a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>
git commit の順番を入れ替える

## コミットの順番を入れ替えたい！
コミットの順番を入れ替えたい時ありますよね。
順番を入れ替えたほうが都合が良い方がありましたので、調べてみたらgit rebaseを使うみたいです。

## 方法
```
git rebase -i [コミットID]
```
上記のコマンドを打つと、[コミットID]以降のコミットを編集できるようになります。
順番を入れ替えて保存すれば、良いです。

※rebaseするとハッシュ値が変わります。ご認識ください。

## 参考
- [Git: コミット履歴の順番を変えたい](http://sutara79.hatenablog.com/entry/2015/07/28/134629)

- [gitのコミットの歴史を改変する(git rebase) 2 / 2](http://tkengo.github.io/blog/2013/06/08/git-rebase-reference2/)
HUBOTの構築（CentOS7）

試してみたのでメモ。Node.jsはインストールした状態を想定

# 手順
1. YeomanとHubotのパッケージをインストール

    ```
    # npm install -g yo generator-hubot
    ```

2. Hubot用のフォルダを作成する

    ```
    $ mkdir myhubot
    $ cd myhubot
    ```

3. Hubotのひな型を作成する

    ```
    $ yo hubot
    ```

## 確認
```
$ bin/myhubot
myhubot> myhubot ping
myhubot> PONG
```

# 参考
- [Getting Started With Hubot](https://hubot.github.com/docs/)
- [DEPLOYING TO UNIX](https://hubot.github.com/docs/deploying/unix/)
NotSerializableExceptionで詰まった話

# 現象
SerializableなクラスAAAをArrayListに格納してファイル書き出ししようとしたところ、NotSerializableExceptionが発生しました。
（もちろん、AAAのフィールドも全てSerializable）

そのときのコードは次のようなものです。
（コードがアレなのはお許しください。。。）

```Navigator.java
public class Navigator {
    AppCompatActivity activity;


    public void navigateToFuga(ArrayList<AAA> list) {
        // FugaActivity.createIntent内でIntent生成し
        // hogesをファイルに書き出し、ファイルパスをIntentに詰める
        activity.startActivity(FugaActivity.createIntent(activity, list));
    }
}
```

```HogeActivity.java
public void go() {
    navigator.navigateToFuga(new ArrayList<AAA>(){{
        add(bbb.aaa);
    }});
}
```

# 解決方法

コードを次のように書き換えました。

```HogeActivity.java
public void go() {
    ArrayList<AAA> list = new ArrayList();
    list.add(bbb.aaa);
    navigator.navigateToFuga(list);
}
```


# あとがき
Activityの画面遷移のためにIntentにデータを詰める、ということはよくやるわけですが
Intentに想定外の大容量データを入れたことでアプリがクラッシュしました。
なので、一時的に上のような方法で対応したのですが、まさかの例外で困りました。
デバッガを見ると、
```FugaActivity.createIntent```で受け取ったArrayListのデータ型が ```HogeActivity$1``` のようなものになっていたので、まさかなぁと思って修正した結果うまくいったという次第です。
解決に数時間を要してしまったので、今後は同じ問題に引っかからないようにしないとですね。

NotSerializableExceptionで調べても同じような原因で悩まれている方がいらっしゃらないようだったので記事に書きましたが、なんと調べればよかったんでしょう。。。
flutter チュートリアルを実際に動かして見た①

**初投稿です、稚拙な部分は優しくご指摘頂けると喜びます。**


#flutterチュートリアルを実際に動かして見た

知り合いと話している際に「flutterって面白そう」という話になり
実際に下記のチュートリアルを参考に動かして見ました。

https://flutter.io/get-started/codelab/#step-1-create-the-starting-flutter-app

ちなみにインストールも公式サイトを参照しながらでうまく行きました。
困った時は
**flutter doctor**
コマンドで足りないものやインストールのし忘れを確認できるので
とても便利です。

今回使用したのはチュートリアルの中の
*Step 1: Create the starting Flutter app*

以下実際のコードです。

```dart:my_app.dart
import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Welcome to Flutter",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Welcome to Flutter"),
        ),
        body: new Center(
          child: new Text("Hello World"),
        ),
      ),
    );
  }

}
```

- Observationsより
    - このexampleはMaterial.appを作るためのものみたいですね。
MaterialはWebやモバイルをのためのデザインでflutterは豊富なWedgetを持ってるみたいです。

 - =>記号を使って短い関数を扱えるみたいですね、Javaでいうラムダ関数みたいなものでしょうか。
 - flutterではおおよそappに関するほとんどのものがwidgetでできてるみたいです。 
 - Material library配下にあるScaffold widgetから基本的なアプリの画面を配置することができるます。BarやらBodyやらTitleのプロパティに値を設定することで画面上での表示が行えます。
 - Widgetはbuild()によって画面にWidgetをどう表示するかを決めるのが仕事です。build()メソッドさえ書いてしまえば動く手軽さがウリみたいですね。

# まとめ
flutterにはMaterialデザインを行うための部品がたくさん詰まっている。
部品はWidgetと呼ばれる。
Widgetをbuildすることで画面上に配置することができる。
プロパティに値を持たせることで、色の変更や文字の変更が行える。
GPSの研究　その10

#概要
GPSを理解したかった。
NMEAを調べてみた。

#$GPGGA

$GPGGA,m1,m2,c1,m3,c2,d1,d2,f1,f2,M,f3,M,f4,d3*cc


```
m1	UTC時刻	hhmmss.ss形式です
m2	緯度	ddmm.mmmm
c1	緯度の種類	北緯=N 南緯=S
m3	経度	ddmm.mmmm
c2	経度の種類	東経=E 西経=W
d1	位置の種類	0=無効 1=自律測位 2=差分補正(ディファレンシャル補正またはRTCM基地局補正)
d2	測位に利用した人工衛星の個数	
f1	位置の精度(水平方向)HDOP	n.nn
f2	標高(基準楕円体からの標高)	n.nn
M	高さの単位	M=メートル
f3	ジオイドからの距離(ジオイド高)	n.nn
M	ジオイドからの距離単位	M=メートル
f4	ディファレンシャル補正値	
d3	RTCMの基地局ID	
cc	チェックサム	
```


#$GPGSA

$GPGSA,m1,m2,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,pd,hd,vd*cc


```
m1	モード	M=2D/3Dマニュアル A=2D/3D自動
m2	モード	1=無効 2=2D 3=3D
d1～d12	衛星番号	
pd	PDOP	
hd	HDOP	
vd	VDOP	
cc	チェックサム	
```


#$GPGSV

$GPGSV,n1,n2,n3,n4,d1,d2,sn,ssv1,ssv2,ssv3,ssv4,tsv1,tsv2,tsv3,tsv4,fsv1,fsv2,fsv3,fsv4*cc


```
n1	メッセージの個数	
n2	メッセージ番号	
n3	取得できた人工衛星の個数	
n4	人工衛星のID番号(PRN)	
d1	人工衛星の仰角	90度が最大値
d2	人工衛星の方位角	0～359度の範囲
sn	SN比	0～99dBの範囲
ssv1	2番目の人工衛星の人工衛星のID番号(PRN)	
ssv2	2番目の人工衛星の人工衛星の仰角	
ssv3	2番目の人工衛星の人工衛星の方位角	
ssv4	2番目の人工衛星のSN比	
tsv1	3番目の人工衛星の人工衛星のID番号(PRN)	
tsv2	3番目の人工衛星の人工衛星の仰角	
tsv3	3番目の人工衛星の人工衛星の方位角	
tsv4	3番目の人工衛星のSN比	
fsv1	4番目の人工衛星の人工衛星のID番号(PRN)	
fsv2	4番目の人工衛星の人工衛星の仰角	
fsv3	4番目の人工衛星の人工衛星の方位角	
fsv4	4番目の人工衛星のSN比	
cc	チェックサム	
補足
n1が2の場合は $GPGSV行が2行続き n2=1,n2=2の行がある。
```


#$GPRMC

$GPRMC,m1,c1,m2,c2,m3,c3,f1,f2,d1,f3,c4*cc

```
m1	測位時刻(UTC) hhmmss.ss
c1	ステータス A:有効 V:無効
m2	緯度 ddmm.mmmmmm
c2	ステータス N:北緯 S:南緯
m3	経度 ddmm.mmmmmm
c3	ステータス W:西経 E:東経
f1	対地速度（ノット）
f2	進行方向　真北に対しての度
d1	日付 ddmmyy
f3	地磁気の偏角　度
c4	偏角の方向　W:西 E:東
cc	チェックサム
```

#$GPVTG

$GPVTG,f1,c1,f2,c2,f3,c3,f4,c4,c5*cc

```
f1	真北に対する進行方向（度）
c1	T
f2	磁北に対する進行方向（度）
c2	M
f3	対地速度（ノット）
c3	N
f4	対地速度（km/h）
c4	K
c5	モード　A:単独測位 D:ディファレンシャル測位 N:無効
cc	チェックサム
```

#$GPGLL

$GPGLL,ddmm.mmmm,N,dddmm.mmmm,E,hhmmss,x,a*cc

```
ddmm.mmmm  緯度（度、分、１／１００００分）
N          N：北緯、S：南緯
dddmm.mmmm 経度（度、分、１／１００００分）
E          E：東経、W：西経
hhmmss     測位時刻（ＵＴＣ、時、分、秒）
x          測位状態
           A：単独測位中またはＤＧＰＳ測位中
           V：未測位
a          測位モード
           N：未測位
           A：単独測位中
           D：ＤＧＰＳ測位中
cc        チェックサム
```


#使い方

緯度経度が欲しい場合、＄GPGGAか＄GPRMCか$GPGLLをパース。
高さが欲しい場合、＄GPGGAをパース。
衛星の仰角、方位角が欲しい場合、＄GPGSVをパース。
日付が欲しい場合、＄GPRMCをパース。
時間が欲しい場合、＄GPGGAか＄GPRMCをパース。
利用した衛星の数、＄GPGGAをパース。
移動速度が欲しい場合、＄GPVTGか＄GPRMCをパース。
移動方向が欲しい場合、＄GPVTGか＄GPRMCをパース。
健康状態が欲しい場合、＄GPGSAをパース。
測位モードが欲しい場合、＄GPGLLをパース。


以上。
Railsのセッションフォームとユーザー登録フォームの違い

# はじめに

[Rails チュートリアル](https://railstutorial.jp/)などで、Railsの勉強をしていてフォームの実装をしていた時に、ユーザー登録などのフォームと、ログインに使うフォームでコードが違っていたので、何が違うんだろうと調べていたら勉強になったので、まとめておきます。

# 環境

この記事では以下の環境（2018年6月15日時点）で動作確認できました。

- Ruby: 2.4.1
- Rails: 5.0.7

# 主な違い

セッションフォームとユーザー登録フォームの主な違いは、セッションには`Session`モデルというものが無いため、例えば、ユーザー登録のフォーム（`View`）でよく見る`<%= form_for(@user) do |f| %>`で始まるフォームにある`@user`のようなインスタンス変数に相当するものが無いことだと思います。それに対して、セッションフォームの場合、`form_for`の`View`に関するヘルパーにリソースの名前とそれに対応するURLを明示する必要があります。

まず前提として、HTTPはステートレスな通信プロトコルなので、一度の送受信がわかったら（例えばページを遷移したら）、前に持っていた情報（状態（ステート））は失われます。例えばログインに関してだと、これでは困りますよね？だって、ページ遷移するたびにログインしなきゃいけないのですから。Amazonで欲しい商品をカートに入れて違う商品ページに遷移したら、カートに入れた商品がカートから無くなってしまいます。だけど実際はそうなっていないですよね？それは、サーバにセッションという技術が、ブラウザにはクッキーという技術が用いられているからです。

そして、これは推測なのですが、なぜログイン情報をセッションでも持つのかについては、例えばログイン情報やAmazonのカートの中に入っている商品情報は、DBに格納するような永久的に保存する情報では無いからというのと、何度かページ遷移する（アクセス頻度が高い）ことを考えると、いちいちDB保存するのはパフォーマンスが悪いからだと私は考えてます（間違ってたらご指摘ください）。

# ユーザー登録のフォーム

ユーザー登録のフォーム（`View`）は以下のようになってることが多いと思います。（インスタンス変数名（`@user`）は仮）

```erb

<%= form_for(@user) do |f| %>
　　　　...
<% end %>

```

`@user`は、`Controller`の`new`アクションで用意して（と仮定して）フォームを作成することを明示しています。ここで入ったデータが、`create`へ送られます。フォームの内容は`params[:user]`に入っていきます。

Rails では、`form_for(@user) `と書くと、フォームに入ったデータのアクションは`/users`というURLへのPOSTだと、自動的に判定してくれます。しかし、セッションの場合はリソースの名前とそれに対応するURLを指定する必要があります。


# セッションフォーム

セッションフォーム（View）は以下のようになってることが多いと思います。

```erb
<%= form_for(:session, url: login_path) do |f| %>
...
<% end %>
```

セッションフォームの場合、`form_for`の`View`に関するヘルパーにリソースの名前とそれに対応するURLを具体的に指定する必要があります。

- リソース名：`:session`
- 対応するURL：`login_path`（POST）

Railsにおけるリソースとは、コントローラが扱う対象に名前をつけたものです。リソースには、モデルや、セッション、画像などがあります。今回は、セッションを扱うよと明示的に宣言したことになります。（実は、名前（今回なら`:session`）は、なんでもいいみたいです。ならどうやって、セッションだと判定してるのだろうか。。）

セッションフォームなので、例えば、この後、`new`のページから送信されたフォーム（仮にメアドやパスワードの情報があるとする）を処理する`create`アクションでは

```erb
email = params[:session][:email]
password = params[:session][:password]
```

こんなのが出てくると思います。

```erb
params[:session][:email]
```

これはフォーム（`new`）から送信されたメールアドレスです。

```erb
params[:session][:password]
```

これはフォーム（`new`）から送信されたパスワードです。

こうすることで、`create`アクションでは、ログインに必要な情報を`params`ハッシュから簡単に取り出せます。

---

以上です！

# この記事を読んだ方に

この記事を読んで、誤っている箇所をみつけたり、追記した方がいい内容などありましたら、編集リクエストやコメント欄で指摘していただけると助かります。

# 参考
- http://railspro.net/questions/1573
- https://railstutorial.jp/chapters/log_in_log_out?version=4.2#cha-8_footnote-ref-3
- http://stonebeach-dakar.hatenablog.com/entry/2016/07/14/222653#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%A8%E3%81%AF
- https://qiita.com/To_BB/items/dc37877eebd0c45f758a
- https://qiita.com/hththt/items/07136ad74127999df271
- https://qiita.com/7968/items/ce03feb17c8eaa6e4672
App Store ConnectでSandboxテスターを追加できないときはパスワードを見直す

## 概要

App Store Connect(iTunes Connect)でSandboxテスターを追加してくれと依頼されたのだが、なぜか `Unknown Errors while creating Sandbox Tester, Please check Error Log, email=*******@***.**` というエラーが表示されて困ったので解決方法メモ。

## 解決方法

[フォーラム](https://forums.developer.apple.com/thread/103032) によると、パスワードが簡単なものだとエラーになるようだ。
実際、 最初に試していた簡単なパスワード(`fugafuga`) ではダメで、大文字数字を交えたパスワード(`Fugafuga1234`) に変更すると無事Sandboxテスターを追加できた。

また、 `pompopo+sub@example.com` のようなサブアドレスは、パスワードが複雑であってもエラー（上と同じ）になる。
Node.js のインストール（ソースから）

epelリポジトリにあるNode.jsのバージョンが古かったのでソースから入れ直した時のメモ
ソースからインストールする場合はGCC 4.9.5 以上が必要らしいので、それを済ませたうえで実施します。

# 手順
1. ソースをダウンロードする

    ```
    # curl -LkvOf https://nodejs.org/dist/v8.11.3/node-v8.11.3.tar.gz
    ```

2. ダウンロードしたソースを展開する

    ```
    # tar zxf node-v8.11.3.tar.gz
    ```

3. 展開してできたディレクトリに移動する

    ```
    # cd node-v8.11.3
    ```

4. configureコマンドを実行する

    ```
    # ./configure --prefix=/usr
    ```

5. makeコマンドを実行する

    ```
    # make
    ```

6. インストールする

    ```
    # make install
    ```

### 確認

```
# which node
/bin/node

# node -v
v8.11.3
```

# 参考
- [CentOS 7 に Node.js をインストールする](https://qiita.com/moris/items/4850d4e19392186e34f0)
- [How To Install Node.js on a CentOS 7 server](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-a-centos-7-server)
SOLIDの原則〜備忘録〜



# 目的
S、O、L、I、D　の
S、Oまでは思い出せるけど、L以降がなんの略なのかを忘れてしまうので書いておく。


# SOLIDの原則とは

* 「S」　...単一責任の原則(Single Responsibility Principle)

* 「O」　...オープン・クローズド[開放/閉鎖]の原則（Open-Closed Principle）
* 「L」　...リスコフ置換原則 (Liskov substitution principle)
* 「I」 　...インタフェース分離の原則 (Interface segregation principle)
* 「D」　...依存性逆転の原則 (Dependency inversion principle)
Geolocation APIのgetCurrentPosition()よりwatchPosition()のほうが早い気がする

スマートフォン用の位置情報を使ったWebアプリを開発していて思った。
**なんか遅えな…！**と。
体感なので詳しいことは調べてないです。
#正直watchPosition()だけで十分
```javascript
id = navigator.geolocation.watchPosition(
  function(position) {
    // 成功時処理
    
    // 処理が終わったらモニタリング終了
    navigator.geolocation.clearWatch(id);
  }, 
  function() {
    // 失敗時処理

    // 処理が終わったらモニタリング終了
    navigator.geolocation.clearWatch(id);
  }, {
    // オプション
  }
);
```
こうしたら1回処理走って監視終了する。
`getCurrentPosition()`より断然早い（気がする）のでこの方法使っていこうと思います。
機械学習って何だよ…

前回こんな記事([TensorFlowをインストールしてみる](https://qiita.com/Nehushtan_/items/a96c8463003b68873d3f))書いて機械学習するやでって言ったけど、そもそも機械学習ってなんや？ってなったので自分なりにまとめたものをメモがてら書きます。間違ってても怒らないで…

##機械学習ってなんだよ・・・
> 機械学習（きかいがくしゅう、英: machine learning）とは、人工知能における研究課題の一つで、人間が自然に行っている学習能力と同様の機能をコンピュータで実現しようとする技術・手法のことである
[──wikipedia(機械学習)](https://ja.wikipedia.org/wiki/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92)

<img width="233" alt="キャプチャlplplp.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/264189/6b096d49-2dd6-23f7-3785-363e13038831.png">

AIの研究課題の１つってことでいいのかな…？
じゃあ技術・手法って何があるんじゃろか・・・？

##技術・手法って何があるのー？
>決定木学習
相関ルール学習
ニューラルネットワーク
遺伝的プログラミング
帰納論理プログラミング
サポートベクターマシン
クラスタリング
ベイジアンネットワーク
強化学習
表現学習

多すぎィ！！！
ニューラルネットワークとか強化学習は聞いたことあるけど他の聞いたことないなぁ…
とりあえずニューラルネットワークと強化学習をまとめてみますかー。

##ニューラルネットワークってなんぞや？
>ニューラルネットワーク (NN)
人工ニューラルネットワーク (ANN) とも呼ばれ、生物の神経ネットワークの構造と機能を模倣するという観点から生まれた学習アルゴリズムである。人工神経を相互接続したもので計算を構造化し、コネクショニズム的計算技法で情報を処理する。現代的ニューラルネットワークは非線形な統計的データモデリングツールである。入力と出力の間の複雑な関係をモデル化するのに使われ、データのパターン認識や観測された変数間の未知の同時分布における統計的構造を捉えるなどの用途がある。
[──wikipedia(機械学習)](https://ja.wikipedia.org/wiki/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92)

はい。またwikiです。
何が書いてあるかわっかんねぇなこれ…

ざっくりいうと人間の脳の仕組みを模倣しようぜ！ってこと。
人間の脳にはニューロンって言う神経細胞が信号のやりとりしてて、その仕組みをコンピュータでも再現できるんじゃね！？ってことらしいっす。

![images.jpg](https://qiita-image-store.s3.amazonaws.com/0/264189/d94ef20c-7a84-7d19-ed9e-31a23972fed7.jpeg)


詳しい話は…んにゃぴよくわかんないです(逃げ)

Q:ニューラルネットワーク使ったら何が出来るの？
A:学習重ねて画像解析とか音声解析が出来るようになるで！


##強化学習ってなんだよ
教師あり学習と似てるけど「答え」は提示されない。
じゃあ何が提示されるんだよ…　行動の選択肢と報酬です。
答え＝報酬になるじゃないか・・・！ってなりますが、強化学習の報酬は各行動に対してではなく、連続した行動の結果に対して与えられます。

例えるなら、あるクエストをクリアする。これが強化学習における報酬になります。クエストをクリアする過程で敵を探す、攻撃をするなんて言った各行動を報酬を与えない。逆に逐一与えるのが教師あり学習ゾ。

Q:じゃあどうやって各行動を評価すんだよ(困惑)
A:最後の行動から遡って各行動を評価していくゾ

強化学習では連続した行動の結果に対する報酬から、各行動の評価を自分自身で評価する。これにより各行動に対する報酬を逐一設定しなくても、自分の評価を基に報酬が得られ、連続した行動を学習してくれる訳です

強化学習のモデル化とかあるけどその辺よくわかんないんで後日。


##まとめ
んにゃぴよくわかんないです
DataBindingで下にあるViewにonClickイベントをマスクする

基本的にやりたいことは下の記事と同じような内容
https://qiita.com/shimbaroid/items/46b0462bf192d99b9883

だけども、TextViewでマスクするのも、レイアウトファイル見てわかりにくいなって思ったのでDataBindingでXMLファイル内で完結するようにした

`@id/submit_area` がマスクしたいViewだとすると、 `android:onClick="@{() -> null}"` をしていすればイベントがマスクされる

``` xml
...略

<android.support.constraint.ConstraintLayout
    android:id="@+id/submit_area"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:layout_marginBottom="0dp"
    android:onClick="@{() -> null}">

    <Button
        android:id="@+id/submit"
        android:onClick="@{() -> viewModel.submit()}"
        android:text="ボタン"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</android.support.constraint.ConstraintLayout>

...略
```
[ESP8266]HUZZAHをつかってDHT-11。その02

#Huzzah関連

1. [HUZZAHと遊び。その01](https://qiita.com/Dreamwalker/items/2b744cc4d67e349aa185)

#DHT-11
国民温湿度センサー

１１や２２が使われている。

#Code

```c++:dht11.ino
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
}
void loop() {
  delay(2000);
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" C");
}
```

#Result

![20180615_130253.jpg](https://qiita-image-store.s3.amazonaws.com/0/137182/de30e627-a985-97bc-bc9d-7a5b88672dbb.jpeg)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/3eb2d43c-932c-0385-41b1-454dc5a42c8e.png)

#参考

1. https://akizukidenshi.com/download/ds/aosong/DHT11.pdf
ちょっとびっくりした、setTimeout, setIntervalの戻り値

Typescript(Anugalr)でこんな感じのコードを書いていた。

```typescript
const a = setInterval( () => {
  console.log( 'test' );
}, 1000)

// ↓何らかのトリガーの後
clearInterval( a );
```

で、ちゃんと型を書かないとな〜とか思いながら、setIntervalの戻り値の型を調べるもなかなか見つからず、
dev tool の console　に打ち込んで見ると、何と

```
10
```

number型が返るんですね！

試しにコンソールに以下のように記述したら、ちゃんとclearIntervalできました。

```console
> a = setInterval( () => { console.log( 'test' ); }, 1000 );
10
> clearInterval( 10 );
```

知ってる人からすればあたり前ですが、
個人的にびっくりしたのでメモ。

Timerの実体はどこに格納されているのだろう。知っている方がおりましたら、ぜひご教授ください。

> 2019/05/06(令和) 追記
> コメントから素晴らしい回答を頂けましたので、ぜひ参照してください。
OculusGoに入れたUnityアプリのコンソールログを確認・表示する方法

OculusGoに入れたUnityアプリが落ちてしまった...ッ！

エラーメッセージ出てるか確認したいなーと思い調べたら
OculusGoのアプリのログ表示、で調べてもなかなかヒットなかったのでまとめておきます。

##手順

１.Oculus GoをPCにつなぐ

２.Android>Sdk>tools的な場所に移動し(sdkの場所は各自で確認)、monitor.batを開く
>どうしても場所がわからないとき
UnityでAndroidビルドの設定済みの人はEdit>Preference>External Toolsから場所の確認が可能

３.以下のAndroid Device Monitorが開かれる
※この時PCに接続しているOculus Goが左上のDeviceウィンドウに表示されている

<img width="400" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/249053/3c5341b9-45e2-2484-f9eb-193c027e7303.png">

４.画像左下のLogCatのウィンドウを選択

<img width="400" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/249053/85747b57-4b9f-e626-75f3-dbc2bbadfab8.png">

５.LogCatのウィンドウにある黄緑色の + ボタンを押下

６.以下の画面で、File Nameとby Log Tagの項目にUnityを入力
これによりUnityアプリのログだけ表示するフィルターをかけることが可能

<img width="400" alt="キャプチャ (1).PNG" src="https://qiita-image-store.s3.amazonaws.com/0/249053/e9a75a8f-9996-6045-fce1-28cb73e933a1.png">

７.対象のUnityアプリを、(PCに繋いだままの状態で)Oculus Goで実行する

以上！
CentOS7にsshで公開鍵認証を使って接続するまで

## CentOS側

ルートユーザーに変更
sshd_configを編集

```
$ su-
# vi /etc/ssh/sshd_config
```
ポート修正
ルートログインしない

```:sshd_config
#Port 22
Port 10022
#PermitRootLogin yes
PermitRootLogin no
```

SELinuxの設定変更コマンドをインストール
SELinuxで10022ポートを許可
ファイヤウォールのSSH設定ファイルをコピー

```
# yum -y install policycoreutils-python
# semanage port -a -t ssh_port_t -p tcp 10022
# cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/
# vi /etc/firewalld/services/ssh.xml
```
22=>10022に書き換え

```:ssh.xml
- <port protocol="tcp" port="22"/>
+ <port protocol="tcp" port="10022"/>
```

ファイヤウォールの設定変更を反映
SSHサーバーを再起動

```
firewall-cmd --reload
systemctl restart sshd.service
```
## 自分のPC
SSHで接続

```
$ ssh -p 10022 [ユーザー名]@[ホスト名]
```

### 公開鍵認証設定

.sshディレクトリで鍵生成id_rsaのパーミッションを600に
（秘密鍵がid_rsa、公開鍵がid_rsa.pub）


```
$ cd ~/.ssh
$ ssh-keygen -t rsa
$ chmod 600 id_rsa
$ scp -p 10022 id_rsa.pub [ユーザー名]@[ホスト名]:.ssh/.
```

.ssh/configを下記のようにしておくと

```
ssh 〇〇
```
で接続できるようになる。

```:.ssh/config
Host 〇〇
 HostName [ホスト名]
 Port 10022
 User [ユーザー名]
 IdentityFile ~/.ssh/id_rsa
 ServerAliveInterval 60
```

## CentOS側

.sshディレクトリに移動
id_rsa.pubの内容をauthorized_keysにコピー
authorized_keysのパーミッションを600に

```
cd .ssh
cat id_rsa.pub >> authorized_keys
chmod 600 authorized_keys
```


## 参考

sshで公開鍵認証を使ってアクセスする
https://qiita.com/mountcedar/items/43157ff1225c56500655
VirtualBoxの復旧

## はじめに
かなり危険なことをしているので、試す場合は自己責任でお願いします 。:bow:

## 動作環境
* Windows10 Professional 64bit
* VirtualBox 5.2.8

## 顛末
１. さーて、作業を始めようか、と思ったらWindows 10の起動中のプログラムがかなり少ない…… **どうやら、システム再起動がかかったようだ。**
２. VirtualBoxのVMを起動しようとすると……「セッションを開けませんでした。」終了コード：E_FAIL、コンポーネント：SessionMachine
 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90217/11302e19-aa13-2729-22bc-329de131ad7c.png)
３.「仮想マシン」→「ログを参照」すると、

```
aText={VM cannot start because the saved state file 'D:\(略)\Snapshots\2018-06-14T10-13-03-782142100Z.sav' is invalid (VERR_FILE_NOT_FOUND). 
Delete the saved state prior to starting the VM}
```

となっている。savファイルを消せばいいのかなー、と思ったものの、行ってみるとそんなファイルはない。

４. 「ないんなら、作っちゃえばいいんじゃね？」みたいな安易な気持ちで、同じディレクトリにあるsavファイルを上記ファイル名としてコピー。起動。ダメでした。表示されたのは下記。VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH。どうやら、以前のセッションファイルとではメモリの割当量が違うみたい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/90217/41b77b34-b127-30d3-215a-88e4d53ead63.png)

５. 仕方がないのでバージョンアップ。過去、こういう場面を何度もバージョンアップで切り抜けてきた経験則。5.2.8からバージョンアップ。最新版は5.2.12だが、できるだけチャンスは残しておきたいので、わざわざ5.2.10に上げた（ちなみにVirtualBoxは、0.0.2刻みで安定バージョンがあがる。）しかし、起動に失敗。どうしよう。

６. 仕方がないのでGoogle先生。『「ヘッドレス起動」してから正常終了して起動したら、正常に起動したよ！』という記述を見つけ、初めてのヘッドレス起動。はいダメー。 :disappointed: 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/90217/b1a32dc4-a987-7317-38dd-1dab20f8bbeb.png)

７. ちょっと気になっていた「保存」の文字。ここに着目してみると……「保存状態を破棄」を発見。試してみる。正常に起動した！ :grinning: 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/90217/0da770cc-fb31-12c6-2e40-927686c8fc19.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/90217/af44ed40-72b7-22f8-c673-7ab485e802f0.png)

８. 保存状態を破棄しているので、ディスクに保存していないメモリの状態とかは消し飛びますが、VMとしては記憶をなくした状態から正常に起動しました。良かった。

９. 不意な再起動でVirtualBoxが壊れることは良くあるので、作業が完了したらちゃんとVMを終了させた方が良いですよ。 :expressionless:
Bigquery | UNION ALL ではカラム順だけを見ている (後方のカラム名は無視される)

(2018年6月15日現在)

カラムの順番だけを見て最初のテーブルに UNION されていく模様。

# 例

(カラム名が違っても気にしない)

```sql
SELECT
  *
FROM (
  SELECT
    'value' AS column_name)
UNION ALL (
  SELECT
    'value' AS another_column_name)
```


![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/5fa6fd77-ceb2-c9a7-bb3a-431af8a6a471.png)

# 例2

2番目のテーブルでは順番だけを見ている。
カラム名を入れ子にしても気にしない。

```sql
SELECT
  *
FROM (
  SELECT
    'value1' AS column_name,
    'value2' AS another_column_name )
UNION ALL (
  SELECT
    'value3' AS another_column_name,
    'value4' AS column_name )
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/67fa172c-cc01-9b30-2ea5-3ebea659416c.png)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Pythonで白画像を作成する時のメモ。


たびたび空白画像を作りたいことがあるが、その度に調べてたのでメモっとく。

グレースケール版です。

```py:
import numpy as np
import matplotlib.pyplot as plt

img_white = np.ones((300,300),np.uint8)*255
print(img_white)
plt.plot(), plt.imshow(img_white, cmap='gray', vmin=0, vmax=255)
plt.show()
```


カラー版

```py:
import numpy as np
import matplotlib.pyplot as plt

img_white = np.ones((300,300, 3),np.uint8)*255
plt.plot(), plt.imshow(img_white)
plt.show()

```


# 参考

https://stackoverflow.com/questions/49217587/creating-a-white-image-in-numpy-2-d-image

https://sites.google.com/site/aacallaboutmyclasses/home/dip/-python-opencv-create-an-image
phpbrew でベータ版やアルファ版をインストールできるようになってた

（たぶん）v1.23 からインストールできるようになったみたいです。

PHP 7.3 のアルファ版を試したかったので、（phpbrew ではアルファ版のインストールは出来ない、という先入観から）docker に環境を作って遊んでました。

docker 環境いでに phpbrew でビルドできる方法を調べようと思ったら、 CHANGELOG に `Added support for php pre-release versions, including alpha, beta and RC (#915)` という、そものズバリっぽい記述がありました。

https://github.com/phpbrew/phpbrew/blob/master/CHANGES.md#version-1230
https://github.com/phpbrew/phpbrew/pull/915

```console
$ phpbrew install 7.3.0alpha1
$ phpbrew use php-7.3.0alpha1
$ php -v
PHP 7.3.0alpha1 (cli) (built: Jun 15 2018 12:00:29) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.0-dev, Copyright (c) 1998-2018 Zend Technologies
```

試してみたら、すごく簡単だったので嬉しいです。
バージョンの指定はリリースされてるタグを自由に使えそうです。

https://github.com/php/php-src/releases
データソースの新規追加・更新について【Tableau 2018.1】

# 前書き

下記に記載する内容は、あくまで私はこうしている。というものです。
調べてもよくわからず、時間をかけて試行錯誤した結果うまく行ったので、共有させていただきます。

もしこうすべきだ！などあればコメントいただけると嬉しいです。

## 構成

▼version
Tableau Desktop: 2018.1
Tableau Server: 2018.1

　　　　　　　　　　①データ抽出
【Tableau Desktop】→→→→→→→→→→→→→→→→→→→→→→【DB】
　　　↓　　　　　　　　　　　　　　　　　　　　　　　　　　↓
　　　↓　②パブリッシュ　　　　　　　　　　　　　　　　　　↓
　　　↓　　　　　　　　　　　　　　　　　　　　　　　　　　↓
【Tableau Server】←←←←←←←←←←←←←←←←←←←←←←←←↓
　　　↓　　↑　　　　　③定期更新
　　　↓→→→↑
　　　※Server内にある抽出データを参照。DBへの接続は定期更新時のみ

というシンプル構造


## 新規データソースを含むワークシートをTableau Serverにパブリッシュする場合の流れ

　　　　　　　　　　①データ抽出
【Tableau Desktop】→→→→→→→→→→→→→→→→→→→→→→【DB】
　　　↓　
　　　↓　②ワークシートと一緒に個別にパブリッシュ
　　　↓
【Tableau Server】


### ①データ抽出

![1.png](https://qiita-image-store.s3.amazonaws.com/0/45170/ee40514d-8e8c-77e4-83d4-13a9e9901b76.png)

抽出を選択し、Ctrl+sで保存。

これでデータベースへのアクセスが不要になるので、サクサク作業ができる。


### ②ワークシートと一緒に個別にパブリッシュ

シート右上のアイコンをクリック

![2.png](https://qiita-image-store.s3.amazonaws.com/0/45170/e9decb74-89ec-dca3-e8d9-c9820a5194d1.png)

名前を適当に設定し、
データソースを「個別にパブリッシュ」に変更し、
パブリッシュ

![3.png](https://qiita-image-store.s3.amazonaws.com/0/45170/0c378330-5838-eeb0-1b05-1f89935c3500.png)

※個別にパブリッシュにする理由はデータソースを乱立させたくないためです。
　埋め込みと個別で、それぞれメリット・デメリットがあるので、詳しくは下記を参照ください。

▼データを個別にパブリッシュするか、ワークブックに埋め込む(Tableauヘルプ)
https://onlinehelp.tableau.com/current/pro/desktop/ja-jp/publish_datasources_about.html#publish-data


## パブリッシュしたデータソースを更新する際の流れ

パブリッシュすると、Tableau Desktop上ででもTableau Server上の抽出データを見に行ってしまうので、
そのままだと編集することができない。

まずはTableau Desktop上で、更新したいデータソースのローカルコピーの作成を行う(右クリックで表示されます)

![5.png](https://qiita-image-store.s3.amazonaws.com/0/45170/226347b9-7439-b576-b743-e7ff70a3e6c0.png)

データソースタブをクリックすると、新規で作成したときのように、編集できる画面が表示されるので、編集する。

編集が完了したら、先程のシートに戻り、ローカルコピーのデータを再度右クリックし「サーバーにパブリッシュ」

![6.png](https://qiita-image-store.s3.amazonaws.com/0/45170/a356ee71-da6b-3335-6542-83f4228758ae.png)


名前の部分を更新したいデータソースの名称に修正し、パブリッシュすることで
データソースが更新できる
slickで複数スライダーを設置

 * 同じ動きで良い場合はまとめて ``$(selector).slick()`` でOK:ok_hand:
 * サムネイルナビを連動させたい…などでオプション指定が異なる場合は .each() で設定する:fist:

<p data-height="500" data-theme-id="0" data-slug-hash="gKxNzw" data-default-tab="html,result" data-user="anchoor" data-embed-version="2" data-pen-title="slickで複数のスライダーを設置" class="codepen">See the Pen <a href="https://codepen.io/anchoor/pen/gKxNzw/">slickで複数のスライダーを設置</a> by anchor (<a href="https://codepen.io/anchoor">@anchoor</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## :no_good:NG例
最初連動するスライダーをまとめて指定しようと思い下記の通り記述したのですが、うんともすんとも言わず頭を捻っていました。
が、該当スライダーが複数あるため ``$(this).attr("id")`` を取得できていない…というごくごく初歩的なミスでした。

```js
$(selector).slick({
　　asNavFor: "#" + $(this).attr("id") + "-nav"
})
```
Parcel v1.9.0 がリリースされました 🎉

本日、**Parcel v1.9.0**がリリースされました

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Parcel v1.9.0 is out! 🚀<br><br>🌳 Tree Shaking + scope hoisting for both ES6 and CommonJS modules!<br>👀 Up to 2x faster file watcher<br>💵 Cache resolved file names<br>🔎 Extended resolver for SASS, LESS, and Stylus<br>🚨 Improved browser error reporter<br><br>📝 Read more: <a href="https://t.co/6IXWVOkMRC">https://t.co/6IXWVOkMRC</a> <a href="https://t.co/LcdVsKt0RK">pic.twitter.com/LcdVsKt0RK</a></p>&mdash; Parcel (@parceljs) <a href="https://twitter.com/parceljs/status/1007291019602169857?ref_src=twsrc%5Etfw">2018年6月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

元記事） [📦 Parcel v1.9.0 — Tree Shaking, 2x faster watcher, and more! 🚀](https://medium.com/@devongovett/parcel-v1-9-0-tree-shaking-2x-faster-watcher-and-more-87f2e1a70f79) 

関連記事）[Parcel v1.5.0 〜 v1.8.0で追加された機能](http://simoothie-cafe.hatenablog.com/entry/2018/05/06/123752)

# tl;dr

* Tree ShakingとScope Hoistingが追加されてバンドルサイズをかなり小さくできるようになった
* 開発時のビルドタイムが半分になった
* SASS/LESS/Stylusから`node_modules`内をImportできるようになった
* ブラウザのエラーレポートが改善された

# 新機能

v1.9.0で追加された主な機能は次の通りです

* CommonJS/ES6の双方に対応したTree Shakingの追加
* File Watcherの高速化
* Importされたモジュールのキャッシュ
* SASS/LESS/Stylusでnode_modulesを参照可能に
* ブラウザのエラーレポートの改善

それぞれ見ていきましょう

## CommonJS/ES6の双方に対応したTree Shakingの追加

ついにTree Shakingが追加されました

特に、他のバンドラーとは違い**ES6とCommonJSモジュールの双方**に対してTree Shakingをサポートしています

また、Tree Shakingはメインプロセスと並行して実行され、結果はキャッシュされるため、Parcelの持ち味である高速ビルドは健在です

加えて、Scope Hoistingを行うオプションが追加されました。これまではモジュールごとにクロージャーでラップし関数名の衝突などを避けていました。Scope Hoistingでは全てのモジュールを一つのクロージャーに含めてしまうため、ファイルサイズの圧縮や実行速度の向上が可能になります

Scope Hoistingはビルド時に `--experimental-scope-hoisting` オプションを付与することで利用できます

### ベンチマーク

Scope Hoistingがどれほどなのか、以下のファイルをビルドした場合のベンチマークをv1.8.1と比較して見ました

```javascript
// entry.js
import { add } from 'lodash';
```

|Version|Size|Time|Time (w/cache)|
|:--:|:--:|:--:|:--:|
|v1.9.0|21.4KB|6.75s|1.08s|
|v1.8.1|91.94KB|4.70s|0.41s|

ファイルサイズが91.94KB→21.4KBへ約80%も小さくなりました

ビルドタイムもScope Hoistingしないときのタイムが凄まじいですが、十分な早さです

仕組みについては[ParcelのMediumエントリー](https://medium.com/@devongovett/parcel-v1-9-0-tree-shaking-2x-faster-watcher-and-more-87f2e1a70f79)をご覧ください

## File Watcherの高速化

v1.9.0ではファイルの監視をバックグラウンドのワーカーに移行させました。そのおかげで、開発時のビルドの時間が半分になりました

![1_sJ1sM3hriq2gj56cf-8aAw.jpeg](https://qiita-image-store.s3.amazonaws.com/0/127934/601b3ad8-3ee7-8f12-f3ed-a64e8811dd7d.jpeg)
[画像元](https://medium.com/@devongovett/parcel-v1-9-0-tree-shaking-2x-faster-watcher-and-more-87f2e1a70f79)

特にWindowsでは70%もビルドが早くなったようです

## Importされたモジュールのキャッシュ

モジュール解決し、コンパイルされたものをキャッシュするようになりました

たとえば、`import 'React'`されたものは最初の１度のみコンパイルされ、コンパイルごとに`/my-project/node_modules/react/index.js`が参照されることはなくなりました

# 参考

* [📦 Parcel v1.9.0 — Tree Shaking, 2x faster watcher, and more! 🚀](https://medium.com/@devongovett/parcel-v1-9-0-tree-shaking-2x-faster-watcher-and-more-87f2e1a70f79) 
* [webpack 3 リリース内容まとめ - Scope Hoisting](http://dackdive.hateblo.jp/entry/2017/06/20/200830)
VSCodeでパラメータヒントを消す

VSCodeを使ってて、カーソルの近くにポップアップが出てきて、記述中のMethod呼び出しのパラメタを教えてくれるやつ。
あいつ、画面をクリックしないと消えなくて、改行してMethod呼び出し書いてると上の行が見えずに邪魔。。

そんなときは

```json
{
    "editor.parameterHints": false
}
```

を設定するとでなくなります。
手動でこいつを表示したい場合は

Mac: `Cmd` + `Shift` + `Space` で一時表示できます。
C インタープリター？

今回、私は C コンパイラを改造して、C 言語のインタープリターのようなものを作成しました。
目指した仕様は

$ gcc -o a.exe a.c && ./a.exe          # (1)
$ hcc1.exe --generator tacsim.dll a.c  # (2)

(1) と (2) の実行結果が同じになるというものです。

そこで、皆さんに、このようなインタープリターのようなものがどのような
場面で役立つのか、アイディアをいただきたいと思い投稿させていただきました。
たくさんのアイディア、ご意見等をお待ちしております。

長谷川啓
kei.hasegawa.18@gmail.com
@kei_hasegawa_18
@kei_hase_40