OmniAICreator/Qiita-1.07M huggingface dataset:
UCS-2 か UCS-4 かによって len や unichr の戻り値が変わることがある

Mac OS X の標準の Python 2 は UCS-2 でビルドされているため、Linux ディストリービョンで広く採用されている UCS-4 の場合と比べて、標準関数の len や unichr が返す値が異なることがある。

## UCS-2 のビルドオプションでのふるまい

ビルドオプションが UCS-2 である場合、U+10000 とそれ以降の文字が含まれる場合、len をそのまま使って文字数を求めることはできない。homebrew で導入した場合も USC-2 でビルドされる。

ビルドオプションに UCS-2 が指定されたかどうかを調べるには sys.maxunicode の値を使う。

```py
>>> import sys
>>> 0xFFFF == sys.maxunicode
True
```

次の文字列 (U+20BB7 U+91CE U+5BB6) に len を適用すると、戻り値は4になる。

```py
>>> str = u'?野家'
>>> 4 == len(str)
True
```

U+20BB7 の内部表現はサロゲートペアの U+D842 U+DFB7 となる。

```py
>>> 0xD842 == ord(str[0])
True
>>> 0xDFB7 == ord(str[1])
True
```

## UCS-2 を考慮して文字数を求める

上位サロゲートの範囲は U+D800 から U+DBFF までであることを踏まえて、文字数を求めてみよう。コードをかんたんにするために、上位サロゲートもしくは下位サロゲートが孤立する場合は考慮しない。UCS-4 であれば、for ループを使うことができる。

```py
# -*- coding: utf-8 -*-

import sys

def utf8_len(str):

    length = 0

    if sys.maxunicode > 0xFFFF:
        for c in str:
            length += 1

        return length

    code_units = len(str)
    pos = 0
    cp = -1

    while pos < code_units:

        cp = ord(str[pos])
        length += 1

        if cp > 0xD7FF and 0xDC00 > cp:
            pos += 2
        else:
            pos += 1

    return length
```

先ほどの文字列を再度試してみよう。

```py
str = u'?野家'
print(3 == utf8_len(str))
```
練習として、少しコードを修正して、1文字ずつコールバックを適用する関数を定義してみよう。

```py
# -*- coding: utf-8 -*-

import sys

def utf8_each_char(str, func):

    if sys.maxunicode > 0xFFFF:
        for c in str:
            func(c)
    else:
        code_units = len(str)
        pos = 0
        buf = ''
        cp = -1

    while pos < code_units:
        buf =str[pos]
        cp = ord(buf)

        if cp > 0xD7FF and 0xDC00 > cp:
            buf += str[pos+1]
            func(buf)
            pos += 2
        else:
            func(buf)
            pos += 1
```

1文字ずつ表示してみよう。ラムダ式で print を使うには print_function をファイルの冒頭でインポートする必要がある。

```py
from __future__ import print_function

str = u'?野家'
f = lambda c: print(c)
utf8_each_char(str, f)
```

## UCS-2 を考慮してコードポイントから文字を生成する

USC-2 の制約はコードポイントの整数から文字を生成する unichr も受け、0x10000 とそれ以降の整数を受けつけない。

```py
>>> unichr(0x20BB7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unichr() arg not in range(0x10000) (narrow Python build)
```

Unicode エスケープシーケンスは UCS-2 の影響を受けない。

```py

>>> print(u"\U00020BB7")
?
```

UCS-2 の制約を考慮したユーザー関数を定義すると次のようになる。

```py
# -*- coding: utf-8 -*-

import sys

def utf8_chr(cp):
    if 0xFFFF < sys.maxunicode or cp < 0x10000:
        return unichr(cp)

    cp -= 0x10000
    high = cp >> 10 | 0xD800
    low = cp & 0x3FF | 0xDC00

    return unichr(high) + unichr(low)

print(utf8_chr(0x20BB7))
print(utf8_chr(0x91CE))
```
gitの複数のブランチを一括で削除する


gitで開発を行っていると、不要なブランチが溜まってきて削除したくなることがあります。

以下のコマンドでgitのブランチを削除できますが、一回のコマンドで一つのブランチしか削除できません。

```
git branch -d <ブランチ名>
```

そこで、以下のようにすることで <文字列> にマッチするブランチを一括で削除することができます。

- while を使った例

```
git branch | grep <文字列> |  while read branch ; do git branch -d ${branch} ; done ;  
```

- xargs を使った例

```
git branch | grep <文字列> | xargs git branch -d
```

xargsの方が簡単ですね。
世界最速でFluentdを立ち上げる on Heroku

# Treasure Agentをさらに使いやすく

ご存知の方も多いかと思いますが、トレジャーデータ社では、out_tdプラグインを使うことで、Fluentdから簡単にデータを流し込めるようになっています。これはHeroku上でも動くようになっており、[heroku-td-agent](https://github.com/treasure-data/heroku-td-agent)として公開されています。

ただこれ、意外と面倒くさいです。具体的には

1. Treasure Dataのアカウントを持っていることが前提。
2. そして[APIキー](http://docs.treasuredata.com/articles/get-apikey)をメモ。
3. GitHubのHerokuアプリをクローンしてきて
4. bundle install...

あああああああああああああああああああ、やってられるかボケえぇぇぇ!!!!

これではいかん。せっかくHerokuという、ソフトウェアのデプロイを抹殺してくれたプラットフォームにいるんだ。その恩恵を100％受けてやろうじゃないか。

#出ましたTreasure Agent Herokuボタン

ということでHerokuボタンの登場です。[Herokuボタンに関する説明](http://d.hatena.ne.jp/naoya/20140809/1407556488)はテクニカルsushiアドバイザーの方にお任せしまして、ここでは実際にやり方を記述します。

1. ブラウザ上でHerokuにログインした状態で
2. [このリンク](https://heroku.com/deploy?template=https://github.com/kiyoto/heroku-td-agent)をクリック

するとこんな画面が出てきます。

<img src="https://raw.githubusercontent.com/kiyoto/heroku-td-agent/master/heroku-td-agent-screenshot.png"/>

スクショの下となってしまいますが、"Deploy for Free"ボタンを押すとTreasure Agentが起動されます。そう、たったこれだけです。

**このワンクリックデプロイは、トレジャーデータの既存アカウントにデータを入れたい場合にも使えます。**その場合は、既存トレジャーデータアカウントのAPIキーを、`TREASURE_DATA_API_KEY_OVERRIDE`（緑の枠のとこです）にコピペしてから"Deploy for Free"ボタンを押してください。

大事なことなのでもう一度。**ボタンを二回押すだけで、HTTP経由でトレジャーデータにデータが流し込めるようになりました。**

#挙動を確認

インプットとして、[in_http](https://docs.fluentd.org/ja/articles/in_http)をサポートしています。例えばHerokuのアプリ名がaoiyuだとして、

```bash
curl -X POST aoiyu.herokuapp.com/td.db_name.table_name -d 'json={"message":"hello world"}'
```

みたいにHTTPリクエストを送ると、バファリングされた後、トレジャーデータにアップロードされます。

以上です。~~今のところはぼくの個人レポジトリにありますが、近いうちに本家にマージされる予定です。~~**[本家にマージしました。](https://github.com/treasure-data/heroku-td-agent)**

バグ報告、他のバックエンドへのポートなどなど、お待ちしております！
Rails selectでinclude_blankやpromptを表示する


自分向けのメモです。


```ruby

# include_blankやpromptは３番目の引数(タグ情報)に指定する

 f.select :prefecture, Prefecture.all.map { |obj| obj.value },{include_blank: true}, {class: 'form-control'} 
```

selectにclass属性を適用する場合は、4番目の引数(オプション)に指定する

```ruby
 f.select :prefecture, Prefecture.all.map { |obj| obj.value },{}, {class: 'form-control'} 

```
テスト環境で使えるクレジットカード番号

ECサイト開発中にテスト環境で使えるクレジットカード番号です。

## テストで使えるクレジットカード番号一覧

* テスト環境では、本物のクレジットカードの代わりに以下のテスト番号を使って、課金処理をテストすることができます。

| クレジットカード番号 | カードの種類 |
|:--|:--|
| 4111111111111111 | Visa |
| 4242424242424242 | Visa |
| 4012888888881881 | Visa |
| 5555555555554444 | MasterCard |
| 5105105105105100 | MasterCard |
| 378282246310005 | American Express |
| 371449635398431 | American Express |
| 30569309025904 | Diner's Club |
| 38520000023237 | Diner's Club |
| 3530111333300000 | JCB |
| 3566002020360505 | JCB |

* 実在するカード番号を利用することもできます。
* カードの番号として妥当であれば上記以外の番号も利用することができます。
* こちらのページで、番号の確認ができます。
[【PHP】クレジットカードチェックサンプル](http://blog.so-lat.com/service/card.php)

## カード番号以外の情報について
基本的に何でも大丈夫です。

* 名前・・・スペース区切りで名字と氏名を記入した名前なら何でも使用できます。(例: Taro Tanaka)
* 有効期限・・・現在時刻より未来の年月を有効期限として指定してください。
* セキュリティーコード・・・適当な任意の3桁か4桁の数字を入れてください。

## エラーさせるカード番号
テスト環境では、有効期限切れや、カード会社に決済を拒否されたり、偶発的に接続へ失敗した場合などに発生する例外（card_error）を、以下の番号を指定することで意図的に発生させることができます。

| クレジットカード番号 | card_errorのcode | エラー内容 |
|:--|:--|:--|
| 4000000000000002 | card_declined | カードが決済に失敗しました |
| 4000000000000127 | incorrect_cvc | セキュリティーコードが間違っています |
| 4000000000000150 | incorrect_expiry | 有効期限が間違っています |
| 4000000000000119 | processing_error | 処理中にエラーが発生しました |
| 4242424242424241<br>（ [Luhnアルゴリズム](http://ja.wikipedia.org/wiki/Luhn%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0)でのチェックに通らない番号） | incorrect_number | カードの番号が不正です |

以下の番号を指定することで、トークン作成時や顧客作成時にはエラーにならず、課金する時にエラーを発生させることができます。

| クレジットカード番号 | card_errorのcode | エラー内容 |
|:--|:--|:--|
| 4000000000080202 | card_declined | カードが決済に失敗しました |
| 4000000000080327 | incorrect_cvc | セキュリティーコードが間違っています |
| 4000000000080350 | incorrect_expiry | 有効期限が間違っています |
| 4000000000080319 | processing_error | 処理中にエラーが発生しました |

これら以外のカードに関する例外は、有効期限が指定されているフォーマットに従わないなど、カード番号以外の部分で引き起こすことができます。

| エラー引き起こす方法 | card_errorのcode | エラー内容 |
|:--|:--|:--|
| card[name]に"田中太郎"などA-Z,a-z,半角スペース以外の文字列を含んで指定する | invalid_name | カード名義のフォーマットが不正です |
| card[exp_month]に"13"など1-12の数字以外を指定する | invalid_expiry_month | カードの有効期限の月が不正です |
| card[exp_year]に"1980"など過去の年を指定する | invalid_expiry_year | カードの有効期限の年が不正です |
| card[cvc]に"12"など数字3,4桁以外を指定する | invalid_cvc | カードのセキュリティーコードが不正です |
| active_cardを持たないCustomerを用いてChargeを作成する | missing | 請求を行った顧客にカードが紐付いていません
私がPythonにはまった5つの理由

##はじめまして

　かたやなぎです。
　農業系独法研究機関で契約研究員として生態系の物質動態をモデルを使って予測する研究をやっています。
　
　技術者でもなく、プログラミング初心者で、Pythonは今年の5月から始めたばかりの私ですが、PyDataの師匠からこのカレンダーを紹介されて、勢いでエントリしてみました！
　
　今日は最近使っているRとはまっているPythonのことを書こうと思っていたのですが、どちらも初心者でたいしたことが書けないと気づいたので、今年、自分のPython熱がなぜこんなにも上がったのかを振り返るべく、**私がPythonにはまった理由**を5つにまとめてみました。

　では早速5つの理由へGO!

##私がPythonにはまった5つの理由
###1. 整理すべき大量のデータが現れた。

手で整理するには気が遠くなる数のcsvファイルを整理して解析しなければならなくなった。
手でデータ抽出とかありえない、もうプログラミングするしかない。


###2. Natureにも論文が掲載されている同じ研究分野のスター研究者がPython使ってるらしいという情報を聞いたことがあった。

　モデリング研究をやっている優秀な研究者仲間から、インタプリタ型言語を一つ覚えておくと便利だよってアドバイスをもらった。

　よし、インタプリタ型言語なるものに着手してみよう。
　アドバイスくれた人はPerlユーザーだから、同じ言語選択した方がわからないこと聞きやすくていいかな？
　でもいまはPythonが人気？
　そういえば、ドイツのスター研究者もPythonやっているって以前小耳にはさんだな。
　**いつかドイツにいって一緒に仕事する機会があったらPythonできたら便利だよね?**
　うん、Pythonやろう。

  アドバイスくれた先輩ごめんなさい。ミーハー心に勝てませんでした。

###3. 難しそうだと思っていた作業が初心者の私でもあっさりできてしまった。

　Pythonを始める少し前に上司が入れてくれた仮想マシンのCentOSにPythonがインストールされていたため、あっさりPython稼働。
　しかもPython＋PSQLでさくっと大量のデータ処理が完了。
　（PSQLは使わなくてもよかったのかもしれないけど、ちょうどしばらく前に使い始めていたので、使ってみた）
　学習コストも含めてExcelでやるより早かった。

　私でもPythonならさくっとできるかも？（勘違い）

###4. ファイルの処理もデータ解析もPython一本でいけることを知った。
　Rは周囲にユーザー多いし、コード書き楽だし、聞けばすぐ教えてくれるし便利なんだけど。
　でもループ計算苦手っていうし、ファイルの処理からRでやってたら時間かかりそうだな。
　え？Pythonならファイル処理もデータ解析もRより高速ででできちゃう？
　numpyとかscipyとか拡張モジュールがあって、結構科学コミュニティで使われている？
　**目的に応じてツールを使い分ける必要なし？**

　やっぱりPythonできたら便利だな－。

###5. コミュニティの雰囲気がよかった。
　あっさり動いて浮かれたのもつかの間、scipyとかnumpyとかどうやったら使えるのかわからない（涙）
　やっぱり人に聞くのが早いよね-->PyConJP2014+PyDataチュートリア参加。

　チュートリアル自分にとってはレベル高すぎ。でもなんかPyDataできそうな気がしてきた。
　PyConJP2014もおもしろいプレゼンがたくさんあって、コミュニティの雰囲気いい。
　お友達できた。PyCon楽しい！

　もっとPythonやりたい！
　勢いでhack-a-thonに参加したらみんな親切だった。
　さらなる勢いで翌週のPythonもくもく会にも参加したらやっぱりみんな親切でいい人だった。
　Pythonistaいいひとたくさん。
　コーディングもたのし。
　もっとやりたい。（いまここ）

##まとめ
以上をまとめると、私がPythonにはまったのは、

1. 言語を学ぶ必要に迫られた。
2. 憧れの研究者との共同研究に役立つかもっていうミーハー心が刺激された。
3. 初期の学習コストが低く、自分でもできるかもって勘違いさせてくれた。
4. 一つのツールでやりたいことを全部できる可能性を感じた。
5. 学習を支えてくれるすてきなコミュニティがあった。

からですね。自分のめんどくさがりさとミーハー心が透けて見えてほほえましいですね。		
	
皆さんはどんな理由でTechな女子になられたんでしょうか。
いつかみなさんがプログラミングににはまった理由・特定の言語が好きになった理由をお伺いしてみたいです☆
Dartの最新情報の集め方

こんにちは、らこです。今回は私がDartの最新情報を集めている場所を紹介します。活発な更新に置いていかれないように頑張りましょう。

## フォローしたほうがいいTwitterアカウント

### [@dart_lang](https://twitter.com/dart_lang)
Dart team公式アカウントです。公式のアナウンスはこのアカウントをチェックすれば追えると思います。

### [@sethladd](https://twitter.com/sethladd)
我らがDartisan、Seth Ladd氏です。Dart teamはGooglerなだけあってGoogle+での活動のほうが活発な方が多いですが、Seth氏は珍しくTwitterでもよくつぶやいてくれます。

### [@kevmoo](https://twitter.com/kevmoo)
こちらもDart teamの開発者、Kevin Moore氏です。Seth氏ほどではないですがDart関連のツイートをしてくれます。

### [@AngularDart](https://twitter.com/AngularDart)
AngularDartの公式アカウントです。AngularDartに興味がある方はフォローしておいて損はないでしょう。

### [@googledevs](https://twitter.com/googledevs)
GoogleDevelopersの公式アカウントです。Dart以外にもすべてのGoogleの開発に関わる情報が流れますが、Dart好きならGoogle好きだと思うのでフォローしておいて損はないです。

### [@dartosphere](https://twitter.com/dartosphere)
後述するDart関連記事のまとめブログのアカウントです。ニュースだけでなく、StackOverFlowにDart関連の質問が投稿されたときも拡散してくれます。

## Google+も見る方は
私はあまり頻繁にはチェックしませんが、Google+も見る方は

### [Dartisans](https://plus.google.com/communities/114566943291919232850)

に参加するとたくさんの情報が得られます。また、個別のアカウントでは

### [SethLadd](https://plus.google.com/+SethLadd/posts)

### [Dart](https://plus.google.com/+dartlang/posts)

あたりをフォローしておくとよいでしょう。

## ブログ

### [Dart News & Updates](http://news.dartlang.org/)
言わずと知れたDartの公式ブログです。

### [Dartosphere](http://www.dartosphere.org/index.html)
Dart関連の情報をなんでもかんでも集めてくれるまとめサイトです。
ほぼ毎日更新されるので、ここを追うだけでもDartの最新情報はある程度つかむことが出来ます。

### [Seth Ladd's Blog](http://blog.sethladd.com/)
Seth氏のブログです。「何かを試してみた」みたいな記事が多いので有益なサンプルコードが見つかることが多々あります。

## もっと生の議論まで見たい方は
Googleグループのディスカッションを追うのが一番新鮮な情報を得る方法ですが、あまりに雑多で追いきれるものではないので、自分の興味のあるスレッドだけをチェックするのがいいでしょう。

### [Dart Announcements](https://groups.google.com/a/dartlang.org/forum/#!forum/announce)
Dartの公式アナウンスがどこよりも先に貼りだされる場所です。

### [Dart Bugs](https://groups.google.com/a/dartlang.org/forum/#!forum/bugs)
報告されたバグが自動的にリストアップされるグループです。バグかな？と思ったらここを覗いて似たものを探してみるといいかもしれません


### [Dart Misc](https://groups.google.com/a/dartlang.org/forum/#!forum/misc)
質問や要望、バグ報告、その他いろいろ、ユーザー側が書き込むことができるグループです。

----
以上、Dartの情報収集におすすめのアカウント、サイト紹介でした。
言わずもがなですが、QiitaでDartタグを追うのも忘れないようにしましょう！

明日はzukkunさんです。
《小ネタ》SoftLayerの中の人が使うツール

#はじめに
SoftLayerをお使いの方は、多かれ少なかれTicketやChatでサポートとのやりとりをされたことがあると思います。では、中の人（サポートチーム）はどのようなツールを使用して回答や問題解決を行っているのでしょうか？
ここでは少しだけその中身についてご紹介したいと思います。

#チケットのやりとり

SoftLayerユーザーになるとまず[SoftLayerポータル](http://control.softlayer.com)を使用してすべての作業を行いますが、中の人が使用しているポータルがIMSと呼ばれるものです。SoftLayerのクラウド管理システムもIMS(Infrasstructure Management System)といいますがややこしいですね。

以下がIMSの画面サンプルになりますが、[旧SoftLayerポータル](http://manage.softlayer.com)に似た画面です。が、表示されている情報が旧ポータルとは異なりますね。それもそのはずで、IMSではすべてのアカウントのリソースやチケットを取り扱うことが可能になっています。チケットやチャットでVLANやインスタンスのオーダーを行った場合もここから操作を行ってるんですね。

![IMS.jpg](https://qiita-image-store.s3.amazonaws.com/0/60280/4d0ae206-835a-f9d5-5795-d2983d938a96.jpeg)

以下はチケットの一覧が表示された部分を拡大したものです。チケットは内容によってグループごとに割り当てられ、各ステータスごとに管理されているのが見て取れます。ステータスはO(Open), A(Assigned), Y(Yellow)の3つに分かれてますが、興味深いのはY(Yellow)です。

![tickets.jpg](https://qiita-image-store.s3.amazonaws.com/0/60280/f6a23595-38b9-5b6c-a7c7-aa97861f771c.jpeg)

Yellowチケットは実際にもIMSでチケットを表示した時に黄色で表示されているのですが、何かしらのアクションが必要なチケットのことです。SoftLayerではユーザーがチケットをupdateした際などに、すぐ（15分以内）に反応がありますが、このようなステータスで管理しているんですね。
ちなみに内部的に障害発生を検知した時や、オプションでNOC通知を選択している場合のチケットはBlueのチケットとなり、もっとも優先度の高いチケットとして取り扱われるようです。

#チャットのやりとり

チケットと同様にチャットも頻繁に使用されている方も多いかと思います。使用してお気付きの方もいるかもしれませんが、ユーザーとのチャットはLivePersonというツールを使用しています。以下はLivePersonのサンプル画面です。何もエントリーがないのでよくわかりませんが、ユーザーからチャットとリクエストが来ると、上部の画面に表示されチャットを行います。ちなみに当然ですが、過去のチャット履歴や他の担当者が実施中のチャットもリアルタイムで参照することが可能です。

![Screen Shot 2014-12-09 at 9.53.29 AM.png](https://qiita-image-store.s3.amazonaws.com/0/60280/b94753cc-0a25-098d-262c-721bc068e972.png)

ちなみに中の人の間でのやりとりは別のチャットシステムを使用しているそうです。

#SLIKI

IMSやLivePersonなどのツールの他に面白いものでは、SoftLayer内での情報の源としてのSLIKIがあります。SoftLayer版のwikiなのでSLIKIというそうです。面白いですね。
外部向けには[knowledge Layer](http://knowledge layer.com)などに各種技術情報が公開されていますが、SLIKIにはベアメタルサーバーの機種（写真付き）やSoftLayerに関するありとあらゆる用語の解説、さらにはトレーニングマニュアルや中の人の勤務スケジュールなんかも入っています。

![Screen Shot 2014-12-09 at 9.52.24 AM.png](https://qiita-image-store.s3.amazonaws.com/0/60280/1df01d7e-c853-7110-2ef5-df3dbdfffe41.png)

何かわからないことがあれば、中の人はまずはここを参照するようですが、ここで中身を詳しく紹介できないのが残念です。

#まとめ

ユーザーの方は通常目にすることはない（当然のことながらネットワーク的にも認証的にも、がっちり守られていて通常はアクセスできません）ものばかりをご紹介しましたが、普段やりとりをしている中の人がこのようなツールなどを使用して日々対応しているというのを思い浮かべると、少しは英語でのやりとりも楽しくなる？のではないでしょうか。
ストライプボリュームの作り方 on AWS


RHEL6の場合の手順です。

## インスタンス起動時の注意

EBS最適化オプションを使ってインスタンスを起動し、EBS用のトラフィックを安定化させることが望ましい。但し別途料金はかかります。

EBS最適化が利用可能な場合はマネジメントコンソールで以下の赤枠にあるようなチェックボックスが表示される。

![EBSOptimized.png](https://qiita-image-store.s3.amazonaws.com/0/43246/7704390a-a5c9-532d-dc14-be7f754b66f9.png "EBSOptimized.png")

## ストライピング用のボリュームの作成

マネジメントコンソール上で、ボリュームを作成する。たいした注意点はありませんが、このVolumeをAttachするインスタンスと同じゾーンに作成する、適切なIOPSを指定する点に気をつけます。

![CreateVolume.png](https://qiita-image-store.s3.amazonaws.com/0/43246/37bbbfd9-8e58-5351-6dc7-3e769d5b4ee5.png "CreateVolume.png")

## ボリュームのEC2インスタンスへのAttach

Attachしたいインスタンスを指定するとともに割り当てるDeviceを指定します。

`/dev/sdf`と指定したものは実際にはインスタンス内部では`/dev/xvdf`になります。

![AttachVolume.png](https://qiita-image-store.s3.amazonaws.com/0/43246/0aa01ef6-67c0-20f6-d2c1-fc53a8edd127.png "AttachVolume.png")


## PVの作成

```bash
sudo pvcreate /dev/xvdf
sudo pvcreate /dev/xvdg
...(ストライプする分だけ作る)
```

以下のようなログが表示されればOKです。

```
Physical volume "/dev/xvdf" successfully created
Physical volume "/dev/xvdg" successfully created
```

## VolumeGroupの作成

最初の引数にVolumeGroup名、それ以降の引数にグループ化するPVのデバイスパスを指定。複数本を束ねる場合は全部を引数に入れる

```bash
sudo vgcreate MyVolumeGroup1 /dev/xvdf /dev/xvdg 
```

以下のようなログが表示されます。

```
Volume group "MyVolumeGroup1" successfully created
```

ここまでうまく行ってるか確かめるには以下を実施

```bash
sudo vgdisplay -v MyVolumeGroup1
```

## 論理ボリュームの作成

```bash
sudo lvcreate -i ストライプする本数 -l 100%free -n MyLogicalVolume1 MyVolumeGroup1
```

以下のようなログが表示されます。

```
Using default stripesize 64.00 KiB
  Logical volume "MyLogicalVolume1" created
```

## ファイルシステム作成

```bash
sudo mkfs.ext3 /dev/MyVolumeGroup1/MyLogicalVolume1
```

以下のようなログが表示されます。

```
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=16 blocks, Stripe width=32 blocks
131072000 inodes, 524285952 blocks
26214297 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
16000 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
	102400000, 214990848, 512000000

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 39 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
```

## マウント

```bash
sudo mkdir -p /mnt↲
sudo mount /dev/MyVolumeGroup1/MyLogicalVolume1 /mnt
```

最後に`df`コマンドで確認してみましょう。無事マウントできているのが分かります。

```
df -m
Filesystem           1M-blocks  Used Available Use% Mounted on
/dev/xvda1               10080  1987      7581  21% /
tmpfs                     7442     0      7442   0% /dev/shm
/dev/mapper/MyVolumeGroup1-MyLogicalVolume1
                       2015858   199   1913260   1% /mnt
```
CentOSにnew relicの監視デーモンをインストール

サーバー監視用のデーモンと、php監視用のモジュールの入れ方 φ(..)メモメモ


```
# sudo yum install -y newrelic-php5

cd /usr/local/src
sudo wget http://download.newrelic.com/php_agent/release/newrelic-php5-4.14.0.72-linux.tar.gz
sudo tar xvf newrelic-php5-4.14.0.72-linux.tar.gz
cd newrelic-php5-4.14.0.72

# 実行後シリアル入力
sudo ./newrelic-install install


# php.iniに追記
vim /usr/local/apache2/conf/php.ini
# パスミスってたので書き変えた
extension='/usr/local/lib/php/extensions/no-debug-zts-20090626/newrelic.so'

# ないなら書き込む 基本書かれてる
newrelic.license="「ここにライセンスキーをかいてね」"
```


```
sudo rpm -Uvh http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm

sudo yum install -y newrelic-sysmond
sudo nrsysmond-config --set license_key=「ここにライセンスキーをかいてね」
sudo cp /etc/newrelic/newrelic.cfg.template /etc/newrelic/newrelic.cfg

sudo chkconfig newrelic-sysmond on
sudo chkconfig newrelic-daemon on
sudo /etc/init.d/newrelic-sysmond start
sudo /etc/init.d/newrelic-daemon start
```
Haskellの関数合成が苦手に感じるわけを考察してみた

最初に断っておきますが、当エントリは実用的ではありません。
Haskell初心者が挫折しがち（と思われる）関数合成について、思いを共有出来ればいいなと思っています。

# 関数合成を書くのって、何だか難しい

Haskell初心者の鬼門、関数合成。

なんかかっこいいから使ってみたい。```let```を使ったら負け、```$```を使った負け・・・という思いで頑張ってみるものの、なかなかうまく書けない・・・

なぜ私はこんなに関数合成を苦手に感じるのか。整理して解決への糸口を探してみることにしました。

# 関数合成は思考と記述の順番が逆

私が感じるに、関数合成が分かりにくいのは __後ろから__ 関数が適用されるのに違和感があるからです。

例として複数行から成る文字列の各行の先頭に行番号を付けるプログラムを書いてみます。

```Haskell
f = unlines . map (\(f, s) -> f ++ s) . zip (map show [1..]) . lines
```
（合成回数を増やすために```zipWith```は使っていません）


関数適用毎の型変換を書き出してみると、やってることが理解しやすくなるかもしれません。

```Haskell
f = unlines                   -- [String]          -> String
    . map (\(f, s) -> f ++ s) -- [(String,String)] -> [String]
    . zip (map show [1..])    -- [String]          -> [(String,String)]
    . lines                   -- String            -> [String]
```

この関数を読むには、後ろの関数から見て行かないとデータの変換の流れが読み解けません。

書くときも読むときも、このことが思考の妨げになっている気がします。

# Unixのパイプは書きやすい

Unixのパイプによる処理を書くときは、処理の順番と記述が一致していて、良いリズムでタイプすることが出来ている気がします。
例えば今動いているjavaプロセスの数は以下のように書けます。

```sh
ps aux | grep java | wc -l
```

psの結果をgrepで絞り込んでwcで数えてます。思考と記述の順番が一致していて、分かりやすい。

Haskellの関数合成を書く時は、後ろの関数から考えて行くので、エディタを行きつ戻りつしながら書くことになり、リズムが悪くなる。

このことが「関数合成で書くのって苦手だ」と思ってしまう原因になっている気がします。

# Javaの場合は？

ここで気付いたのですが、Javaを考えてみると、実はHaskellの関数合成と同様、思考と記述の順番が逆です。

先ほどの処理を、擬似的にJavaコードを書いてみると以下のようになるでしょうか。

```Java
return unlines(concatTaple(zip(lines(arg))));
```

関数呼び出し結果を直接関数の引数に渡すスタイルは、ときに「読みにくい！」として忌避されます。

でも、Javaに慣れている私は、これをそれほど読みにくいとは感じませんし、もちろん書くときも特に苦手に感じているわけではありません。

結局は慣れの問題・・・？

# 引数にやられることも？
とは言え、他にも関数合成で書くことをあきらめてしまう原因があります。

引数に関連していることが多く、例えば

* 引数が複数ある関数を関数合成で書くのは可能なのか？
* 合成に使いたい関数の引数の順番がまずくて型が合わないときにどうすればいいんだ・・・

などですね。

これらは、真剣に考えれば解決しそうな気がするのですが、これまでそこまで突き詰めて考えたことがありませんでした。
これを機会に考えてみようと思います。
苦手を克服するには成功体験が重要ですので。

# モナドは思考と記述の順番が一致

一方、もう１つのHaskellの鬼門・モナドを使うときは、思考と記述の順番が一致しています。

先ほど作った関数```f```を使って、標準出力から得た文字列を加工してみます。

```Haskell
main = getContents >>= return . f >>= print
```

do記法を使うと以下のようになります。

```Haskell
main = do
     cs <- getContents
     s  <- return $ f cs
     print s
```

いずれも、思考と記述の順番が一致しています。

思うに、このことも関数合成を苦手に思う原因になっている気がします。

モナドで書く時と関数合成（これは関数適用でも同じ）で書く時とで、頭を切り替えないといけないのが、脳みその負担になっているのです。

# 苦手感を克服するには？

ここまでなぜ苦手なのか？を考察してきました。
最後に、解決策をいくつか考えてみました。

* モナドと関数合成（適用）とで頭を切り替えるように心がける
* 関数合成にこだわりすぎない
* Haskellに慣れる
* とにかく慣れる

いろいろ書いた割には安易なオチで恐縮です。
Haskellでもっとプログラム書かないといけないな、というお話でした。
アジャイルとはなんぞや

# アジャイルとはなんぞや
　この記事は[アジャイルCasual Advent Calendar 2014](http://qiita.com/advent-calendar/2014/agile_casual)の9日目のエントリです。

　前回は[ayasudaさんの「PDCA as a Game」](http://qiita.com/ayasuda/items/d5aa1998842d3be63a6c)でした。PDCA導入時のあるあるや、PDCAを楽しむためのayasudaさんなりのアプローチが書かれていました。

　アジャイル Casual Calenderの9日目となる本日はご覧の通りの表題から始めたいと思います。もしかしたら皆さん既にご存知で何を今更、と思われることばかりかも知れませんが優しく見守っていただければと思います(予防線)

# アジャイル＝開発手法？
　なぜアジャイルという言葉がこんなにもソフトウェア業界でもてはやされるようになったのでしょうか
「アジャイル」という言葉をgoogleにお尋ねすると言葉の意味などよりも先に「[アジャイルソフトウェア開発](http://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA)」がトップにランキングされている今日、アジャイルといえばソフトウェア開発における一手法である、という認識が一般的なようです。
　しかしながらもともとの「アジャイル(agile)」という言葉はただの形容詞でしかありません。意味は「すばしこい、身軽な、敏捷な」対義語としては「dully」(鈍く、ぼんやり、不活発に、退屈するように)あたりでしょうか。
　上記のwikipediaの記事でもあるとおり、"アジャイル"ソフトウェア開発という言葉の初出は2001年になります。それまでは「軽量ソフトウェア開発」などの呼称で呼ばれていたようです。つまりはそれまで(文脈としては[アジャイルソフトウェア開発宣言](http://www.agilemanifesto.org/iso/ja/)が出されるまででしょうか)は「鈍重な」ものであることが多かったソフトウェア開発に、「機敏さ」を獲得する(あるいは取り戻す)ことが必要だとされたのでしょう。

# Why Agile?
　ではなぜ「アジャイル」であることがソフトウェア開発に求められたのか。[4日めのshin_semiyaさんのエントリ(時は80年代、仕様は変化することがわかった)](http://shinsemiya.hatenadiary.jp/entry/2014/12/04/200620)に書かれているとおり、「仕様が変化する」という事実が人類に周知されたことにより、それまでの「鈍重な」大規模計画駆動型プロジェクトではコストに見合う価値を届けることが難しいということに人類が気づきはじめたことと深く関係しています。
　そんな環境の中で、ソフトウェア開発手法の分野において成功を収めていた17人がスキーリゾートに引きこもって考えた結果、「アジャイルソフトウェア開発宣言」がつくられました。
それぞれソフトウェア開発において、異なる手法を提唱していた彼らにあって、「顧客満足を最優先い、価値のあるソフトウェアを早く継続的に提供」するためには「機敏であること」が必要である、ということについて意見の一致を見たのです。

# What's Agile?
　では「機敏である」とはいったい何なのか？[アジャイル宣言の背後にある原則](http://www.agilemanifesto.org/iso/ja/principles.html)にさまざまな原則が示されています。定められてから13年が経過したこんにちにおいてもこれらの原則は決して、陳腐化していません。むしろ未だに軽視されていると感じることが多くあります。
　世にあるさまざまなアジャイル開発手法とよばれるプラクティス郡は、総じてこの原則を基としています。あらためてこの原則を確認した上で、普段活用しているプラクティスを振り返ることでより深く、プラクティスが根ざす原点を学ぶことができるでしょう。

# 終わりに
　アジャイルソフトウェア開発宣言がなされてから13年。アジャイルという言葉それ自体はソフトウェアに係る人間であれば、ほとんどの人間が知るようになりました。また、ソフトウェアという存在自体も、13年前よりも更に身近に、なくてはならないものとなっています。しかしながら、アジャイルという言葉の根ざす根本はいまだ十分に理解されたとは言いがたい現状があると思います。
　あらためて[アジャイルソフトウェア開発宣言](http://www.agilemanifesto.org/iso/ja/)と[アジャイル宣言の背後にある原則](http://www.agilemanifesto.org/iso/ja/principles.html)を通して、古きを温ね新しきを知るのはいかがでしょうか？
最後にアジャイルのもう一つの原則を記して、終とさせていただきたいと思います。

*「Not do agile, be agile」*
carrierwaveで NameError uninitialized-constantのようなメッセージが出た場合

[パーフェクトRuby on Rails](http://www.amazon.co.jp/%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88-Ruby-Rails-%E3%81%99%E3%81%8C%E3%82%8F%E3%82%89-%E3%81%BE%E3%81%95%E3%81%AE%E3%82%8A/dp/4774165166)の6章を写経してて、carrierwaveで画像を添付する処理を実装してたら、なぜか
**uninitialized constant Event::EventImageUploader**というエラーが出て上手くいかなかったのでその対応方法を書いておきます。

ちなみに、自分の環境は以下です。

- Mac OS X 10.9.5
- Ruby
  - rbenvを利用
      - ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
- 今回関連するGem
  - rails (4.1.1)
  - carrierwave (0.10.0)

## 対応方法

[13 Jul 2011 にオープンしてるcarrierwaveのissues](https://github.com/carrierwaveuploader/carrierwave/issues/399)の最後の方のコメント、[具体的には、8月7日のfredngoさんのやつ](https://github.com/carrierwaveuploader/carrierwave/issues/399#issuecomment-51422423)で解決しました。


### config/application.rbに、autoload_pathsの記述を以下のようにする。

```ruby
module AwesomeEvents
  class Application < Rails::Application
    config.autoload_paths += Dir[Rails.root.join('app', 'uploaders')]
    # 以下省略

  end
end
```

修正が完了したら、起動中のWebrick（もしくは利用されてるアプリケーション・サーバー）を再起動します。

これで私の環境では無事にcarrierwaveが利用できるようになりました。
h2oとUnixドメインソケット

h2oは部分的にではありますが、Unixドメインソケットをサポートしています。

## Unixドメインソケットでlisten

h2oでUnixドメインソケットでlistenするには例えば以下のようなconfを用意します。

```yaml:h2o.conf
listen:
  port: /tmp/h2o.sock
  type: unix
hosts:
  default:
    paths:
      /:
        file.dir: examples/doc_root
    access-log: /dev/stdout
```

この設定で起動しましょう。

```bash
$ make h2o && ./h2o -c h2o.conf
```

また/tmp/h2o.sockにアクセスするプログラムを用意します。ここではPHPで書いていますが、Unixドメインソケットを扱えるならなんでもいいです。

```php:connect_h2o.php
<?php

$sock = fsockopen("unix:///tmp/h2o.sock", 0);

fwrite($sock, "GET / HTTP/1.1
Host: 127.0.0.1
Connection: Close

");

while (!feof($sock)) {
    echo fgets($sock);
}

fclose($sock);
```

connect_h2o.phpを実行してみます。

```bash
$ php connect_h2o.php
HTTP/1.1 200 OK
date: Tue, 09 Dec 2014 23:38:04 GMT
server: h2o/0.1
connection: close
content-length: 180
content-type: text/html
last-modified: Sun, 09 Nov 2014 20:07:25 GMT
etag: "545fc97d-b4"

<!DOCTYPE html>
<html>
  <header>
    <title>Welcome to H2O</title>
  </header>
  <body>
    <p>Welcome to H2O - an optimized HTTP server</p>
    <p>It works!</p>
  <body>
</html>
$
```

ちゃんとレスポンスが返ってきました。

## Unixドメインソケットへリバースプロキシ

まだmasterにマージされていませんが、Unixドメインソケットにリバースプロキシを行えるようにするためのブランチとPRがあります。(時間取れてなくて絶賛放置中です。自分から送っておいてすいません to @kazuho )

https://github.com/h2o/h2o/pull/51

試しにこのPRのブランチをcheckoutします。

```
$ git remote add cubicdaiya https://github.com/cubicdaiya/h2o.git
$ git fetch cubicdaiya
$ git checkout cubicdaiya/feature/revproxy-unix
```

設定はこんな感じになります。(多分masterにマージされる時には別の書式になると思います)

```yaml:h2o.conf
listen:
  port: 8081
hosts:
  default:
    paths:
      /tcp:
        proxy.reverse.url: http://127.0.0.1/
      /unix:
        proxy.reverse.path: unix:/tmp/nginx.sock:/
```

プロキシ先はnginxなのでnginx.confも用意します。

```nginx.conf
worker_processes 1;
 
events {
    worker_connections 1024;
}
 
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    keepalive_timeout  65;
 
    server {
        listen 80;
        root   html;
    }
 
    server {
        listen unix:/tmp/nginx.sock;
        root   html;
    }
 
}
```

手元(MacBook Pro)でh2oとnginx両方を起動した状態でh2oにabによるベンチを実行した結果が以下になります。

```
$ ab -k -n 10000 -c 500 "http://127.0.0.1:8081/tcp" 2>&1 | grep "Requests per second:"
Requests per second:    8818.33 [#/sec] (mean)
$ ab -k -n 10000 -c 500 "http://127.0.0.1:8081/unix" 2>&1 | grep "Requests per second:"       
Requests per second:    17492.24 [#/sec] (mean)
$
```

というわけで大体2倍くらいのパフォーマンスが出ました。
Elixir開発環境の構築をDockerでやる

# はじめに

今年を振り返って、最もバズったキーワードは Docker であるということで、異論は無いと思います。
実際私も Docker を使っていて、Elixir と同様、美しく、便利で、楽しいと感じています。
今回は、Docker を使ってElixir の開発環境を構築するやり方をご紹介します。


# Dockerで何ができるのか

端的に言うと、クリーンな環境を、任意の構成で、簡単に作り上げることができます。
軽量なので、同じ環境を何度も繰り返し作るのに向いています。
環境は冪等性が保証されており、CIやDevOpsへの応用が期待されます。


# Elixirプログラマにとってのメリット

OS Xは、Elixirプログラミングをするには最高の環境だと思います。
しかし、我々の目指すところはElixirで作ったクールなコードをプロダクションで動作させることであり、大抵のプロダクション環境はLinuxだったりします。
Elixirを動作させるには、Erlang/OTP バージョン17のインストールが必要ですが、少なくとも大抵のメジャーなLinuxでは、これを自分でビルドしなければなりません。
さらに、ElixirもGitHubからクローンする必要があります。
brew install elixir でサクッと入るわけではないのです。(何度 make clean test したことか。)

Dockerを使えば、この悩みを解消することができます。
すなわち、Docker以外ほとんど何も入っていない状態のLinux上でも、サクッとElixirの開発環境を構築することができるのです。


# 今回の環境

Ubuntu 14.04 LTS


# 全体の手順

Dockerをインストール
|> Docker Hubからイメージをダウンロード
|> コンテナを起動
|> Elixirする


# やってみよう

## Dockerをインストール

```
$ sudo apt-get install -y docker
```

## Docker Hubからイメージをダウンロード

ここでは、手順をシンプルにするため、予め私がビルドしてDocker Hubで公開しているイメージを使います。
Docker Hubのリポジトリはこちら。 https://hub.docker.com/u/keithseahus/

```
$ sudo docker pull keithseahus/elixir-ubuntu-14.04lts
```

初回は、ダウンロードに時間がかかります。コーヒー淹れるなりコード書くなりして待ちましょう。

## コンテナを起動

```
$ sudo docker run -i -t keithseahus/elixir-ubuntu-14.04lts zsh
```

## Elixirする

```
% iex
```


# 中身は何なのか

Dockerイメージの構成を定義するのがDockerfileですが、私が公開しているイメージは、複数のDockerfileから成り立っています。

* base-ubuntu-14.04lts
* erlang-otp-ubuntu-14.04lts
* elixir-ubuntu-14.04lts

ベースは、公式のUbuntuイメージをベースに、どの開発にも共通して最低限必要となる(又は入っていると非常に嬉しい)ツールをインストールしたものです。また、いわゆるドットファイル(.emacsとか.tmux.confとか.zshrcとか)も、私のGitHubからクローンしており、コンテナを起動したら即座に開発を開始できるようにしています。
このイメージは汎用的に使うことを目的としたもので、他の言語向けイメージの土台にもなっています。

Erlang/OTPのイメージは、上記イメージにErlang/OTP 17をインストールしたものです。
Ubuntu 14.04 LTSのリポジトリにあるバージョンは16なので、ソースをダウンロードしてコンパイルしています。
その際に、configureオプションを指定し、極力多くの機能を有効にしています。なので、JavaもWxも入っていますし、HiPEも有効です。

そして、Elixirのイメージ。Elixirの最新版をダウンロードして ```make clean test``` しています。


# 自分でやるには

必要なDockerfileを作って、動作確認した後、GitHubで公開しましょう。(参考: https://github.com/keithseahus/dockerfiles )
Docker Hub から Automated Build を選ぶと、GitHubを連携して、Dockerfileのあるディレクトリ・パスを指定すると、Docker Hubが取り込んでくれます。
GitHubにpushしたら自動的にDocker Hubでビルドを行う設定もあります。ただ、私のように一つのGitHubリポジトリで複数のDockerfileを管理していると、一つpushしただけで、Docker Hubでは全部ビルドが走ってしまうのが玉にキズです。(かといって、GitHubでリポジトリを分けるのは、個人的にはやりたくないのですが。)


# まとめ

Dockerを使ってElixirの開発環境をサクッと構築するやり方をご紹介しました。
実際、CIやDevOpsに向いていますので、これをベースにElixirのアプリケーションをJenkinsでテストする環境も、簡単に構築できますね。
また、今回Ubuntuでしたが、CentOS 7のイメージも近日作成しようと思います。

明日は @mtwtk_man さんです。
Lightningコンポーネントのソースコードを取り出す


開発者コンソールで開発したLightningコンポーネントのソースコードを取り出して、リポジトリに登録したり、別組織に移行したいことがあります。[Salesforce1 Lightning Advent Calendar 2014](http://qiita.com/advent-calendar/2014/lightning)の[1日目](http://qiita.com/a_kuratani/items/09dbd66f796b40ecea2a)の投稿ではデプロイ方法について書きましたが、同様に取り出すこともできます。

### ソースコードを準備する(デプロイするなり、開発者コンソールで作成する)
```bash:ソースコード
src
 |--sampleCmp
    |--sampleCmp.cmp
    |--sampleCmp.css
    |--sampleCmpController.js
    |--sampleCmpHelper.js
````

### package.xmlを準備する
```xml:src/package.xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>sampleCmp</members>
        <name>AuraDefinitionBundle</name>
    </types>
    <version>32.0</version>
</Package>
```

### Salesforce移行ツールで取り出す
build.xmlを準備します。

```xml:build.xml
<project name="LightningSample" default="deploy" basedir="." xmlns:sf="antlib:com.salesforce">
  <property file="build.properties"/>
  <property environment="env"/>

  <target name="retrieve">
    <mkdir dir="code"/>
    <sf:retrieve username="(ユーザID)" password="(パスワード)" serverurl="https://login.salesforce.com" retrieveTarget="code" unpackaged="src/package.xml"/>
  </target>
</project>
```

Antを利用してSalesforce移行ツールを起動します。

```bash
> ant retrieve
```

以上のように、通常のForce.comのリソースを取り出す場合と同様の方法でLightningコンポーネントのソースコードを取り出すことができます。

この投稿は[Salesforce1 Lightning Advent Calendar 2014](http://qiita.com/advent-calendar/2014/lightning)の10日目の投稿です。
go1.4で追加されたinternal packageについて

## 概要
internal packageはgo1.4で追加されたものです。
Goでのアクセス制御は、大文字で始まるものがpublic、小文字で始まるものがprivateの2種類でしたが、
internal packageを使うことによって、package privateにすることができるようになりました。

## 背景

以下のような問題を解消するために、internal packageは追加されました。

- パッケージ外非公開とするために、標準ライブラリ内でコードが重複するケースがあった

`net/http`を例に上げると、go1.3では、`chunked.go`という全く同じファイルが`net/http`と`net/http/httputil`に2つ存在していました。

ソースコードにも、下記のようなコメントがあったりして残念な感じでした。

```
// This code is duplicated in net/http and net/http/httputil.
// Please make any changes in both files.
```

go1.4では、この重複は`net/http/internal/chunked.go`として1ファイルにまとめられています。

- goのmain repositoryのに必要な外部packageを、標準ライブラリに含めたくない

`cmd/internal`にある`rsc.io/x86/x86asm`や`rsc.io/arm/armasm`とか。

- compileをself hostingするとき、標準ライブラリには含めないlibrary packageを書く方法が必要になるはず

## 仕様

パッケージパスに`internal`が含まれる場合、import側は`internal`ディレクトリのあるパッケージと同一パッケージ内でなければいけません。

**注意**
ユーザのワーキングディレクトリ(GOPATH)では、まだ使えません。
様子を見て、go1.5以降からGOPATHにも適用されるようです。

以下は、`net/http`パッケージの例です。
go1.4から新たにinternal packageが追加されています。

このinternal packageは、`net/http`以下のpackageでのみimportできます。
`net/url`や`net/rpc`などからはimportできません。

```
src/net/http
├── cgi
│   └── testdata
├── cookiejar
├── fcgi
├── httptest
├── httputil
├── internal
├── pprof
└── testdata
```

はやく、GOPATH以下でも使えるようになるといいですね。

## 参考

[go1.4 Release Note#internal packages](http://tip.golang.org/doc/go1.4#internalpackages)

[go1.4 Internal Packages design doc](https://docs.google.com/document/d/1e8kOo3r51b2BWtTs_1uADIA5djfXhPT36s6eHVRIvaU/edit)
WebRTCで「ピー」をやってみる

ちょっとお遊びで、WebRTCの音声通話で、音声の途中で都合の悪い言葉を隠すのに「ピー」という音を入れることができるようになる方法を試してみます(笑)。

*Chrome for Androidでは残念ながら動作しないようです。
(参考: http://caniuse.com/#search=web%20audio )*

# まずはマイクの音声をキャプチャ

お約束の`navigator.getUserMedia()`です。

```js:音声キャプチャを開始
var mic;
navigator.getUserMedia =
  navigator.getUserMedia ||
  navigator.webkitGetUserMedia ||
  navigator.mozGetUserMedia;
navigator.getUserMedia(
  { audio: true },
  function(s) { mic = s; },
  function(e) { console.log(e); }
);
```

# 「ピー」を作る

「ピー」という音を、今回はWeb Audio APIを使って作ってみます。正弦波のオシレータを使えば、十分それっぽい雰囲気が出るのではと思います。

```js:「ピー」の音をオシレータで再現
var context = window.AudioContext || window.webkitAudioContext;
var ctx = new context();
var osc = context.createOscillator();
osc.frequency.value = 880 * Math.pow(2,2/12); // シの音階(ラの音階より全音上)
```

# マイクと「ピー」をミキシング

まず、WebRTC Advent Calendar 9日目の[getUserMedia使ってJSで動くチューナー作った。](http://qiita.com/ymmtmdk/items/0d8a3d6d613ff61e65be)の記事と同様に、マイクの入力ノードを`createMediaStreamSource()`で取り出します。

その後、マイクと「ピー」のそれぞれの音量をコントロールするゲインノードを作って接続し、それらを`createMediaStreamDestination()`で生成した出力ノードに接続してミキシング、という順序になります。

```js:マイクと「ピー」をミキシング
var micNode = context.createMediaStreamSource(mic);
var micGain, oscGain;
if(context.createGain) {
  micGain = context.createGain();
  oscGain = context.createGain();
}
else {
  // 多分不要だと思われますが、念のため古いWeb Audio APIへの対処
  micGain = context.createGainNode();
  oscGain = context.createGainNode();
}
micNode.connect(micGain);
osc.connect(oscGain);
// まずはマイクを鳴らして「ピー」をミュート
micGain.gain.value = 1;
oscGain.gain.value = 0;
// ミキシング
var output = context.createMediaStreamDestination();
micGain.connect(output);
oscGain.connect(output);
if(osc.start)
  osc.start(0);
else
  // 多分不要だと思われますが、念のため古いWeb Audio APIへの対処
  osc.noteOn(0);
```

# いよいよWebRTC

さて、いよいよWebRTCの初期化です。ここでは詳細は省かせていただいて、要点に絞って説明します。

`RTCPeerConnection`の初期化やoffer/answerのやりとり等は通常の手順と同様で、`RTCPeerConnection.addStream()`で渡すストリームだけ変えればよい、ということになります。

ひとまず、通常と同じようにRTCPeerConnectionインスタンスを生成し、必要な初期化を行います。
そして、`addStream()`で、先ほど生成したミキシングの出力ノードのストリームをここに渡せばよい、ということになります。`output`自体ではなく、`output.stream`を渡す点に注意が必要です。

```js:RTCPeerConnection初期化
var PC =
  window.RTCPeerConnection ||
  window.webkitRTCPeerConnection ||
  window.mozRTCPeerConnection;
var peer = new PC({ iceServers: [ { ... } ] });
peer.onicecandidate = function(ice) { ... };

// ミキシングの出力ノードのストリームをRTCPeerConnectionに追加
peer.addStream(output.stream);
```

あとは、引き続きoffer/answerを経てセッションを確立させれば、いつもどおりWebRTCで通話ができるようになるわけですが、ここでもう少々細工をして、好きなタイミングでマイクの音声の代わりに「ピー」が相手に聞こえるようにしてみます。ここでは「P」キーを押している間はマイクがミュートされて「ピー」が相手に聞こえる、というようにしています。

```js:「ピー」の切替
function startCensor(evt) {
  if(evt.keyCode == 'P'.charCodeAt(0)) {
    micGain.gain.value = 0;
    oscGain.gain.value = 1;
  }
}

function stopCensor(evt) {
  if(evt.keyCode == 'P'.charCodeAt(0)) {
    micGain.gain.value = 1;
    oscGain.gain.value = 0;
  }
}

document.addEventListener('keydown', startCensor, false);
document.addEventListener('keyup', stopCensor, false);
```

...というわけで、WebRTC音声チャットで「ピー」、という非常にくだらない使い道を例として(笑)、WebRTCにWeb Audio APIを組み合わせる方法、でした。

この他にも、Web Audio APIをWebRTCに組み合わせて、例えば、音楽ファイルがあれば保留音を相手に聞こえるようにする、等の使い方ができます。色々とお試しあれ。
Laravel 4のDBのクエリログを淡々と流す

OR Mapperを使っているとどうしても実際に吐いているクエリが見えづらくなって、非効率になっても気づかないので、クエリログを淡々と流そうとした。
そのものズバリの答えが俺たちのStackOverflowにあったので、参考にさせていただく。

[Laravel 4 - logging SQL queries](http://stackoverflow.com/questions/19131731/laravel-4-logging-sql-queries)

以下の様にイベントに反応すれば良い模様。このコードのよい所はdatabaseのconfigで切り替えられるようにしてあるところ。localの場合のみ出力するとかにしておけば、ローカル環境だけでテストできる。

```php
if (Config::get('database.log', false))
{
    Event::listen('illuminate.query', function($query, $bindings, $time, $name)
    {
        $data = compact('bindings', 'time', 'name');

        // Format binding data for sql insertion
        foreach ($bindings as $i => $binding)
        {
            if ($binding instanceof \DateTime)
            {
                $bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
            }
            else if (is_string($binding))
            {
                $bindings[$i] = "'$binding'";
            }
        }

        // Insert bindings into query
        $query = str_replace(array('%', '?'), array('%%', '%s'), $query);
        $query = vsprintf($query, $bindings);

        Log::info($query, $data);
    });
}
```

上記StackOverflowでは、`routes.php`に貼れよ的なことを書いてあるけれど、ルーティングのところにこれ貼るの気が引けるので、別途`listners.php`見たいのを作って`app/start/global.php`とかで読み込むようにするのがいいのかもしれない。

あとは、`app/config/local/database.py`とかで、`'log' => true`とか書いてあげればOK。

１回のアクセスに対して大量にクエリが発行れてたら、例えばeager loading使うなどして減らすといいですね。
man見まくっているヘタレ行為をzshのコマンド履歴に入れない方法

zshで「manの実行をコマンド履歴に入れない」ことを紹介します。

# 結論

```zsh:.zshrc
setopt hist_ignore_space

alias man=' man'

autoload -Uz run-help
autoload -Uz run-help-git
# ... 中略 ...
alias run-help=' run-help'
```

# `hist_ignore_space`

zsh には `hist_ignore_space` というオプションがあって、これを設定すると先頭に半角スペースを入れたコマンドは履歴に入らない。実行に注意が必要なものや、その場限りでしか使わないようなコマンドのときに便利であろう。

    % setopt hist_ignore_space
    % ls        ←履歴に入る
    %  rm -rf * ←履歴に入らない

# `man(1)` をコマンド履歴に入れない方法

    % man git

筆者としては「man見まくっているヘタレ行為をzshのコマンド履歴に入れたくない・後で自分が見たくもない」というしょうもない理由がある。よって、上のようにあわてて入力したとしても履歴に残らないで欲しいのである。

zsh の man で `hist_ignore_space` の説明を見ると下記のようなことが書いてある。

> <dl>
> <dt><code>HIST_IGNORE_SPACE (-g)</code></dt>
> <dd>Remove command lines from the history list when the  first character on the line is a space, or when <strong>one of the expanded aliases contains a leading  space</strong>.   Only normal aliases (not global or suffix aliases) have this behaviour. Note  that the command lingers in the internal history until the next command is entered before it vanishes, allowing  you  to briefly reuse or edit the line. If you want to make it vanish right away without entering  another command, type a space and press return.</dd>
> </dl>

上で強調しておいた箇所のとおり、エイリアスを展開した結果で半角スペースから始まっているときも、履歴に入れない挙動となる。

    % setopt hist_ignore_space
    % alias a=echo
    % a foobar  ←履歴に入る
    % alias a=' echo'
    % a foobar  ←履歴に入らない
    % alias b=a
    % b foobar  ←履歴に入らない

よって、目的を達成するには下記のようにエイリアスを `.zshrc` などに設定すれば良い。

```zsh:.zshrc
setopt hist_ignore_space

alias man=' man'
```
もちろん、`man(1)` に関わらず任意のコマンド・関数に対してこの方法は使える。

# `^[h` の実行をコマンド履歴に入れない方法

zsh では <kbd>^[h</kbd> (すなわち<kbd>M-h</kbd>) を押して man を見ることの方が遥かに便利である。（詳細は[zsh で Git の man を素早く見る][mollifier-zsh-git-man]を参照のこと）

[mollifier-zsh-git-man]: http://qiita.com/mollifier/items/81a9daf716d94b63f94f "zsh で Git の man を素早く見る"

この場合は `man` ではなく `run-help` が実行されるので注意が必要なことがある。`run-help` を `man` のエイリアスとしている場合、`man` を既述のとおりの半角スペース始まりのエイリアスになってれば履歴に追加されない。`run-help` が関数定義の場合、明示的に `run-help` を半角スペース始まりのエイリアスを定義する必要がある。

特に `autoload run-help` をする場合で、履歴に追加されないようにするためには、`alias run-help=' run-help'` が必須だ:

```zsh:.zshrc
setopt hist_ignore_space

autoload -Uz run-help
autoload -Uz run-help-git
# ... 他の run-help-* はお好みで ...
alias run-help=' run-help'
```
Cisco L3スイッチでhttpアクセス設定

参考: [TEMPEST社長ブログ: IOSでのhttp serverの設定](http://tempest.dcnblog.jp/blog/2011/04/io-80be.html)

httpアクセスしようとしたらアカウントを作成する必要があったので。

## アカウント作成

```bash:アカウント一覧を確認
(config)#do sh run | i username
```

何も表示されなければアカウントは居ない。

```bash:ユーザ名ciscoをパスワードhogehogeで作成
(config)#username cisco secret hogehoge
username cisco secret 5 xxxxxxxxxxxxxxxxx
```

```bash:アカウントが作成されたか確認
(config)#do sh run | i username
```

## httpアクセスのためにアカウントlevel 15に設定

```bash:設定
(config)#username cisco privilege 15
(config)#do sh run | i username
username cisco privilege 15 secret 5 xxxxxxxxxxxxxxxxx
```

* user: cisco
* pass: hogehoge

でhttpログインができることを確認。
特定配列内の長さの不定な配列同士の直積を得る。

上手いタイトルが付けられなかったのですが、やりたいことは単純です。
# やりたいこと
長さが違う長さが違う配列の配列の直積を得たい！

```py3
A = [[1,2],[3,4]]
f(A)
```
↑これの出力がこれ↓

```py3
(1, 3)
(1, 4)
(2, 3)
(2, 4)
```

```py3
B = [[1],[2,3],[4,5,6]]
f(B)
```
↑これの出力がこれ↓

```py3
(1, 2, 4)
(1, 2, 5)
(1, 2, 6)
(1, 3, 4)
(1, 3, 5)
(1, 3, 6)
```

## unpack!
*をつけると配列とか辞書をほぐせるらしい。

```py3
A = [1,2]
print(*A) #1 2 
```
つまり！こんなふうに書けばいい↓

```py3
import itertools

def f(X):
    for x in itertools.product(*X):
        print(x)

A = [[1,2],[3,4]]
B = [[1],[2,3],[4,5,6]]

f(A)
f(B)
```

これでいい！
IntelliJ導入（Mac版）


2014/12/10 05:00

本家サイト
http://www.jetbrains.com/idea/
トップページ

![kobito.1418154507.152074.png](https://qiita-image-store.s3.amazonaws.com/0/33317/019ff96e-77b7-20ff-dae8-86b3e8a7e6b0.png "kobito.1418154507.152074.png")

ダウンロードページ
http://www.jetbrains.com/idea/download/
![kobito.1418154721.578740.png](https://qiita-image-store.s3.amazonaws.com/0/33317/ad33f56d-74eb-ea2e-b7c8-f09060deefed.png "kobito.1418154721.578740.png")

dmg
![kobito.1418172767.354067.png](https://qiita-image-store.s3.amazonaws.com/0/33317/140292cd-7f15-0e47-acc2-3a5541f2d1e2.png "kobito.1418172767.354067.png")

チュートリアルはこちら
http://confluence.jetbrains.com/display/IntelliJIDEA/Tutorials
cocos2d-xモバイルデバイスのマルチ解像度対応を実現するための setDesignResolutionSize の注意点

#モバイル環境の罠

```cocos2d-x:AppDelegae.cpp

    if(!glview) {
        glview = GLViewImpl::create("My Game");

        //モバイルだとココに書いても通らないので設定されない
        //glview->setDesignResolutionSize(2048,1536, ResolutionPolicy::SHOW_ALL);

        director->setOpenGLView(glview);
    }
    
    //Set Design Resolution
    glview->setDesignResolutionSize(2048,1536, ResolutionPolicy::SHOW_ALL);

```

iOSアプリで何故かDesignResolution効いてないなと困っていたのですが・・・モバイル環境だとif文の中を通らないようなので、setDesignResolutionSizeする場所に注意です。

##DesignResolution使い方

```cocos2d-x:Scene.cpp
    auto size = Director::getInstance()->getOpenGLView()->getDesignResolutionSize();
```
DesignResolutionに設定した解像度をシーンの中で取得できます。

##ご参考
[setDesignResolutionSize() is being ignored?](http://discuss.cocos2d-x.org/t/setdesignresolutionsize-is-being-ignored/15764)
【AndroidStudio】ver.up時runProguard()でひっかかったときの直し方

随分前から、AndroidStudioを使っていると
「バージョンアップがありますよ」と表示されるのはわかっていた。
ただ、プログラムが動かなくなると厭なのでしなかった。

さっき、ある程度状況が落ち着いたのでやってみたら。。。
案の定、プログラムが動かなくなった。

よく見るとbuild.gradleの「runProguard()がアカンやつや」ということらしい。

ググったらこちらの記事発見。
http://d.hatena.ne.jp/paraches/20141128/1417154420

runProguard　→　minifyEnabled　で無事解決！
parachesさまに本当に感謝！
あきらめて、また最初から！？！？と思いかけていたので。。。
Objective-C, Objective-C++ のコードを Swift で使う

iOS Advent Calendar 10日目は、いわゆる __Bridging-Header__ の話です。
Swift は素晴らしい言語で積極的に使っていますが、過去の優秀なライブラリは Objective-C で書かれています。
また、 Objective-C はただの C 拡張なので C++ を書くこともできました。
これらのコードを Swift で利用するときはどうしたらいいのでしょうか。
## これはなに
- Swift から Objective-C のコードを参照するときは __Bridging-Header__ を使う
- Bridging-Header の作り方を調べた
- 参照先の Objective-C ヘッダから C++ が参照できてはならない

## Bridging-Header の作り方
既に Swift を書いているエンジニアなら大抵の方が使用しているとは思いますが、[公式サイト](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html) のやり方だとイマイチよくわからないということもあります。

### 自動的に作られない
先ほどの[公式サイト](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html)には、 __Objective-C のファイル(.m)を Swift プロジェクトに入れると以下のようなダイアログが出る__ と書いてある。
![](https://qiita-image-store.s3.amazonaws.com/0/56442/11dede89-769d-4cbf-bab4-34933cad3963.png)
*developer.apple.com より引用*

しかし、主に CocoaPods を利用する際などプロジェクトに Objective-C ファイルを入れない場合は自動的に作られません。

### 自分で作る
ならば自分で作ってしまいましょう。
手順は簡単で、

1. .hファイルを作る
2. Build Settings で設定する

だけです。

#### .h ファイルを作る
よく検索すると、 ProjectName-Bridging-Header.h という名前にしろ、と書いている記事が多いですがぶっちゃけ名前はなんでもいいです。
今回は Hoge.h という名前で作ってみました。
*自動生成のものに名前を合わせて ProjectName-Bridging-Header.h で作るのがいいと思いますが…*

#### Build Settings で設定する
検索窓に "Bridging" くらいまで入れると当該の欄しか出てこないと思います。
そこに Bridging-Header までのパスを書けば終わりです。
プロジェクトルートに置いているならば、
```
$(SRCROOT)/$(PROJECT)/Hoge.h
```
でOKです。

![](https://qiita-image-store.s3.amazonaws.com/0/56442/73493b77-f8bf-c496-2cfc-2ac90e055863.png)

あとは Bridging-Header 内で Objective-C のヘッダを `#import` して Swift で使っちゃいましょう。

## Objective-C++ のコードを Bridge する
Swift は Objective-C のコードを上記の Bridging-Header で呼び出すことができます。
しかし、 C++ には対応していません。ゆえに Objective-C++ を使用する場合は気をつける点があります。

### Bridging-Header で import するヘッダから C++ を参照できてはいけない
考えてみれば納得できるのですが、Swift が Bridging-Header を見ているわけで、そこに C++ があってはいけないということですね。これは Objective-C++ であっても同じです。
Bridging-Header に import するヘッダからはなんとかして C++ 成分を除きましょう。
どうしてもだめな場合は

```
#ifdef __cplusplus

... cpp code...

#endif
```

として逃げた経験がありますが、本来の意図と異なるのでできればやりたくないですね。

## 所感
Bridging-Header のおかげで CocoaPods も使えるし過去の遺産を再利用できるのですばらしい仕組みだと思っています。
でもあえて欲を言うなら C が見えるなら C++ も見てほしかった…
というのも C++ のモジュールを Swift で使いたかったので一度 Objective-C++ で C++ モジュールのラッパを書き、参照しようとしたら上記の罠にハマったからです。

もっと Swift エンジニアが増えて全部 Swift でまかなえるようになる日を願って…
Hiveのパフォーマンスチューニングで試した７つのこと

[Spark, SQL on Hadoop etc. Advent Calendar 2014 - Qiita](http://qiita.com/advent-calendar/2014/distributedcomputing) 10日目の記事です。

とあるプロジェクトにて、パフォーマンスチューニングのために実施した７つのことをまとめました。

この内容は[Cloudera World Tokyo 2014](http://www.cloudera.co.jp/jpevents/cwt2014/session/)でお話しさせていただいた内容を再編したものです。

[登壇資料 - Hadoopで作る広告分析プラットフォーム](http://www.cloudera.co.jp/jpevents/cwt2014/static/pdf/B-1.pdf)
[登壇の様子 - 国内最大級のHadoop関連カンファレンスに登壇してきました！](http://www.lockon.co.jp/officialblog/work/9378/)

##1.YARNが利用可能なリソースの変更
YARNではMR1と異なりスロットではなくコンテナという概念でリソースが管理されます。
以下のパラメータでノードマネージャがコンテナに利用可能なメモリ量、CPU数を変更しました。
`yarn.nodemanager.resource.memory-mb`
`yarn.nodemanager.resource.cpu-vcores`

##2.クエリパラメータの変更
###2.1.Mapperあたりの最大読み取り量を変更
以下のクエリパラメータを利用して1Mapperあたりの入力サイズを制限することでMapperの同時起動数を増加させました。
`mapreduce.input.fileinputformat.split.maxsize`

###2.2.Reducer数の変更
以下のクエリパラメータを利用してreducer数を変更しました。
`mapred.reduce.tasks`

##3.ファイルフォーマットの変更
同一データを異なるファイルフォーマットのテーブルに格納して検証を行いました。
検証したのは以下の４フォーマットです。
RCFile, SequenceFile, Avro, Parquet

RCFile - 弊社環境では最も性能が良かった
SequenceFile - RCFileより少しだけ性能が低かった
Avro, Parquet - 書き込み性能が大幅にダウン

##4.バケット化
バケット化を利用すると指定した列のハッシュ値を元にバケット（データブロック）が作成されます。
テーブルをJOINする場合、結合に使う列がバケット化されていればテーブル全体をフェッチする必要がなくなるのでJOIN処理が効率的に行えます。
残念ながら弊社の環境では効果がありませんでした。

Sort Merge Bucket Map Join
結合対象の列がバケット化されており、かつソートされているとJOINがさらに効率化されます。
しかし、こちらも弊社環境では効果がありませんでした。

[JOIN, バケット化に関する参考資料](https://cwiki.apache.org/confluence/download/attachments/27362054/Hive+Summit+2011-join.pdf)

##5.ファイルのマージ
small files problem対策として以下のクエリパラメータを利用してファイルのマージを行いました。
`hive.merge.mapfiles=true`
`hive.merge.mapredfiles=true`
`hive.merge.size.per.task=xxx`
`hive.merge.smallfiles.avgsize=xxx`
※ただしファイルマージステップが実行されるのでINSERTクエリの処理時間が若干増加しました。

##6.レプリカ数の変更
HDFSではブロックを複数ノードにレプリケーションする事で耐障害性を高めています。
このレプリケーション数をテーブルの用途に応じて変更して検証を行いました。
###6.1.ワークテーブルのレプリケーション数を１に変更
ワークテーブルはバッチ処理の都度生成し直すのでレプリケーション数を１とすることでレプリケーション時間の短縮を試みました。

###6.2.頻繁に読み込むテーブルのレプリケーション数をノード数と一致させた
頻繁に読み込むテーブルのレプリケーション数をノード数と一致させることで、各ノードがローカルからデータをロードできるようにしました。（ただし、レプリケーション時間が増加します）

バッチ全体で見た場合にさほど効果が得られなかったため、採用を見送りました。


##7.UDF(User Defined Function)の作成
PHPで作成したストリーミング処理をUDFに書き換えることで、処理時間を40%程削減できました。
これは、
　・UDFではHiveQLを処理するタスクと同一のプロセスで処理が行われる
　（ストリーミング処理では標準入出力を介した外部プロセスとのデータ受け渡しを行う）
　・PHPとJavaの処理性能の差によるものだと考えています。

以上、弊社で試した７つのことでした。
[Java 8][Stream API] オブジェクトの List から Map を生成する方法を模索する

# はじめに

Java 8 を導入し始めて既に半年以上になるけど、未だに Java 8 の Stream API で複雑な処理をしようとすると頭を抱えてしまうので、その時々の **自分なりの** ベストプラクティスをメモしておくことにします。

# 今回のお題

Stream API に慣れてくると、データクラスのオブジェクトからなる `List` オブジェクトに対して、データクラスのある属性をグルーピングのキーに、もう一つ別の属性をグルーピングされた結果を保持する `List` の構成要素として持つような `Map` オブジェクトを Stream API で華麗に表現したくなるのが人間ってもんです。

今回はこの問題について、 `Collectors.toMap()` を使った方法と `Collectors.groupingBy()` と `Collectors.mapping()` を組み合わせて使った方法で解消してみることにしました。

# 実装例

```java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * オブジェクトのリストから、そのオブジェクトの属性を key / values にした Map を Java 8 の Stream で生成する。
 */
public class HowToBuildMapFromObjectList {
	public static void main(String[] args) {
		List<GroupUser> groupUsers = Arrays.asList(
				GroupUser.newGroupUser("でぃずにーぐみ", "泡姫（ありえる）"),
				GroupUser.newGroupUser("じぶりぐみ", "永瞳月（ととろ）"),
				GroupUser.newGroupUser("でぃずにーぐみ", "黄熊（ぷう）"),
				GroupUser.newGroupUser("じぶりぐみ", "今鹿（なうしか）")
		);

		// Collectors.toMap() を使う
		System.out.println(byCollectorsToMap(groupUsers));

		// Collectors.groupingBy() と Collectors.mapping() を組み合わせて使う
		System.out.println(byGroupingByAndMapping(groupUsers));
	}

	/**
	 * {@link Collectors#toMap(Function, Function, BinaryOperator)} を使う方法。
	 */
	static Map<String, List<String>> byCollectorsToMap(List<GroupUser> groupUsers) {
		return groupUsers.stream()
				.collect(Collectors.toMap(
						GroupUser::groupName,
						gu -> new ArrayList<>(Collections.singletonList(gu.userName())),
						(l1, l2) -> Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList())));
	}

	/**
	 * {@link Collectors#groupingBy(Function, Collector)} と
	 * {@link Collectors#mapping(Function, Collector)} を組み合わせて使う方法。
	 */
	static Map<String, List<String>> byGroupingByAndMapping(List<GroupUser> groupUsers) {
		return groupUsers.stream()
				.collect(Collectors.groupingBy(
						GroupUser::groupName,
						Collectors.mapping(
								GroupUser::userName,
								Collectors.toList())));
	}

	/**
	 * グループ名とユーザ名を保持するよくあるクラスです。
	 */
	static class GroupUser {
		private String groupName;
		private String userName;

		static GroupUser newGroupUser(String groupName, String userName) {
			GroupUser o = new GroupUser();
			o.groupName = groupName;
			o.userName = userName;
			return o;
		}

		public String groupName() {
			return groupName;
		}

		public String userName() {
			return userName;
		}
	}
}
```

# 感想

- `Collectors.groupingBy()` と `Collectors.mapping()` を組み合わせて使った実現方法が断然スマートに見えますね
- これよりもっとスマートな解決方法はないものだろうか…