OmniAICreator/Qiita-1.07M huggingface dataset:
見易い定数同値テストのためのRSpec matcher その2

[前回](http://qiita.com/gimKondo/items/7273f6877a689c6d9d94)の投稿で、定数の同値テストの結果を見易くするmatcherを作成した。
今回も類似のネタだが、もう少し細かく制御できるmatcherを作る方法を取り上げる。

## 概要
- モジュールで定義した定数の同値テストをするためのmatcherを生成するメソッドを実装する。
- 生成したmatcherは、前回紹介したmatcherと比較して以下の特徴を持つ。
    - モジュール内の特定の定数グループのみを対象とした比較ができる。
    - matcherを生成するので、テストケースを書く際にはモジュール名は書く必要がない。

## 解決したい問題
以下のようなクラスのrequestの結果をテストしたいケースを考える。

```ruby
class Widget
  RES_SUCCESS = 0
  RES_SUSPEND = 1
  RES_ERROR   = -1

  STATUS_OK = 0
  STATUS_NG = -1

  def request
    # RES_XXXXを返す処理
  end
end
```

素直にテストを書くと記述すると以下のようになる。

```ruby
wid = Widget.new
# requestがRES_ERRORを返す場合
expect(wid.request).to eq Widget::RES_SUCCESS
# => expected: 0
# =>      got: -1
```

しかし、これでは失敗したときのメッセージが分かりにくい。
我々は0とか-1とかではなく、`RES_SUCCESS`や`RES_ERROR`という表記で読みたいのだ。

シンプルなケースでは、[前回](http://qiita.com/gimKondo/items/7273f6877a689c6d9d94)の`const_eq`でも良い。
しかし、同じ値を持つ定数がクラス内に複数定義されていた場合(今回の場合は`RES_SUCCESS`と`STATUS_OK`が同じ値になる)に上手くいかないケースがある。


## 解決方法
### matcherを生成するメソッドを定義
このようなクラスやモジュールの個別の問題に対処するためのmatcherを生成するメソッドを実装する。

```ruby
def define_const_matcher(mozule, matcher_symbol, &filter)
  RSpec::Matchers.define matcher_symbol do |exp_symbol|
    match do |act_val|
      mozule.const_get(exp_symbol) == act_val
    end
    failure_message do |act_val|
      act_symbol = mozule.constants(true).
        select { |c| filter.call(c, mozule.const_get(c)) }.
        find { |c| mozule.const_get(c) == act_val }
      act_msg = if act_symbol.nil? then "     got: invalid value(#{act_val})"
                else "     got: #{mozule.name}::#{act_symbol}(#{act_val})"
                end
      exp_val = mozule.const_get(exp_symbol)
      "expected: #{mozule.name}::#{exp_symbol}(#{exp_val})\n" << act_msg
    end
  end
end
```

### matcherを生成
今回の場合はWidgetクラスの定数の中でも、'RES'から始まる一群の定数を対象にテストできるmatcherが欲しい。
そのmatcherを生成するには次のように`define_const_matcher`メソッドを呼び出してやればよい。

```ruby
define_const_matcher(Widget, :widget_res_eq) { |c, _| c.to_s.start_with?('RES') }
```


### 使用例
生成したmatcherを先程の例に適用すると読み易いエラーを出力するテストケースを作ることができる。

```ruby
wid = Widget.new
# requestがRES_ERRORを返す場合
expect(wid.request).to widget_res_eq :RES_SUCCESS
# => expected: Widget::RES_SUCCESS
# =>      got: Widget::RES_ERROR
```


## 補足
- 今回は定数名で対象を絞り込んだが、`define_const_matcher`に渡すブロックを使い、値で絞り込むこともできる。
FCM(API)を利用したプッシュ通知用の社内ライブラリを作りました

#はじめに
みなさん、最近楽しくアプリを開発していますか？スマートデバイス横断チームのduanです。今回はFirebaseの推進に伴い、プッシュ通知の共通ライブラリを作った話をさせていただきます。

#Firebaseとは
　アプリ開発者としてもう知らない人はいないでしょう。今年のGoogle I/Oで発表され、現在最も熱いスマートフォン開発プラットフォームでもあります。ログ解析、データベース、 プッシュ通知、A/Bテストなどアプリ開発上に必要な機能をAll In Oneで提供され、開発、施策、分析のサイクルを今までより効率的に実施できるようになっています。また、ユーザープロパティーとイベントの組み合わせて、より高度なターゲッティングユーザーリストを作成でき、アプリ施策（プッシュ通知、広告など）で簡単に利用することができます。
　(公式サイト：[Firebase](https://firebase.google.com "Firebase"))

#ライブラリ作成
###経緯
　社内都合上、Firebase Notificationsを利用した配信ではなく、API経由方式の配信を採用することになり、Firebase Notificationsの一部機能や計測イベントを自前で実装する必要が出ています。それを受けて、共通的な実装をまとめてライブラリとして提供することになりました。

###ライブラリで実現したいこと
　1. FCM API経由配信の共通機能を実装
　2. Firebase SDKのバージョン管理
　3. 自社ビジネス要求に満たすデータ計測機能の共通実装

###全体構成と配信流れ
![全体像.png](https://qiita-image-store.s3.amazonaws.com/0/109089/6d9b1ff8-bb2b-46b0-a4ba-5d679dde9626.png)
　①ライブライリ側でFCM Tokenを取得し、Firebaseに送信する。
　②配信先リストを抽出する為のユーザープロパティーをFirebaseに送信する。
　③FirebaseのBigQuery連携機能を利用して、送信されたデータをBigQueryから参照できるようにする。また、社内管理しているデータと結合し、配信先リストを生成する。
　④自社サーバでメッセージ識別子を生成し、計測有効期限も含め、FCM(API)経由で配信を依頼する。
　⑤Firebaseから配信実施する。
　⑥効果測定イベント（受信、開封、コンバージョンなど）をFirebaseに送信する。

###いくつかの実装方針
#####1. Android, iOS配信処理の相違点を意識したpayload利用
採用方針は下記のようになっています。

|OS|paylaod利用|理由|
|---|---|---|
|Android|dataのみ|notification指定且つbackgroundである時、通知が自動的にSystem trayに入り、受信時独自実装できない為|
|iOS|notification, data|backgroundで受信する為にnotificationの指定が必要になる|

なぜAndroidでdata payloadのみ利用するかを簡単に説明しましょう。
公式ドキュメント[Handling messages](https://firebase.google.com/docs/cloud-messaging/android/receive "Handling messages")で下記内容が書かれていて、実際技術検証でも
確認できています。

|App state|Notification|Data|Both|
|---------|-----------|----|----|
|Foreground|onMessageReceived|onMessageReceived|onMessageReceived|
|Background|System tray|onMessageReceived|Notification: system tray Data: in extras of the intent.|
Android側でNotification payloadが入っている場合、backgroundにある時通知がsystem trayに自動的に入り、受信イベント取得や通知表示のカスタム処理ができなくなるので、止む得ずdata payloadのみ指定する方針になりました。そのため、共通ライブラリ側Notifications payloadを同様に機能を実装する必要があり、iOSより実装工数及び考慮すべきところを大幅に増えました。

#####2. FCM Token管理方式
　現時点でBigQuery上に自動的に送信、管理されていない為、自社管理データと結合して配信先リストを抽出する要件を満たす為に、独自で実装し、管理する必要があります。下記のように三つの案を検討しました。

|検討案|メリット|デメリット|
|---|---|---|
|カスタムイベントで管理|BigQuery連携できる、実装工数が少ない|データ抽出する時工夫が必要|
|User Propertyで管理|BigQuery連携できる、実装工数が少ない|長さ制限の原因、複数User Propertyを利用する必要がある。|
|自社サーバでマッピング表を持つ|一般的な実装方法|実装工数がかかる|
社内BigQuery利用したデータ解析することもあり、できればBigQuery上で管理したい、また、個数制限(最大25個)もあり、User Propertyを極力利用したくありません。最終的にカスタムイベントで管理する案を採用しました。

#####3. 共通計測イベントの実装
　現状FCM API経由の配信でFirebase Console, BigQuery上でデータ確認できない為、独自で現在Notificationsで自動取得できた下記イベントをFirebase上で管理できるように実装しました。

|OS|イベント|対応するNotificationsイベント|
|---|---|---|
|Android|受信、開封、Dismiss|notification_forground, notification_background,notification_open,notification_dismiss|
|iOS|受信、開封|notification_forground, notification_open|

#まとめ
Firebaseが世の中に出たのはまだ1年未満ですが、Google側で積極的に開発者要望を取り入れて機能更新を進めていて、凄く将来性を感じています。今後も引き続き注目して、こちらのライブラリを進化しつつ、他の機能もどんどん試していきたいと思います。また、今回のライブラリ作成を通して、FCMの配信仕様を深く理解できたのはもちろん、利用者視点のインタフェース設計の重要性も改めて認識しました。
redis-py を安全に使うために gxredis を書いた

## 概要

python には [redis-py](https://redis-py.readthedocs.io/en/latest/) という便利な redis ライブラリがあるのですが、安全に使うのが難しかったので、シンプルで直感的なラッパーライブラリを書きました。

- https://github.com/groove-x/gxredis

インストール方法

``` bash
$ pip install gxredis
```

## 設計思想

- 無理に Active Record 仕様にしないで、素直に redis の特性を活かす
- 誤った操作が発生しにくい構成にする
- redis-py で提供されているメソッドをそのまま活かす

## 使い方

### DAO の定義

DAO には key の書式と種類を指定します。

``` python
import redis
from gxredis import *

class ItemDao(RedisDao):
       item = RedisString("device:{device_id}:item:{item_id}")
       item_list = RedisList("device:{device_id}:list")
       item_set = RedisSet("device:{device_id}:set")
       item_hash = RedisHash("device:{device_id}:hash")
       item_zset = RedisSortedSet("device:{device_id}:zset")
```

### DAO の初期化

redis-py の `StrictRedis` を第1引数に渡してください。第2引数には、key を構成するためのパラメータを渡します。足りないパラメータは後で補完できるので、 DAO の生成時点で確定しているパラメータだけを渡せばよいです。

``` python
client = redis.StrictRedis("localhost", 6379, 15)
dao = ItemDao(client, key_params={"device_id": "GX123"})
```

### DAO の属性

DAO の属性は redis にアクセスするためのアクセサです。

``` python
>>> dao.item
RedisString(key="device:{device_id}:item:{item_id}", key_params={'device_id': 'GX123'})

>>> dao.item_list
RedisList(key="device:{device_id}:list", key_params={'device_id': 'GX123'})
```

### 基本的な使い方

アクセサに対して、型に見合った操作が実行できます。key はアクセサに対応したものが使われるので、redis コマンドの第2引数以降を指定して下さい。

``` python
>>> dao.item_list.lpush("a")
>>> dao.item_list.lpush("b")
>>> dao.item_list.lpush("c")
>>> dao.item_list.lrange(0, 3)
['c', 'b', 'a']
```

key に対するパラメータが十分に提供されていない場合は、例外が発生します。

``` python
>>> dao.item.get()
...
AttributeError: Not enough keys are provided for redis operation
```

### パラメータを補完する

アクセサに追加のパラメータを渡して実行することで、パラメータの補完された新しいアクセサが得られます。

``` python
>>> dao.item(item_id=1)
RedisString(key="device:{device_id}:item:{item_id}", key_params={'item_id': 1, 'device_id': 'GX123'})
```

新規に生成されたアクセサに対して redis コマンドが発行できます。

``` python
>>> accr = dao.item(item_id=1)
>>> accr.set("abc")
>>> accr.get()
'abc'
```

### pipeline を利用する

pipeline も利用できます。

``` python
>>> pipe = dao.pipeline()
>>> accr1 = pipe.item(item_id=1)     # accessor for item01
>>> accr2 = pipe.item(item_id=2)     # accessor for item02
>>> accr1.set("item01")
>>> accr2.set("item02")
>>> pipe.item_list.rpush(accr1.key)
>>> pipe.item_list.rpush(accr2.key)
>>> pipe.execute()
>>> dao.item_list.lrange(0, 100)
['device:GX123:item:1', 'device:GX123:item:2',]
```

### JSON を利用する

JSON で入出力するために、一部、便利関数を用意しています。

``` python
>>> dao.item(item_id=1).set_json({'hello': 'world'})
>>> dao.item(item_id=1).get_json()
{u'hello': u'world'}
```

### SET や LIST に格納された key で MGET する

こちらも便利メソッドを用意しています。

``` python
>>> dao.item_list.lrange_mget(0, 100)
({'device:GX123:item:1', 'device:GX123:item:2'}, ['{"hello": "world"}', 'item02'])
>>> dao.item_set.smembers_mget_json(0, 0)
(['device:GX123:item:1'], [{u'hello': u'world'}])
```

`smembers_mget`, `smembers_mget_json` も使えます。

## まとめ

redis-py を安全に使うための、軽めのラッパーライブラリを実装しました。コード行数は短めなので、良かったら読んでみて下さい。

今後、key の validation 機能などを追加する予定です。


~~あ、その前に pypi に登録しなきゃですね。~~ 

PyPi 登録 Done !
aタグ内の擬似要素にはunderlineを付けたくない（IE対応）

この記事は、[早稲田大学 AdventCalender 2016](http://qiita.com/advent-calendar/2016/waseda) 15日目です。

Internet Explorerは未だ息をしています:angel:
なので、「少なくともInternet Explorer 11には対応しなければならない」案件が多いのが実態です。

今回も、ブラウザ検証中に「IEでの表示崩れ」が発生したのですが、ググっても解決策がスパッと見つからなかったので、対応策を残しておきます。

# やりたかったこと

aタグ内に擬似要素（:before)を生成して、list-style-typeの真似事をしたい。
ただ、以下の条件を満たさなければならない。

- aタグにunderlineをつけるが、
- 擬似要素にはunderlineをつけない

上記の条件を満たす解決策は、すぐに見つかります。
擬似要素のスタイルに、display: inline-blockを付ければ良い。

```html:sample
<a href="#">ナビゲーション1</a>
```

```css:sample
a {
  text-decoration: underline;
}

a:before {
  content: "▶︎";
  display: inline-block;
}
```

[DEMO](https://jsfiddle.net/93y4kdya/)


# はまったこと

ブラウザ検証を行うと、IEでは擬似要素もunderlineが付いたままだった...

IE対応をするために、解決策を挙げるとすれば、「aタグに内のテキストノードをspanで囲って、そのspanにunderlineを引く」がある。

```html:sample
<a href="#"><span>ナビゲーション1</span></a>
```

```css:sample
a {
  text-decoration: none;
}

a:before {
  content: "▶︎";
  display: inline-block;
}

span {
  text-decoration: underline;
}
```

[DEMO](https://jsfiddle.net/2qv9gpug/1/)

## だがしかし...

場合によっては、こんな状況が考えられます。

#### 納品前のブラウザ検証でこの問題が発覚した:tired_face:
- 大規模サイトの制作案件...
- 途中からアサインされた...
- 定義済みのaタグは、spanで囲ってない...
- javascriptでのDOM操作は制約的にNG...


## CSSだけで解決したい

ゴリ押しですが、こんな解決方法がありました。

[DEMO](https://jsfiddle.net/ew4qyngL/2/)

```html:sample
<a href="#">ナビゲーション1</a>
```

```css:sample
a {
  text-decoration: underline;
}

a:before {
  content: "▶︎";
  display: inline-block;
  height: 11.5px;
  overflow-y: hidden;
  font-size: 10px;
}

```

擬似要素の高さをunderlineを含まない程度に調整して、overflowをhiddenにしてしまうという方法です。

これで応急処置はできたかな、というところです。
しかし、場合によっては微妙なheightの調整が必要だったりします...

「IEではこんな表示崩れが起こるぞ！」ということを知っていれば、こんな面倒なことをしなくても済むのですが...😇

---

次は、@susuwatarinの「初心者がhubotをうんたら~の実践編です。火曜はハグの日。」です。
Reactで動的なclassNameを指定する方法

最近また睡眠時間が減ったせいか、逆流性食道炎ぎみなアトラエデザイナー、紺谷でございます。
弊社も最近、Reactを導入し始めまして、デザイナーの私としてはかるーくキャッチアップしていじってる具合であります。

以前はRailsでなんとなーくif文とか使いながらHTMLの中にゴリッと動的なclass名を割り当ててましたが、Reactになってどうも勝手が違う。
そこでちょっと調べてみたら `classnames` っていう便利なものがあったので触ってみました。

まずは `npm` で `classnames` をインストールします。

```
npm install classnames --save
```

で、以下のように利用しましょう。

```
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import ClassNames from 'classnames';


class ListItem extends Component {
  render() {
  
    const classNameForListItem = ClassNames({
      "list-item": true,
      "is-newest": this.props.status === "non-read"
    });
    
    return (
      <ListItem className={classNameForListItem}>
        ・・・
      </ListItem>
    )
  }
}

```

上記の例だと、
`list-item` が常に利用するクラスなので `true` 。
`is-newest` が `this.props.status === "non-read"` の時だけ利用するクラス。

他の書き方としては、

```
    const classNameForListItem = ClassNames(
    	"list-item",
    	{
	      "is-newest": this.props.status === "non-read"
    	}
    );

```

 と書いても上記と同じ意味になります。
 
さて、今年も残り攻めようっと。
来年はもっと攻めようっと。

みなさん良いお年を。
Go+GAE+Angular2で簡易的なWebサービスを構築

11月に学んだものを使ってシンプルなWebサービスを構築してみました。
GCP + Go + Angular2 のgoogleful的なヤツです。
夜中に少しづつ書いた超絶シンプルなモノですが、如何せんAngular2でかなり苦戦してしまい、この程度のでもトータル20～30時間くらいかかってしまいました…

https://silverfox-sample1.appspot.com/

![ss.png](https://qiita-image-store.s3.amazonaws.com/0/144652/6299633e-88bc-74f5-8a22-b4e1c3aeaa93.png)

## サービスの内容

1. datastoreに登録されているデータの一覧表示
2. 登録されているデータの編集

これだけです笑。
<font color="#f00">とりあえず今回は[ソースの公開](https://github.com/silverfox-vaice)だけを行い、ノウハウとして役立ちそうなことはピックアップして今後記事にしていく予定です。</font>
また、今後はこのソースに機能追加をしながら様々なサービスの学習を行う予定です。

## 今回やりたいこと

- go言語でREST APIを構築する
- Datastoreのレコードの登録・削除を管理者権限でのみ行えるようにする
- とにかくAngular2を使ってみる

## 実装内容

### サーバーサイドで利用したもの
- Go
- Google AppEngine
- Google Cloud Datastore

### フロントエンドで利用したもの

- Angular2 (TypeScript)
- ビルド時にSassやejs等

### 簡易シーケンス

![簡易シーケンス.png](https://qiita-image-store.s3.amazonaws.com/0/144652/351df7d8-7317-9c8f-a260-7a4c1c57df67.png)

### データの登録

https://silverfox-sample1.appspot.com/admin/

![admin_サンプル.PNG](https://qiita-image-store.s3.amazonaws.com/0/144652/d88bc641-5e7b-1737-e344-ba85c8b6457c.png)

管理権限のあるgoogleアカウントでログインしないと登録・削除が行えないため、実質利用できません。
ローカル環境でお試しください。


## ソースコード

過去の記事の内容をMIXしているだけなので、今回はソースコードの説明無しでgithubの公開だけとなります。
正直どちらもツッコミどころが満載だと思いますので、指摘内容含め随時updateをかけていく予定です。

### サーバーサイド（golang）のgithub

https://github.com/silverfox-vaice/qiita-go-sample/tree/develop

まだdevelop版ですが参考までに。
パッケージ構成等、試行錯誤しています（苦笑）

### フロントエンド（angular2）のgithub

https://github.com/silverfox-vaice/qiita-angular2-sample/tree/v_0.1.0

こちらはβ版をmasterにpush済み。v0.1.0としてreleseしています。

## ローカル実行方法

フロントエンドのangular2については[README](https://github.com/silverfox-vaice/qiita-angular2-sample/tree/v_0.1.0#qiita-angular2-sample)に書いてあるのでそちらをご参照ください。
gulpで実行している内容は以下の過去記事とほぼ同様のものとなります。

- [Angular2開発をTypeScript+Sass+ejsで行う & gulpでsrcと別ディレクトリに構築](http://qiita.com/silverfox/items/ec649b2eb1d9e6b4e188)
- [Angular2のリリース用ソースをgulp + webpack + inlineNg2Templateで1ファイル+αに圧縮してみる](http://qiita.com/silverfox/items/825409b4046095e85190)

サーバーサイドのgolangについてはまだREADMEをpushできておりません。
が、たいしたことはやっていないです。
golangとappengine sdkが動作する環境であれば、cloneしてきて`goapp serve src`で動くと思います。
一応過去記事の「[Go+GAE+Cloud Datastoreで簡単なREST APIを構築](http://qiita.com/silverfox/items/81769425e51f24e676d2)」の[この辺](http://qiita.com/silverfox/items/81769425e51f24e676d2#%E5%AE%9F%E8%A1%8C)が参考にはなると思います。

データの登録については、http://localhost:8080/admin にアクセスし管理権限のあるgoogleアカウントでログインすればデータの登録が可能です。

## 次回～やりたいこと

- API側にエラーコードを返す処理を入れる
- SearchAPIの利用
- Memcacheの利用
- Task Queueの実践的な利用
- Angular2でのテストケースの作成
- 双方向バインディングをいい感じに利用する
- **沐浴が上手くできるようになりたい**

今回の記事は本当は12月初旬に記事にする予定だったのですが、 **めでたく念願の第一子が誕生したので**2週間ほどPCに触れていませんでした。。
やや落ち着てきたので今後は定期更新を再開します。

～ではまた次回～
js 配列から目的の要素を取り除く

##お題
配列から目的の要素を取り除く。


```script.js
function removeElementFromArray(arr) {
//write your code.
 }
removeElementFromArray([1, 2, 3, 1, 2, 3], 2, 3);
```

##出力結果　

```script.js
([1, 2, 3, 1, 2, 3], 2, 3) //[1, 1]
([3, 5, 1, 2, 2], 2, 3, 5) //[1]
([2, 3, 2, 3], 2, 3) //[]
(["tree", "hamburger", 53,1,2], "tree", 53 ,2) //["hamburger", 1 ]
```


##使ったもの
[slice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/slice)
[filter()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
[splice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
[arguments](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments)

##思考の流れ
・配列から要素を取り除くにはfilter()が使えそう
→filter()の条件をどのように設定したらよいだろう?
→removeElementFromArrayの引数の配列に続く値（2,3）を取得できたら条件に設定できそうだ、、、

→配列と続く値の扱いに手こずる。なにかないかと調べる。

→"複数の文字列を連結する関数を定義する"Array.prototype.slice.call(arguments)を探し当てる。
入力してみると[[1, 2, 3, 1, 2, 3], 2, 3]が返ってくる！

→splice(0,1)で最初の配列を除いて変数にいれる。
　　配列に続く値（2,3）の取得ができた。

→filter()の条件の設定方法を考える。
→indexOf()で−1となる値(2,3に対して誤）を返るようにする。

結果、[1,1]の取得ができました。

##実行したコード

```script.js
function removeElementFromArray(arr) {
  var args = Array.prototype.slice.call(arguments); //args [[1, 2, 3, 1, 2, 3], 2, 3]
  args.splice(0, 1); //args [2,3]
  return arr.filter(function(element) { //element 1, 2, 3, 1, 2, 3
    return args.indexOf(element) === -1; 
  });
}
removeElementFromArray([1, 2, 3, 1, 2, 3], 2, 3);
```

###他にもコードが浮かんだ方、コメントお待ちしてます。
Arduino Fio + XBee Series1 で スリープモード(SM=1)を実現する

使うデバイスがそもそも古くてスーパーニッチな記事なのですが、
一応メモ程度に残しておきます。

# つかうもの

![](https://docid81hrs3j1.cloudfront.net/contents/large/615_1.jpg)
Arduino Fio
https://www.switch-science.com/catalog/615/

![](https://docid81hrs3j1.cloudfront.net/contents/large/996_1_4.jpg)
XBee Series1(ファームのバージョンは10CD)
https://www.switch-science.com/catalog/996/

# やりかた

Arduino Fio + XBee + リポ電池で単独動作可能なもの作ろうと思ったのですが、
よくよく考えるとXBeeさんスリープしてくれなくて消費電流が削れないので、
どうしようかなと思ったところ、下記の記事をみつけました。
http://www.semifluid.com/2012/09/07/arduino-fio-low-power-setup/

要約すると、
XBeeのスリープモードをSM=1に設定し、
XBeeの9番ピンで制御するようにすれば、FioのDTRが9番ピンだからいいんじゃね、
という感じの内容でした。

## はいせん

![15657817_10210948502486240_2001243968_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/2915/3eebfe11-e990-e498-4b44-557146b8148f.jpeg)

10kΩをGNDとD2のほうに挟んであげて、
D2とDTRをつないであげればok。

## ぷろぐらむ

```c++:xbee.ino
#define XBEE_SLEEP_PIN 2 // D2

unsigned long sendTimer;

void setup() {
  Serial.begin(9600);
  Serial.println("init");

  // setup sleep pin of XBee
  pinMode(XBEE_SLEEP_PIN, OUTPUT);
  digitalWrite(XBEE_SLEEP_PIN, HIGH); // disable
}

void loop() {
  // 10秒ごとに起きてping送るよ
  if (millis() - sendTimer > 10000) {
    digitalWrite(XBEE_SLEEP_PIN, LOW); // enable
    delay(50); // wait for wakeup
    
    Serial.println("ping");
    
    digitalWrite(XBEE_SLEEP_PIN, HIGH); // disable

    //delay(500); // 送信完了までちょっと待ったほうがいいかもしれない
    
    sendTimer = millis();
  }
}
```

## おまけ

FioのONと書いてるLEDは、Fio自体の電源確認用ではなく、
XBeeが起きてる時に光るようになっているので、
上記プログラムの場合10秒ごとについてるか確認することで、
XBeeが起きてくれてるか確認できます。

XBeeのスリープモードに関する記事は下記あたりがいいかも。
http://ikeyasu.hatenablog.com/entries/2008/05/31

以上、めでたしめでたし。
パラメータを引き継いでPOSTやPUTにリダイレクトっぽいことをする


誰しも一度は考えたことがあると思います、**POSTやPUTにリダイレクトしたい・・・できればパラメータも引き継いで**、と。

しかし、HTTP/1.1 プロトコルの制約があるため、これを実現するのは不可能だと思われます。

ググってみると、sessionにパラメータを一時的に保存して、ページ遷移後に復元するという方法を見かけました。

[RailsでPOSTリクエストではリダイレクトできないことへの対応](http://easyramble.com/cannot-post-redirect-on-rails.html)

しかし、この方法はGET以外にリダイレクトさせたい場合は手間が増えますし、汎用化も難しい気がします。

そこで、別の方法を考えてみました。

## 概要

実現方法をざっくり説明すると、**空ページをrenderし、そこに引き継ぎたいパラメータを埋め込んだフォームを設置して自動サブミットする**、と言う感じです。特定の処理専用にこれを実現するのは簡単ですが、今回は汎用的に実現する実装を行いました。

## 実装:paramsをhidden_field_tagに展開

まずはapplication_helperあたりに下記のようなメソッドを定義します。今回はhelperに定義しましたが、viewから呼び出せればどこでも構いません。

```rb
def parse_from_params(params, anc = nil)
  @tags ||= []
  params.each do |row|
    key = if anc
            f, b = anc.split
            f + "\[#{row.first} \]" + b.to_s
          else
            row.first.to_s
          end
    if row.last.is_a?(Hash)
      parse_from_params(row.last, key)
    else
      @tags << hidden_field_tag(key.delete(' '), row.last)
    end
  end
  @tags.reduce(:+)
end
```

かなり雑にコーディングしたので分かりにくい思いますが、簡単に説明すると、**paramsを再帰的に分解して、hidden_field_tagを生成する**、って感じです。

例えばparamsが以下のような状態の場合、

```rb
params = {a: 1, b: {c: 2, d: 3, e: {f: 4}}}
```

`parse_from_params`は以下のhidden_field_tagを生成します。

```rb
hidden_field_tag "a", 1
hidden_field_tag "b[c]", 2
hidden_field_tag "b[d]", 3
hidden_field_tag "b[e[f]]", 4
```

## 実装:踏み台viewをrenderするメソッド

次に、application_controllerあたりに以下のメソッドを定義します。

```rb
private

def redirect_keeped_params(url, **options)
  @url = url
  params_option = options.first
  @params = { params_option.first => params_option.last }
  @method = options.last.last
  render_text = <<-EOS
    <%= form_tag @url, method: @method, id: "redirect_form" do %>
      <%= parse_from_params(@params) %>
      <%= javascript_tag 'document.getElementById("redirect_form").submit()' %>
    <% end %>
  EOS
  render inline: render_text
end
```

先ほどhelperに定義した`parse_from_params`によって生成されたhidden_field_tagを含むフォームが埋め込まれた空ページをrenderします。そして、描画されたら自動でsubmitし、引数で指定したurlに遷移します。

## 使用例

例えば、以下のようなcontrollerがあるとします。

```rb
class HogeController < ApplicationController

  def new
    〜 #何らかの処理
  end

  def create
    〜 #何らかの処理
  end
end
```

この`HogeController`のcreateアクションに、外部のcontrollerからリダイレクトしたい場合を考えます。createアクションのurlは、`hoge_url`とします。

controller側の処理としては、リダイレクトしたいタイミングで`redirect_keeped_params`を呼び出すだけです。引数には遷移先のpathと、渡したいパラメータ、遷移先のリクエストメソッドを指定します。

```rb
class FugaController < ApplicationController

  def new
    〜 #何らかの処理
    redirect_keeped_params(hoge_path, fuga: permited_params, method: :post)
  end

  private

  def permited_params
    params.require(:fuga).permit(以下略)
  end
end
```

このように、普段`redirect_to`を使ってるような感覚で、POSTやPUTに遷移することが可能です。

## 最後に

力技ではありますが、最小限の実装で目的を実現することができました。しかし、この方法にはいくつか問題もあります。例えば、ページ遷移時に一瞬白いページが表示されてしまうことです。ユーザビリティ的にはあまり影響はありませんが、やはりスマートではないので、何か対策を考えたいです。他にも、ブラウザバック時の挙動も考えたほうがよさそうです。現状だとブラウザバックすると、踏み台ページに遷移し自動サブミットになるので、結局バックする前のページに戻ってしまいます。

まあそもそも、このような手法を検討しなければならないようなアプリケーションは、基本的な設計から見直すべきかもしれませんが・・・
上、真ん中、下で覚えるバージョニング範囲指定

前に node の package.json の中での semver を使ったバージョン範囲の指定方法について[メモを書いた](http://qiita.com/takayukioda/items/359ed79e881ea7578291)けど、もう少し覚えやすそうな覚え方を思いついたからメモ

## おさらい
`^`: Minor Range
Major バージョンまでを固定して、Minor バージョン以下を可変にする

`~`: Patch Range
Minor バージョンまでを固定して、Patch バージョンを可変にする

## 新しい覚え方
バージョンを `^`.`~`.`_` という記号で表すと考えてしまう。
Major バージョンは一番上の `^`
Minor バージョンは真ん中の `~`
Patch バージョンは一番下の `_`

そうすると
`^x.y.z` は一番上のバージョンを固定してる => `x`.`~`.`_`
`~x.y.z` は真ん中までのバージョンを固定してる => `x`.`y`.`_`
`_x.y.z` は一番下のバージョンまでを固定してる => `x`.`y`.`z`
`_` は結局普通にバージョン書いてるのと変わらないので省略
と捉えられる。
記号の位置関係とバージョンの位置関係をうまく紐付けられて、わかりやすくなった。

言語とか、ライブラリで変わったような気もするから、あまり過信はできないけど :P
（Gemfileとか違った気がする）
pingで使用中のIPアドレスを調査

#Windowsのbatファイル
pingとarpコマンドを使って使用中のIPアドレスを調査する。
応答が返ってきたIPアドレスは使用中である。
arpコマンドでIPアドレスとMACアドレスの対応がわかる。

```bat:pingAll.bat
@rem ping all

for /L %%f in (1,1,254) do ping -n 1 -w 50 192.168.0.%%f >> pingAll.log

arp -a >> arp.log

pause
```
※バッチファイルから実行する場合には変数を%%fとすること。
QGISでタイル地図を手抜きで作る方法

QGISでタイル地図を手抜きで作る方法
=

WEB地図で使用できるタイル地図を**手抜き**で作る方法です。
手抜きなのでちゃんと作ってる人に怒られそうな気がしますが、こんな作り方もあるよ、ということで共有しておきます。

まずは作ったものを見ていただきましょう。
[OpenLayers3で表示したデモページ]

1. QGISで調製
2. プリントコンポーザを起動
3. ワールドファイル付きで出力
4. ```gdal_translate```でGeoTiffを作る
5. ```gdal2tiles.py```を実行

### QGISで調製

適当に調製します。ここでは試しに基盤地図情報10mメッシュ標高データから作成した八溝山の地図を出力します。

![QGISで調製](https://qiita-image-store.s3.amazonaws.com/0/154454/97f5cd17-2a7b-edf4-f1e2-52bfc8cd0539.png)

なおレイヤーは以下の通り

- 標高
- 陰影図
- 傾斜量図
- Morphometric Protection Index

一番最後の**Morphometric Protection Index**はQGISのツールボックスで利用できるSAGA GISで生成できるもので、このレイヤーによって尾根は明るく、谷は暗く表現することができます。

なお基盤地図情報を使って新たに地図を作成しウェブで公開する場合は、測量成果の複製・使用承認の申請が必要です。（正直このデモページもグレーゾーげふんげふん）

### プリントコンポーザを起動

![プリントコンポーザで位置を調節](https://qiita-image-store.s3.amazonaws.com/0/154454/a036db5c-27c2-79f8-74b7-e214ca795f69.png)


QGISの地図を画像やpdfで出力したい場合は**プリントコンポーザ**を利用します。
タイルにしたい範囲を適当に調整し、プリントコンポーザで出力します。

### ワールドファイル付きで出力

QGISのプリントコンポーザでは、生成した画像（jpgやtiff）と共に**ワールドファイル**という位置情報を持ったファイルを生成することができます。
ちなみにプリントコンポーザで出力する画像のサイズは紙のサイズ（mm）と解像度（dpi）の組み合わせに依ります。
例えば、A4サイズ(210mm x 297mm)、300dpiでpngファイルを出力すると画像のサイズは2480px x 3508pxとなります。

ここでは適当にA4サイズ、600dpiとしておきます。

地理情報を持たない画像ファイル**A.png**とワールドファイル**A.pgw**が生成されます。

### ```gdal_translate```でGeoTiffを作る

ワールドファイルについてですが、自分もあまりよくわかってないのですが、これによって、地理情報を持たない画像ファイルA.pngは地理情報を持つ画像ファイルとして振る舞うようになります。試しにQGISでA.pngをラスターレイヤーとして追加してみてください。A.pngは地理情報を持っていないにも関わらず正しい位置に配置されるはずです。

![A.pngは正しい位置に配置される](https://qiita-image-store.s3.amazonaws.com/0/154454/14e059f0-92f2-3078-c385-70d3fc4f2e6a.png)

GDALのコマンド```gdal_translate```でA.pngから地理情報を持つGeoTiffファイルを作成します。
ちょっと待って、A.pngはワールドファイルによって地理情報を持つように振る舞うのだから、この行程必要ないんじゃないの？と思いますが、それだと```gdal2tiles.py```が正しく動きません（理由はわからない）。よって必要な行程となります。

コマンドラインを起動します。

```
  gdalinfo --version
```
と打って、GDAL Frameworksにパスが通ってるかどうかを確認してください。

次にA.pngを保存したディレクトリに移動して、

```
  gdal_translate A.png B.tiff
```

と打ちましょう。新たに地理情報を持つGeoTiffファイル**B.tiff**が生成されます。

### ```gdal2tiles.py```を実行

```
  gdal2tiles.py -r "bilinear" -s "EPSG:3857" -z "11-14" B.tiff
```

オプションの```-r```は生成するタイル画像のデフォルトは```"average"```ですが、ここでは```"bilinear"```（バイリニア法）に設定しています。
続いて```-s```というオプションですが、変換元の投影法です。```"EPSG:3857"```（Google WEBメルカトル）を設定します。
最後に```-z```というオプションですが、これで生成するタイルのズームレベルを指定できます。本来なればインプットする画像（ここではB.tiff）のサイズから画質の劣化なく生成できるサイズを計算し指定するのが望ましいと思うのですが、手抜き法なので適当にズームレベル11から14と設定します。
オプションの詳しい説明は[gdal2tilesのドキュメント]を参照ください。

[OpenLayers3で表示したデモページ]

QGISで調製した地図を手抜き法でタイルにするのはあまり良い方法ではないかもしれませんが、ワールドファイルを使って地図画像を制御する方法は意外と応用が効くかもしれません。

例えば、

1. A4サイズの白地図とワールドファイルを生成
2. 白地図に手書きで書き込み
3. 白地図の解像度と同じ解像度でスキャン
4. ワールドファイルをスキャンした地図に使って```gdal_translate```
5. ```gdal2tiles.py```でタイル化

というようなこともできるのではないかと思います。

[OpenLayers3で表示したデモページ]: http://map310.com/demo/yamizo.html
[gdal2tilesのドキュメント]: http://www.gdal.org/gdal2tiles.html
Vue.js 2.0のパフォーマンスについて


Vue.jsがリリースされてから1.x系については触っていたのですが、2.x系に更新されてからはまだ触れていなかったので、改めて2.xについて調べてみました。

以前1.xで色々試していた頃と現在を比較するとドキュメント（特に日本語ドキュメント）が充実したなあと感じました。:relaxed:
また、参考になる情報やコミュニティなど以前と比較して大変増えているようです。
そういう点からは他のフレームワークと比較しても、非常に取り掛かりやすいフレームワークといえると思います。
（学習コストが低い点も大きなアドバンテージ）

## Vue 2.0 でパフォーマンスがさらに向上!?

Vue.jsの2系のドキュメントを調べていると、パフォーマンスが大幅に向上したとの記載があり、興味があり調べて見ました。
以下は他フレームワークと比較した数値です。
（数値が低いほうがパフォーマンスが高い）

![1-Lu6OJiraJYShl4aBppoh3w.png](https://qiita-image-store.s3.amazonaws.com/0/47083/cc5e7f98-cae9-4270-75ff-3ebbaf92f4a4.png)

もちろんフレームワークには向き、不向き、得意、不得意があるので、純粋に上記が早いからといって必ずしも全ての点で優れているとは考えてはいませんが（各フレームワークには一長一短があるので）、こと表示系のパフォーマンスに関して言えばほとんどのケースにおいてVue.jsが優位にあるようです。
Vue.jsは小回りがきくライブラリという点でパフォーマンスが優れているのはやはり魅力です。

さて、上記グラフを見ていて目を引いたのがVue1.X系と比較して2.xで大幅にパフォーマンスが改善されている点です。(2.16x→1.37x!?)

## 2.0でパフォーマンスが向上したワケ！？

簡単に2.0でパフォーマンスが向上した理由について調べてみました。
誤解を恐れずに言ってしまえば、以下の２点のようです。  

1. Virtual DOMを導入
2. 軽量化

### Virtual DOMを導入
Virtual DOMについては端的に言ってしまうと、実際のDOM操作は非常に重いため、通常DOMにアクセスはせず、更新などの必要な場合のみ必要な部分のみDOM更新を行うような仕組みです。

Virtual DOMはアドベントカレンダーの7日目の、@chi-bdさんが大変わかりやすくまとめておりますので、そちらを見ていただくのが良いかと思います。（ありがとうございます）:relaxed:

MVVMの双方向データバインディングを単一方向のみに限定することで速度更新が図れるようです。
Virtual DOMの仕組みもVue.jsは最適化が図られているようでそちらもパフォーマンスに寄与しているようです。(自動でVIrtual DOMにしてくれるような仕組みのようです)


### 軽量化
ライブラリ自体の軽量化はもちろんですが、Virtual DOMも軽量化が図られているようです。

![軽量化](https://cdn-images-1.medium.com/max/1600/1*xV2_bx4eWC9RXiBZjeAMrw.png)

こちらのグラフですが、ランタイムのみのビルドはわずか 16kb（min+gzip時）とかなり軽量です。
vue-router と vuex を含めても合計 26kbであり、1.0xよりも圧倒的にパフォーマンスが改善されているようです。
また、初期レンダリング速度やメモリ消費量が圧倒的に抑えられているようで、パフォーマンス向上が図られているようです。

# まとめ
Virtual DOMの仕組みを導入したことがVue2.0でのパフォーマンス向上に大きく寄与したようです。
さらにただ、単純にVirtual DOMを導入しただけでなく、そのあたりの仕組みが考慮されている点が大きいと思います。
今後は１．x系で作成したものを2.x系に移行してみたいと思います。
今回の調査を行ってみて、以前1系で試していた頃より、調査がものすごく楽になったように感じました。
extensionでストアドプロパティもどきを追加する（リーク付き）

```swift
fileprivate var objects:[Int:AnyObject] = [:]

extension Hoge {
    var appended: AnyObject? {
        get {
            return objects[hash]
        }
        set {
            objects[hash] = newValue
        }
    }
}
```

`AnyObject`のところは型が明確であるならそれで。
Stringのような`hash`が特別な値になるクラスでは使えません。
あと、後始末してないのでリークします。

デフォルト実装のhashは生成と削除の回数が多い場合コンフリクトしやすいので注意。
*（デフォルト実装のhashはオブジェクトのアドレスを返してるだけです）*
*（後始末をしてないので以前使われた値が残っていればそれが使われます）*


**追記**
### 使用上の注意
`hash`プロパティは主に重い処理となりうる`isEqual(_:)`を高速化するためのプロパティでその**一意性は保証されていません**。
そのため、別のインスタンスのhashが同じ値となることが往々にしてあります。
例えばStringはその文字列が同じであれば別のインスタンスであっても同じhashを持ちます。

hashが同じ値を持つインスタンスが存在する場合この実装は**破たんします**。

この実装を使う場合は、その点を十分理解の上お使いください。
.NET Framework のプログラミング言語

# .NET Framework の概要
https://msdn.microsoft.com/ja-jp/library/hh425099(v=vs.110).aspx)

.NET Framework はランタイム実行環境ということなので Java でいう JRE と同等の役割を担っていると考えて良さそうだ。

.NET Framework の概要に下記記載とそれに含まれるリンクがあるが 404 となっている。

> .NET Framework のアプリケーションを開発できるプログラミング言語は、[共通言語基盤 (CLI) 仕様](http://go.microsoft.com/fwlink/?LinkId=199862) に準拠します

## プログラミング言語

「.NET Framework のアプリケーションを開発できるプログラミング言語」で検索すると、下記ページが見つかった。
https://msdn.microsoft.com/ja-jp/library/aa292164(v=vs.71).aspx

Visual Studio .NET 2003 に紐付いた情報のようなので現在の状況とは異なる可能性あり。

- Visual Basic .NET
- Visual C# .NET
- Visual C++ .NET
- Transact-SQL
- Windows Script Host
- VBScript
- JScript
- XML
- Visual J++
- COBOL for Microsoft .NET
- Perl for Microsoft .NET
- Eiffel for Microsoft .NET
- Python for Microsoft .NET
- Pascal for Microsoft .NET
- Mercury for Microsoft .NET
- Mondrian for Microsoft .NET
- Oberon for Microsoft .NET
- Salford FTN95 (Fortran) for Microsoft .NET
- SmallTalk for Microsoft .NET
- Standard ML for Microsoft .NET
- Dyalog APL for Microsoft .NET

## 共通言語基盤 (CLI) 仕様

「共通言語基盤 (CLI) 仕様」で検索すると、下記ページが見つかった。
https://msdn.microsoft.com/ja-jp/library/cc825639.aspx

古い情報なのかページのリンク切れが怪しい。
Lucene/Solr の数値フィールドについて

この記事は Solr Advent Calendar 2016 の 21日目です。
数値を扱うフィールドに焦点を当てたいと思います。
Solr と言いつつコアとなっている Lucene 側の話がメインですが、きっと大丈夫だと信じています。

# Lucene 6.0 から加わった新しい数値フィールド
Lucene 6.0 から、数値を表すフィールドとして、`IntPoint`, `LongPoint`, `FloatPoint` などの「ﾅﾝﾀﾗPoint」というフィールドが追加されました。それまでに存在していた `IntField`, `LongField`, `FloatField` などの数値フィールドとの違いの一つは、多次元空間における点の座標を表すことができるという点です。例えば、(x, y, z) といった座標をドキュメントに持たせようとしたときに、`FloatField` を三つ用意する必要があったところが、`FloatPoint` 一つで表現できるようになります。

この新しいフィールドは昔のフィールドをただ束ねたものではなく、レンジによる検索や距離による検索が速くできるような工夫が施されています。
Point 系のフィールドは通常の転置インデックスの構造はとっておらず、[k-d tree](https://ja.wikipedia.org/wiki/Kd%E6%9C%A8) をベースとした構造になっています（正確に言うと Block k-d tree という構造をとっています）。Lucene の実装では、切り分けられた空間の中で最も幅が広くなる次元を選択し、その次元の中央値となる点を通るようにさらに空間を切り分ける、ということを再帰的に繰り返します。切り分けた空間の中で点の数がある程度まで少なくなったらそこで切り分けるのをやめます。こうすることで、空間を木構造に分けたうえで、点の密度が高いところは細かく、点の密度が低いところは粗く分割されるようになっています。
ある領域に含まれる点を検索する際は、木の根ノード（空間全体）から、子ノード（分割された空間）に向かってたどっていき、調べたい領域とノードの対応する領域が重なっている場合は探している点が存在する可能性があるということを利用していきます。調べたい領域にノードの対応する領域がすっぽりと包まれている場合はそのノードの先は全てヒットした点ということになるので、いちいち全ての点を調べることなく検索が実現できます。

と、ここまで文字だけで説明を書いてきましたが、何だか小難しくなってしまったので、次のElastic社のブログの記事の中の動画を見ると良いかと思います。
https://www.elastic.co/blog/lucene-points-6.0
Block k-d tree を利用した検索の様子を可視化した動画が貼ってあります。k-d tree がどんなものか何となく感じ取れるのではないでしょうか。ちなみに上の記事は dimensonal points の紹介記事で、本記事もこちらの内容を大いに参考にして書いています。

多次元の座標をドキュメントに入れることはないので、あまり関係のない話だと思う方もいらっしゃるかもしれませんが、そうとも言い切れません。二次元でも一次元でも、以前の数値フィールドに比べて検索・更新ともに速く、インデックスサイズ・ヒープ使用量も小さくなっているという結果が、先ほどの Elastic 社のブログ記事に記されています（ブラウザによっては一部の図が見られなくなっているようです）。この記事は Lucene 6.0 が出たころのものですが、その後も Point のインデックス構造の改善は進められている（[LUCENE-7371](https://issues.apache.org/jira/browse/LUCENE-7371)、[LUCENE-7563](https://issues.apache.org/jira/browse/LUCENE-7563)）ので、さらに圧縮率や速度などは良くなっているかもしれません。

# 一方 Solr は・・・
さて、ここまで Lucene に加わった数値フィールドの良さを紹介してきましたが、Solr Advent Calendar なので Solr の数値フィールドの話をします。

**残念ながら、Solr では Point 系のフィールドは利用されていません。** (v6.3.0 時点)

Solr 側のフィールドであるところの`TrieIntField` や `TrieFloatField` などは、Lucene の旧式の数値フィールドを使い続けています。ちなみに 5 系までは `IntField`, `FloatField` というような名前だった旧式のフィールド達は 6.0 でその名前を `LegacyIntField`, `LegacyFloatField` に変えられ、7.0 からはパッケージも `org.apache.lucene.document` から `org.apache.lucene.legacy` に移される予定となっており、なかなか憂き目にあっています。

Solr 側も何も対応していないというわけではなく、Point 良さそうだから使ってみよう、というチケットは上がっていて、たまに更新されています。
https://issues.apache.org/jira/browse/SOLR-8396
Lucene 側としては旧式のフィールドを使わせない方向に動いているので、きっと Solr 側もそのうち対応してくれることでしょう。

# まとめ
本記事のまとめです。

- Lucene の新しい数値フィールド `*Point` は「多次元、速い、小さい」といいことずくめ
- 現状だと Solr は昔の数値フィールドのまま

Solr を利用している人にとってはあまり役に立たない内容になってしまい恐縮ですが、いつか Solr の数値フィールドが Point 系に移行したときに薄ぼんやりと思い出していただければ幸いです。
OpenLayers3で地図を乗算合成する

(追記 2021/02/01)
OpenLayers v6 以降では地図の乗算合成が CSS で実装可能になりました。
**この記事のコードは OpenLayers v5 以前でしか使えません**。

v6 以降の実装方法については↓の記事をどうぞ
OpenLayers で地図をグレースケールにしたり乗算合成したり
<https://qiita.com/cieloazul310/items/19de09ffdd3c1df8a396>

---

普段GISやPhotoshopを使っている方ならWEB地図のレイヤーも乗算で合成したくなりますよね？
OpenLayers3では、canvasの```globalCompositeOperation```属性を使って簡単に乗算合成ができます。

### サンプル（地理院地図+色別標高図）
[デモページ](//cieloazul310.github.io/demo/multiply.html)

#### html
```html
<div id="map" class="map"></div>
```

#### JavaScript
```JavaScript
//色別標高図のレイヤーオブジェクトを作成
const relief = new ol.layer.Tile({source: new ol.source.XYZ({
				url: "http://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png",
				attributions: [
					new ol.Attribution({html: "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>"})
					],
				minZoom:5,
				maxZoom:15
				}),
			title: "色別標高図",
			visible: true
		});

//地理院地図のレイヤーオブジェクトを作成
var cjstd = new ol.layer.Tile({
			source: new ol.source.XYZ({
				url: "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
				attributions: [
					new ol.Attribution({html: "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>"})
					],
				minZoom:5,
				maxZoom:18
				}),
			title: "地理院地図",
			visible: true
		});

cjstd.on("precompose", function(evt){
	evt.context.globalCompositeOperation = 'multiply';
});
cjstd.on("postcompose", function(evt){
	evt.context.globalCompositeOperation = "source-over";
});

var map = new ol.Map({
		target: "map",
		view: new ol.View({
				center: ol.proj.fromLonLat([140.4599, 36.3696]),
				zoom: 14
			}),
		layers: [relief,cjstd]
	});
```

OpenLayers3で地図を表示する一般的なコードに、

```JavaScript
cjstd.on("precompose", function(evt){
	evt.context.globalCompositeOperation = 'multiply';
});
cjstd.on("postcompose", function(evt){
	evt.context.globalCompositeOperation = "source-over";
});
```

を付け足すだけで、乗算合成が可能になります。


### 参考

- [ol.render.Event (OpenLayers API Doc)](http://openlayers.org/en/latest/apidoc/ol.render.Event.html#event:precompose)
- [Blend Modes(OpenLayers Examples)](http://openlayers.org/en/latest/examples/blend-modes.html)
- [globalCompositeOperation(MOZILLA)](https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation)
SPLITをARRAYFORMULAさせるために使っていた数式が動かなくなった件


SpreadsheetのSPLIT関数は、ARRAYFORMULA関数では動作しません。

その解決策として以下のような数式を使っていました。

`=ARRAYFORMULA(IFERROR(REGEXEXTRACT(","&input!G2:G,"^"&REPT(",+[^,]+",COLUMN(OFFSET(A1,,,1,6))-1)&",+([^,]+)")))`

参考：[ARRAYFORMULA() does not work with SPLIT()](http://stackoverflow.com/questions/26137115/arrayformula-does-not-work-with-split)


それが 2016/12/19 前後から動かなくなっています。
原因は不明ですが、全く違う2つのファイルが両方とも動かなくなっていたので、仕様変更かな？

`OFFSET(A1,,,1,6)` のあたりを `OFFSET(A1,,)` とかにすると動きますが、単一の列にしか展開してくれません。
第５回 Web API を利用するには？ ～コーディング編：CData API Drivers～

#はじめに
[前回](http://qiita.com/yugoes1021/items/1b72b582c19e32ee203f) は Web API に接続可能な EAI ツールを紹介させていただきました。

前回までが、ノンコーディングで使用できるものでしたが、今回はいよいよコーディングをするパターンになります。
ですが、ソースコードは一切載せません('◇')ゞビシッ

代わりに CData さんの API Drivers をどういったときに利用するのか。
ここに注力してお話させていただきます。

#コーディングが必要な時
ここまでノンコーディングで Web API につなぐお話をしてきましたが、確かにこれだけ簡単に接続することができると、「いったいどういったときにコーディングが必要になるの？」って思いますよねw

大丈夫です。それを説明するのが今回です。

[CData API Drivers]
https://www.cdata.com/jp/drivers/default.aspx

CData API Drivers は、繋ぐ先がデータベースはもちろんのこと、 SaaS であろうとADO.NET を使用して、SQL にてデータが取得できるという、素晴らしいツールになります。接続先の API のお作法を気にせず、すべて SQL で接続できるというのは、開発者のリソースを広げなくてよいという利点があります。

#きめ細かな制御が必要な時
これはわかりやすいですよね。SaaS や PaaS を使用すると、確かに簡単に API に接続できますが、きめ細かな制御、例えば入力チェック、レスポンスデータの整形等は、ツールやサービスでは、正直限界があったりします。

また順次処理ではなく、同時に複数のサービスを呼び出さなければいけないようなときもコーディングが必要になります。

あるいは複雑な条件分岐やエラー処理が必要とされる場合も、コーディングが必要になるかもしれません。
「ある条件の時は A というサービスからデータを取得するが、別の条件の時は DB からデータを取得する」といった場合は、ツールやサービスでは難易度がグッと上がります。

ほかにはトランザクションを厳密に管理する必要がある場合もコーディングを必要とするかもしれません。

#求められる「選択」
以上のように、様々な要件は考えられますが、結局のところ、実現するための費用対効果。これに尽きると思います。運用面まで含めて、ノンコーディングのサービスやツールで行くのか、CData のようなコンポーネントを使用して接続先を意識することなく、自分たちのサービス実現を目指すのか。

これは選択になります。優劣はつけられません。
大事なことは、まずは API を呼び出すと一言で言っても、多種多様な方法があるということを知ることです。

取りうる方法を知ってから、2年後、3年後、10年後を意識して、どうあるべきか。どうあることが最適かを考え、選択することが必要不可欠となります。この選択は、すなわちビジネスを選択すること、方針を決めることになります。

#最後に
5回に渡って、Web API を利用する方法をご紹介してきました。
この5回で皆様がいろいろな可能性を模索して、自分が実現したいことにはどれが適切なのか。これを考えるきっかけになれば、幸いでございます。

最後まで読んでくださった方に、心より御礼申し上げます！
MagentaのDQNについてまとめてみた

# 概要
今更ですが、Magentaで公開されたDQNを用いた音楽生成についてまとめてます。
DQN、LSTMを知っている人向けです。
https://magenta.tensorflow.org/2016/11/09/tuning-recurrent-networks-with-reinforcement-learning/

# 従来の方法
LSTMを用いて行っています。
時間tでなっている音が入力、時間t+1でなっている音が出力＆ラベルとなっています。
Lookback RNNやAttention RNNというものを使ってやっていたりもしますが、DQNの仕組みを学ぶ上では必要ありません。
上の2つを知りたい方は[ここ](https://magenta.tensorflow.org/2016/07/15/lookback-rnn-attention-rnn/)にのってます。

# DQNを用いた方法
モデルの画像は上に記載したURLで見てください。
音楽生成でDQNを用いる場合に一番気になるのは報酬だと思います（私はそうでした）。
なので、どうやって報酬を決めているのかを書きます。

## 報酬
現在の状態(s)と行動(a)から報酬を求めるにあたり、Music Theory RulesとReward RNNの2つを用いて行います。
Music Theory Rulesはdomain knowledgeと[この本](http://www.jstor.org/stable/40213921?seq=1#fndtn-page_scan_tab_contents)に基づいて作成しています。
Reward RNNは、従来使っていたRNNがsにおけるaの確率を求めるものになっているのでこれを用います。
Music Theory Rulesを$r_{MT}(a,s)$と表し、Reward RNNは$p(a|s)$で表します。
そして、報酬は下記の式になります。

```math
r_t(a,s) = \log p(a|s) + \frac{1}{c}r_{MT}(a,s)
```
ここでのcはどのくらいMusic Theory Rulesに重点を置くのかというハイパーパラメータになっています。
この報酬関数を用いると損失関数は

```math
L_t(\theta_t)=(r_t(a,s)+\gamma  \max_{a′}Q(s′,a′;θ_{t−1})−Q(s,a;\theta_t))^2
```
のようになります。
二条誤差を使っているようですね。
他にも[ψ Learning](http://homepages.inf.ed.ac.uk/svijayak/publications/rawlik-RSS2012.pdf)や[K Learning](https://arxiv.org/pdf/1512.08562.pdf)も使って比較しているようです。
あとは、体験再生(experience buffer)やdeep double Q Learningを用いて学習しているそうです。
実際にこれらを使って作成した音楽も聞けるので一回きいてみてください。

# 最後に
MagentaがDQNを用いた音楽生成をやった！ということは聞いていたのですが、なかなか調べる機会なかったのでこの機会に調べました。
報酬に従来の方法で使っていたLSTMを使うって発想がいいですねー。
Music Theory Rulesって入れなくてもうまく学習するのでは？という疑問が最後に残ったので今度自分のPCで走らせてみます。
あ、ちなみにインターンが作ったみたいです。
コード見たけど他のモデルとかと書き方が違ってて、むむむっとなったのはインターンが作ったからみたいですねー。
金融系インフラSIerがAnsibleを勉強しようと考えた理由

#はじめに

この記事は[Ansible Advent Calendar 2016]の22日目です。
[Ansible Advent Calendar 2016]:http://qiita.com/advent-calendar/2016/ansible

普段は金融系の会社でSIerをしている者です。

業務では、Ansibleはおろか、構成管理の自動化とは一体。。。というような現場で仕事をしている者なのですが、なぜそんな私がAnsibleに興味を持ち、勉強しているかという理由を記載したいと思います。


#Ansibleを勉強しようと考えた理由

Ansibleを勉強しようとした大きな理由として、DevOpsの考え方に共感したことがあります。

私自身、今の現場で働くにあたり、次のようなモヤモヤした気持ちを抱えていました。
・開発者と運用者の仲が悪い。。。
　コミュニケーション不足から、思わぬミスが発生すること。
・設定変更等はすべて手作業で行っており、ダブルチェックを実施しているものの、
　オペレーションミスが発生してしまっていること。
・変更管理の履歴管理が煩雑化しており、管理漏れからミスが発生することがあること。

そんな中、DevOpsの考え方に出会い、**「これだ！！！」**と思ったわけです。

DevOpsのとは、
>>ソフトウェア開発手法の一つで、開発 (Development) と運用 (Operations) を組み合わせたかばん語であり、開発担当者と運用担当者が連携して協力する開発手法をさす

手法とされています。

開発担当者、運用担当者が連携して協力するために、共通のツールを用いることも多く、
そのツールの一つが**Ansible**になります。


#DevOpsの中でのAnsible
Ansibleは、**「構成管理」**と呼ばれる、OSやミドルウェアの設定作業を自動化するツールになります。
構成管理ツールはAnsibleの他にChef、Puppetなどがありますが、私がAnsibleを選択した理由としては大きく以下の理由があります。

・設定ファイルがYAML形式であり、インフラ屋でも理解しやすい
　YAML形式とは、構造化されたデータを表現するためのフォーマットです。
　わかりやすいシンプルな記載ができます。
　![スクリーンショット 2016-12-22 0.00.17.png](https://qiita-image-store.s3.amazonaws.com/0/81895/e7114d9b-9afa-2e56-2338-710496381090.png)

・エージェントレスのため、管理コストが低い
　エージェント型では、管理する側の「マネージャ」と、管理される側の
　「エージェント」で構成されます。
　エージェント型は細かい管理ができるものの、管理対象のサーバすべてにエージェントを
　導入する必要があり、導入コストが高いことがデメリットです。
　一方、エージェントレス型は、管理する側の「マネージャ」のみで構成されます。
　エージェント型と比べ導入コストが低いことがメリットです。


Ansible、Chef、Puppetの比較は以下の通りです。

![スクリーンショット 2016-12-21 23.18.30.png](https://qiita-image-store.s3.amazonaws.com/0/81895/03268941-bc63-c52d-d02b-cc19b1b29ffd.png)


#勉強している書籍

###IT技術者のための現場ノウハウ Ansible実践ガイド

![スクリーンショット 2016-12-21 23.29.47.png](https://qiita-image-store.s3.amazonaws.com/0/81895/e2b8a986-776c-b3ae-45af-076e85a3dd19.png)


http://book.impress.co.jp/books/1115101157

DevOpsの説明から、Ansibleの構成などが丁寧に記載された良書だと思います。
当分はこちらで勉強予定。

###初めてのAnsible

![スクリーンショット 2016-12-21 23.32.43.png](https://qiita-image-store.s3.amazonaws.com/0/81895/9c4e9469-7f56-ab62-a385-0d0f863c10f9.png)

http://www.oreilly.co.jp/books/9784873117652/

オライリーのAnsible本。初めての、と記載はあるものの、中級者よりな気がします。

#まとめ
Ansibleを勉強しようとした理由をまとめました
まだまだ勉強不足もあり、技術的なところは全然記載できませんでしたので、
他の方のAnsible記事を参考に勉強させていただきます。
今後としては、少しずつでもいいので現場でこの動きを取り入れられたら。
(新しいものを入れるハードルはめちゃくちゃ高いので、難しそうですが。。。)
Facebook Messenger chat bot on AWS Lambda

Facebook and Line both announced their own messenger bot platform. Tried to develop a sample bot on AWS Lambda.

Network diagram
![Screenshot from 2016-12-22 00:06:10.png](https://qiita-image-store.s3.amazonaws.com/0/149869/ddf7d811-acfa-ce7d-4b12-e51526870414.png)

Took some time to get the HTTP request passed from AWS API Gateway to AWS Lambda function. Choose to do it in Node.js as I found an example online in medium blog.

Developed a simple bot that spill out the suggested recipe if you send him the ingredients.

For example, you send "Tomato egg" to the bot, it will response with recipe link and photo.

![recipe-bot.PNG](https://qiita-image-store.s3.amazonaws.com/0/149869/470ceb30-7503-596c-afd9-e7da30aa29f4.png)

Reference
https://medium.com/@igorkhomenko/run-facebook-messenger-chat-bot-on-aws-lambda-2fa800a67d76#.s01lov2ib
初めてのnativecast

こんにちは、Perl 6アドベントカレンダーの22日目の投稿になります。
昨日は、@magnolia_k_さんの、[Perl6の中を覗いてみる](http://qiita.com/magnolia_k_/items/a59587634a51b7144666)でした。
今日は[nativecast](https://docs.perl6.org/language/nativecall#sub_nativecast)の使い方を紹介しようと思います。

# イントロダクション

+ 20日目で紹介した[NativeCallを使ったプログラムの一部だけを最小構成で再現する方法](http://qiita.com/titsuki/items/568384788f1c7178d6c7)のファイルを下記のように書き換えましょう

+ 関数`load`は`void*`型の与えられた引数をそのまま返す関数です

```c:example.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "example.h"

#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT extern
#endif

void* load(void* payload) {
    return payload;
}
```

```c:example.h
#if ! defined(HEADER_EXAMPLE_H)
#define HEADER_EXAMPLE_H

#ifdef __cplusplus
extern "C" {
#endif

void* load(void* payload);

#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif

#endif /* HEADER_EXAMPLE_H */
```

```pl:01-basic.t
use v6;
use Test;
use MyNative;
use NativeCall;
use lib <lib t>;
use CompileTestLib;

compile_test_lib('example');

my sub load(Pointer[void] $payload) returns Pointer[void] is native('./example') { * }

my $a = CArray[int32].new;
$a[0] = 1;
$a[1] = 2;
$a[2] = 3;

my $from-c = load($a); # C言語側に$aを渡したい

done-testing;
````

+ 下記コマンドで実行してみてください

```bash:実行
$ prove -e "perl6 -Ilib" -r -v t/01-basic.t 
```

+ 下記のようなエラーがでてしまったはずです

```
Native call expected return type with CPointer representation, but got a CArray (NativeCall::Types::CArray[int32])
  in method CALL-ME at /home/itoyota/.rakudobrew/moar-nom/install/share/perl6/sources/24DD121B5B4774C04A7084827BFAD92199756E03 (NativeCall) line 333
  in block <unit> at t/01-basic.t line 17
```

`load`関数が要求している引数の型(i.e. `Pointer[void]`)と違う型(i.e. `CArray[int32]`)を渡しているのだから当然ですね。
nativecastを使ってキャストすれば、このようなエラーを回避することができます。
では実際に使っていきましょう！

# Let's try!

+ 01-basic.tを下記のように書き換えて再度実行してみましょう

```pl:01-basic.t
use v6;
use Test;
use MyNative;
use NativeCall;
use lib <lib t>;
use CompileTestLib;

compile_test_lib('example');

my sub load(Pointer[void] $payload) returns Pointer[void] is native('./example') { * }

my $a = CArray[int32].new;
$a[0] = 1;
$a[1] = 2;
$a[2] = 3;

my $from-c = load(nativecast(Pointer[void],$a)); # C言語側に$aを渡したい

done-testing;
````

```bash:実行
$ prove -e "perl6 -Ilib" -r -v t/01-basic.t
```

+ 今度はエラーが出なくなりましたね。
+ これは、`CArray[int32]`をPointer`[void]`にきちんとキャストしてからC言語側に渡したからです。
+ では、返ってきた値を使いたかったらどうしたらよいでしょうか。
+ このときもnativecastを使うとよいです。


```pl:01-basic.t
use v6;
use Test;
use MyNative;
use NativeCall;
use lib <lib t>;
use CompileTestLib;

compile_test_lib('example');

my sub load(Pointer[void] $payload) returns Pointer[void] is native('./example') { * }


my $a = CArray[int32].new;
$a[0] = 1;
$a[1] = 2;
$a[2] = 3;

my $from-c = load(nativecast(Pointer[void], $a));
my $b = nativecast(CArray[int32], $from-c); # (#1)
is $b[0], 1;
is $b[1], 2;
is $b[2], 3;

done-testing;
```

+ 上記の例では、`load`関数が返した`Pointer[void]`を`CArray[int32]`にキャストして、Perl6側で使えるようにしています。
+ では、実行してみましょう

```bash:実行
$ prove -e "perl6 -Ilib" -r -v t/01-basic.t 
```

```bash:実行結果
t/01-basic.t .. 
ok 1 - 
ok 2 - 
ok 3 - 
1..3
ok
All tests successful.
```

+ きちんと`$b`に値が入っていることが確認できましたね。


以上、Perl 6アドベントカレンダーの22日目の投稿でした。
Magento2.1のintl問題@CentOS7に対処する

このエントリーは[Magento Advent Calendar 2016](http://www.adventar.org/calendars/1372)の16日目です。

<= 15日目 [Satisを使って自作Magentoエクステンションを管理する](https://principle-works.jp/blog/how-to-manage-magento-extension-with-satis)
=> 17日目 [Google Cloud PlatformでMagento2 〜 RedisとCloud SQLまで](http://qiita.com/macseto/items/e0c814abe5f7f6160d34)

決済ページへのフォーム追加の手順を書こうかと思っておりましたが、2016年12月16日リリースのMagento2.1.3においても既知の「intl問題」が解決していなかったので対処方法を書きます。

※ちなみにintlは「Internationalization」の省略名らしい。つまりi18n。

# intl問題とは

投入リソース世界最強！のオープンソースECソフトウェアであるMagento2ですが、残念なことにRedHat系Linuxでは日本語と韓国語利用で動作不良が判明しています。これは各種yumリポジトリで提供されているPHP拡張intlが利用するlibICUのバージョンが古く、日本語月名の省略形が含まれていないことが原因です。なお、libICUのバージョンが比較的新しいUbuntuでは発生しません。

Magento公式開発でも「[MAGETWO-60828](https://github.com/magento/magento2/issues/5356)」として対応してくれていますが、2016年12月にリリースされた2.1.3においてもまだ解決していません。

動作不良の内容は「日本語入力内容が消える」「管理画面に入れなくなる」（2.1.2での内容）など様々で、動作不良対象はCentOS7系であればPHP5.6でもPHP7でも発生します。（調査内容は[ベリテワークスさんの記事](https://principle-works.jp/blog/magento2-setup-guide-2016-edition)も参照）

Ubuntuなら動くとはいえどAmazonLinuxをはじめRedhat系が使えないというのも困ったものですので、公式が対応するまでの凌ぎ方をこのエントリでは共有します。

## libICUが古くてダメなのであれば用意する

ポイントは3点、
1. libICUとintlを自前でコンパイルする
2. PHP5.6を利用する
3. PHP7系を使わない
です。

PHP7系についてはpecl/intlが対応していないので以下の方法でコンパイルできません。ここでは無難にPHP5.6を使う方法を紹介しています。

## 動作確認環境
Magento 2.1.2, 2.1.3
CentOS 7.2
Apache 2.4.6
PHP 5.6.29(ius)
libICU 55.1

## 作業内容

```:~/
# libICU,intlのコンパイル

yum remove libicu*
wget http://download.icu-project.org/files/icu4c/55.1/icu4c-55_1-src.tgz
tar zxf icu4c-55_1-src.tgz
cd icu/source/
./configure
make
make install
pecl install pecl/intl
```

以下新規作成（PHP拡張読み込み）

``` :/etc/php.d/intl.ini
extension=intl.so
```

そしてhttpd再起動。

## intlの動作確認
intlの動作確認はベリテワークス西さん[@hirokazu1225](https://twitter.com/hirokazu1225)が作ってくれたシンプルなスクリプトで確認できます。

[HirokazuNishi/check.php](https://gist.github.com/HirokazuNishi/f5586b3710e25e487a8667969a47c369)

## まとめ
以上でintl問題は一応解決しますが、このままだとPHP7が使えませんので、pecl/intlと[MAGETWO-60828](https://github.com/magento/magento2/issues/5356)のリリースをチェックしておきましょう。

## 参考
[issues:「PHP message: PHP Fatal error: Uncaught TypeError: Argument 1 passed to iterator_to_array() must implement interface Traversable」](https://github.com/magento/magento2/issues/5356)
[HirokazuNishi/check.php](https://gist.github.com/HirokazuNishi/f5586b3710e25e487a8667969a47c369)
Onsen UIで VRアプリも顔認識アプリも、ロボット連携アプリも作ってみた。

3、4年ほど前からOnsen UIを使ったアプリを作ってきました！！
今回はせっかくなので、最近Onsen UIを使って、作ってみたアプリをいくつか紹介しますーー。

## Pokémon GO風 VRアプリを作ってみた。

ちょうど、`Pokémon GO`が爆発的なヒットを飛ばしている頃、
`Mozilla` から [A-FRAME](https://aframe.io/) っていう WebVRフレームワークが出ているのを知って、
これは！と思い Pokémon GO風の VRアプリを作ってみましたー。

<img width="594" alt="like_pockego.png" src="https://qiita-image-store.s3.amazonaws.com/0/67525/9ba5c6bc-f5f9-97f7-4220-34f6cc3193dd.png">

> 僕の同僚が書いてくれた `スペインアングリーアント` というモンスターを、特別なボールを使ってGETしようとしているところ

触って見て面白かったので、OnsenUI x A-FRAME で本格的なVRアプリにチャレンジ中です！
A-FRAMEのサイトを見ると、いろいろサンプルがあるので、WebVRに興味がある方は是非お試しの価値アリです！！
ちょっといいヘッドギアで、作ったアプリを見ると結構興奮しますw

コードとかは、こちらのブログに簡単ですが書いてます！
[Monacaで Pokémon GO風 VRアプリを作ってみた](https://utage.headwaters.co.jp/blog/?p=5344)

## 顔認識して店舗の常連さんを判別する 注文タブレット

居酒屋さんでたまに見かける注文用のタブレットデバイスに、
顔認識のコグニティブ機能を持たせて、常連さん向けのサービスが提供できたら面白いんじゃないか！
と思って、Onsen UIでタブレットアプリを作ってみました！

<img width="594" alt="like_pockego.png" src="https://qiita-image-store.s3.amazonaws.com/0/67525/4ed4e908-ea23-9870-0d4c-494afb66cb66.png">

Onsen UIでフロント部分を1週間くらいで組み上げて、
バックエンドとの連携部分を作り込むまで、2週間くらいで実装しました。
初めて、`component指向`で実装を進めてみたのですが、チームでの共同開発がしやすいなーと思いました！
先日、未来のオーダー端末としてテレビの特番で取り上げてもらいましたw

アプリの紹介動画も作ってみました！
[SynApps Tablet: 顔認識機能を使って常連客にアプローチするO2Oタブレットアプリ](https://www.youtube.com/watch?v=9tuXoipspHw&feature=youtu.be)

## Sota（ロボ）に、セリフを言わせて楽しむ スマートフォンアプリ

ロボットとモバイルを連携させて、面白いことしたい！
と思い、Onsen UIで、[Sota（ソータ）](https://sota.vstone.co.jp/home/)と連携したアプリを作ってみました！！
こちらも、顔認識の機能を持たせて、Sotaが自分のことを思い出してくれるっていう演出など入れて、
新しいモバイルアプリの形にチャレンジしてみました。

<img width="594" alt="like_pockego.png" src="https://qiita-image-store.s3.amazonaws.com/0/67525/7cb5b0b3-1ae4-cf4a-4c7b-e0451179e1de.png">

こちらも、短期で作ったので、Onsen UIのコンポーネントを使いまくりました。
ロボとの連携部分は、初めての試みだったので結構手こずりました・・・

今後、こういったモバイルとIoTデバイスの連携がどんどん進んでいくなーと思っているので、
この経験を生かして、いろんな IoTデバイスとの連携アプリを作って行こう！と思っています
いまは、こちらをベースに、Onsen UI と [Azure IoT Hub](https://azure.microsoft.com/ja-jp/services/iot-hub/) を連携させて改善させた取り組みをしていますー

IoT連携ならではのアプリの設計になるので、日々いろいろ考えながら、ベストプラクティクスを探っています。
新しい知識がどんどん入ってくるので、すごい楽しいです！

ちなみにこちらのアプリは、くろきん神田本店の「[飲みニケーションロボット席](http://www.headwaters.co.jp/news/communication_robot.html)」で実際に試せます！！
興味があれば、是非。

アプリの紹介動画も作ってみました！
[SynApps Mobile: 顔認識して、Sotaにセリフを言わせて楽しむ スマートフォンアプリ](https://www.youtube.com/watch?v=EuD7625f_og&feature=youtu.be)

## まとめ

いかがでしたでしょうか？？
今後も、Onsen UIを使って、いろんなライブラリやクラウドサービスと連携した面白いアプリを作っていきます！
Onsen UIを使うと、MVPを爆速でつくって、改善に時間が割けるようになるので、
サービスやプロダクトを作りたいっていう方には是非オススメです！

是非、OnsenUIで楽しい開発を。では。
既存の一覧ページにMithril.jsを混ぜ込もう

こちらは Mithril.js advent calendar 22日目の記事です

今日は既存のコードにmithrilを混ぜ込む話をします。

# どんなことをする？

* 既にサーバサイドでviewをレンダリングしている
* 何かの商品一覧ページの
* 各商品に
* お気に入りボタンを設置する

slimで書いてみます。

```slim:app/views/items/index.html.slim
.item-list
  @items.each do |item|
    .item
      strong = item.name
      a href="/item/#{item.id}"
        | 詳細ページでみる
```

何らかの商品の名前とその商品の詳細ページへのリンクが貼られている一覧ページぽいですね。

## 各商品に「お気に入り」ボタンを設置する

mithrilのマウント例って大体``m.mount(document.getElementById('mount-id'), component);``という感じなので、複数マウントしたいケースで一瞬迷いますが、結構簡単にできます。
方法としては、マウント先としてmount-item-favoriteクラスを各商品に置くだけです。
js側で利用したいデータは、マウント先にdata属性として書いておきましょう。

```slim:app/views/items/index.html.slim
.item-list
  @items.each do |item|
    .item
      strong = item.name
      a href="/item/#{item.id}"
        | 詳細ページでみる
      .mount-item-favorite data-is-favorite="#{user.favorite?(item)}"
```


```coffeescript:app.coffee
Array.prototype.forEach.call document.getElementsByClassName('mount-item-favorite'), (element) ->
  isFavorite = element.getAttribute 'data-is-favorite'

  vm = 
    doFavorite: ->
      isFavorite = true
      m.request(....) # サーバサイド変更
    doUnFavorite: ->
      isFavorite = false
      m.request(....) # サーバサイド変更

  component = 
    view: ->
      m('div', [
        if isFavorite
          m('a.btn', { onclick: vm.doUnFavorite.bind(vm) }, 'お気に入り済み')
        else
          m('a.btn', { onclick: vm.doFavorite.bind(vm) }, 'お気に入りにする')
      ])

  m.mount(element, compenent)
```

Array.prototype.forEach.callでdocument.getElementsByClassNameをぶん回して後は普通に書くだけですね。
全部Mithrilに書き直すのは辛くても、部分部分をmithrilで作ることができるので、ちょっと古めのサービスでも導入簡単でおすすめです。

クリスマスはmithrilユーザが増えることを祈っております！