OmniAICreator/Qiita-1.07M huggingface dataset:
【Java】 JavaBeansのメソッドチェーンでの扱いについて

JavaBeansで作成されたオブジェクトをメソッドチェーンでどう扱うかについて考えました。
# JavaBeansの仕様
正確な仕様かどうかはわかりませんが、よくあるJavaBeansの仕様は以下のようなものですね。

* 引き数なしのコンストラクタを持つ
* プロパティを持つ(setter/getter)

ほかにもいろいろありますが、大事なのはこんなもん。
公式の仕様はこちら→[JavaBeans Spec](http://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/)

```java:HogeBean.java
public class HogeBean {

    private String name;

    private String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
```
こんな感じ。lombokを使えば

```java:HogeBean.java
@Data
public class HogeBean {

    private String name;

    private String id;
}
```
これでOK。
# メソッドチェーンでの問題点

例えば似たようなフィールドを持つHogeBeanとFugaBeanがあるとする。

```java:HogeBean.java
@Data
public class HogeBean {

    private String name;

    private String id;
}
```

```java:FugaBean.java
@Data
public class FugaBean {

    private String id;

    private String password;
}
```

Stream中でHogeBeanをFugaBeanに変換したい場合、普通に考えると

```java
List<HogeBean> hoges = ...

hoges.stream().map(hoge -> {

    FugaBean fuga = new FugaBean();
    fuga.setId(hoge.getId());
    return fuga;
    
}).終端処理
```
こんな感じでしか書くことになる。こんなの美しくない。

# 解決策1 匿名クラス + インスタンスイニシャライザ

あまり美しいとは言えないかもしれませんが、map内の中括弧 + return は防げるパターン。

```java
hoges.stream().map(hoge -> new FugaBean(){
    {
        setId(hoge.getId());
    }
}).終端処理
```

さっきのよりはだいぶスッキリ。
ただ欠点があって、

* 匿名クラスを使うため、厳密にはそのクラスではない。→ リフレクションとかでバグる可能性がある
* そもそも対象のクラスがfinalだと使えない

# 解決策2 setterで自身を返すようにして、1行でオブジェクト生成可能なようにする。
JavaBeansをやめるという選択肢。
setterを以下のように改造する。

```java:FugaBean.java
    public HogeBean setId(String id) {
        this.id = id;
        return this;
    }
```

lombokならAccessors(chain = true)を付けるだけ

```java:FugaBean.java
@Data
@Accessors(chain = true)
```

件の処理は下記のように出来て

```java
hoges.stream().map(hoge -> new FugaBean().setId(hoge.getId())).終端処理
```

スッキリ。
でもやっぱり欠点はあって、

* JavaBeans仕様から外れるため、いろんなものが使えなくなる（PropertyDescriptor, apacheのBeanUtils, フレームワーク各種）

# 解決策3 ちょっとしたBuilderを作る

こんなん

```java:BeanCreater.java
public final class BeanCreater<T> {

    private BeanCreater() {
    }

    private T bean;

    public static <T> BeanCreater<T> of(Supplier<T> supplier) {

        BeanCreater<T> builder = new BeanCreater<T>();
        builder.bean = supplier.get();

        return builder;

    }
    
    public BeanCreater<T> construct(Consumer<T> consumer) {

        consumer.accept(this.bean);
        return this;
    }
    
    public T build() {
        return this.bean;
    }

}
```

これを使えば、

```java
hoges.stream().map(hoge -> BeanCreater.of(FugaBean::new)
    .construct(bean -> bean.setId(hoge.getId())).build()).終端処理
```
うーん。やってみたものの、いまいち。コードにノイズが多すぎますね。

# 結論
個人的には解決策2が一番好きです。流れるようなインタフェースをかけるし、本質と儀式的な話でも無駄がない。
JavaBeansが現状を考えてもっと柔軟になってほしいなあと思います。（そんな訳にもいかないんでしょうが... ）
今回作成したBeanCreaterはこちら https://github.com/7tsuno/BeanCreater

何か他に案があればアドバイスください！
js 文字列を逆に並べるには？

##文字列を逆に並べる

```js
function reverseString(str) {
   //write your code.
 }
reverseString("hello");//olleh
```

出力結果　例

```js
reverseString("hello") // "olleh".
reverseString("Howdy") // "ydwoH".
reverseString("Greetings from Earth") // "htraE morf sgniteerG".
```

##試したコード

```js
function reverseString(str) {
   return str.split("").reverse().join("");
 }
reverseString("hello");//olleh
```

##考え方

split()で文字列を分割//["h", "e", "l", "l", "o"]
reverse()で逆に並べる。//["o", "l", "l", "e", "h"]
join("")で一緒にする。//olleh


もっと簡潔に美しくかけるよ！　という方、コメントお待ちしております。

##参考リンク
[split()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split)
[reverse()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)
[join()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/join)
js 文章の最後の文字とtargetの文字の真偽判定する

##文章の最後の文字とtargetの文字の真偽判定する方法
*.endsWith()は使わない。

```script.js
function confirmEnding(str, target) {
 //write your code.
}
confirmEnding("Bastian", "n"); //true 

```

例
("Bastian", "n") //true 
("He has to give me a new name", "name") //true 
("Open sesame", "same") //true 
("Walking on water and developing software from a specification are easy if both are frozen", "specification") //false

##試したコード

```script.js
function confirmEnding(str, target) {
  return str.substr(-target.length) === target;
}
```

##考え方
targetの文字数を取得する
targetLengthの数だけ、strの文末からsliceで変数strEndにいれる。
strEndとtargetを比較する。

もっと簡潔に美しくかけるよ！という方、コメントお待ちしております。
閲覧ありがとうございました。

##参考リンク
[MDN Array.prototype.slice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)

##追記
gaogao_9さんのコメントを反映しました。
IP in IPメモ

# 概要
- IP in IPの動作確認

- 動機：忘れた
- さくらVPS(CentOS 6.8)×２
    - グローバルIPが１個付与、ローカルは仮想(tun)

# 設定
```
# ip tunnel add tun0 mode ipip remote [宛先グローバル] local [送信元グローバル] dev eth0
# ifconfig tun0 [送信元ローカル] netmask 255.255.255.252 pointopoint [宛先ローカル]
# ifconfig tun0 mtu 1500 up
```

# パケットキャプチャ
Ping

```
# ping 10.0.0.2
```
![ScreenClip.png](https://qiita-image-store.s3.amazonaws.com/0/50690/44caabf5-865a-76c8-989c-5cb2786ccf7e.png)

## メモ
- IP in IPは特別なヘッダを挿入しない
- オリジナルIPヘッダのNextプロトコル番号は4番
- 特段のコネクション処理は無い

# 参考
Protocol Numbers
http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
RFC 1853 - IP in IP Tunneling
https://tools.ietf.org/html/rfc1853
How to create IP-IP tunnel between FreeBSD and Linux :: Oleksiy Kovyrin
http://kovyrin.net/2006/03/17/how-to-create-ip-ip-tunnel-between-freebsd-and-linux/
ARM評価ボードを使ったセンサーアプリケーション

#はじめに
ARM評価ボードを使用してセンサーから取り込んだデータを
スマートフォンで表示する環境を構築してみようと思います。

#目標
目標は
ARM評価ボードから
3軸ジャイロ、3軸地磁気、大気圧センサー、湿度センサー、温度センサー
の情報をBLEで送信し、送信された情報をスマートフォンに表示する
ことです。

#使用機器
開発には以下の機器を使用します。

マイコンボード
STMicroelectronics STM32L476RG
[Nucleo-64 L476RG](http://www.st.com/en/evaluation-tools/nucleo-l476rg.html)

BLEボード
[XNUCLEO-IDB04A1](http://www.st.com/ja/ecosystems/x-nucleo-idb04a1.html)

センサーボード
[X-NUCLEO-IKS01A1](http://www.st.com/ja/ecosystems/x-nucleo-iks01a1.html)

![評価ボード.jpg](https://qiita-image-store.s3.amazonaws.com/0/148400/a083551f-078e-fa04-bd70-8879a636f84c.jpeg)

#開発環境
開発環境にはKeil（カイル）の評価版[MDK ARM](https://www.arm.com/ja/products/tools/software-tools/mdk-arm/)を使用します。
**評価版のためリンクサイズは32Kbyteまでの制限があります。**

セッティングツール
[STM32CubeMX](http://www.st.com/ja/development-tools/stm32cubemx.html)

#まとめ
開発機器は下記のサイトから購入することができます。
[秋月電子通商](http://akizukidenshi.com/catalog/c/cstm32/)
[マクニカオンラインストア](https://store.macnica.co.jp/)
[Amazon](https://www.amazon.co.jp/)

開発環境は他にもIARの評価版[EWARM](https://www.iar.com/jp/)や無償で制限のない開発環境を構築することができます。
用途に合わせて開発環境を準備してみてはと思います。
【Android】interfaceの例

Android アプリを作るときに使う interface の具体的な例を紹介していきたいと思います。

# interface の例
## 各種リスナー
- OnClickListener
- OnLongClickListener
- OnTouchListener

このあたりのリスナーは`View.java`で定義されています。
AndroidStudioなら、`command + B`でクラスに定義されている場所に飛べるので、確認してみてください。

イベントリスナーと言われたりします。

## スレッド
- Runnable

マルチスレッドでプログラミングするときに使います。

参考: [Android Developer プロセスとスレッド](https://developer.android.com/guide/components/processes-and-threads.html)

# 書き方の例
OnClickListenerを例に紹介していきます。

## 匿名クラスを引数として渡す
Viewクラスの、setOnClickListenerメソッドに引数として interface を渡します。

```java
Button button = new Button(this);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // button がクリックされた時の処理
    }
});
```

事前に変数に代入しておくこともできます。(やりませんが....)

```java
Button button2 = new Button(this);
View.OnClickListener onClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // button がクリックされた時の処理
    }
};
button2.setOnClickListener(onClickListener);
```

## ラムダ式を使う
### 準備
Java8 で実装された、新しい文法であるラムダをAndroid で使うには準備が必要になります。

こちらのサイトを参考に、
- [Qiita: ラムダ式によってAndroidアプリを簡単に書く！](http://qiita.com/NoriakiOshita/items/6ff8c46d2f8d3378dab2)

```app/build.gradle
android {
  defaultConfig {
    ...
    jackOptions {
        enabled true
    }
  }
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
```
以上の２箇所を書き加えます。

このとき gradle-wrapper.properties で、gradle のバージョンが、2.1.0以上になっていることがが必要です。

### ラムダ式で書く
```java
Button button3 = new Button(this);
button3.setOnClickListener((View v)->{
    // button がクリックされた時の処理
});
```

## 最後に
「どうやって書くのがいいのか？」に対する明確な答えはなさそうです。

少し古い記事になりますが、
- [美しいOnClickListenerの実装方法(を教えてください)](http://qiita.com/t2low/items/8ac683c7ebf4b6dd1b41)

個人的には匿名クラスで書くのが好きで、AcitivytやFragmentにimplementsするのはあんまり好きじゃないです (オブジェクト指向的に変な気がするので...)
Rails Activeadminカスタマイズメモ

Railsのgem、ActiveAdminを使って管理画面を構築する際に利用した機能のメモ。
※随時更新予定。

### ダウンロードリンクを消す。
http://activeadmin.info/docs/3-index-pages.html

```ruby
index download_links: false
```

### 全てのparameterを許可する。 
https://github.com/activeadmin/activeadmin/issues/2875

```ruby
permit_params { User.attribute_names.map(&:to_sym) }
```

### カスタマイズしたカラムにソート機能を追加する。
https://github.com/activeadmin/activeadmin/issues/3085

```ruby

class User < ApplicationRecord
  has_many :messages, dependent: :destroy
end

class Message < ApplicationRecord
  belongs_to :user, counter_cache: :messages_count
end

controller do
  def scoped_collection
    super.joins('LEFT JOIN "messages" ON "messages"."user_id" = "users"."id"')
         .select('users.*, count(messages.*) as message_count')
         .group('users.id')
  end
end

index do
  column 'メッセージ総数', :message_count, sortable: :message_count
end
```

### newとeditでformの内容を変える。
http://stackoverflow.com/questions/6725233/active-admin-customize-only-new-form

```ruby
attributes = User.attribute_names.map(&:to_sym)
attributes.delete(:id)
attributes.each do |attribute|
  if f.object.new_record?
    f.send(:input, attribute)
  else
    f.send(:input, attribute, input_html: { disabled: "disabled" })
  end
end
```

### member_actionで設定したpageのタイトル編集方法。
http://stackoverflow.com/questions/16905616/active-admin-how-to-set-page-title

```ruby
member_action :report, method: :get do
  @page_title = "レポート"
end

```

### リソースの追加。

```ruby
rails generate active_admin:resource MyModel
```

### ページネーションの削除。

```
config.paginate = false
```

### ページネーションの日本語化 
http://zooiiooz.hatenablog.com/entry/20130111/1357905444

```ruby
views:
  pagination:
    first: "&laquo; 最初"
    last: "最後&raquo;"
    previous: "&lsaquo; 前"
    next: "次 &rsaquo;"
    truncate: "..."
```

### レコード数が多いテーブルのindexページが重い時は `select count(*) from table` を消す

https://github.com/activeadmin/activeadmin/pull/2333


```ruby
index pagination_total: false do
  id_column
  column :user_id
  ...
end
```


### パネルを横並びに表示する

```ruby
columns do
  column do
    panel "hogehoge" do
    end
  end
  
  column do
    panel "fugafuga" do
    end
  end
end
```

### 編集画面にエラーメッセージを表示させたい

https://github.com/activeadmin/activeadmin/pull/905

```ruby
form do |f|
  f.semantic_errors *f.object.errors.keys
  f.inputs do
    f.input :name
  end
end
```
JavaScript でニューラルネットワーク

## 動機

前回「[Ruby でニューラルネットワーク](http://qiita.com/elm200/items/24243e106013b6cda979)」では、MNIST のデータを使って、数字認識ができるニューラルネットワークを構築しました。元ネタは、名著「[ゼロから作るDeep Learning ――Pythonで学ぶディープラーニングの理論と実装](https://www.oreilly.co.jp/books/9784873117584/)」です。

ただ、数字の認識を行えるとはいっても、訓練用のデータもテスト用のデータも MNIST から与えられたものにすぎません。自分で実際に手書きの数字を描いてみたらどうなるのだろう？という興味から、ウェブ上で、実際に数値を手書きして、そのまま数字認識が試せるようなものを作ってみました。

[Digit Recognition](https://digit-recognition-nn.herokuapp.com/)
[ソースコード(GitHub)](https://github.com/elm200/digit_recognition)

![image](https://qiita-image-store.s3.amazonaws.com/0/26146/43366b0d-262d-d387-7c8d-277410f6b4e6.png)

手書き数値の右隣の "3: 99.6%" みたいなところは、たとえば「『3』である確率は 99.6%」ということを意味します。確率の一番高い数字を認識結果としています。

## コード解説

`neuralnet.js` がメインのコードですが、その中でも実質的にニューラルネットワークの計算を行っているのはこの部分だけです。

```js

function predict(x) {
  var a1 = nj.dot(x, net_params.w1).add(net_params.b1);
  var z1 = nj.sigmoid(a1);
  var a2 = nj.dot(z1, net_params.w2).add(net_params.b2);
  var z2 = nj.sigmoid(a2);
  var a3 = nj.dot(z2, net_params.w3).add(net_params.b3);
  var z3 = nj.softmax(a3);
  return z3;
}
```
3層のニューラルネットワークです。`net_params.js` で、重みとバイアスの数値を読み込んで、グローバル変数の `net_params` に代入しています。この重みとバイアスの数字自体は、上記の「[ゼロから作るDeep Learning ――Pythonで学ぶディープラーニングの理論と実装](https://www.oreilly.co.jp/books/9784873117584/)」から得たものです。

`nj.*` で始まる関数は、[NumJs](https://github.com/nicolaspanel/numjs) というライブラリのものです。NumJs は名前の通り、Python の行列ライブラリ NumPy 風のインターフェイスを持った JavaScript のライブラリです。とても使いやすかったです。おすすめ。

## 感想

実際の認識精度はというと・・・残念ながらそれほど高くないようです。数字によって明らかに認識率が違います。「3」は、かなりよく認識されるのですが、「4」はほぼ壊滅的です。もともと、MNIST のテストデータを使った正答率は、96% 程度なので、本来はもっとよく認識されてもよさそうなものです。

おそらくは、MNIST の画像と今回の手書きの画像では、なんらかの「画風」の違いがあるのでしょう。もちろん、今回風の画像での学習は行っていませんので、正答率が低めになっているのかもしれません。あるいは、CNNのようなより深層なネットワークを使えば、正答率を上げることができるのかもしれません。今後の研究課題ですね。

それにしても、[NumJs](https://github.com/nicolaspanel/numjs) 。元々は、[math.js](http://mathjs.org/)という数値計算ライブラリを使っていたのですが、reshape の処理がうまくできなかったので、NumJs に切り替えました。NumPy に非常に近い使い勝手があって、簡単な行列計算ならなんでもこなせそうです。Ruby にもほしいです…(Ruby の NMatrix のほうが使いにくい印象)。

今回、実際にウェブサイト（というほど大仰なものではありませんが）を作ってみて、HTML5 の Canvas の使い方や、静的コンテンツを Heroku にホストする方法などを理解することができました。JavaScript には苦手意識があったのですが、実際、腰を入れて取り組んでみると、これはこれで結構面白いと思いました。

## 今後の展望

ニューラルネットワークの仕組みは、実装レベルで理解できたので、これからは、もう少し高レベルに視点を移して、Chainer や TensorFlow と言った、ディープラーニング用のライブラリについて調べてみるつもりです。
どうしてもゲームプログラマになりたい人へ＃０２

# 記述する動機

私、とある専門学校でPGを教えています。はや10年。
いまだにSEもやってます。
学生さんたちに読んでもらうために書いているのですが、全て実例です。学校名は秘密！！

## 即戦力としての採用ー＞結構辛い。
unity,アンリアルはどちらかやっておきましょう。
c、c＋＋、c＃も必須。

## 長期の雇用ー＞技術的にはこちらが大変なのです。
とにかく、Unix、Linuxを理解した上で、
c、c＋＋は当然
Ruby、できれば Python も
LAMPの開発はポイント高いです。
OpenResty(nginx-luaフレームワーク）とRedisでアクセス制限システムの試作

この記事は [リクルートライフスタイルアドベントカレンダー2016](http://qiita.com/advent-calendar/2016/recruitlifestyle) の11日目です。
ホットペッパービューティーでゆるふわエンジニアをしています。しゃぜです。
割りと最近入社したばっかりです。

さて、今回は前から試そうと思って暇がなくてサボっていた、OpenRestyで少し遊んでみました。

# はじめに

* OpenRestyとredisを利用して、簡易的なアクセス制御システムを試作してみます。
* 同じIPアドレスから一定回数のアクセスが合った場合にBANするというものです。
  * 今回は雑に、30秒以内に10アクセス以上あった場合「アクセスしすぎですよ」というメッセージを表示してみます。
  * お仕事の場合だと、404を返すとか、そういう感じになるかとは思います。
* 今回は同じEC2インスタンス(ubuntu)上で、nginxとredis-serverを動かしています。
  * そのEC2にEIPを付与して、そのまま外からアクセスできるような状態です。

# redisの導入と起動

```
sudo apt-get install redis-server -y
sudo service redis-server start
```

# Ubuntu 16.04.1 LTS に OpenRestyの導入（nginx含む）
```
sudo apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make wget gcc -y
cd /usr/local
wget https://openresty.org/download/openresty-1.11.2.2.tar.gz
tar xvfz openresty-1.11.2.2.tar.gz
cd openresty-1.11.2.2
./configure --prefix=/usr/local
make
sudo make install
```

# nginxの操作

* 起動
  * sudo /usr/local/nginx/sbin/nginx
* 再読込
  * sudo /usr/local/nginx/sbin/nginx -s reload
* 停止
  * sudo /usr/local/nginx/sbin/nginx -s stop

# nginxの設定

* location /のところを、sample.luaを見るようにしています。

/usr/local/nginx/conf/nginx.conf

```
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
                default_type 'text/html';
                content_by_lua_file /usr/local/luafiles/sample.lua;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}
```

luaスクリプト配置用のディレクトリをつくります。

```
sudo mkdir /usr/local/luafiles
```

# アクセス制御用のlua scriptの実装

では、実際に、lua scriptを配置してみます。
実装イメージはこんな感じです。
/usr/local/luafiles/sample.lua

```
local redis = require "resty.redis"
local redisObject = redis:new()
redisObject:set_timeout(3000)

local ok, err = redisObject:connect("127.0.0.1",6379)
if not ok then
  ngx.say("connection error",err)
  return
end

redisObject:incr(ngx.var.remote_addr)
redisObject:expire(ngx.var.remote_addr,30)

local counter = redisObject:get(ngx.var.remote_addr)
if tonumber(counter) > 10 then
  ngx.say("アクセスしすぎですよ")
else
  ngx.say("ようこそ")
end
```

# 動作

nginxに対して、同一IPアドレスから、30秒以内に10回アクセスすると、「アクセスしすぎですよ」というメッセージがでるようになりました。


# まとめ

* 今回は手抜きでパッケージ入れましたが、お仕事で使う時は、nginxや、redisの最新版を使うようにしたいですね。
* luaのエラーハンドリングなどは雑なので、あくまでもサンプルということでご容赦を。
  * redisのexpireの仕組みからすると厳密な30sになっていないとかいろいろありますが。。。
* お仕事で使う際はいろいろ要件とかありそうですが、導入の敷居は低いなぁと感じました。気軽に活用できるのではないでしょうか。

ではではーε≡≡ﾍ( ´Д`)ﾉ
カレントディレクトリ以下のGitリモートリポジトリ一覧を出力する

Gitで管理しているレポジトリを`~/src`配下とかにまとめていると、数が多すぎてどこに置いたか分からなくなる時があるので、レポジトリのパスとリモートリポジトリの情報を一覧表示してくれるワンライナーがあると便利。

```zsh:find-git-remotes
#!/bin/zsh
# カレントディレクトリ以下の、Gitのリモートリポジトリ一覧を出力します
# * bundleを含むディレクトリは除外しています。Bundler管理していると出力数が多すぎて出力を汚染するので
# * zsh, realpath が必要です
find . -name ".git" -not -iwholename '*/bundle*' -type d -exec zsh -c 'repopath=`realpath {}/..`; echo -e "\n\e[96mGit repository path: ${repopath}\e[0m"' \; -exec git --git-dir {} remote -v \;
```

`~/bin`とかに置いておき、いつでも実行できるようにしておくともうちょっと便利。
BigQueryのクエリー料金の些細な話

# はじめに

この記事は[Google Cloud Platform(1) Advent Calendar 2016] (http://qiita.com/advent-calendar/2016/gcp) の11日目の記事として書かれています。

BigQueryのクエリー料金で私がハマった些細(でもない)話を書きたいと思います。

# BigQuery の費用のおさらい

某溶かした記事でおなじみの BigQuery ですが、使おうとしている人はもちろん、使っている人たちも一番気にしている部分が「どれくらい費用がかかるのか？」ということになります。

BigQuery では以下のことに費用が発生します。

1. ストレージ料金
    * データの保存費用、保存した容量に対して費用が発生
    * 90日以上使用されていないテーブルは費用がぐっと安くなる
    * そもそも、スゲー安い
2. steaming insert
    * リアルタイムにデータを追加するための費用、転送した容量に対して費用が発生
    * 気をつけないとそこそこかかる
3. クエリー料金
    * スキャンした容量に対して費用が発生(もう少し詳しいことは後述)
    * 気をつけないと溶かすことになる

1と2に関してはシステム運用側でコントロールする費用なのである程度予測ができますが、3のクエリー料金に関しては、分析メンバーや営業メンバーにクエリーするインタフェースを開放してたりするとどれくらい費用がかかるか？ということが気が気でない人たちが多数だと思います。

# クエリー料金のおさらい

BigQueryのクエリー料金は、以下のようにかかります。

* 実行したクエリーが実行時に使用したカラムの全容量に対して費用発生する

たとえば、カラムが10個あるテーブルがあって、そのテーブルに1億レコード保存していた場合、

* id という INTEGER のカラムがあった場合、SELECT id FROM ... とすると、 8byte * 1億 という容量に対して費用計算される
    * これは、LIMIT 1000 としても、1億レコード分スキャンしたことに変わりがないので、費用が安くなることはない
* さらに name という TEXT のカラムがあった場合、 SELECT name FROM ... WHERE id = 1 とすると、 
 name カラムの1億レコード分の容量と、 条件で使用した id カラムの1億レコード分の容量分に対して費用計算がされる
* SELECT * FROM ... なんてことをすると、そのテーブルの全容量分に対して費用計算がされるので、bq使いの人たちから責められる

上記のように、LIMIT でしぼっても、そのカラムの全容量が費用計算の対象となるため、BigQueryを利用している人たちでは、日付ごとにテーブルを分割するというのが常套手段になっています。

例えば、注文テーブルがあった場合、すべてを order テーブルに入れてしまうと、どんどんクエリー料金が膨らんでいくので、

* order_20161201、 order_20161202、 order_20161203、・・・

といったように日付ごとにテーブルを分割し、必要な日付分だけ UNION して集計するということになります。

# クエリー容量の2つのパラメータ

BigQueryのクエリーのAPIに関して、クエリー容量に関するパラメータは以下の2つになります。

1. statistics.query.totalBytesProcessed
2. statistics.query.totalBytesBilled

1 はそのまま、クエリー実行時に使用したバイト数になります。
2 はクエリー料金の費用計算で使用されるバイト数です。

ここまでの説明で、「BigQueryのクエリー料金は、クエリー実行時に使用したバイト数」と説明してきたわけですから、なぜ 1 と 2 が違うのか？ という疑問が出てきます。

ほとんどの場合、 1 と 2 は同じになりますが、これがずれるパターンがあるということになるということです。

実は、クエリー料金の計算にはもう一つあまり気にされていないルールがあります。

[オンデマンド料金] (https://cloud.google.com/bigquery/pricing#on_demand_pricing)

> 料金は MB 単位のデータ処理容量（端数は四捨五入）で決まります。クエリが参照するテーブルあたりのデータ処理容量は最低 10 MB で、クエリあたりのデータ処理容量は最低 10 MB です。

つまり、ものすごく容量が少ないテーブルに対して、クエリーを実行した場合でも、最低 10MB 分の費用がかかるということで、1MBしか容量がないテーブルに対してクエリーを実行した場合、totalBytesProccessed は 1MB といった値になりますが、totalBytesBilled は 10MB となるということになります。

# でようやく、私がハマった話

ここまで説明してようやく私がハマった話ができるわけですが、以下のようなことが発生していました。

* テストをするために、ものすごく容量が少ないテーブル群に対してクエリーを発行したらそこそこ料金がかかってしまっていた
    * 日付ごとのテーブルを準備(データ量は極少数)
    * 3ヶ月間、6ヶ月間といった、期間毎の集計を行うテストをしていた

この原因を突き詰めていくと、

* クエリーの費用計算の最低容量の 10MB というのは、「テーブルあたり」である

つまり、各テーブルの容量がものすごく少なくても以下のような容量に対して、費用計算が発生します。

* 3ヶ月=90日とすると、90テーブルをつかうので、10MB * 90で 900MB
* 6ヶ月間=180日とすると、180テーブルをつかうので、10MB * 180で 1.8GB

# 結論

こういうことが気になるならば、[Partitioned Tables] (https://cloud.google.com/bigquery/docs/partitioned-tables) を使いましょう。

だらだらと書きましたが、BigQueryは正直びっくりするくらい費用がかからないサービスだと思います。
(未だに BigQuery をググると溶かす記事になるのが悔しいなと思うくらいです・・・)

ほんの少し、BigQueryの気持ちになって使えば、お安く気軽に使えるサービスだと思うので、がんがん使うのがいいと思います！
どうしてもゲームプログラマになりたい人へ＃０１

# 記述する動機

私、とある専門学校でPGを教えています。はや10年。
いまだにSEもやってます。
学生さんたちに読んでもらうために書いているのですが、全て実例です。学校名は秘密！！

## 今は結構チャンスです。
２０１６/１２/１１現在
昔も今も「出来るエンジニア」は不足している。
特に最近の不足ぶりは深刻なのです。

## フロントかバックか？
どちらも理解は必要。
現状バックエンドが不足。フロントは難しいわりにはチャンス少なし。
ここのところよく考えましょう。

## 数学はどこまで？
n次式、ベクトル、4❌4行列、空間の幾何学、三角関数、確率、微積分ぐらい。
１月もあれば復習出来る範囲です。
やってなかった人は、時間かかるでしょうから半年ぐらいは仕方ない。毎日やりましょう。


## c、c++が重要
unity,アンリアルで安易に作るのではなく、c系でガリガリ書けること。どの企業さんもこちらが欲しいとのこと。
つまり自作でエンジン書くぐらい。
2019/09/03追記
若干傾向が変わりました。unityは作品的には歓迎の模様。しかし、c系は相変わらず必要
enebularの標準INFOMOTION Type（BarChart, LineChart）の使い方

enebularのINFOMOTION Typeはプラグイン化されていて独自に拡張も可能ですが、まずは標準のINFOMOTION Typeの使い方を見ていきます。

## 初歩デモ準備

[enebular Advent Calendar 2016](http://qiita.com/advent-calendar/2016/enebular)初日の@satton_maroyakaのエントリ、[enebularをつかいはじめる](http://deferloader.blog.uhuru.co.jp/?p=6433)にある[スライド](http://www.slideshare.net/SatoruIshikawa1/enebular-infomotion)を見て準備すると以下のようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/445a645f-6c80-b36f-510d-3a7b8a095a0e.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/a2aa2068-245e-9e05-cfc6-b457cc0f28aa.png)

今回は標準INFOMOTION TypeのBarchartとLinechart用にランダム発生データを少し変更します。Functionノードを開いて以下のように変更します。

```js
msg.payload = {
    id : "value" + Math.floor(Math.random() * 5),
    value : Math.floor(Math.random() * 100)
};
return msg;
```

## BarChart

INFOMOTIONのCreate Graphで以下のような設定でBarChartを作成します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/01465fbd-aa08-edef-2142-f8f5abf53e80.png)

これをLiveモードで開くと以下のようになります。

![infomotion.gif](https://qiita-image-store.s3.amazonaws.com/0/21109/66797ca6-f004-52cf-44d7-0c8514040db7.gif)

## LineChart

続いてLineChartも同様に作成します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/d68d951f-c39c-25c6-741e-1d8126155254.png)

同じようにLiveモードで開くと以下のようになります。

![infomotion.gif](https://qiita-image-store.s3.amazonaws.com/0/21109/faebf96d-f389-0ea1-4c62-18c6249cf7e2.gif)

## まとめ

INFOMOTIONは時系列データを扱いますので、単純な棒グラフや折れ線グラフの方が戸惑うかもしれません。要はグラフの右上にある日付指定コントロールの抽出条件によって絞りこまれたデータの各値の合計が表示されているということです。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/6e70cb30-1422-dd5d-0394-687a6faa4ea1.png)

なので、データを逐次発生させてLiveモードで見てみると、上記のように逐次受け取った値が加算される様をリアルタイムに見るという形になります。つまりINFOMOTIONのBarChartやLineChartは「数量の増え方を見る」という見方に長けています。
アップロードしたファイルの完全性を検証する

[mixiグループ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/mixi)の12日目の記事です。

ユーザから写真をアップロードしてもらう機会が多いのですが、やはり携帯回線からのアップロードしたファイルは壊れているケースが多く、ファイルの完全性をチェックしたいなぁと考えておりました。
じゃあどうやって完全性を検証しようかと調べていたところ、`Content-MD5`ヘッダーにたどり着きました。

## `Content-MD5`ヘッダーって？

まず先にお断りしておきますが、2016年12月現在のHTTP/1.1では定義されていないヘッダーです。
もともと`Content-MD5`ヘッダーは、MIMEでメールの本文の完全性を保証するために定義されていました([RFC 1864](https://tools.ietf.org/html/rfc1864))。
それをHTTPに持ってきたのが[RFC 2616](https://tools.ietf.org/html/rfc2616#section-14.15)です。しかし、2014年のHTTP/1.1の改定([RFC 7230](https://tools.ietf.org/html/rfc7230), [RFC 7231](https://tools.ietf.org/html/rfc7231), [RFC 7232](https://tools.ietf.org/html/rfc7232), [RFC 7233](https://tools.ietf.org/html/rfc7233), [RFC 7234](https://tools.ietf.org/html/rfc7234), [RFC 7235](https://tools.ietf.org/html/rfc7235))で廃止されています。

実際どんなものなのかというと、まぁ名前そのままの通りで、bodyのMD5ダイジェストをbase64でエンコードしたものを`Content-MD5`ヘッダーとして付与するというものです。

## 完全性の検証

どうやって完全性を検証するのかという話は単純で、クライアント・サーバ側でそれぞれファイルのMD5を計算して一致するか検証するだけです。
そのMD5の受け渡しに、`Content-MD5`ヘッダーを使おうというのが今回のお話です。

まずクライアント側でファイルのMD5を計算しておき、それを`Content-MD5`としてリクエストヘッダーに追加してファイルをサーバにアップロードします。
サーバ側では、受け取ったファイルのMD5とリクエストヘッダーの`Content-MD5`が一致するか検証し、適切なレスポンスを返してあげます。

### AWS S3

S3ではこのヘッダーを使っていい感じにアップロードされたファイルの完全性チェックをしてくれます。
アップロード時に`Content-MD5`をヘッダーをつけることで、S3側が勝手にアップロード後のファイルのMD5と比較してくれて一致しないと400エラーを返してくれるようです。

参考: [Amazon S3へアップロードされたファイルの完全性の検証](http://qiita.com/imaifactory/items/4745bde5af1f3d07fdfb)

## 番外編 ETagを利用する

弊社ではmBaaSとしてFacebookのparse.comを利用していた（現在は[GCPへの移行中](http://qiita.com/tacke_jp/items/67eea30e4530e0d13a6a)です）ので、ファイルアップロード時の完全性チェックを挟むことができませんでした。

そのため、parse.comへアップロードしたファイルのETagがファイルのMD5だということを利用してクライアント側だけで完結するような方法をとっております。
具体的には、アップロード前にあらかじめファイルのMD5を計算しておき、ファイルアップロード後にHTTPヘッダーのみを取得し、ETagとあらかじめ計算しておいたMD5が一致するか検証するというちょっと泥臭い方法です。

### AWS S3のETag

S3のオブジェクトのETagは基本的にはMD5になります。
parse.comのファイルホスティングにもS3が使われているので、上記のようなことができるわけです。
しかし、S3へ分割アップロードをした場合は、MD5ではないものがETagに設定されるので注意が必要です。
WPF タグ 'x' は、XML 名前空間 'y' にありません。

# WPF タグ 'x' は、XML 名前空間 'y' にありません。

WPF 始めました。教科書は、
[かずきのBlog@hatena](http://blog.okazuki.jp/entry/2014/12/27/200015)

「その7」で躓いたので回避策をメモ

[WPF4.5入門 その7 「XAMLのオブジェクト要素と名前空間」](http://blog.okazuki.jp/entry/20130103/1357188241)

記事に沿ってプロジェクトを追加し、ビルドすると `Person.xaml` で次のエラーが表示されました。

>タグ 'Person' は、XML 名前空間 'clr-namespace:CustomXaml;assembly=CustomXaml' にありません。 行 1 位置 11.

> 名前 "Person" は名前空間 "clr-namespace:CustomXaml;assembly=CustomXaml" に存在しません。

原因は、ファイル `Person.xaml` の「ビルドアクション」の設定でした。
新規追加しただけだと `Page` になっていました。これを `埋め込みリソース` に変更してビルドし直すとコンパイルでき、`Main()` から読み出せるようになりました。

末筆ながら、[かずきのBlog@hatena] さんに感謝。

## 確認した環境

OS: 日本語 Windows 10 Home 64 ビット
コンパイラ: Visual Studio Community 2015 Version 14.0.25431.01 Update 3
ターゲットフレームワーク: .NET Framework 4.6.2
RaspberryPI3でTensorflowのマルチノードってできるんだ

# 事の発端
ディープラーニング試したいけど、実験のためだけにAWS使うのは高いしなぁ…。
おや、手元にRaspberryPIがあるぞ

RaspberryPIでTensorflow動くかな
　　　　　　　　　+
Tensolflowってマルチノードので動くかな
　　　　　　　　　||
RaspberryPIでTensorflowのマルチノード動くんじゃね？



# 環境構築
samjabrahams/tensorflow-on-raspberry-pi
https://github.com/samjabrahams/tensorflow-on-raspberry-pi

Githubでパッケージと手順が公開されているので、こちらを参考に作っていきます。
現時点(2016/12/11)の最新版は0.11版です。

マルチノードで使おうとすると複数台にインストールしないといけないです。
手動で構築するのが面倒なのでAnsible使いましょう
roleは載せておくので、inventoryとplaybookは難しくないので自作してください。

role/rpi-tensorflow/tasks/main.yml

```
---
- name: apt-get install python-pip python-dev
  apt:
    name: "{{ item }}"
    update_cache: yes
  with_items:
    - python-pip
    - python-dev
- name: wget tensorflow package
  get_url:
    url: "https://github.com/samjabrahams/tensorflow-on-raspberry-pi/releases/download/v0.11.0/tensorflow-0.11.0-cp27-none-linux_armv7l.whl"
    dest: /opt/tensorflow-0.11.0-cp27-none-linux_armv7l.whl

- name: pip install tensorflow
  pip:
    name: "file://opt/tensorflow-0.11.0-cp27-none-linux_armv7l.whl"
```

# Tensorflowを動かしてみましょう
分散TensorFlowでロジスティック回帰 -Distributed TensorFlow- その2
http://x1.inkenkun.com/archives/5487
こちらの方の「並列実行版ソースコード」を試してみます

psノード2台、workerノード2台で実行してみます
各ノードで以下のコマンドを実行します
ノードごとに--job_nameと--task_indexが異なりますので注意してください

```
raspberryPI 1号機
python trainer.py --ps_hosts=192.168.12.111:2222,192.168.12.112:2222 --worker_hosts=192.168.12.113:2222,192.168.12.114:2222 --job_name=ps --task_index=0
     
raspberryPI 2号機     
python trainer.py --ps_hosts=192.168.12.111:2222,192.168.12.112:2222 --worker_hosts=192.168.12.113:2222,192.168.12.114:2222 --job_name=ps --task_index=0
     
raspberryPI 3号機
python trainer.py --ps_hosts=192.168.12.111:2222,192.168.12.112:2222 --worker_hosts=192.168.12.113:2222,192.168.12.114:2222 --job_name=worker --task_index=0
     
raspberryPI 4号機
python trainer.py --ps_hosts=192.168.12.111:2222,192.168.12.112:2222 --worker_hosts=192.168.12.113:2222,192.168.12.114:2222 --job_name=worker --task_index=1
```

結果

```
raspberryPI3号機
(中略)
Step: 2402,  Epoch:  9,  Batch: 400 of 550,  Cost: 30.9763,  AvgTime: 29.30ms
Step: 2477,  Epoch:  9,  Batch: 550 of 550,  Cost: 36.5495,  AvgTime: 26.74ms
Step: 2577,  Epoch: 10,  Batch: 200 of 550,  Cost: 31.5500,  AvgTime: 34.01ms
Step: 2677,  Epoch: 10,  Batch: 400 of 550,  Cost: 36.4854,  AvgTime: 29.63ms
あれ・・・終わらない・・・。
```

```
raspberryPI4号機
(中略)
Step: 2242,  Epoch:  9,  Batch: 199 of 550,  Cost: 10.8887,  AvgTime: 62.20ms
Step: 2342,  Epoch:  9,  Batch: 399 of 550,  Cost: 44.7798,  AvgTime: 29.66ms
Step: 2517,  Epoch: 10,  Batch: 199 of 550,  Cost: 33.3699,  AvgTime: 60.06ms
Step: 2617,  Epoch: 10,  Batch: 399 of 550,  Cost: 70.1540,  AvgTime: 30.21ms
Test-Accuracy: 0.92
Total Time: 144.51s
Final Cost: 20.0725
done
```

workerの片方が処理終わると、もう片方は処理終わらないぞ。。。

# 最後に
ちょっと挙動がおかしいけど、コードそのままでraspberryPIでも動くって素晴らしい
新入社員の間でRuby勉強会をやっている話


この記事は[NIFTY Advent Calendar 2016](http://qiita.com/advent-calendar/2016/nifty) 11日目の記事です。

昨日は@yutaszkさんの[React DnD を使ってMQTT のモニタリングツールを作った](http://qiita.com/yutaszk/items/c4e499582ccce5aaf804)という記事でした。

こんにちは、ニフティ新卒1年目エンジニアの@alice02です。
今日は@yaaamaaaguuu、@umiiiiins、@alice02の3人が運営を務め、2016年度新入社員の技術力向上を目的に（新入社員が勝手に）開催している、Ruby勉強会「ニフティ(よちよち).rb」での取り組みについて紹介したいと思います。（※申し訳ございませんが、技術ネタではありません。）


# きっかけ
ある日、同期に「Ruby勉強会をやろう！」と言われ、「ぜひやりましょう！」と答えたのが全ての始まりでした。
その発言の背景として

- 新入社員の技術力の底上げがしたい
- 皆が普段から技術に触れるようになって欲しい
- 独学よりも周りに一緒に勉強する同期がいることがモチベーションにつながる
- (同期が集まる場になる)

などが挙げられます。

また、言語としてRubyを採用した理由はドキュメントが豊富なことなどが挙げられますが、一番の理由は **単純に自分がRubyを書きたかった** です…！（笑）


# 勉強会の目標
**業務で役立ちそうなスキルを配属までに身につける**
ということを当面の目標としました。


# 取り組み内容
定時後に集まり、週1回1時間30分程度で勉強会を行いました。
以下、具体的な取り組み内容です。

## Rubyの基礎を学ぶ
**目的**

- Rubyの基本的な書き方を習得する
- ドキュメントを読む癖をつける
- 英語への抵抗感をなくす

**内容**

[RubyWarrior](https://www.bloc.io/ruby-warrior#/)というゲーム感覚でRubyの基礎を学べるサイトを用いました。環境構築も不要なため取っ掛かりにはちょうど良かったです。また、RubyWarriorは日本語解説記事が多数存在していますが、それらの記事は極力見ないでで自力で英語を読んで解き進めてもらいました。とはいえ、初心者にとっては少し難易度が高いため、適宜解説とフォローを入れながら進めました。


## 簡単なWebアプリケーションを作れる
**目的**

- 初歩的なプログラミングの問題を通して、プログラミングに慣れる
- Webアプリケーションの基本的な概念を獲得する
- Webアプリケーションを作成できるようになる
- アルゴリズムを自力で考えてみるきっかけを作る

**内容**

Sinatraを用いて、

- じゃんけんアプリ
- 診断メーカー

を作成しました。
このうち、じゃんけんアプリは勝敗判定のアルゴリズムを自力で考えてもらい、自力でアルゴリズムを考えてみるきっかけを与えてみました。（ちなみに勝敗判定アルゴリズムは[こちら](http://staku.designbits.jp/check-janken/)がとても参考になります。）
また、診断メーカーは[C4SAハンズオン資料 (Ruby)](http://liquidz.github.io/c4sa_study/)を参考に作らせてもらいました。


## テストコードが書ける
**目的**

- テストの対象となるコードを書くことにより、プログラミングをより定着させる
- テストコードを書く体験をする
- テストコードを書くことは難しくないと認識させる
- テストコードを書くことを当たり前とする

**内容**

MinitestというRubyのテストフレームを用いて、

- 適当な四則演算
- 自分でSinatraを用いて書いたWebアプリケーション

のテストコードを書いてもらいました。
私自身もテストコードはまだまだ指導できるほどの知識がありませんが、

- どうやってテストコードを書いていくのか
- どういったテスト項目を用意すればいいのか
- テストしやすいコード設計をするにはどのようにすればよいのか？

などの観点で学んでもらいました。


## Dockerを扱える
**目的**

- Dockerの操作体系を覚える 
- 自分の開発環境を作れる

**内容**

DockerはRubyとは関係無い内容ですが、業務のどこかで使う機会が出てくると考え、Dockerの使い方講座とDockerを使ったRuby開発環境の構築を行いました。Dockerを一通り（簡単に）使えるようになってほしかったので、

- コンテナ型仮想化の仕組みを説明
- RubyやSwiftのコンテナをPullし、コンテナ内で作業してみる
- Dockerfileを書き、自分でコンテナを作ってみる

といった内容を実施しました。


# 振り返り
- 少しは同期の技術力向上に貢献できた
	- 勉強会でDockerを使っていたから、業務(OJT)でもDockerを使ってみたという同期がいた
- 自分自身も勉強会を運営する中で技術力を高めることができた
	- 特にDocker
- 参加人数が最初に比べるとかなり減ってしまった
	- 最初：15人程度
	- 現在：5人程度
- 何かを作りたいという願望が無いとモチベーションが持続しないみたい
	- あくまでもこの勉強会は**きっかけを与える場**であり、その先は自力でなんとかしてもらいたい…


# さいごに
勉強会の効果を測ることは難しいですが、技術力の向上・何か技術を学ぶきかっけ作りにはなったのではないでしょうか。来年度以降の新入社員にもぜひ続けていってほしいなっと思っています…！

さて、明日は@umiiiiinsさんの「Pythonとbotocoreで簡単にニフティクラウドAPIを叩く」です！
curlを用いて複数のURLを解析【PageSpeed Insights（ページスピードインサイト）】

モバイルファーストインデックス、AMP、構造化データとモバイルファーストな時代がやってきていますが、共通するのが、いかにモバイルユーザーによりよい体験をしてもらえるかということ。

その中でも、グーグルなどの検索エンジンはモバイル端末での速度を重視しています。理由として、モバイル端末はPC端末に比べると回線速度が遅くなることがあるからです。
例としては、町の中心部だと4GやLTEが使えるのに町外れに行くと3Gしか使えない感じです。

そういった経緯もあり、Googleが提供する[PageSpeed Insights（ページスピードインサイト）](https://developers.google.com/speed/pagespeed/insights/?hl=ja)を使っている方は多いかと思います。

こんな感じで、デスクトップ（PC）とモバイルでのページ速度が100点満点で表示されます。

![ss 2016-12-11 10.56.14.png](https://qiita-image-store.s3.amazonaws.com/0/153088/90baee93-c74e-5707-33b9-0bd492a69bbb.png)

## スコアをまとめて取得したい。

しかし、PageSpeedInsightsでは、基本的に１個のURLに対してスコアが表示される形で、複数のURLには対応していません。
まぁ確かに、ニュース系のサイトであれば、

1. トップページ
2. カテゴリートップページ
3. 記事詳細ページ

の３パターンのスピードをチェックすればほぼ、サイトは網羅できます。

ですが、

* 全ページローラー作戦的にページスピードのスコアを取得したい。
* 複数ドメインでページスピードのスコアを取得したい。

といった時に、URLの数が10個や20個となると１つ１つ取得するのは大変面倒です。
そこで今回はAPIを利用してまとめて取得する方法を紹介します。

## APIを利用して一括取得する方法

### その1. PageSpeed Insights API の API キーを発行

[Google Cloud Platform](https://console.developers.google.com/projectselector/apis/credentials)にログインしてAPIキーを発行します。

![ss 2016-12-11 12.01.33.png](https://qiita-image-store.s3.amazonaws.com/0/153088/731a8ba8-7cb3-aa6a-5213-c882bc4547a6.png)


### その2. 解析したいURLを「url.txt」などとして作成しておく。

``` txt:url.txt
http://www.yahoo.co.jp/
https://www.google.co.jp/
https://www.amazon.co.jp/
http://www.rakuten.co.jp/
http://ameblo.jp/
http://zozo.jp/
```

### その3. PHPスクリプトを作成してAPIキーを入れる。

``` php:mobile.php
<?php
// APIキー
$key = "Your API KEY";
// mobile or desktop
$strategy = "mobile";
// URLリスト読み込み
$lines = file('url.txt', FILE_IGNORE_NEW_LINES);
// URLの分だけAPIリクエストして解析

foreach ($lines as $url) {
    $api = "https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=".$url."&strategy=".$strategy."&key=".$key;
    $ch = curl_init(); // 1. curl 初期化
    curl_setopt( $ch, CURLOPT_URL, $api ); // 2. curl オプションを設定
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    $json = curl_exec($ch); // 3. curl 実行してデータを得る
    curl_close($ch); // 4. curl 終了
    $data = json_decode($json);
    if ($data->responseCode == 200) {
        $score = $data->ruleGroups->SPEED->score;
    } else {
        $score = "error";
    }
    echo $url.",".$score."\n";
}

```

### その4. ターミナルで実行する。

``` txt
$ php mobile.php
http://www.yahoo.co.jp/,61
https://www.google.co.jp/,100
https://www.amazon.co.jp/,62
http://www.rakuten.co.jp/,75
http://ameblo.jp/,56
http://zozo.jp/,49
```

個人的にはamazon、楽天があれだけの情報量にもかかわらず、60点以上というのは、非常に高いのかなと思います。
あとgoogleのトップページは検索窓だけなので、やはり100点ですね笑

## 参考サイトについて

この記事を投稿する前までは、[@ko31さんの記事](http://blog.ko31.com/201602/pagespeed-insights-api/)のまま使わせてもらっていたのですが、ある時から、

```

Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

```

と表示され、file_get_contentsにおいてエラーが発生してしまい使えなくなってしまったので、file_get_contentsの代替にcURLを使うという方法でコードを書き直したのが今回になります。

なので、ベースのコードである@ko31さんと[cURLの記事](http://blog.mach3.jp/2010/12/21/use-curl-for-filegetcontents.html)を参考させてもらった@mach3ssさんには感謝です。

## 最後に

上のエラー文について、なんとかターミナル上でfile_get_contentsが利用できないか、試行錯誤してみたのですが、できなかったので、また時間がある時に考えてみます。

それでもトラブル解決できてよかったです。
Atomをちょっと便利なメモ帳として使う


# 基本
[CheatSheet](https://www.cheatsheetapp.com/CheatSheet/)を見てショートカットに慣れる。

よく使うショートカットは
Command+, （設定画面を開く）
Commond+n （新規ファイルを開く）
Command+f （ファイル内検索）
Shift+Command+f （プロジェクト内検索）
Command+p （ファイル名検索）
Control+0 （ツリービューとタブを切り替え） 
など。

# パッケージ
パッケージで提供される機能（コマンド）はコマンドパレットで実行する。
Shift+Command+p （コマンドパレット起動）
コマンドにもショートカットが割り当てられてる場合があるので、
よく使うコマンドは覚える。

## [japanese-menu](https://atom.io/packages/japanese-menu)
メニューや設定画面を日本語化する。

## [project-manager](https://atom.io/packages/project-manager)
登録したプロジェクト（フォルダ）を簡単に切り替えることができる。
### プロジェクト登録
フォルダを開いている状態で、コマンドパレットで
「Project Manager: Save Project」
を実行する。

### プロジェクト一覧表示、切り替え
Control+Command+p （プロジェクト一覧表示）
からプロジェクトを選択して切り替える。

## [file-icons](https://atom.io/packages/file-icons)
ファイル名の横にファイルの種類が分かるアイコンを表示する。

## [minmap](https://atom.io/packages/minimap)
画面右側にファイル全体を表示する。

## [split-diff](https://atom.io/packages/split-diff)
ファイルの差分を確認する。
コマンドパレットで
「Split Diff: Enable」
を実行する。

## [minimap-split-diff](https://atom.io/packages/minimap-split-diff)
minmap上でもsplit-diffでの差分を表示する。

## [lines](https://atom.io/packages/lines)
行のソートやユニーク化ができる。
コマンドパレットで
「Lines: Sort」
「Lines: Unique」
を実行する。

## [pretty-json](https://atom.io/packages/pretty-json)
JSONのPrettify、Minifyができる。
コマンドパレットで
「Pretty-Json: Prettify」
「Pretty-Json: Minify」
を実行する。

## [vim-mode-plus](https://atom.io/packages/vim-mode-plus)
vimの人用。
vim-modeというパッケージもあったが、Deprecatedになっていた。

# 設定
## エディタ設定
お好みでカスタマイズする。

フォント
font-family
⇒Osaka-Mono

不可視文字を表示
⇒有効
【質問】JSのDOMContentLoadedが発火しません。

【質問】JSのDOMContentLoadedが発火しません。

■事象
iframeを動的に作成(createElement)して、
addEventListenerに「DOMContentLoaded」を追加しているが、
iframeのsrc先のDOM読み込み完了時にイベントが発生しません。

■コーディング
var parent_obj = document.getElementById("top");
var obj = document.createElement('iframe');

if(obj.addEventListener){
	obj.addEventListener("DOMContentLoaded",xxx);//★これが発火しない
	//obj.addEventListener("load",xxx);//☆遅い
}else if(obj.attachEvent){
	obj.attachEvent("onload",xxx);
}else{
	obj.onload = xxx;
}

parent_obj.appendChild(obj);
obj.src = "URL";

function xxx(e){
	alert("発火");★これが発火しない
}

■やりたい事
addEventListener("load",xxx)だと画像読み込み後にイベントが発生するので、遅いです。
iframeのソースが返ってきた直後にイベントを呼びたいのです。

■質問
なぜDOMContentLoadedが発火しないのでしょうか。
コーディングが悪いのでしょうか？

それともcreateElement('iframe')はDOMContentLoadedのイベントに対応していないのでしょうか？
その場合、上記【やりたい事】の代案はございますでしょうか？
goのメモリプロファイリングツール「pprof」

## pprof
[`net/http/pprof`](https://github.com/golang/go/blob/master/src/net/http/pprof/pprof.go)は、[`runtime/pprof`](https://golang.org/pkg/runtime/pprof/)をwrapしているGoの標準ライブラリです。

これすごくよいです。
`net/http`でサーバ立てておいて特定のurlを叩くと、
そのプロセスのメモリプロファイル情報を出力してくれます。
以下は`/debug/pprof/heap?debug=1`の例です。
(heapの他に、goroutine, threadcreate, block等々あります)

```pprof_sample.go
package main

import (
  "fmt"
  "net/http"
  _ "net/http/pprof"
)

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w, "hello, world")
}
```

```
$ curl http://localhost:8080/debug/pprof/heap?debug=1
heap profile: 0: 0 [0: 0] @ heap/1048576

# runtime.MemStats
# Alloc = 584992
# TotalAlloc = 584992
# Sys = 2822144
# Lookups = 5
# Mallocs = 4958
# Frees = 98
# HeapAlloc = 584992
# HeapSys = 1769472
# HeapIdle = 876544
# HeapInuse = 892928
# HeapReleased = 0
# HeapObjects = 4860
# Stack = 327680 / 327680
# MSpan = 13600 / 16384
# MCache = 4800 / 16384
# BuckHashSys = 2598
# NextGC = 4194304
# PauseNs = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# NumGC = 0
# DebugGC = false
```
さらに`go tool pprof`をかませることで人間が読みやすい形で出力してくれます。
上記のサンプルコードだとemptyが返ってきてしまうのですが、
標準入力待ちになったら`text`と打てば出力されます。

```
$ go tool pprof http://localhost:8080/debug/pprof/heap?debug=1
(pprof) text
```

これを使ってメモリリークの原因ぽいで！ってところをどんどん潰していきたいですね。
RubyでBigQueryから引っ張ってきたデータをそのままテーブルに突っ込む


## 前置き
bigqueryとはなんぞや？という話はしません。(当方よくわかっていないので)
簡単なrubyスクリプトをメモ書き程度に残します。

## 使ったライブラリ
- [google-cloud-bigquery](https://github.com/GoogleCloudPlatform/google-cloud-ruby/tree/master/google-cloud-bigquery)

え、[google-api-client](https://github.com/google/google-api-ruby-client)じゃないの？と思われる方いるかもしれませんが、今回はgoogle-cloud-rubyを使いました。理由としては、

- クエリ叩いて、返ってくる値が [{field: value}] の形式だったから、そのままデータを突っ込めるから。
	- google-api-clientだとfield: valueの形式で取れなかった。
	- こういった違いがなぜあるのかはよくわかっていない。
- http://googlecloudplatform.github.io/google-cloud-ruby/ ページ下部のFAQに、google-cloudライブラリは、GCP専用で、Rubyと統合するための推奨って書いてある。
	- GCP以外のAPI(Gmailとか)使いたいときは、google-client-ruby使うって解釈した。

## 簡単なスクリプト解説
### 認証
```ruby:
require "google/cloud/bigquery"

big_query = Google::Cloud::Bigquery.new(
  project: "プロジェクトID",
  keyfile: "key_fileへのPATH"
)
```
これだけ。簡単☆

### データセット
```ruby
data_set = big_query.dataset("データセット名")

# データセット作りたいときは
data_set = big_query.create_dataset("データセット名")
```
どのデータセットにテーブル作るか。

### ジョブとテーブル
```ruby
job = big_query.query_job(sql)
job.wait_until_done!
unless job.failed?
  current_row = 0
  result = job.query_results
  table = big_query.create_table("テーブル名", fields: result.fields)
  while current_row < result.total
    result = job.query_results(start: current_row) unless current_row == 0
    table.insert(result)
    current_row += result.size
  end
```
取得するデータ量が多いと、自動的に分割されて取得してくるので、何回かに分けて、query_resultsを実行する必要がある。result.totalで合計数が取得できるので、ループごとに1回のquery_resultsで取得した数をoffset値として足していき、startでoffset値を指定してquery_resultsを取得して、テーブルへインサートする。これを繰り返して、offset値が合計数より上回ったら終了。

## 所感
やりたいことがシンプルだったので、比較的簡単なコードになったが、もう少し複雑なことをすると大変そうだし、取ってきたデータをruby上で操作するのは、マシン的につらそうなので、できるだけクエリを最適化して、rubyではあくまで自動的に実行するだけ、みたいにしたい。そのためにBigQueryのクエリを学ばねば...

google-api-clientとの違いについても、おざなりに理解しているので、調べたい。(些細な事でもご存知の方おられましたら、ご教授願いたいです)
SwiftでFreeモナド


この記事は[Swift Advent Calendar その2](http://qiita.com/advent-calendar/2016/swift2)の10日目の記事です。

ふと見たら空いてたので、軽めの内容で補填しておきます。

Swiftでは`Functor`も`Monad`も定義できません。ただし、特定の型においてのみメリットを享受することはできます。

FreeモナドのHaskell実装は以下の通りです。

```haskell
data Free f r = Free (f (Free f r)) | Pure r

instance Functor f => Monad (Free f) where
    return = Pure
    Pure a >>= k = k a
    Free fm >>= k = Free (fmap (>>=k) fm)
```

要素rのみとる値コンストラクタ`Pure`と、`f (Free f r))`をとる値コンストラクタ`Free`からなります。大事なのは`instance`文に書かれているように、「`Functor`なものが`Free`を用いることで`Monad`になる」ということです。`Functor`をmapできるもの、`Monad`をflatMapできるものと簡易的に考えるならば、Swiftにおいてイメージしやすくなるのではないでしょうか。

Swift.Arrayに特化したFreeモナドのようなものとして`FreeArray<T>`を以下のように定義します。


```swift
indirect enum FreeArray<T> {
	case pure(T)
	case impure([FreeArray<T>])
}

extension FreeArray {
	func map<U>(_ f: (T) -> U) -> FreeArray<U> {
		switch self {
		case .pure(let t):
			return .pure(f(t))
			
		case .impure(let list):
			return .impure(list.map{ $0.map(f) })
		}
	}
	
	func flatMap<U>(_ fn: (T) -> FreeArray<U>) -> FreeArray<U> {
		switch self {
		case .pure(let t):
			return fn(t)
			
		case .impure(let list):
			return .impure(list.map{ $0.flatMap(fn) })
		}
	}
}
```

`impure`の方は`map`メソッドを実装している`Array`が`FreeArray`を包んでいます。つまりHaskell実装における値コンストラクタ`Free`に相当します。

定義できはしましたが、これの何が嬉しいのでしょうか。例えば以下のようなことができます。


```swift
extension FreeArray : ExpressibleByArrayLiteral {
	init(arrayLiteral elements: FreeArray<T>...) {
		self = .impure(elements)
	}
}

prefix operator %
prefix func % <T>(element: T) -> FreeArray<T> {
	return .pure(element)
}

let a: [Int] = [1]
let b: [Int] = [[[[[[[[1]]]]]]]] // NG

let c: FreeArray<Int> = %1
let d: FreeArray<Int> = [[[[[[[[%1]]]]]]]] // OK
```

いくら包んでやっても同じ型になります。最初に`map`も`flatMap`も定義したので、もちろん使えます。`FreeArray`を`Collection`に準拠させるとこのようなこともできます。

```swift
extension FreeArray: Collection {
	var startIndex: Int {
		return 0
	}
	
	var endIndex: Int {
		switch self {
		case .pure(_):
			return 1
			
		case .impure(let list):
			return list.reduce(0){ $0 + $1.endIndex }
		}
	}
	
	subscript (index: Int) -> T {
		guard startIndex <= index && index < endIndex else {
			fatalError("range over")
		}
		
		switch self {
		case .impure(let list):
			var i = 0
			for aList in list {
				if index < i + aList.endIndex {
					return aList[index - i]
				}
				
				i += aList.endIndex
			}
			
			fatalError("is end")
			
		case .pure(let t):
			guard index == 0 else {
				fatalError("")
			}
			
			return t
		}
	}
	
	func index(after i: Int) -> Int {
		return i == endIndex ? i : i + 1
	}
}

let freeList: FreeArray<Int> = [%1, [%2, %3, [%4]], %5]
freeList.reduce(""){ "\($0) \($1)" } // "1 2 3 4 5"
```

Enjoy Swift life!

### 参考

[Freeモナドって何なのさっ！？](http://d.hatena.ne.jp/its_out_of_tune/comment/20121111/1352632815)
[free monadとはmonadそのものである](https://kimiyuki.net/blog/2013/12/29/free-monad-is-monad-itself/)
cgoを使ったサンプルコード

## cgo
cgoはGo標準ライブラリで、GoからCのコードを実行できるようになります。
詳細は[GoDoc](https://golang.org/cmd/cgo/)をご覧いただきたいですが、
以下のサンプルコードのような形でGoからCコードを実行できます。

```cgo_sample.go
package main

// 読み込むCコード片を、'import "C"'の真上にコメントの形で書く必要がある
/*
#include <stdlib.h>
#include <stdio.h>

void hello(char *str)
{
  printf("hello, %s\n", str);
}
*/
import "C"
import "unsafe"

func main() {
  greetingTo := C.CString("cgo")
  // CStringで得たCのstring型は必ず解放しなければならない
  defer C.free(unsafe.Pointer(greetingTo))
  C.hello(greetingTo)
}
```
実行

```
$ go run cgo_sample.go
or
$ go build
$ ./cgo_sample
=> hello, cgo
```
GoからCのコードを実行することができました。
お手軽ですが、特定の型は自前で解放しなければいけなかったりするので注意が必要です。
NGINXのproxy_hostを動的に指定する(リバースプロキシ)

# 動的にproxy_hostを変える
NGINXのLua拡張を用いると色々と変数を用いて書き換えたり出来て、自由度が更に高くなります。
今回は動的に向き先を変えてほしいという依頼がきたので試してみましょう。

### 用意から行なう場合にはこちらも
CentOS7のNginxのLua拡張の用意の方法であればこちらが大変参考になります。
http://marmotte.pyrites.jp/blog/2015/10/17/build-for-nginx-plus-lua/  

(yum installで入手できるnginxはLua拡張されていないのでrewrite_by_luaなどが使えません。)


## 試してみる
今回私が試したのは、

- サブドメインがなければ、サブドメインを付けないでホストを指定
- サブドメインがあったら、指定されているサブドメイン付きでホストを指定

という動きを期待したリバースプロキシ。
(※環境はDocker上のCentOS 7)

**例：**

- http://new.com → NGINX → http://old.com
- http://hoge.new.com → NGINX → http://hoge.old.com

というわけで書いたconfはこんな感じ。

## nginx.conf

```lua
http {

    # ~~ 中略 ~~~

    # /etc/resolv.confにかいてあるnameserverのIP
    resolver 10.0.2.3 valid=2s;

    server {
        listen       80;
        server_name  .new.com;

        # proxy_set_header    Host               'old.com'; # old.comで固定したい場合
        proxy_set_header    X-Real-IP          $remote_addr;
        proxy_set_header    X-Forwarded-Host   $host;
        proxy_set_header    X-Forwarded-Server $host;
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

        location / {
            set $upstream "";

            # Dynamic rewrite for proxy_pass
            rewrite_by_lua '
                ngx.var.upstream = "old.com";

                domain_table = {}
                for i in string.gmatch(ngx.var.host, "([^.]+)") do
                    table.insert(domain_table, i)
                end

                if table.getn(domain_table) == 3 then
                    ngx.var.upstream = domain_table[1] .. "." .. ngx.var.upstream
                end
            ';

            proxy_pass http://$upstream;
        }
    }
}
```
※4つ目のドメインは知らない漢(おとこ)の設定


rewrite_by_lua内でLuaの記述を行い、変数を書き換えています。
但し、resolverでそのサーバーのDNSを指定しないと動かないです。
(と、ここのコメントにそんな感じのことが書いてある気がする。
http://stackoverflow.com/questions/26956979/error-with-ip-and-nginx-as-reverse-proxy#comment42490335_26957754 )


そして、upstream変数をこんな風に書き換えてしまっても良かったのかしらというところが個人的にもやもやしてたりします。m(＿ ＿)m
ES6で書くRiot - Felt編


[Advent Calendar](http://qiita.com/advent-calendar/2016/riotjs)の10日目です。(すみません、Mac故障につき遅刻しました...) 近年、JavaScriptでプログラムを書くのに避けて通れない「プリコンパイル」について、Riotの文脈で3本ほど書いてみたいシリーズの3本目です。

- [ES6で書くRiot - riot.config.js編](http://qiita.com/cognitom/items/200a96b86eafc463ed24) - ([サンプルコード](https://github.com/riot/examples/tree/gh-pages/riot-config))
- [ES6で書くRiot - Rollup編](http://qiita.com/cognitom/items/c20c22614560627062cb) - ([サンプルコード](https://github.com/riot/examples/tree/gh-pages/rollup))
- ES6で書くRiot - Felt編 - ([サンプルコード](https://github.com/cognitom/felt-example-riot/))

前回まで、各種のツールを組み合わせて「いろいろ乗り越えて使う」印象が強かったかと思いますが、正直避けて通りたいです。もっと、簡単にRiotを始める方法はないのでしょうか? それが、今回のテーマです。

## Feltとは

Feltは一種のHTTPサーバです。将来(1,2年先)の標準で書いて、JavaScript(ES6)やCSS(css4)で書けば、ブラウザには自動的にES5など現在のブラウザが対応するものに変換した状態で送出されます。つまり、riot.config.js編、Rollup編と2回にわたって説明してきた、トランスパイラやバンドラについて、気にする必要がなくなります。

![6d24a8df-14f1-66a8-fe82-c6c07cea43a8.png](https://qiita-image-store.s3.amazonaws.com/0/1858/a2c22b66-9e13-0f10-e2e9-ca82ad6e5969.png)

## 3ステップで試す

チュートリアル用に[使用例のリポジトリ](https://github.com/cognitom/felt-example-riot/)を用意しました。[こちらからダウンロード](https://github.com/cognitom/felt-example-riot/archive/tutorial.zip)してください。

ダウンロードしたファイルを解凍すると`felt-example-riot-tutorial`というフォルダができているはずです。ターミナル(黒い画面)を開いて、その中に移動しましょう。

```bash
$ cd felt-example-riot-tutorial
```

### Step 1: ライブラリのダウンロード

この例では、次のライブラリ(モジュール)を`import`して使っています。

- `riot`: Riotのライブラリ本体
- `marked`: Markdownで書かれたテキストをHTMLに変換するライブラリ

**メモ**: `marked`は例として使っているだけなので必須ではありません。実際に自分のサイトで使う際は、必要に応じたライブラリを読み込んでください。

どんなライブラリを使うかはプロジェクトごとに異なるので、システム全体ではなくプロジェクト(フォルダ)内にインストールします。まずは下準備で次のコマンドを実行します。

```bash
$ npm init -y
```

これで`package.json`というファイルが作成されたはずです。続けて、次のコマンドを実行しましょう。

```bash
$ npm install -S riot marked
$ npm install -D felt felt-recipe-riot
```

1行目で上述のライブラリのインストール、2行目でFeltとその「レシピ」をインストールしています。それぞれのコマンドの実行に1,2分かかるので気長に待ちます。

### Step 2: 起動スクリプトを書く

`package.json`を開くと、`"test": "echo \"Error: no test specified\" && exit 1"`の一行があるはずです。この行の代わりに`start`スクリプトとして`felt -r riot`を追加します。全体としては次のような内容になります。

```javascript
{
  "name": "felt-example-riot-tutorial",
  ...
  "scripts": {
    "start": "felt -r riot --debug"
  },
  ...
  "dependencies": {
    "marked": "^0.3.6",
    "riot": "^3.0.2"
  },
  "devDependencies": {
    "felt": "^0.3.0",
    "felt-recipe-riot": "^0.2.1"
  }
}
```

**メモ**: 上記、バージョン番号については、執筆時の最新なので多少変わっていても構いません。
**メモ2**: `felt`のコマンドに`--debug`フラグを追加しておくと、`felt`がどんな働きをしているかわかりやすいです。

### Step 3: サーバの起動

あとは、もうWebサーバを起動するだけです。次のコマンドを実行して、ブラウザで`http://localhost:3000`を開いてみましょう。

```bash
$ npm start
```

> Hello **Rollup**!

と表示されていれば成功です :smile:


## まとめ

最初は、黒い画面や`package.json`の扱いが面倒に思えるかもしれません。ただ、Riotを含めてnpmのライブラリは必ず必要になってくるので、その点だけは乗り越えてしまいましょう。ただ、いままでの2編(riot.config.js, Rollup)と比べると、各段に簡単だったのではないかと思います。

- レシピが[felt-recipe-riot](https://github.com/cognitom/felt-recipe-riot)として用意されている
- バンドル後のファイルの置き場所を気にしなくていい

などの点が大きいですね。まずは、Feltで簡単に始めて、開発の規模やサーバ環境に応じて(Nodeが動かせるかほか)、Rollupやwebpackに取り組むとよいのではないでしょうか。

Feltについての詳細は、以前[こちらの記事](http://qiita.com/cognitom/items/010dd3b9a0c0a5dd22d0)にまとめました。詳しくはそちらをどうぞ。