OmniAICreator/Qiita-1.07M huggingface dataset:
Raspbianを音楽サーバ化するビルドレシピ

本記事は[ラズパイオーディオ Advent Calendar 2017](https://adventar.org/calendars/2078)の3日目の記事でもあります。

# 概要
ラズパイオーディオ用ディストリビューションの有名どころは[Volumio](https://volumio.org/)、[moOde audio](http://moodeaudio.org/)[^1]、[symphonic-mpd](http://mpd.sytes.net/ja)でしょう。僕も最近までmoOdeを使っていましたが「バージョンアップ→再インストール→自分の環境に合わせて再設定」のコンボが段々と煩わしく感じてきました。その解決策として、**自分の環境用の設定をRaspbian上に自動で展開するスクリプト**を作成したので公開した次第です。別のモチベーションとしては、**ラズパイ3向けに最適化してビルドされた、最新のソフトウェア**を使いたかったというのもあります。

自分のビルドレシピがそのまま他人の環境で使えるとは思っていませんが、ラズパイ設定に関する情報をまとめた点には意義があると思います。設定の詳細は、ビルドレシピに記載してある参考文献を見てください。

# 想定する環境
- Raspberry Pi 3（最適化オプションの関係で3専用）
- OS: Raspbian Stretch Lite (2017-11-29)
- 音楽フォーマット：mp3, m4a, flac （DSDなし）
- NAS中の音楽をラズパイ上のMPD経由でI2S DACから出力（USBは使用しない）
- last.fmに再生履歴を保存
- MPDクライアントでMPDをコントロール（DLNA機能なし）
- I2S DAC: Hifiberry DAC+ Pro 互換ボード ([msberrydac](https://bispa.co.jp/1698))
- ネットワーク：有線LAN接続、DHCP使用
- WindowsでRaspbianの書き込み

# Windows上での前処理
## Raspbian Liteダウンロード
日本のミラーサイト

- http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian_lite/images/
- https://www.raspbian.org/RaspbianMirrors

## Raspbian書き込み
[etcher](https://etcher.io/)を使う

## ssh有効化
SDのルートフォルダに`ssh`ファイルを配置する

sshログイン情報：

- user: pi
- pass: raspberry

# ビルドレシピ
## 設定概要
本ビルドレシピでは以下の設定を行います

- **ラズパイ3向けの最適化オプションを付与して、最新のalsa-lib, libflac, mpg123, FFmpeg, MPDをソースからビルド**
-  MPDの処理の優先度を変更
- 起動完了後に赤色LEDを消灯
- MPDクライアントがhttp経由でカバーアートを取得できるようにnginxを導入
- mpdasで再生情報をlast.fmに送信
- スワップ、HDMI、Wi-Fi、Bluetooth、UART、オンボードサウンド、USBの電源、不必要なサービスを無効化
- 一時ファイル、ログファイルをRAM diskに配置
- GPUに割り当てるメモリを削減
- rsyslogとnginxのログ出力を削減
- 日本人向けにNTPサーバー、タイムゾーン、言語を設定
- NASの接続設定

CPUのクロックはいじっていません。
デフォルトの設定通り、負荷に応じて600 or 1200 MHzで動作します。

## ビルドレシピDL＆インストール
次のスクリプトでビルドレシピがDLできます。

```bash:download.sh
mkdir ~/setup
cd ~/setup
wget https://raw.githubusercontent.com/estshorter/raspi-autosetup/master/setup.sh -O ./setup.sh
chmod u+x ./setup.sh
```

リポジトリ： https://github.com/estshorter/raspi-autosetup

DL完了後、ビルドレシピを順に実行すれば終了です。
`apt`関連・FFmpeg・MPDのビルドに時間がかかるので、所要時間は1時間程度です。

`setup.sh`の3度目の実行前には`NAS_USER, NAS_PASS, NAS_ADDR, LAST_FM_USER, LAST_FM_PASS`を自分の環境に合わせて設定してください。

```bash:install.sh
cd ~/setup
./setup.sh
sudo reboot

cd ~/setup
./setup.sh
sudo reboot

export NAS_USER=user
export NAS_PASS='pass'
export NAS_ADDR=addr
export LAST_FM_USER=user
export LAST_FM_PASS='pass'

cd ~/setup
./setup.sh
sudo reboot
```

# 補遺
- wav専用のデコーダが欲しい場合には`libsndfile`などをインストールしてください。ffmpegでも再生できますが、そちらのほうが精神衛生上よいでしょう。
- DLNAで再生したい場合には`--enable-curl`オプションとともにMPDを再度ビルドし、`upmpdcli`をインストールしてください。
- アクセスランプを消灯する方法は[ここ](https://github.com/estshorter/raspi-autosetup/blob/master/README.md)に書いてあります。`upmpdcli`のインストール法も載せてあります。

# まとめ
自分の環境向けの設定を、Raspbian上に自動展開するスクリプトを紹介しました。
最適化された最新のソフトウェアで音楽を楽しめます。

# 謝辞
参考文献の方々のおかげで、自分用ビルドレシピが完成に至りました。ありがとうございました。


[^1]: 自分のバグ報告が元で一時公開停止&ビルドレシピ配布方式に変更になったりしました。。迷惑かけた人がいたら申し訳ないです。。
AWS S3 をファイル置き場として快適に使うためのツール (Tool for using AWS S3 as file storage)

I introduce the software to use AWS S3 as file storage. (It is not the way to use S3 as file server like samba.)
(Би AWS S3-г файлын хадгалалт болгон ашиглах програм хангамжийг танилцуулсан. (Энэ нь samba шиг файлын сервер S3-г ашиглах зам биш юм.))

I recommend [CrossFTP](http://www.crossftp.com).
(Би [CrossFTP] (http://www.crossftp.com) санал болгож байна.)

## The Most Important Point (Хамгийн чухал цэг)

* Free (Үнэгүй)
* We can Drag and Drop into AWS S3 directly, even the target object is a folder.
    * Usually, we can't drag and drop to AWS S3 on the AWS web console.

## What can we use it for? (Бид үүнийг юунд ашиглаж болох вэ?)

* FTP client (FTP клиент)
* AWS S3 client (AWS S3 клиент)

And serching web and so on. (Програм нь төлбөртэй хувилбар ч юм.
)

## Preparation to use it (шиглах бэлтгэл)

* Create AWS Access Key (AWS-ийн нэвтрэх түлхүүр үүсгэх)
    * To use it as S3 client, it is necessary to add AWS Access Key.

## Other (Бусад)

The application has paid version.
(Програм нь төлбөртэй хувилбарыг ч төлсөн.)
エンジニアが住む場所としてどこがいいの？

首都圏での話なので、他の地域にお住まいの方にはスマソ。

さて、首都圏と言えば通勤ラッシュが特にひどいですよね。
しかし、小田急の複々線化が3月に完成して大幅なダイヤ改正があるとのことで、通勤ラッシュにも変化が出てきそうです。
小田急と言えば、長距離路線で特急電車も多く走っているので、通過待ちも頻繁にあり、時間がかかる上に混んでいるというイメージが定着していたのが変わりそうです。

そこで、都心3区のどこか(港区南部は丸の内から遠いので別扱いとして)へ通勤するエンジニアという観点で、沿線ごとに考えてみました。



自分の経験と次のサイトの情報などを参考にしています。
https://trafficnews.jp/

**横浜方面からのJR線**
　路線の駅数が少ないので速い。混んでいることに変わりないが、京浜東北線はややマシなレベル。
　横浜から先の根岸線や横須賀線の各駅へは意外と時間がかかり、夜は本数が減って待ち時間がけっこうあったりする。
　家賃は、駅からバスを使うような場所でもけっこう高い。

**埼玉方面からのJR線**
　埼京線はチカンが多いとか、イメージがよくない。通勤時間帯の朝は乗ったことないが、京浜東北線利用の人の話だと普通に混んでいる状況らしい。
　大宮から先は本数が減るが、千葉ほどひどくはない。
　埼京線は終電が速いので有名。沿線に住んでいる人に聞いた話では、赤羽からタクシーで帰ることがよくあるとか。
　家賃は比較的安い。大宮から先だと、かなり安くなる。

**中央線**
　混んでいるが、駅間が長く京王線に比べて速い。新宿からの乗り換え客がどっと乗ってくる。青梅方面からだと、駅間が短いので意外と時間がかかる。
　帰りの電車で豊田止まりや立川止まりが多く、八王子方面の客はけっこう待たされることがある。
　家賃は、都心からの距離がある駅でも意外と高い。吉祥寺とかは高いので、貧乏人は住めない。

**千葉方面からのJR線(常磐線は除く)**
　通勤時間帯の上りの電車に乗ったことないが、各駅停車がめちゃくちゃ混んでるらしい。快速はもちろん混んでいるが、駅間が長いので、その分、苦痛時間が短い。
　津田沼から先は大幅に本数が減る。千葉から先はかなり本数が少ない。
　家賃は江戸川区とか都内でも比較的安い。

**常磐線**
　つくばエキスプレスができて大幅に楽になった。土浦寄りの車両はけっこう余裕。取手から先は、大幅に本数が減る。
快速は、品川へ直通になり、駅間が長くてスピードが速いので意外と便利。
　各駅停車は、北千住で猛烈に混む。
　家賃は比較的安い。始発駅の我孫子、取手辺りがねらい目。

**京急線**
　上大岡と横浜の間は混んでいるが、横浜で乗り換える客が多い。各駅停車で都心方面へ向かえば余裕か？(時間はかかる)
羽田空港直結なので、出張の多い人には向いてるかも。
　家賃は、東横線などと較べてかなりお得だが、横浜から先の駅は、都心からの距離がある割には高い。

**東横線**
　田園調布などの高級住宅地のあるハイソな路線。
　同じ東急の田園都市線に比べればマシなレベル。でも、昼間でもけっこう混んでいる。
　家賃が高いので、給料が安い人には向かない。昔は元住吉あたりは比較的安かったが、今はずいぶん上がったはず。

**田園都市線**
　混雑路線として有名。通勤時間帯の混雑が限界を超えていて、客同士のトラブルも多い。中央林間から通っている人の話では、朝は座れるからいいが、本当に疲れるとか。
　家賃が高いので、給料が安い人には向かない。

**小田急線**
　現在は複々線が完成していないので、メチャクチャ時間がかかる(町田から急行で新宿まで1時間近くかかる?)。複々線開業後は、スピードも上がり、混雑も大幅に緩和されるようです。ただ、他の路線から移ってくる客も増えそうなので、また、だんだん混んでくるかも。
　複々線化されると千代田線直通電車が増えて、都心への通勤が便利になる。
　都内(世田谷区)の家賃は高い。町田から先ならマシなレベルになるが、都心からの距離を考えると割高。

**京王線**
　朝はダンゴ運転でメチャクチャ時間がかかる。仮に複々線化されたとしても、ずっと先の未来なので、現状がずっと続くはず。高幡不動に住んでいる人の話では、快速も各駅も時間はほとんど同じなので、朝は各駅停車で座ってると言ってました。
　都営新宿線直通だが、神保町や岩本町あたりを走っているので、丸の内方面へは不便。
　調布から新宿寄りの家賃は高い。それ以外も割高。

**西武新宿線**
 朝の通勤時間は、ずっと昔にしか乗ったことないの最近の状況は知らない。
都心まで直通ではなく、高田馬場で地下鉄東西線に乗り換える必要があるので不便。
　家賃は沿線の大部分が都内なので、比較的高い。

**西武池袋線**
 通勤時間に乗ったことがないので知りませんが、けっこうな混雑路線だそうです。
副都心線と有楽町線に直通で、通勤には便利な路線。横浜へも直通で行けるようになった。
　沿線の多くが埼玉なので、全般的に新宿線より安いはず。
　豊島区あたりの家賃も、新宿区や中野区と比べて安い。

**東武東上線**
　東松山在住の知り合いの話では、毎日、座って通勤できるらしい。
　ただ、混雑するのは川越市から都心寄りの区間で、普通に混雑するはず。
　西武新宿線同様、副都心線と有楽町線に直通で、通勤には便利な路線。
　家賃は全般的に安く、稼ぎが悪くても住めるレベル。

**東武スカイツリーライン**
　複々線化されているので、電車本数が多くスピードも速い。そのため、混雑は他の路線に比べてかなりに緩い。
　大部分の電車は日比谷線(各駅停車)と半蔵門線(急行)へ直通。
　職場が地下鉄駅の近くならいいが、JR駅だと不便。
　渋谷へは直通で行けるが、新宿、池袋方面へは不便。
　家賃は全般的に安く、稼ぎが悪くても住めるレベル。

**つくばエクスプレス**
　新しい路線なので、踏切が一切なくホームドアも設置されていて、事故などで止まることが少ない。
車両もJR特急と同じスピードの130km/hなので速く、駅間も長いので距離があっても通勤時間は相対的に短い。
　沿線開発が進んで、最近は混雑が激しくなってきたが、6両編成を8両編成にするなど対策は取れるので、激混み状態には今後もならない見込み。
　家賃は全般的に安く、稼ぎが悪くても住めるレベル。

**京成線**
　複々線化はされていないが、JRに通勤客を取られて比較的空いている。千葉在住の人に聞いてみたら、時間がかかるので空いていても京成は使わないとか。
　成田空港への客が多い下りのアクセス特急とかのほうが混んでいるかも。
　北総線は、運賃がバス並みに高いので注意。
　家賃は全般的に安く、稼ぎが悪くても住めるレベル。
【アンチパターン】全部nil(null)かもしれない症候群


## はじめに：Rubyの&.演算子やtryメソッドについて

Rubyには`&.`という演算子があります。
この演算子を使うと、メソッドのレシーバが`nil`（他の言語でいうところの`null`）であっても、メソッド呼び出し時にエラーが起きません。（`nil`が返る）

```ruby
# ユーザが見つかる場合
user = find_user('Alice')
user&.name #=> "Alice"

# ユーザが見つからない場合（userがnilの場合）
user = find_user('Foo')
user&.name #=> nil
```

同じようなメソッドに、Railsの`try`メソッドがあります。

```ruby
# ユーザが見つかる場合
user = find_user('Alice')
user.try(:name) #=> "Alice"

# ユーザが見つからない場合（userがnilの場合）
user = find_user('Foo')
user.try(:name) #=> nil
```

## &.演算子やtryメソッドを多用しすぎることの問題

`&.`や`try`を使うと、`nil`かどうかの条件分岐を書かなくて済むので、非常に便利です。
ですが、こうしたテクニックを多用しすぎると、奇妙なコードを作り出す原因になります。

たとえば次のようなコードです。

```ruby
def find_friend_message(name)
  friend = self.user&.friends&.find_by(name: name)
  if friend&.message.blank?
    'no message'
  else
    friend&.message
  end
end
```

上のコードでは`&.`が4箇所も出てきます。

とりあえず、一番最後に出てくる`friend&.message`の`&.`は不要です。
なぜなら上の条件分岐（`if friend&.message.blank?`）で、`friend`が`nil`でないことが保証されているからです（にもかかわらず、`&.`をおまじないのように付けまくる人はよく見かけます）。

しかし、それを無視したとしても、まだ`&.`が3箇所も出てきます。
`&.`だとさらっと書けてしまうので、問題が見えづらいですが、上のコードは次のようなコードを書いていることと同じです。

```ruby
def find_friend_message(name)
  unless self.user.nil?
    unless self.user.friends.nil?
      friend = self.user.friends.find_by(name: name)
      unless friend.nil?
        unless friend.message.blank?
          return friend.message
        end
      end
    end
  end
  'no message'
end
```

こんなロジック見せられたら、普通は「うえっ」ってなりますよね。
でも`&.`によって消臭されてるだけで、実際やってることはこれと同じなわけです。

オブジェクトが`nil`/`null`になる可能性がある言語は、大なり小なり、「`nil`/`null`に対してメソッドを呼びだして爆死💥☠️」のリスクがあります。
しかし、そのリスクを過剰に恐れてしまうと、上のコードのように「これは`nil`かもしれない、これも`nil`かもしれない、全部`nil`かもしれない・・・！！！」と思って、`&.`や`try`を連発してしまうことになります。

いわば「全部nil(null)かもしれない症候群」です。

## この問題の処方箋

「全部nil(null)かもしれない症候群」を治すためには、次のようなアプローチを取るのが良いでしょう。

### モデルやメソッドの設計をきちんと確認する

まず、`&.`や`try`を使う前に「これは`nil`かもしれない」ではなく、「ここは`nil`が来る可能性が十分ある」なのか、「`nil`は通常あり得ない」なのかをハッキリさせる必要があります。

そのためにシステムのデータ構造（DB設計やDB制約、バリデーション処理等）や、呼びだしたメソッドの戻り値をきちんと確認して、`nil`が来るのか、来ないのかをハッキリさせましょう。

### エラーを恐れない

「`nil`は通常あり得ない」のであれば、やみくもに`&.`や`try`を付けるのはやめましょう。
通常あり得ないのに、`nil`がやってきたのであれば、それは異常事態です。
実行時エラーを発生させてプログラムを停止させ（`&.`を使わなければエラーが発生します）、`nil`がやってきた原因を調査すべきです。

下手に`nil`を許容すると、そこで問題が起きなくても、他の場所で別の問題を引き起こす恐れがあります。

また、コードを読んだ人間も「ここ、`&.`を使ってるけど、`nil`のケースがあるのかな・・・？？」と首をかしげることになります。
つまり、一種の可読性の低下につながります。

### ガード条件をうまく使う

「`nil`がありえる、なおかつ、`nil`でないときだけ処理したい」という場合は、`&.`を連発するよりも、ガード条件を使った方が可読性がよくなることがあります（まあ条件分岐が多い問題は解決してないのですが）。

```ruby
def find_friend_message(name)
  no_msg = 'no message'
  
  return no_msg if self.user.nil?
  
  friend = self.user.friends.find_by(name: name)
  return no_msg if friend.nil?
  
  friend.message.blank? ? no_msg : friend.message
end
```

### そもそもの実装を見直す

もし、`&.`を連発しているのであれば、そもそも何か根本的な間違いをしている可能性もあります。
クラス設計やメソッドの責務を見直すことで、きれいな実装に直せるかもしれません。

## まとめ

`&.`演算子や`try`メソッドは便利ですが、多用しすぎると逆にデメリットが出てきます。
「全部`&.`を付けておけば、エラーが起きないからあんしーん！」ではなく、

- 原則、`&.`は付けない。本当に`nil`を考慮すべきタイミングに限って使用する
- `&.`を連発してしまったら、自分の設計や実装を疑ってみる

と考えるようにしてください。
AWS Cloud9が発表されました！

![screenshot-console.aws.amazon.com-2017-12-01-11-59-47.png](https://qiita-image-store.s3.amazonaws.com/0/2567/e9b21a84-6877-a1aa-31fd-f3d9230b5f24.png)

まだ東京リージョンには来てませんが、興奮気味に記事を書いてます。（※）

AWSがCloud9の買収を発表したが2016年7月。

[Amazon、クラウドIDEを提供する「Cloud9」買収。AWSが統合開発環境をSaaSとして提供する布石か](http://www.publickey1.jp/blog/16/amazonidecloud9awssaas.html)


その直後にQiitaにCloud9の記事を書いたものでした。

- [Cloud9で快適開発環境構築 - Qiita](https://qiita.com/fk_2000/items/e23e0b692eb8b44151c8) - 2016年08月30日に投稿  880 views

また今年のはじめにもCloud9についての記事を書いてました。

- [Ruby on RailsをCloud9からHerokuへデプロイする](https://qiita.com/fk_2000/items/f9667bce3f435b160678) - 2017年02月24日に投稿  1793 views

昨日までのCloud9の環境はリソースが貧弱な印象をお持ちの方も多いと思います。

でもこれからは違います。EC2インスタンスとして立ち上げることができるのです！

（※）昨日Cloud9に課金した矢先にこのビッグニュースでした。

## 関連ニュース
- [Amazon、AWS Cloud9をリリース――デベロッパーはブラウザからクラウドソフトの開発ができる](http://jp.techcrunch.com/2017/12/01/2017-11-30-amazon-launches-aws-cloud9-a-browser-based-ide-for-cloud-developers/)
- [AWS、ブラウザベースの統合開発環境「AWS Cloud9」発表](https://japan.zdnet.com/article/35111241/)
EC-CUBEでDBをマスタースレーブ構成にする

EC-CUBEでデータベースをマスタースレーブ構成にするケースはよくあると思います。

EC-CUBE3で利用してるDoctrineには、[MasterSlaveConnection](https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php)というConnectionのラッパークラスがあり、簡易的ではありますが、マスタースレーブ構成を実現することができます。

MasterSlaveConnectionの使い方は、[Doctrine2 でレプリケーションする（マスタースレーブ構成）](http://www.atroom.info/article/62) がとても参考になります。

EC-CUBEで利用する場合は、database.ymlの設定を以下のように記述します。

```yaml:app/config/eccube/database.yml
database:
    wrapperClass: 'Doctrine\DBAL\Connections\MasterSlaveConnection'
    driver: pdo_mysql
    master:
        host: 127.0.0.1
        dbname: db_master
        user: root
        port: 33051
        password: password
        charset: utf8
        defaultTableOptions: { collate: utf8_general_ci }
    slaves:
        slave1:
            host: 127.0.0.1
            dbname: db_slave1
            port: 33052
            user: root
            password : password
            charset: utf8
        slave2:
            host: 127.0.0.1
            dbname: db_slave2
            port: 33053
            user: root
            password : password
            charset: utf8
```

これだけで、参照系クエリはスレーブに、更新系クエリはマスターに投げてくれます。
また、トランザクション中は参照・更新ともにマスターを見るようになります。
その他にも、スレーブではなくマスターを確実に参照したい、というようなケース(例えば在庫数とか)では、

```php:
$app['db']->connect('master');
```
をクエリ発行前に実行すると、以降はマスターを参照するようになります。

と、ここまで書いて、便利だなあと思ったのですが、EC-CUBE 3.0.11から、TransactionListenerという仕組みが導入されました。https://github.com/EC-CUBE/ec-cube/pull/1632 

現状では、アプリケーションの起動終了のタイミングでトランザクションがかかるようになっており、MasterSlaveConnectionを使っても、マスターしか見ない状態になってしまいます。

Application.phpの以下の箇所をコメントアウトすれば、TransactionListenerを無効にでき、期待通りに動作します。

```php:src/Eccube/Application.php
        // add transaction listener
        // TransactionListenerをコメントアウト
        //$this['dispatcher']->addSubscriber(new TransactionListener($this));
```

ただこの機能を無効にすると全体に影響するため、少し扱いが難しいところです。。。

pgpoolのように、トランザクション中でも更新クエリ以降がマスターをみるようになっていればいいのですが、そこまでは残念ながら実装されていませんでした。

EC-CUBE3はsymfonyやdoctrineなど各種フレームワークに乗っかっており、こういった便利な機能も簡単に利用できるようになっています、というご紹介でした。
Laravelのトランザクションはネストできる

一部のRDBだけできるトランザクションのネストに対応してるってわけじゃなくて擬似的にネストさせてる。

内部的にトランザクションのカウント取っていて、
一番外側の `\DB::commit()` もしくは `\DB::rollback()` のみ実行される。

他のフレームワークでもこういう仕組み結構ありそう。

```php
function tranA()
{
    \DB::transaction(function ()
        \DB::insert("QueryA");
        tranB(); // 別のトランザクション使った関数呼び出し
    });
}

function tranB()
{
    \DB::transaction(function ()
        \DB::insert("QueryB");
    });
}
```
`tranA()` を呼ぶと `BEGIN --> QueryA --> QueryB --> COMMIT` となるし、
`tranB()` を呼ぶと `BEGIN --> QueryB --> COMMIT` となる。

以下も同様

```php
function tranA()
{
    \DB::beginTransaction();

    try {
        \DB::insert("QueryA");
        tranB(); // 別のトランザクション使った関数呼び出し
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}

function tranB()
{
    \DB::beginTransaction();

    try {
        \DB::insert("QueryB");
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}
```

と、ここまで書いておいてなんだけど個人的には**使わないほうがいいと思う**。
理由は以下

* コード追いかけてると「ファッ？！！！」って多くの人がなりそう
* 書き方によってはQueryAだけ成功とかQueryBだけ成功ってケースができそう（思いつかなかった
* トランザクションってRDBに対するひとまとまりの処理だからなんかヤダ

---

[おまえ、もしかしてまだ、beginTransactionが死なないとでも思ってるんじゃないかね？](https://qiita.com/tori076/items/3453829432729ff0c46b)

同じような書き方すると下記のような感じ。

```php
function tranA()
{
    try {
        \DB::beginTransaction();
        \DB::insert("QueryA");
        tranB();
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}

function tranB()
{
    try {
        \DB::beginTransaction(); // ここで失敗したとき
        \DB::insert("QueryB");
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}
```

`tranA()` を呼び出して `tranB()` の `beginTransaction()` で失敗すると、
その下の `rollback()` に対応してるのは `tranA()` の  `beginTransaction()`  だぞ！！
Slackで調整さん的なことをすると参加者確認が大変だったのでコードで解決してみた

本記事は、[Slack Advent Calendar 2017](https://qiita.com/advent-calendar/2017/slack)の8日目の記事です。

***

株式会社CyberZの木村です。この記事を書くきっかけは、先月末にあったこんなやりとりから生まれました。
<img width="345" alt="slack1208.png" src="https://qiita-image-store.s3.amazonaws.com/0/26501/c36bb18f-1494-28d2-dfc1-966f74e28a9a.png">

弊社では毎月末に締め飲み会というイベント（？）があり、その出欠がSlack上で問われたのでした。  
ここの`OK`の人数でお店に予約するのです。Slack上で解決とは、なんとお手軽なのでしょう・・・！！  
ちなみにこの投稿をしたのは俺じゃないです。（なのでモザイクいれときました！）

***

このように、お店の予約をとるまでは問題がなく、便利だなーと見ていたのですが、出席者も欠席者も多かったので、いざお店に向かう段になって「行くの誰だっけ？」問題が発生しました。

そうです。点呼する必要があるのです。

PCだとそれぞれのリアクションの上にマウスを持っていくと誰のリアクションかわかりますし、スマホだと長押ししてるとわかります。でも、すこぶる見づらいのです。

会社のSlackでその画面を出すと個人情報の嵐なので、とりあえず個人Slack作って同じ状態を再現してみました。

***

<img width="345" alt="Screenshot_20171208-063459.png" src="https://qiita-image-store.s3.amazonaws.com/0/26501/43caa07b-60d9-0573-bc1c-e034d5e148a9.png">

<img width="345" alt="Screenshot_20171208-063219.png" src="https://qiita-image-store.s3.amazonaws.com/0/26501/2f55584a-3f58-3064-0ec4-45f2f712e45d.png">

おわかりいただけるだろうか？

***

スマホのリアクション表示は、割と見やすいんですが、ユーザ名のところはリストではなく結合された文字列で表現されているので、人数が多いと区切りがわかりにくかったです。
なのでいつも見慣れているJSONかCSVの形で出力したいなぁと思いました。

Slackで特定の投稿のリアクションを見るのはAPI一発でできます。なんてヌルゲーなのでしょう・・・！！

https://api.slack.com/methods/reactions.get

<img width="345" alt="スクリーンショット 2017-12-08 6.46.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/26501/d68a6287-bc73-6810-b0a5-132599d4a160.png">
`U88DPF001`さんて誰ですの(´・ω・｀)？

当日は時間もなかったのでここで諦めました。。。

***

SlackのAPIドキュメントに書かれている`Channel`とか`User`とかは、IDだけ返ってくるんですね。
なので表示名や氏名(Full name）を知るためには、別途`users.info`APIを叩いて、ユーザ情報を取ってこなければならなかったのです。

なのでコードを書きました。

出来上がったものがこちらです。

https://github.com/yu0819ki/slack-reactions

APIトークンを環境変数`SLACK_API_TOKEN`に指定して、第一引数にパーマネントリンクを指定するとつぎのようなJSONがとれます。

```
[{
	"reaction": "ok_woman",
	"users": ["yu0819ki", "yu0819ki_bbb"]
}, {
	"reaction": "no_good",
	"users": ["yu0819ki_aaa"]
}]
```

ああ、これで参加者がわかりそうですね！ね！！

***

このソースにはもうちょっと手を加えるつもり（Slackに投稿したり、CSV化したり、Webから使えるようにしたり）ですが、SlackのAPIの取り回しの勘所はこんなところです。

というところでよろしくご査収ください。
バックエンドな人が一からcreate-react-appして認証とAPIアクセスを実装するまで:その１

#まずはじめに

もともとAWSとかバックエンドを中心に触っていたんですが、
会社にてJavaScriptでもろもろのサービスを作るところをやることになりました。
雰囲気JavaScriptをなんとなく程度で理解しているくらいだったので
一から徹底的にやるのも時間がもったいないなと思ったので
今回はいきなり諸々をすっとばして、Reactをいちからさわりながら、
WEB上で簡単なSPAを作るまでの過程で得られた知見とTipsをまとめてみました。
なので、

- JavaScriptを一から基礎をみっちりやってやってReactでSPAを作りたい人
- React-Nativeを考慮してReactでSPAを作りたい人
- Reactのライフサイクルとか動作原理とかを詳しく理解してアプリを作りたい人

って人にはあまりこの記事は向いていないかもしれません。

どちらかというとウェブフレームワークで認証ができてAPIを叩いてDBにアクセスして
データをひっぱったり更新したりするようなチュートリアルくらいの内容でSPAができるといいなーくらいな気持ちで、実際仕事上仕様を決める際に設計であれこれ試行錯誤したところをまとめてみたつもりです。

#node.jsまわりの環境調整

https://github.com/creationix/nvm
公式を参考にコマンドを実行して整備しておく

```
# コマンド実行
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

# .bash_profileに保存
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
```

だいたい以下を覚えておけば環境整備には困らない。
下記コマンドを駆使してnpmのバージョンをコントロールして使ってくれれば大丈夫なはず。

```
nvm ls-remote
nvm ls
nvm use {vから始まるバージョン}
nvm install {vから始まるバージョン}
```

今回はv6.11.2を使うことにします。

#create-react-app

https://github.com/facebookincubator/create-react-app

crete-react-appをインストール

```
npm install -g create-react-app
```

インストール完了後、create-react-appで実行

```
create-react-app {プロジェクト名}
```

ちゃんと動いてくれるかどうかを確かかめる

```
cd {プロジェクト名}
npm start
```

ブラウザで` https://localhost:3000 ` にアクセスしてみると
下記のような感じでデフォルトで` src/ `に用意されているスクリプトが動く。

ちなみに、サンプルアプリまで動かしてみて、「とりあえず動いた」って感じになったと思うんですが、
実際何故localhost:3000にアクセスしたらうごくのかいまいち腑に落ちない。
そんな人は、サンプルアプリを実行した後下記も実行してみて、

```
npm run eject
```

実行すると、defaultで用意されたディレクトリとは別の` config `, `scripts`が形成されている。これが` npm start `で実行された時に動作する処理の構成要素になる。時間ある人はこのあたりも読んでみると、概ねnpm startで何してくれているのか理解できかもしれません。（本稿の主題ではないので自力で読んでみてください。）

#必要なライブラリ
下記を揃えておけば概ねこまらないはずです。
今回UIにはreact-bootstrapを採用します。（今時はMaterial-UIを採用するのが最善ではありますが）
本稿で使ってないライブラリとかは一旦おいときつつ、とりあえず入れておけばいい、って感じで別のライブラリもいれておきます。

```
npm install react-bootstrap react-redux react-redux-form react-router redux-thunk redux-logger prop-types react-router-dom axios --save
```

#src配下の構成
- web, nativeで同じ要素はもたせてみてもいいかも
  - webを先につくるが、ゆくゆくはnativeにもうまく対応させたい
  - UIの構成要素をちゃんと分割しておきたい
    
みたいなことくらいは考えておいて、nativeのことはさておき、一旦こういう形にきればなんとかなると思います。だいたいの役割関係はこんな感じ

```
├── actions 　## actionに該当、returnだけする、通常api配下のいくつかのモジュールをimportして連携することが多い
├── api　 ## 外部通信してデータをとりにいったりする、などなどのモジュール
├── constants　## action, APIなどでも使う定数の置き場所
├── store　　## あらゆる状態を一元管理する場所
│   └── reducers ##各状態の変化を設定するためのモジュールを置く場所
├── index.js　## webのRoot config/paths.jsのappIndexJsにこのファイルを指定してあげると、このindex.jsを呼び出してくれる
├── components ## presentaional componentの役目、レンダリング周りのモジュールを書く
├── containers ## connectsと各componentをつなぎ合わせるためのモジュール置き場、大抵componentとcontainerは基本1:1でファイルが存在する
```

##レイアウト構成

いわゆるwebページ上のヘッダー部分、フッター部分、メニューやエラーのポップ、複数データの１レコード分の表示部分などのパーツは、わかりやすくcomponents/common等で固めておいた方がわかりやすいとは思いますが、個人のセンスの問題なのでそこは自由にまとめればいいかと思います。
一方container側は必ずしもcommonが存在する必要はないです。

##つづく

本稿ではcreate-react-appからReactプロダクトを作り、
Mockで動くところまでを作りました。
そのあと、構成の概要を説明し、作りの大枠の一例を示しました。
次回は本格的にReduxを中心にimportしてきたライブラリを駆使してAWS API Gateway, Cognitoを用いて、認証の作りとAPIを叩くところを整備できるものにします。
Androidエミュレータのコマンドラインからの作成からの起動

Android 4.4のエミュレータの作成をコマンドラインから行ってみましたので、メモとして記載しておきます。

```
# SDKのDL
cd /Users/**（ここはユーザー名）**/Library/Android/sdk/tools/bin
./sdkmanager "system-images;android-19;google_apis;x86"

#エミュレータの作成（デバイス指定はNexus 4となってますが他でも可能です）
./avdmanager create avd -n <名前> -k "system-images;android-19;google_apis;x86" -b x86 -c 100M -d 7 -f  --device 'Nexus 4'

#エミュレータの起動（画面サイズ指定）
cd /Users/**（ここはユーザー名）**/Library/Android/sdk/tools
./emulator -avd <名前> -skin 768x1280
```
Nexus 4以外も

```
avdmanager list device
```

で表示されるデバイスが指定できると思います。

ちなみにエミュレータの削除は

```
avdmanager delete avd -n <名前>
```

です。
Galaxyでファイルを削除してみよう

ファイルを削除するのはとても簡単。

画面右の"History"領域で、削除したいファイルを選んで"X"アイコンをクリック。
![History_Delete.png](https://qiita-image-store.s3.amazonaws.com/0/213053/eba7337a-8447-3410-5a99-a38d9b0f1013.png)

これで、いらないファイルは(^_^)/~。
![History_Empty.png](https://qiita-image-store.s3.amazonaws.com/0/213053/ff308949-7e2f-aafa-70ef-62fe53ca15fa.png)

ここでは確認のダイアログも何も表示されない。
そして、本当は消しては駄目だったと後で気づいた:scream:

俗に言う「稀によくある」事態...

そんな時は、まずはコーヒーでも飲んで落ち着こう:coffee:

そして"History"の"deleted"をクリック
![History_deleted.png](https://qiita-image-store.s3.amazonaws.com/0/213053/619b68a4-83d8-7751-a202-440bcf5dd44f.png)

間違えて消したファイルを見つけて、そのファイル名の上のオレンジのボックスの"Undelete it"をクリック
![Screen Shot 2017-12-01 at 11.46.21.png](https://qiita-image-store.s3.amazonaws.com/0/213053/b4513795-781f-3013-da82-ac7e3fc2d059.png)

ファイルを救出したら、"hide deleted"をクリック
![History_hide_deleted.png](https://qiita-image-store.s3.amazonaws.com/0/213053/ff390257-2c16-465b-d7c8-6479b220e851.png)

消したファイルが戻ってくる
![History_after_hide_deleted.png](https://qiita-image-store.s3.amazonaws.com/0/213053/5605f675-a8ec-fcd5-9f4a-23113d1fb8fd.png)

今日はここまで:smiley:
Vagrant upエラー ※VirtualBox使用

#Vagrant upエラーの対処法
##Vagrant upエラー
```
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'bento/centos-6.8' is up to date...
==> default: A newer version of the box 'bento/centos-6.8' is available! You currently
==> default: have version '2.3.1'. The latest is version '2.3.4'. Run
==> default: `vagrant box update` to update.
==> default: Resuming suspended VM...
==> default: Booting VM...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "f1754b77-ea50-4a5d-a878-ce14eb1f34e8", "--type", "headless"]

Stderr: VBoxManage.exe: error: Interface ('VirtualBox Host-Only Ethernet Adapter #4') is not a Host-Only Adapter interfa
ce (VERR_INTERNAL_ERROR)
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component ConsoleWrap, interface IConsole
```

いつもどおりローカル開発環境を構築するためにVagrant upを行ったら、まさかのエラー。
いきなりエラーが起きると困りますね。

さっそくグーグルで「Vagrant up エラー」で検索。
記事を色々見てみたら、**一度Virtual Boxをアンインストールして、新しいバージョンをダウンロードすれば解決する**とのことだったので、やってみた。

が、しかしエラーは治らない。

そこで、Vagrantのコマンドを眺めていたら、**reload**というそれっぽいコマンドを押してみたら、なんとエラーが治ったので、もし同じ状況の方がいればおすすめしたい。

※なぜエラーが治ったのか解析できていないので、分かる方は教えてください。。。
Rails RunnnerでControllerの機能を使ったバッチ処理を書きたい

# 概要

Rails Runnnerを使ってバッチ処理を作成したい。
バッチ処理はModelの操作が主だが、一部Controllerに実装されている機能を使用したい。

* Ruby 2.3.4
* Rails 5.0.3


# 結論

処理はControllerに実装してしまって、バッチからはControllerだけを呼び出すだけにする。


# 実装

`./lib`配下が本番環境ではautoloadされない件への対応。

````ruby:./config/application.rb
# 下記の一文を追加
config.paths.add 'lib', eager_load: true
````


Controllerに処理を実装。

````ruby:./controllers/test_controller.rb
class TestController < ApplicationController
  def batch
  	# runnnerで起動したい処置をこのあたりにゴニョゴニョ
  end
end
````

呼び出し。


````ruby:./lib/tasks/test_batch.rb
class TestBatch
  def self.execute
    controller = TestController.new
    controller.batch
  end
end
TestBatch.execute
````

`bundle exec bin/rails runner lib/tasks/test_batch.rb`
上記コマンドで実行。controllerの処理が呼び出されるので、あとはいつもどおりに実装すればOK。

とりあえず動いたのでよいものとします。
Rubyは触りたてなこともあり、実は他にやりようがあったのでは感が否めないところないでもありません。


# 参考

* [A Guide for Upgrading Ruby on Rails — Ruby on Rails Guides](http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#autoloading-is-disabled-after-booting-in-the-production-environment)
* [Rails5 でバッチ処理を利用する際に知らないとハマるかもしれないポイント! - ダメでしょ！](http://useless.hatenablog.com/entry/2017/03/27/190000)
* [Rails ターミナルからコードを実行する - KeruuWeb](http://keruuweb.com/rails-%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%81%8B%E3%82%89%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B/)
ionicのpluginのアップデート

ionicアプリも数ヶ月ぐらいかけて作っていると、使っているプラグインのバージョンも上がっていきますが、バージョン間の齟齬がでないように管理されているようなので、バージョンを気にすることなく開発を進めることができます。

しかし、その状態で新しいプラグインを導入しようとすると、バージョンの齟齬が出る場合があります。
例えば、現在plugin A, B, Cの三つを使っていて、Plugin AとCは内部でBを使っているとします。

```
Plugin A (1.1.0)
    |
  Plugin B (2.0.1)
    |
Plugin C (1.5.0)
```
ここに新しくPlugin Dをインストールするとし、このPlugin Dは最新のPlugin B(3.1.0)を使っているとすると、インストール時にPlugin Bが古い (2.0.1が存在しているが、3.1.0が必要）というエラーメッセージが出ます。そこでPlugin Bをアップデートすることにします。ionicでは一つのコマンドでプラグインをアップデートできないので、アップデートするには一旦該当のプラグインを削除して、再インストールします。

例えば、plugin Bをアップデートするには、以下のようにします。

```
$ ionic cordova plugin rm pluginB
$ ionic cordova plugin add pluginB
```
この時、今度はPluginAとCが古いとエラーが出てしまいます。古いとエラーがでたpluginを順にアップデートしていけば、必要なプラグインが全部アップデートされますが、使用しているプラグインが多いとかなり大変です。しかも、アプリの開発が進んでいると、すでに動いているところも再度確認する必要が出てきます。

新しい機能を開発するために新しいプラグインを使いたいだけの場合、全体を再検証する時間は取れないので、すでに使っているプラグインを迂闊にアップデートしたくはありません。この場合は、新しいプラグインのバージョンを現在の環境で動くバージョンにしてまず新機能の開発を進める方が良いです。ionicではインストールするプラグインのバージョンを@マークを使って指定できます。

上の例で、Plugin Dが2.5.0だとPluginB (2.0.1）で動くとすると、バージョン2.5.0のPluginDをインストールするには以下のうようにします。

```
$ ionic cordova plugin add pluginD@2.5.0
```

現在の環境でどのバージョンが整合するかを簡単に調べる方法はないので、一つずつ古いバージョンを試していくしかないようです。
Swift Optionalの基本に関して

#SwiftとObjective-Cとの大きな差の一つは？
**Optionalです。**
Optionalを理解しましょう。

#SwiftのOptionalとは
**'nilを扱うことができるタイプ'と言う意味です。**
逆に言うとOptionalではない一般**変数(Variables)**/**常數(Constants)**には**nil**を入れ代入することは出来ないです。

これを利用すればSwiftの基本タイプ（Bool, Int, Floatなど）にもnilを使用できます。

##Optionalの宣言
```
var optionalValue1: Bool? = nil
var optionalValue2: Optional<Int>
var optionalValue3: Int?
var optionalValue4: String!
var optionalValue5: [String: Any]?

**特に初期化宣言がない場合nilが基本的に代入される**

例）
var optionalValue: Int?
print(optionalValue)
optionalValue = 5
print(optionalValue)

result:
nil
optional(5)
```
##Implicitly Unwrapped Optional
上の宣言を見るとoptionalValue4は**'?'**ではなく**'!'**で初期化された。
これをImplicitly Unwrapped Optionalと言う。nilで初期化されたのは同じだが少し差はある。
<img width="464" alt="Screen Shot 2017-12-01 at 11.18.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/166098/93811bda-8750-e03b-0851-7476ac190fa8.png">

上のイメージのように**！(暗視的Optional)**で初期化された変数はコンパイラーからWarningが出ないのが確認できる。これは初期化視点では明確なデータが代入することはできないが以降使用されるときには必ず代入されるのを保証するとき使用する。もし**nil**が代入されたらランタイム中クラッシュするので注意が必要だ。

##Optional使用
Optionalはnilが含まれる場合があると言うことでランタイム中nilかどうか確認する必要がある。
###nil確認(if, guard)
```
var optionalValue: String?

if optionalValue != nil {
    print("optinalValueの値 = \(optionalValue)")
} else {
    print("optinalValueの値 = nil")
}

または

guard optionalValue != nil else {
    print("optinalValueの値 = nil")
    return
}

print("optinalValueの値 = \(optionalValue)")
```

###Optional binding
```
if let nonOptionalStr = optionalValue {
    print(nonOptionalStr)
} else {
    print("nil")
}
```

###Optional Chaining
```
var optionalValue1: String? = "efg"
var optionalValue2: String? = "123"

let str1 = optionalValue1?.uppercased()
let str2 = optionalValue2?.uppercased()
print(str1)
print(str2)

result:
Optional("EFG")
Optional("123")
```
そもそもベクトルタイルをどう説明するか

オープンソースのベクトルタイル実装の普及が始まってしばらく経ちますので、様々なイベントで多くの人がベクトルタイルについて説明しています。説明の仕方もかなり落ち着いてきましたので、私が考えるベクトルタイルのわかりやすい説明について、二つご紹介します。

# 区切られたベクトルデータ、それがベクトルタイル
ウェブ地図の画面に正方形を書いて、そこに別の正方形を接続し、その別の正方形の中にベクトルデータを書くことでベクトルタイルを説明する、ということがよく行われるようになりました。

今回の記事の機会に、少し図を作ってみたところ、次のとおりです。

![イメージ](https://qiita-image-store.s3.amazonaws.com/0/102082/b0045e11-d8f4-a86e-0d3a-c1721b7a41bb.jpeg)

# ベクトルタイルのシンボル
これも、多くの人が説明をするなかで落ち着いてきたのだと思いますが、ベクトルタイルのシンボルは日本でいう割り菱（❖）に定着してきました。データベースをいったんベクトルタイルにしてから提供する、ということをシンボリックに表した図として、次のような図がかけます。

![❖](https://qiita-image-store.s3.amazonaws.com/0/102082/14c73734-5826-347a-0b21-dc8e9e645103.png)

# See Also
様々なイベントで多くの人がベクトルタイルについて説明しています。その例をいくつか紹介します。
- [Getting Crafty with Vector Tiles — Hanbyul Jo](https://www.youtube.com/watch?v=J7L5UvIAtf8)
- [Esri UC 2017: Vector Tile Basemaps—DYK?](https://www.youtube.com/watch?v=GxbTqCMlvBA)
- [2016 - FOSS4G: Create Vector Tiles from OpenStreetMap](https://www.youtube.com/watch?v=D7mmXonFIqA)
- [Vector tiles from OpenStreetMap](https://www.youtube.com/watch?v=Jt2b0qXHucE)
- [Processing OpenStreetMap Into Vector Tiles - Dane Springmeyer](https://www.youtube.com/watch?v=5xa7eMMYH9A)
- [Vector Tiles for Distributed, High Performance Rendering of OSM – Dane Springmeyer](https://www.youtube.com/watch?v=nhqc4z5676I)
クラウド機械学習APIの個人情報利用にご用心

こんにちは、LIFULL 新UX開発部の二宮( @ninomiyt )です。
この投稿は[Lifullその2 Advent Calender](https://qiita.com/advent-calendar/2017/lifull2)の1日目の投稿になります。

結論から言うと「クラウドAPIを使う際は、データの個人情報の扱いがどうなのかちゃんと確認しよう」ということです。

# Microsoft LUISを使いたい！

「今まで活用できてなかった対話ログデータを分析する」という仕事があり、Microsoftの[LUIS(Language Understanding Intelligent Service)](https://azure.microsoft.com/ja-jp/services/cognitive-services/language-understanding-intelligent-service/)の利用を検討していました。

もっと具体的には、会話の**意図(Intents)**と**エンティティ(Entities)**を同時に抽出できるため、例えば「引っ越しについて言及している発話がどれか」や引っ越そうとしているのが「"どこ"から"どこ"なのか」を集計しようと考えてました。

一部に個人情報を含むデータ（今住んでいる住所など）が含まれているため、[テスト用に作ったデータを試しながら](https://qiita.com/ninomiyt/items/ad7cec26f3ad7d52ca72)、法務と相談して進めていました。

ここでの論点は、[平成29年5月3日より施工された改正個人情報保護法](https://business.bengo4.com/category3/article146)を踏まえて、データをクラウドサービスに送信することが「第三者提供」にあたるかという点で、「クラウド事業者側がデータを扱うのかどうか」が重要だという点です。

もし事業者が扱うなら、最初からユーザーの同意を取る必要があるため、例えば過去に取得したデータは利用できなくなってしまいます。

# Cognitive Servicesの個人情報の扱いだけ異なっていた

Microsoft Azure全体のポリシーを見て「おそらく大丈夫だろう」と踏んで検証を進めていたのですが、ある日、法務の方から以下のニュースとともに「確認させてほしい」という連絡が来てしまいました。

[プライバシー規約に要注意、マイクロソフトのクラウドAI](http://itpro.nikkeibp.co.jp/atcl/column/14/346926/090401111/?rt=nocnt)

ニュースを要約すると「Microsoft Azure全体ではユーザーのデータを触らないけど、LUISを含むCognitive Serviceでは扱う可能性があるよ」とのことです。

> ところがCognitive Servicesには、Microsoft Azureのサービス全般に共通するプライバシー規約が適用されない。「顧客データをマーケティングや宣伝目的でマイニングしない」「顧客データのアクセスについては、Microsoft社員や委託先会社に対する制限を含め、強力な措置を講じている」といった規約は、Cognitive Servicesについては対象外で、マイクロソフトが一般利用者のデータを使えることになっている。


> ユーザー企業が、マイクロソフトが顧客データを処理することについて、一般利用者から同意を取る必要があることについては、「特にガイドラインなどは用意していないが、当社の営業担当経由で適宜法務担当に相談のうえ、ユーザー企業に対応している」（日本マイクロソフト）とのことだ。

そのため、「対話ログを貰う際にユーザーの同意を取る（過去のデータは分析できない）」のか、「他の類似サービスを使うか、自前で分類器を作るか」など、方向転換が必要であることが分かりました。

# まとめ

結論から言うとこの通りです。

* クラウドAPIを使う際は、法務にも確認して個人情報の扱いを確認しよう
* 特に機械学習サービスは、こちらが送ったデータを精度改善に使いたいという意図もありそう

今回の話は2017年時点での当プロジェクトでの判断なので、会社やプロジェクト内容によってはこのあたりも変わると思います。その都度ごとに、法務と相談して判断してもらう必要があります。

話としては省略してしまいましたが、社内での連絡・調整や各クラウドサービスとの連絡等、どうしても検証・開発以外の手間がかかってしまうため、面倒でもこういう点は早めにクリアしておいたほうが良いでしょう。

最後に、LIFULL Advent Calendarのほうもご注目頂けると嬉しいです。

* https://qiita.com/advent-calendar/2017/lifull
* https://qiita.com/advent-calendar/2017/lifull2
連想リストのUPSERT

## UPSERTとは
データが存在するかどうかをチェックし、存在すれば更新、存在しなければ挿入を行うという処理は、よく行われます。

リレーショナルデータベース（RDBMS）上のSQL言語では、こうした処理を一文で行うためのコマンドを俗にUPSERTと呼び、長年にわたって実装や標準化が望まれていました。UPSERTは結局、SQL:2003にてMERGE文という形で標準化され、Oracle DatabaseやMicrosoft SQL Server、IBM DB2などの主要なRDBMS製品で実装されるようになっています。

## Emacs Lisp連想リストのUPSERT
UPSERTは、Emacsで連想リストを扱う場合でも使いたい場合があります。例えば、フレームの形状を設定する連想リストdefault-frame-alistでEmacsのフレームの幅を100に設定する場合です。
```default-frame-alist```で```width```がすでに設定されている場合は```width```の値を```100```に更新し、設定されていない場合は```(width . 100)```を```default-frame-alist```に挿入するという処理になります。しかし、こうした処理をいちいち```init.el```などの初期化ファイルに記述していったのでは、面倒ですし、初期化ファイルのメンテナンスもたいへんになります。そこで作ったのがEmacs Lispで連想リストのUPSERTを実現する次の関数```update-or-add-alist```です。

```
(defun update-or-add-alist (alist-var key value)
  "If KEY in ALIST, update VALUE of the KEY.
Unless, cons cell (KEY . VALUE) is added."
  (let (acell (alst (symbol-value alist-var)))
   (if (setq acell (assoc key alst))
       (unless (equal (cdr acell) value)
         (setcdr acell value))
     (set alist-var (push (cons key value) alst)))
   alst))
```

この関数を定義したあと、```default-frame-alist```でフレームの幅を100に設定するには、次のようにします。

```
(update-or-add-alist 'default-frame-alist 'width 100)
```

よければ、お試しください

## おまけ
実は、こういう関数はすでに標準で存在しているはずなのに…といろいろ調べたのですがついに見つけられず、自分で実装したという経緯があります。心当たりの方がいれば、教えてください^^
各OSのデプロイ方法

Qtのデプロイ方法についての手順を以下に説明いたします。

#Windows
何も考えずにQt Frameworkをインストールした場合、リリースするEXEに必要なライブラリを集めてくれるwindeployqt.exeは、以下に格納されています。

```
c:\Qt\QtX.X.X\msvc_20XX\bin\windeployqt.exe
```

Qtをインストールしたときに、binまでのパスが通っているので、コマンドプロンプトでリリースするEXEのパスまで移動して、以下のコマンドを実行するだけでOKです。

```
windeployqt リリースするEXE
```

#mac OSX
何も考えずにQt Frameworkをインストールした場合、リリースするモジュールに必要なライブラリを集めてくれるmacdeployqt.appは、以下に格納されています。

```
~/Qt/QtX.X.X/clang_x64/bin/macdeployqt.app
```

Qtをインストールしたときに、binまでのパスが通っているので、ターミナルでリリースするモジュールのパスまで移動して、以下のコマンドを実行するだけでOKです。

```
macdeployqt リリースするapp
```

#Linux
Linuxには、Qt Frameworkにlinuxdeployqtが含まれていません。しかし、有志が作ったlinuxdeployqtがあるため、これを自分の環境でビルドして使用する必要があります。

[linuxdeployqt ソース一式](https://github.com/probonopd/linuxdeployqt "linuxdeployqt")
※ビルドで私がハマった箇所は、qmakeのパスを使用したいQtバージョンに合わせていなかったのでビルドで失敗しました。

上記モジュールを作成して、他OSと同様にリリースしたいモジュールを引数に指定します。
※以下は、linuxdeployqtを/home/user/linuxdeployqtにて展開した場合

```
　~/linuxdeployqt/Release/linuxdeployqt リリースするモジュール
```

#android
勉強中です。

#iOS
勉強中です。

#終わりに
デプロイコマンドで実行環境が整ったら、いよいよ一般公開に向けての作業として、Qt Installer Frameworkでインストーラを作成する手続きを行います。この手順については、次の機会でご説明いたします。
位置情報（ビッグデータ）解析のここが難しい！

株式会社iRidgeのアドベントカレンダー初日の投稿を任されました@aimofです！　本来なら初日は偉い人がやるところですが、12/1が誕生日なので投稿を譲っていただきました。

会社のアドベントカレンダーなのでネタに走りたい気持ちを抑えて真面目に業務に絡んだ話をさせいただきます。

## 今回のトピック「位置情報解析」

最近iRidge関係、プライベートともに社外で話す機会が増えてきました。その時に良い反応をいただけるのが位置情報解析の話です。

さて、iRidgeには一日あたり二億件の位置情報が集まってきます。膨大な量なので、その活用をビジネス化すべく日夜がんばっているかんじです。B2B2C企業なので利用にあたり制約は多いのですが、非常に面白みのある仕事です。

## 今回のテーマ「なぜ位置情報解析は難しいのか？」

位置情報の解析は非常に難しいです。こないだLT会で、位置情報解析に必要なものは「気合と根性=前処理」なんて話をしてきたのですが、とにかく面倒臭いです。

### 位置情報が持つ情報

* 緯度
* 経度
* 正確さ
* 時刻
* 端末、アプリ情報
* その他付随する情報

### 位置情報分析を難しくする要素

* 切り捨てる情報の選び方が難しい
* 一つの点だけではほぼ意味がない（点同士の関係が大切）
* 正確さが数十メートル単位なので正確な場所判定は難しい
* 一つの端末、アプリに対して点の数がバラバラ
* 他の情報をどのように組み合わせるか考えるのが難しい
* 機械学習しづらいよ！
* 道具の整備が不十分

#### 切り捨てる情報の選び方が難しい

これは位置情報に限った話ではありませんが、ビッグデータ分析は使わない情報を考えてノイズを削除するのが大変です。

#### 一つの点だけでは意味がないが関係性を考えると問題が生じる

おおよそ上のリストの通りなのですが、要は、計算がすごく大変だよってことです。

色々な手法を使って扱いやすい形にデータを落とさなければなりません。

- 一つの端末あたりで取得できる位置情報の数とタイミングがバラバラ
- 経度、緯度は楕円体（歪んだ球）上の点を表すため点同士の演算が複雑になる
- ただでさえ複雑な計算に時刻が絡む（しかも間隔は一定ではない）

この辺りが下手人。

#### 正確さが数十メートル単位なので正確な場所判定は難しい

特定の確率で範囲内にいることを示す円の半径が正確さなのですが、数十メートル単位です。言い換えると、小さな店舗、ビルにいたかどうかを一点の位置情報のみから判断するのはほぼ不可能です。連続して近くにいれば、近くにいたことはわかりますがそれでも近くにいた、以上の情報とはなりません。部屋の位置レベルで特定できるの正確さがあれば、話は別なのですが……

位置情報から自店、競合店の来店情報を解析しています！みたいなことをいう企業は大概他の情報も利用しています。

#### 一つの端末、アプリに対して点の数がバラバラ

一日を通して一回しか位置情報を送ってこない端末があれば、　1000回単位で送ってくる端末もあります。端末たちをうまくまとめ上げ、使いやすい情報にするのが難しいです。

#### 他の情報と組み合わせるのが難しい

位置情報は付随する情報が大切です。普通の分析と違うのが、どの情報と結合するか考えるところでしょう。

#### 機械学習しづらいよ！

* カラムバラバラ
* 点同士の関係が特殊
* バランスが悪い

というわけで機械学習するのが難しいです。

前処理が大変！

#### 道具の整備が不十分

[【脱GIS】Pythonとかで地理空間情報、位置情報を扱うための情報まとめ【随時更新】](https://qiita.com/aimof/items/b4e4551d27abaf5bb258)

昔書いた記事です。この記事に書いたのですが、一般に流通している分析ツールがまだ整備されているとは言いがたく、なかなか大変です。やりたいことが多岐にわたり、データが一定でないのが原因かなと思っています。

## 大変！でも楽しい

位置情報を処理するのは大変ですが、まだまだ誰も気づいていない新しい事実がそこら中に転がっている分野です。大変だからやりたがる人は少なめだけど皆が皆期待を感じている、そんな分野なのです。

## 位置情報分析をしよう！

位置情報分析、楽しいのでやりましょう。

もし同士がいればご連絡いただければ幸いです。
Processingで3次元空間に画像を貼り付ける方法

#1. 貼り付ける位置の座標を決める
![coord.png](https://qiita-image-store.s3.amazonaws.com/0/83787/4e012938-13be-f1ec-2ae7-1bca22de09c6.png)
#2. 画像を用意する
![texture.png](https://qiita-image-store.s3.amazonaws.com/0/83787/7aee2b19-7960-60f0-cb04-0fd1c2bd3d2c.png)
ここでは正方形の画像を正方形の領域に貼り付けようとしています。NORMALモードで行うので0と1で指定しています。DefaultのIMAGEモードを使う場合は、画像のサイズ(pixel)を指定してください。
#3. コードを書く
・vertexのパラメータ5個の前半はxyz座標(x,y,z)、後半は画像の座標(u,v)。

```
PImage snowParticleImage;

void setup(){
  size(300,300,P3D);
  snowParticleImage = loadImage("flake.png");
  textureMode(NORMAL); // NORMALモードを使用
}

void draw(){
  lights();
  rotateY(0.5);
  beginShape();
  texture(snowParticleImage); 
  vertex(50,50,0,0,0); //V1
  vertex(200,50,0,1,0); //V2
  vertex(200,200,0,1,1); //V3
  vertex(50,200,0,0,1); //V4
  endShape();
}
```
#4. 実行結果
![スクリーンショット 2017-12-01 11.15.36.png](https://qiita-image-store.s3.amazonaws.com/0/83787/416825b5-01b4-4db0-d7c5-cc750ac345ee.png)
MiniShiftのBoot2Dockerで内部レジストリにdocker pushできなくて苦労した話

MiniShiftは普段使っているパソコンでOpenShiftの動作確認ができるので重宝しています。

oc new-appコマンドで簡単にアプリケーションをデプロイできるのですが、手動でDockerImageをOpenShiftの内部レジストリにpushした際に下記のように「 unauthorized: authentication required 」と認証できなくて先に進む事ができなくて一時期悩んでました。

```
$ docker push $(minishift openshift registry)/test01/busybox:latest
The push refers to a repository [172.30.1.1:5000/test01/busybox]
0271b8eebde3: Preparing
unauthorized: authentication required
```

本件はMiniShiftのgithubのissues 「[Authentication required when trying to push to OpenShift registry #817](https://github.com/minishift/minishift/issues/817)」には登録(2017年4月)されているのですが、現時点では解決していなく回避策を見つけるまで結構時間がかかったので備忘録を兼ねて投稿します。

## 事象を確認した環境
  - Linux
    - CentOS7.4 + KVM 
    
  - Mac
    - macOS Sierra + xhyve

  - minishift 
   - v1.6.0+7a71565

## 原因 と回避策
11月下旬にGitHubのMiniShiftのdocsに追加された [Authentication required to push image to OpenShift integrated Docker registry](https://github.com/minishift/minishift/blob/master/docs/source/troubleshooting/troubleshooting-misc.adoc#authentication-required-to-push-image-to-openshift-integrated-docker-registry)　によると

- 原因
ホストのDockerClientとMiniShiftが起動したVM内のDockerDaemonと互換性がないため事象が発生していてる。

- 回避策
  Fedora、CentOSまたはRHELで使用している場合は、CentOS ISOを使用する。

MiniShftは起動するとLive ISOイメージ使ってハイパーバイザーから MiniShift VMをプロビジョニングをします。現在以下の3つの Live ISOが提供されている中で

- Minishift Boot2Docker (Default) 
- Minishift CentOS
- minikube

デフォルトで起動するBoot2Dockerから　Minishift CentOS　に変更すれば回避できます。具体的には MiniShiftの起動コマンドを 「 minishift start 」から 「 minishift start --iso-url centos 」に変更します。

## 回避策の確認

実際に下記の手順で確認を行いました。

- 現在動作している MinSsihft(Boot2Docker)のVM停止と削除

```
$ minishift stop
$ minishift delete
You are deleting the Minishift VM: 'minishift'. Do you want to continue [y/N]?:
Deleting the Minishift VM...
Minishift VM deleted.
```

- Minishiftを Live isoイメージを Minishift CentOS 指定で起動する。

```
$ minishift start --iso-url centos
-- Checking if KVM driver is installed ...
   Driver is available at /usr/local/bin/docker-machine-driver-kvm ...
   Checking driver binary is executable ... OK
-- Starting local OpenShift cluster using 'kvm' hypervisor ...
-- Minishift VM will be configured with ...
   Memory:    2 GB
   vCPUs :    2
   Disk size: 20 GB

   Downloading ISO 'https://github.com/minishift/minishift-centos-iso/releases/download/v1.2.0/minishift-centos7.iso'

````

- developerユーザでログインして test01プロジェクトを作成

```
$ oc login -u developer
$ oc new-project test01
```

- DockerHubからbusyboxをpullしてOpenShiftの内部レジストリにpushする

```
$ docker pull busybox
$ docker login -u developer -p $(oc whoami -t) $(minishift openshift  registry)
Login Succeeded
$ docker tag docker.io/busybox $(minishift openshift registry)/test01/busybox:latest
$ docker push $(minishift openshift registry)/test01/busybox:latest
The push refers to a repository [172.30.1.1:5000/test01/busybox]
0271b8eebde3: Pushed
latest: digest: sha256:91ef6c1c52b166be02645b8efee30d1ee65362024f7da41c404681561734c465
                                          size: 527
```

「 Pushed　」の出力から無事pushできてことが確認できました。
## 最後に
fedora/CentOS/REHLだけかと思ったら私のmacOS Sierra + xhyveの環境でも事象が発生しています。
いつかは解消すると思いますが、もし事象に遭遇した時にこの投稿でトラブルシューティングする時間が短縮されると幸いです。
[Jupyter Advent Calendar 2017] 実際に書いた手書き数字を当てるデモをした話

これは [Jupyter Advent Calendar 2017](https://qiita.com/advent-calendar/2017/jupyter)の第1日目の記事です。  

## 経緯
手書き数字の識字率がめちゃくちゃ高いという話は聞いたことあったけど、  
自分で書いた文字を識別させたことはなかったので、  
いい機会だと思い、デモを作った。

## 環境  
jupyter-notebook は、 ubuntu docker 上で起動している。  
python -V

```
Python 3.6.2
```

使うライブラリ等

```
import numpy as np
import fileupload
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display
from PIL import Image
from keras.models import model_from_json
```

jupyter widgets
file upload と button widgets を利用している。  
https://qiita.com/driller/items/0730325bf5c1cd689979
https://qiita.com/shinya7/items/745486ef2dae61ae49ca

とてもわかり易く書いてあるので、このあたりを参考にインストールすると良い。  
(widgets を使わない場合、少しコードの修正が必要になる。)


## 事前準備
3層のニューラルネットを作って、学習させた。  
ネットワークはこんな感じ。  

```
Dense(512, relu) -> Dense(512, relu) -> (10, sigmoid) 
```

ライブラリには、Keras を使用した。  
本デモでは、事前にトレーニングした重みを読み込み利用している。  


## コード

コードは、gist に登録している。  
https://gist.github.com/gorogoroyasu/76cffe71ac828e29d43580cea201d0f4
(上述の通り、widgets が必要)

# デモ
デモは、jupyter を使って行った。  
必要なボタンは、以下の3つ。

![advent_calendar.png](https://qiita-image-store.s3.amazonaws.com/0/115634/7bdbb468-3759-316f-10dc-a8f8c863da62.png)

### browser
これで、ファイルを探してくる。
iPad Pro の GoodNotes というアプリを使って手書き文字を書き、
ファイルを Google Drive にアップロードした。
アップロードしたファイルをjupyter から探すというしかけ。
また、アップロードしたファイルは、下記のとおり前処理を行った。



### 画像をチェックする (オプション)
入力した画像とニューラルネットに入れる画像をチェックすることができる。

![advent_calendar.png](https://qiita-image-store.s3.amazonaws.com/0/115634/ed02ad65-5ec7-442b-6caf-53117e358488.png)


### 予想する
このボタンを押したら、ニューラルネットが入力された画像を予想してくれる。  
![advent_calendar.png](https://qiita-image-store.s3.amazonaws.com/0/115634/ddae69c1-a68e-68c2-dd76-37ad7a06da98.png)


## 前処理
画像に対して、
- グレースケール
- リサイズ
- 白黒反転
という処理を行った。
特に、白黒反転をしなくてはならないことを知らなかったので、焦った。


## 感想  
widgets が、とても便利でした。
`lambda` を乱用しなくてはならないのが難点ですが、
基本的にはとても使いやすかったです。
毎回 `shift + enter`　を押して実行する必要もないし、
なんか、見た目もかっこよくなるし。  

ただ、`Browser` ボタンを押してアップロードする前に`予測する`ボタンを押しちゃうとエラーになっちゃったりするので、
その辺を改善する必要はありそうです。
できるんだろうけど。  

ということで、実際に動くdocker 環境を作っときます。
作ったら追記させて頂きます〜。


以上です。  
Advent Calendar、盛り上げていきましょう！！
UE4 プロジェクト移行 4.15 から 4.18 に移行する際に苦戦したこと

Unreal Engine 4.18 が出てしばらく経ったが、今回 4.15 で作成したプロジェクト(C++コード含む)を 4.18 に移行する際にハマった点、解決のためにやったことを書いておく。

# 環境

* Win10 Pro
* UE 4.18
* VisualStudio Community
* UE 4.15 で作成したプロジェクト(C++コード含む)

# UE4 の自動移行にお任せ

1. 4.18 を起動して、 4.15 で作成したプロジェクトを開く
1. 移行するか確認されるのでGO！
1. ビルドエラーで開けない

# sln を作りなおす

1. .sln 削除
1. .uproject 右クリックで "Generate Visual Studio 〜"

SCM 使ってる関係なのか、.sln はうまく開けないことがあり、その時にやる手順。

# Rules 関連ファイルの修正

## Target.cs

まず ```Source/ProjectName.Target.cs``` のビルドエラーになるので修正する。

```csharp
public class ProjectNameTarget : TargetRules
 {
	public ProjectNameTarget(TargetInfo Target)
  
    // ↓このように後ろに追加

    public ProjectNameTarget(TargetInfo Target) : base(Target)
```

TargetRules を継承するクラスのコンストラクタが変わったようだ。

```Source/ProjectNameEditor.Target.cs``` も同様の変更が必要。

## Build.cs

```Source/ProjectName/ProjectName.Build.cs``` を修正する。

```csharp
 public class ProjectName : ModuleRules
 {
    public ProjectName(TargetInfo Target)

    // ↓このように修正

    public ProjectName(ReadOnlyTargetRules Target) : base(Target)
```

ModuleRules を継承するクラスのコンストラクタも変わっており、パラメータも新たなものになっている。

また、今回移行したプロジェクトで使用しているライブラリで、今までは

```
UEBuildConfiguration.bForceEnableExceptions = true;
```

の記述が必要だったが、この行があるとビルドエラーになるので削除した。


## ProjectName.h

```Source/ProjectName/ProjectName.h``` の修正。
これも若干変更することになる。

```cpp
#pragma once
 
#include "Engine.h"

// ↓ Engine.h の include は非推奨となり CoreMinimal.h に変更

#include "CoreMinimal.h"
```

用途別にどのヘッダを include するか選択できるようになったようだ。
必要に応じて、最低限のヘッダを選択することにより、余計なヘッダを見に行かなくなる。


## ProjectName.cpp

```Source/ProjectName/ProjectName.cpp``` の修正。

```cpp
#include "Modules/ModuleManager.h"
```

が必要になっていた。


## 自前で作成したクラス全般

今までは

```
#include "ProjectName.h"
```

が必要だったが不要になった模様。


## IPlatformFile を使用している場合

ローカルのファイル検索で ```IPlatformFile::FDirectoryVisitor``` を実装しているコードがあったが、
```GenericPlatformFile.h``` の include が必要になった。
また、処理中で ```FPaths``` を使用していたが、こちらは ```Paths.h``` の include が必要になった。


## UTexture2D を使用している場合

```Engine/Texture2D.h``` の include が必要になった。
これは ```ProjectName.h``` で ```Engine.h``` を include しないよう変更したのが影響している。


## IImageWrapper.h を include している場合

ヘッダそのものが無くなっていた...

```cpp
#include "ImageWrapper.h"

// ImageWrapper.h は無くなり、以下の3つの追加が必要になっていた

#include "ModuleManager.h"
#include "IImageWrapper.h"
#include "IImageWrapperModule.h"
```

コードについても ```IImageWrapperPtr``` から ```TSharedPtr``` にするよう警告が出るので、

```cpp
IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);

// ↓このように変更

TSharedPtr<IImageWrapper> ImageWrapper =
    ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
```

と変更した。

## Fpaths の変更

IPlatformFIle の所でヘッダについては触れたが、

```FPaths::GameDir()``` は ```FPaths::ProjectDir()``` への置き換えが推奨されていた。

## まとめ

概ね Visual Studio でのビルドエラーのメッセージを見ると、どのように変更すべきかが書かれているので、
メッセージに従い順番に解決していけば問題はない。

ヘッダごと移動してしまったものについては、公式リファレンス（日本語は古いことが多いので英語ページ）を参照するのが良い。
箱玉系について

# はじめに
[総合数理AdventCalender](https://qiita.com/advent-calendar/2017/meiji-ims)がいつの間にか始まっていたので、自分もノリで参加することに。 何回かに分けて、"箱玉系"や”超離散化法"といった事柄について軽く触れていこうと思う。本稿では、超離散の発見の元となった**箱玉系**を紹介する。

# 本稿の目標
箱玉系について知ってもらう。

# 背景
まず、事前知識としてCAとSolitonの説明から。

## CA (Cellular Automata, セルオートマトン)

**CA**は、"離散的な発展方程式"で表される。 (e.g. $u_n^{t+1}=f(u_{n-1}^t, u_n^t, u_{n+1}^t)$)
すなわち、CAとは
**次の時間($t+1$)におけるセルの状態**が
**今の時間($t$)におけるセルの状態**によって決まる、計算モデル。
(状態とは、"0"か"1"の値、もしくはその他整数を考える。)

2次元CAの有名なものに、 **ライフゲーム (Conway's Game of Life)**がある。
![LifeGame](https://upload.wikimedia.org/wikipedia/commons/e/e5/Gospers_glider_gun.gif)
(wikipedia/Conway's_Game_of_Life)

以下は、1次元のものについて見ていく。

### ECA (Elementaly Cellular Automata)
1次元CAの最も単純なものは、**ECA (Elementaly Cellular Automata)**と呼ばれる。
**次の時間でのセルの状態**(0 or 1)が
**前の時間でのそのセルの状態とその両隣のセルの状態**から決まるようなCAで、
ルールは$2^8=256$通りある。全ての型はそのルールによって名前がつけられている。

**e.g.** Rule90のECA

|  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|--:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|時間$t$での $n-1,n,n+1$|000|001|010|011|100|101|110|111|
|時間$t+1$での$n$| 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
(Ruleの番号 $90 = 2^1+2^3+2^4+2^6$)

シェルピンスキーのギャスケットとして有名な下の形は、Rule90のECAによって作られる。
![sierpinski_gasket](https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/Sierpinski_triangle.svg/220px-Sierpinski_triangle.svg.png)
(wikipedia/Sierpinski_triangle)


### Filter型CA (Filter Automata)
先ほどまでのCAは、時間t+1における状態を得るためには、時間tの状態がわかっていれば十分である。それに対し**Filter型CA**は、
**時間$t+1$における状態**を得るために、
**時間$t+1$の状態**をも必要とするようなCAである。
その性質から、処理を左から順に行うことが多い (ECAはどこから処理しても変わらない)。

## Soliton (ソリトン, 孤立波)
Solitonとは、
波の**形状、速度が変わらず**、
互いに衝突しても**衝突の前後で各波の形状を保つ** ような波のことである。
他に、性質として波の大きさによって速度が変わり、一般に波の大きい方が速度も大きい。

津波なんかもこれで説明できる(らしい)。
([こんなの](https://jp.mathworks.com/help/symbolic/examples/solve-a-partial-differential-equation-tsunami-simulation.html))

![soliton](https://upload.wikimedia.org/wikipedia/commons/2/23/BBM_equation_-_overtaking_solitary_waves_animation.gif)



# 箱玉系 (Box&ball system)
一言で言えば、「ソリトン的性質を持つ1次元Filter型CA」
箱と玉により説明されるので、箱玉系と呼ばれるようになった。

## 箱玉系のルール
![box-ball2_3.006.jpeg](https://qiita-image-store.s3.amazonaws.com/0/137522/ad88512a-7c2b-5cc0-9e02-e496ad5a1072.jpeg)
![box-ball2_3.007.jpeg](https://qiita-image-store.s3.amazonaws.com/0/137522/f16c6448-93d9-f0d7-dd00-528f41afaf1f.jpeg)
![box-ball2_3.008.jpeg](https://qiita-image-store.s3.amazonaws.com/0/137522/94c446e9-5ad0-60eb-9241-5c554793d3ba.jpeg)
![box-ball2_3.009.jpeg](https://qiita-image-store.s3.amazonaws.com/0/137522/b0ab4a36-252f-379e-be0a-69c881e250e7.jpeg)
![box-ball2_3.013.jpeg](https://qiita-image-store.s3.amazonaws.com/0/137522/ec028216-6f26-8a70-1160-459a97d0bbfd.jpeg)
![box-ball2_3.014.jpeg](https://qiita-image-store.s3.amazonaws.com/0/137522/b79f1221-73c2-8999-4a7f-92101bb9c023.jpeg)

## 箱玉系の性質
**箱玉系は、Solitonの性質を持っている。**
玉の塊を一つの波とみなすと、波が衝突した前後でそれぞれの波が保存されているのがわかる(右下に3つの玉がないのは見切れてるから..)。また、玉の数を波の大きさとすれば、波の大きさに速度が比例していることも見て取れる。
![box-ballSystem.001.png](https://qiita-image-store.s3.amazonaws.com/0/137522/75ce8e25-8b6c-fa7f-8f97-8507406092b7.png)

# まとめ
箱玉系は、

- **Filter型CA**である。
- **一番近い空箱に玉を移動させる**ルールで表される。
- **Soliton**の性質を持つ。
d3.jsでの試行錯誤にBlock Builderがとても便利

ブラウザー上でインタラクティブに可視化を行うのにd3.jsが使えると知っていても、やりたい事を実現するにはちょっとハードルが高い。

d3.jsが実際に行ってくれるのは

- データが変更になった時のDOMの再設定
- クリック等のイベントの処理
- トランジション

等の基本的な事項で、グラフを記述する基本的な処理は前部自前で行わなくてはならない。

先日の"東京Node学園"で講演したShirley Wuさんが利用していた[Bitblock Builder](http://blockbuilder.org)。

インタラクティブにd3.jsを利用してコードを書いて保存できる上、多数のサンプルが参照できるのでとても参考になる。