OmniAICreator/Qiita-1.07M huggingface dataset:
Kotlinのフォルダ構成にしたらブレークポイントに止まらなくなった

#経緯
kotlinで実装しているのに*src/main/java*というフォルダがあるのが嫌で、
フォルダ名を変えた所、ブレークポイントで止まらなくなるという現象が発生。
*android:debuggable="true"*でないとか*minifyEnabled='true"*になってるとか
巷であふれてる解決法でどうにもならなくて匙を投げかけていたところ、AndroidManifestのクラス参照が未解決になっていたので"main/java"でGrep掛けたら解決したというオチ。

#解決策
フォルダ名と"app.iml"内の記述の祖語による。
"app/src/main/java"フォルダ名を"app/src/kotlin"等にする場合、ソース参照フォルダを正しく設定する必要がある。

```xml:app.imp
<!--<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />-->
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
```
#結論
そもそもフォルダ構成を変えたタイミングでこういう事象が発生すると思ってなかったので切り分けに時間がかかったのが敗因。ビルドは通るのにブレークポイントは止まらないとか嫌がらせか。
Android Studioの不親切さに比べ、Visual studioはすごい。
もっとMSを讃えていいと思うの。(個人の感想であり、個人差があります)
これやったらディレクターの仕事が捗ったこと2点まとめ


# はじめに

この記事は[MicroAd Advent Calendar 2017](https://qiita.com/advent-calendar/2017/microad)の4日目の記事です。

本稿では、4年目システムディレクターの僕がこれまでに「エンジニアだったら当たり前だけど、ディレクターも最低限これくらいはできるようにしておくと仕事捗るなあ」と思ったことを2点まとめていきます。


# どこにどんなデータがあるのか把握すること

まずは、どこにどんなデータがあるのか把握することです。  
僕の会社でもHadoopやMySQL、ElasticSearch、Redisなど、いろいろなデータソースがあります。僕はこれらからいろいろなデータを出せるようにしています。  

結果、システム理解に大きくつながり、すごく捗っています。


## 実現可否の判断

例えば、ビジネス的にやりたいことがシステム的に実現可能か、実現できないなら何を追加開発すれば実現できるのか、おおよその開発項目、工程を大枠でイメージできるようになりました。  
「あそこにあのログあるな。こっちにはこのログあるな。後はここにフラグつければ、判断処理追加して。。。イケる！」みたいな。  
システムディレクターだとビジネスロジックの理解は深いと思うので、組み合わせると最強だと思います。


### information_schemaのcolumnsテーブルを検索

MySQL限定ですが、こういうカラムがどっかにあるはずなのにテーブルやDBが多すぎて全部覗いていくのは骨が折れるという時に使えるクエリを紹介します。  

カラム名に「_id」が含まれているカラムを持つテーブルを全DBから検索するSQLです。

```
use information_schema;
select column_name, table_schema, table_name from columns where column_name like "%\_id";
```



# ログファイルを見ること

次はログファイルを見ることです。  
サーバのログファイルを直接見れるようにしたら、仕事がだいぶ捗りました。

## 未加工の状態の方が嬉しい時もある

分析に使うログやビジネスロジックで使ったアプリログは、サーバの容量の制限や処理パフォーマンス等を考慮して情報が削られたり、丸められたりします。  
そのため、新機能開発のための事前調査などで、「ちょっとここのデータの全体の割合が欲しい」「ここのデータをもう少し細かい粒度で、しかも今日分のものが急ぎで欲しい」という場合に、欲しい情報が十分な形で見られないケースが多いです。  

このような場合は、データソースに入っていない未加工のログファイルを直接参照することで欲しい情報がをすぐに得られたりします。  

僕は以下のlinuxコマンドを覚えるだけで容易に見れるようになりました。

| コマンド | ざっくり概要     |
| :------------- | :------------- |
| ssh | サーバにログインする。 |
| cd /hoge/log | /hoge/logディレクトリに移動する。 |
| ls -la | 今いるディレクトリのファイル、ディレクトリ一覧。 |
| less hoge.log |  hoge.logを開く。ただし編集不可。圧縮済みファイルの中身を解凍せずに覗ける。 |
| wc -l hoge.log | hoge.logの行数を出力する。 |
| grep 'abc' hoge.log | hoge.logから'abc'という文字列が含まれる行だけを抽出する。 |


これに「 |（パイプ）」「*（アスタリスク）」を組み合わせたりして、未加工済みのログから欲しい情報を得ることができるようになりました。

#### 例：apacheのaccessログで特定のUAをサンプリングしたい時

```
# ここではaccess.log.1の件数を見ています。
Udai928@wordpress:/var/log/apache2$ wc -l access.log.1
2099 access.log.1

# ここではaccess.log.1に文字列'Fire'が含まれている行を取り出し、「|」でwc -l をつなげて行数を見ています。
Udai928@wordpress:/var/log/apache2$ grep 'Fire' access.log.1 | wc -l
1

# 上記で1行あることがわかったので、中身を見てみました。
Udai928@wordpress:/var/log/apache2$ grep 'Fire' access.log.1
169.53.184.23 - - [01/Dec/2017:10:58:37 +0000] "GET / HTTP/1.0" 200 37036 "-" "Mozilla/5.0(WindowsNT6.1;rv:31.0)Gecko/20100101Firefox/31.0"

# UAがFireFoxのログは2099件中1件しか無いことがわかりました。

```



# 終わりに

本稿が「仕事が捗らないなあ。。。」とお思いの世のシステムディレクターのみなさんの参考に少しでもなれば幸いです。
Alexa Skillのエラーハンドリング

Amazon Echoがついに日本でリリースされ、日本語版のAlexa開発環境も公開されましたね。
僕のもとにはまだAmazon Echoの購入招待メールが届かず寂しい思いをしておりますが、開発について語れることはいくつかありそうなので、今回はAlexa Skillのエラーハンドリングについて語りたいと思います。

## お品書き
1. ユーザーが予期せぬ言葉を発してきた
2. 予期せぬ発話に対応したはずなのにまたエラー
3. ユーザーが黙ってしまった
4. アカウントはリンクされてますか？

以上の４点について対処方法を紹介したいと思います。

## ユーザーが予期せぬ言葉を発してきた
例えば外食検索サービスを作っていたと仮定して、以下の例を考えましょう。

例）
Skill 「和食、中華、イタリアンなど、どんな種類の料理を食べたいですか？」
User 「具志堅用高」

みたいにユーザーがやばいやつだった場合にはきちんと「何言ってんだお前。こっちはどんな種類の料理を食べたいか聞いてるんだ」と返してやる必要があります。
Google HomeのAction開発によく使用されるDialogflowであればfallback intentが用意されていますが、Alexaの場合その役割を担うintentがデフォルトで用意されていません。
自分で用意してあげましょう。

**対処方法**
intentSchemaのintents配列のトップに以下のようにfallback intentを追加する。

```json
{
  "intents": [
    {
      "intent": "FallbackIntent"
    },
    {
      "intent": "AMAZON.YesIntent"
    },
    {
      "intent": "AMAZON.NoIntent"
    },
  ]
}
```

更にSampleUtterancesでFallbackに落としたい文言を書く。
とりあえず「あ」とかだけでもFallbackに落ちてくれますが、絶対にFallbackに落としたい文言も書いておくと良いでしょう。

```
FallbackIntent あ
FallbackIntent 具志堅用高
```

## 予期せぬ発話に対応したはずなのにまたエラー
上記の対応をした上でもまだ予期せぬ発話へのエラーハンドリングとしては足りていません。
こんな例で考えてみましょう。

例）
Skill 「和食、中華、イタリアンなど、どんな種類の料理を食べたいですか？」
User 「3000円」
Skill 「スキルからの応答に問題があります」（Skill終了）

なんとFallbackを設定したにも関わらずそちらには落ちず、Skillは不吉なメッセージを残して勝手に終了してしましました。
なんてこったい！

実はこの外食検索サービスは以下のような手順でお店を探すサービスだったとします。

1. 駅名・地名を聞く
2. 料理の種類を聞く
3. 価格帯を聞く 
4. 3つの条件からお店を検索する

3番に`価格帯を聞く`という項目があります。
怪しいですね。
そうです、今回ユーザーは料理の種類を聞かれているにも関わらず早まって価格帯を言ってしまったのです。
今いるStateで呼び出せるintentではないけれどもintentSchemaに登録されているintentの場合は中途半端に反応してしまうようです。
Skillの質問をちゃんと聞けよと思いますが、何度もSkillを使ってなれてくると質問を聞かずにしゃべってくることも無きにしもあらず。

**対処方法**
`ask`を使用するstateの中では必ず`Unhandled`を設定してやりましょう。

```js
var cuisineTypeHandlers = Alexa.CreateStateHandler(states.CUISINE_TYPE_MODE, {
  cuisineType: function() {
    var message = '和食、中華、イタリアンなど、どんな種類の料理を食べたいですか？'
    this.emit(':ask', message, message);
  },

  /* 省略 */

  Unhandled: function() {
    var message = '和食、中華、イタリアンなど、どんな種類の料理を食べたいですか？';
    this.emit(':ask', message, message);
  }
});
```

## ユーザーが黙ってしまった
Skill起動中にユーザーが黙ってしまうこともあるでしょう。
もしくは宅配便が来て放置されるとか。
Alexaは８秒以上放置されるとaskのreprompt設定されたメッセージを喋り（多分設定したほうが良い）、更に8秒以上放置されるとセッションを終了します。
この時何も対処していないと「スキルからの応答に問題があります」と言われてしまいます。

**対処方法**
`ask`を使用するstateの中では必ず`SessionEndedRequest`を設定してやりましょう。
`SessionEndedRequest`で`emit`することはできないので関数の中身は空で大丈夫です。

```js
var cuisineTypeHandlers = Alexa.CreateStateHandler(states.CUISINE_TYPE_MODE, {
  cuisineType: function() {
    var message = '和食、中華、イタリアンなど、どんな種類の料理を食べたいですか？'
    this.emit(':ask', message, message);
  },

  /* 省略 */

  SessionEndedRequest: function() {}
});
```

## アカウントはリンクされてますか？
actions on googleとDialogflowを使っている場合はチェックボックスによる設定だけで、アカウントがリンクされていない旨を示すメッセージを読み上げや、Google Homeアプリへのアカウントリンクカードを送信をしてくれるので楽ちんです。
一方、Alexaではアカウントリンクがされているかを確認し、Alexaアプリにカードを出力するようコーディングしてやる必要があります。

**対処方法**
最初に呼び出されるintentに以下のようなコードを書いておけば良いでしょう。

```js
if (!alexa.event.session.user.accessToken) {
  var message = 'アカウントリンクされてないのでアプリからリンクよろしくです。'
  this.emit(':tellWithLinkAccountCard', message);
}
```

`alexa`はalexaのhandlerです。

## まとめ
音声UIはユーザー入力の自由度が高いのでとにかくエラーハンドリングが大事です。
SICP読書録 #2 1.1 式 - 1.1.6 条件式と述語

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
練習問題等は[Gauche](http://practical-scheme.net/gauche/index-j.html)で実行。

[前回はこちら](https://qiita.com/shuetsu@github/items/5e4edad839565cc75b3f)

#1 手続きを用いた抽象化の構築

この本で紹介されるコードは全てLispの方言であるSchemeで記述されています。なぜこんなマイナーな言語を使うのか？

> これらの特性の中でも最も意義深いものは、プロセスのLispによる記述(これは手続き(procedure)と呼ばれます)が、それ自身Lispのデータとして表され、操作できるということです。

つまり、Lispには「手続き」と「データ」との間の区別がないという特性があり、これが高い柔軟性を生んでいる。乱暴に言うと、何らかのデータを計算して生成するプログラムが作れるんだから、プログラムを生成するプログラムだって作れる。

#1.1.5 手続き適用の置換モデル

``` 1.1.5.0.scm
(define (square x) (* x x))
(define (sum-of-squares x y)
  (+ (square x) (square y)))
````

と、定義されていたとして・・・

以下のように展開されるのが、適用順序評価。

```1.1.5.1.scm
(sum-of-squares (+ 5 1) (* 5 2))
(sum-of-squares 6 10)
(+ (square 6) (square 10))
(+ (* 6 6) (* 10 10)
(+ 36 100)
136
```

以下のように展開されるのは、正規順序評価。

```1.1.5.2.scm
(sum-of-squares (+ 5 1) (* 5 2))
(+ (square (+ 5 1)) (square (* 5 2)))
(+ (* (+ 5 1) (+ 5 1)) (* (* 5 2) (* 5 2)))
(+ (* 6 6) (* 10 10))
(+ 36 100)
136
```

普通は適用順序評価が採用される、よね。
適用順序評価のほうが効率はいい。例えば`(+ 5 1)`を何度も計算せずにすむ。
しかし実行結果は変わらないはず・・・と思いきや、練習問題1.5を見よ。


##練習問題1.1

以下の式に対するインタプリタの応答は？
自明だけどさぼらずやろう。

```ex1.1.scm
gosh> 10
10
gosh> (+ 5 3 4)
12
gosh> (- 9 1)
8
gosh> (/ 6 2)
3
gosh> (+ (* 2 4) (- 4 6))
6
gosh> (define a 3)
a
gosh> (define b (+ a 1))
b
gosh> (+ a b (* a b))
19
gosh> (= a b)
#f
gosh> (if (and (> b a) (< b (* a b))) b a)
4
gosh> (cond ((= a 4) 6)
            ((= b 4) (+ 6 7 a))
            (else 25))
16
gosh> (+ 2 (if (> b a) b a))
6
gosh> (* (cond ((> a b) a)
               ((< a b) b)
               (else -1))
         (+ a 1))
16
```

##練習問題1.2

以下の式を前置記法に置き換えよ。
数式を書く練習。

```math
\frac{5+4+(2-(3-(6+\frac{4}{5})))}{3(6-2)(2-7)}
```

```ex1.2.scm
gosh> (/ (+ 5 (+ 4 (- 2 (- 3 (+ 6 (/ 4 5))))))
         (* 3 (- 6 2) (- 2 7)))
-37/150
```

####練習問題1.3

３つの引数をうけとり、そのうち大きい２つの２乗の和を返す手続き。

```ex1.3.scm
(define (ex_1_3 x y z)
        (cond ((and (< x y) (< x z)) (sum-of-squares y z))
              ((and (< y x) (< y z)) (sum-of-squares x z))
              (else                  (sum-of-squares x y))))
```

##練習問題1.4

演算子が複合式であるような以下の例。そのふるまいを説明せよ。

```ex1.4.scm
(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))
```

正規順序評価での展開例を示す。
引数bが正数ならば

```ex1.4.answer1.scm
(a-plus-abs-b 5 2)
((if (> 2 0) + -) 5 2)
(+ 5 2)
7
```

負数ならば

```ex1.4.answer2.scm
(a-plus-abs-b 5 -2)
((if (> -2 0) + -) 5 -2)
(- 5 -2)
7
```

引数bが正数なら+、負数なら+と、呼ばれる演算子が動的に決定される。

##練習問題1.5

以下のコードは、適用順序評価と正規順序評価とで、異なる結果になるのだとか。

```ex1.5.scm
(define (p) (p))
(define (test x y)
  (if (= x 0) 0 y))

(test 0 (p))
```

それぞれ展開してみよう。まずは適用順序評価。

```ex1.5.answer1.scm
(test 0 (p))
(test 0 (p))
(test 0 (p))
...
```

(p)を評価すると(p)なので無限ループに。実際、Gaucheで実行すると固まる。

正規順序評価ならば。

```ex1.5.answer2.scm
(test 0 (p))
(if (= 0 0) 0 (p))
0
```

ifは特殊形式なので、条件句が真ならば(p)は評価されない。
SICP読書録 #1 前書き-序文

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
[和田訳本](https://www.amazon.co.jp/dp/4798135984)も持ってるけど。。。。こちらの方が読みやすくていい感じ。

SICPというのは[計算機プログラムの構造と解釈(Structure and Interpretation of Computer Programs)](https://ja.wikipedia.org/wiki/%E8%A8%88%E7%AE%97%E6%A9%9F%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E6%A7%8B%E9%80%A0%E3%81%A8%E8%A7%A3%E9%87%88)という本の略称で、かつてMIT(マサチューセッツ工科大学)で行われていたプログラミング入門コースの教科書です。

# 前書き

> 計画を⽴てるということ⾃体を知的な活動として理解するためには、コンピュータプログラミングに⽬を向ける必要があります。
> コンピュータプログラムを読み書きする必要があります— それも、⼤量に。何のプログラムか、どういう応⽤のためかというところはあまり重要ではありません。重要なのは、それらがどのようにふるまい、またより⼤きなプログラムを作る中でそれらがどれだけスムーズにほかのプログラムと協調できるかということです。

SICPが取り扱うのは、ある特定の課題を解決する方法ではなく、計画を立てるということ自体をを対象とする、もっと一般的なものだ、ということ。

日々巨大化し、気まぐれな変更が入り、ほうっておくとすぐ手に負えなくなるほど複雑化してしまうソフトウェアという怪物を、いかに暴走させずに飼いならすか？

> 完全な形式的な正しさの論証というものが⼤きなプログラムについてくるということはめったにありません。⼤きなプログラムは⼩さなものから成⻑していくものなので、正しさについて確信を持てるような標準的なプログラム構造(これをイディオムと呼びます) の武器庫を作り上げ、確⽴された組織化技術によってより⼤きな構造に組み⽴てていく⽅法を学ぶことが決定的に重要になります。

この本を読み進めていけば、解決したい問題に合わせて、プログラミング言語そのものを作り替えていくというアプローチが行われていく、はず。
誰かに用意してもらった環境を利用するだけでなく、自ら環境を作り出すのだ！

・・・ところが、[現代のエンジニアリングにおいては既存の資産を組み合わせて目の前の問題を解決していく能力の方が重要だ](https://cpplover.blogspot.jp/2016/05/mitsicp.html)という考えもあって、それが件の入門コースが廃止された理由らしい。

しかし、まだまだソフトウェア開発というのは、便利な部品さえ手に入ってしまえばシステムとして完成させるのは簡単、といった風にはなっておらず、未だにこの怪物と格闘していかなければならない現実が続いている、と私は感じています。

我々が自ら環境を作り出す能力、という武器を捨てるのはまだ早いでしょう。また、拾った武器を使うのだとしても、それを有効に使う能力を身につけるためにも、SICPの内容は有効なはずです。

> コンピュータプログラミングに関する興奮の源は、プログラムとして表現されたメカニズムが私たちの⼼の中とコンピュータ上で絶え間なく広がっていくことと、またそれが⽣み出す知覚の爆発です。芸術が私たちの夢を解釈するものだとすると、コンピュータは夢を、プログラムという形で実⾏するものなのです！

夢、というか頭の中だけで考えていたアイディアを、プログラムという形に具体化することで、その本質が浮かび上がる。
例えば、システムの複雑さを緩和する技術として抽象化というのがあるけど、この抽象化を繰り返すことによって、その問題について整理・単純化して理解を深めることができる。
つまりプログラミングによって人間は賢くなれる。プログラミングの本当の楽しさはそこにある！

と、こういう解釈でいいのかな？　だとしたら個人的にすごく共感します。

余談ですが、これに対して、こんな抽象的で難解な本を読ませたら、プログラムを学ぼうと情熱を燃やす若人の心を折ってしまうのでは？という意見もあるようです。
代わりに、思い通りに動くプログラムをさくっと作らせる経験を積ませて、「楽しい！」って思わせたほうがよい、と。

うーん。私としては、本当に最初のうちはそれでいいんだけど、コンピュータが「思い通りに動く」だけでは、その喜びは薄っぺらいものにすぎないと思います。それは単に予想通りの結果が得られたというだけ。それより自身の知覚そのものが拡がるほうが楽しいでしょう？

そりゃもちろん、プログラミングは手段にすぎなくて、結果できあがるソフトウェアによって現実社会へインパクトを与えるという経験こそが芳醇なんだと考える立場もわかります。
でもそれだけじゃ、プログラミングがもたらす「知覚の爆発」という果実を、バッサリ切り捨ててしまうことになる。せっかくソフトウェアに関わるんなら、それはあまりにもったいないことです。

# 第１版序文

> プログラムは⼈間が読めるように書かなくてはならず、それがたまたま機械によって実⾏できるというだけのことです。

出ました。[「ハッカーと画家」](https://www.amazon.co.jp/dp/4274065979)でも引用されてたこの格言。プログラミングはソフトウェアを作るための手段でしかないとする考えに真っ向から対立してます。

（機械によって）ソフトウェアとして実行できるかどうかはたまたまのことでしかない？
じゃあ何のためにかと聞かれれば、人間が読むため？　まるで禅問答のようですが・・・

データをいかに処理するかについて表現するなら、自然言語を利用するよりもプログラミング言語を用いる方が簡潔だし、あいまいさも排除できる。人間同士のコミュニケーションを行うのだとしても、自然言語よりもプログラミング言語を介して行う方が良い場合もあります。
プログラムを自ら読み書きできるかどうかは、ソフトウェアに関わる仕事をする上で必要なコミュニケーション能力のひとつと言えるでしょう。

・・・と、まあこんな調子で暑苦しい感想を書きたくなる文章が次々出てくる恐るべき本なのですが、進まないので次からはサラリと（練習問題中心に）やってきたいと思います。
Amazon RDS Read ReplicaをNLBでロードバランシングする

この記事は [Relux AdventCalendar](https://qiita.com/advent-calendar/2017/relux) 4日目の記事です。

## RDS Read Replicaのロードバランシング
複数のRead Replicaをロードバランシングする方法はいくつか考えられます。

- Reader Endpointを使用する
- HAProxyやNginxなどのソフトウェアを使用する
- NLBを使用する

#### Reader Endpoint
Reader EndpointはAWS RDSの機能として用意されたもので、特別な設定をすることなく利用できます。
クラスタ内のRead Replica全てに均一に分散するもので、特定のRead Replicaを対象から外すといったことはできません。
短い時間(1秒ごと)でCNAMEを切り替えてラウンドロビンするような実装となっており、実際はロードバランサではありません。

#### HAProxyやNginx
AWSで行うとしたら、専用のEC2インスタンスを用意し、自分でインストール・設定・管理をする必要があります。

#### NLBを使用する
2017年9月ごろに、ELBの一種としてリリースされた Network Load Balancerは、EC2インスタンスだけでなく、任意のIPアドレスをターゲットとしてTCPロードバランサを構築できます。
これを使用することで、特定のRead Replicaのみをターゲットとした負荷分散環境を簡単に実装することができます。

## NLB で Read Replica のロードバランシングを行う

### NLBの構築

<img width="610" alt="Screen Shot 0029-12-04 at 7.21.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/4181a936-6df4-388d-efad-6856e369950b.png">
EC2 Load Balancersの設定画面から「Create Load Balancer」をクリック

<img width="1415" alt="Screen Shot 0029-12-04 at 7.21.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/7f651b97-9155-6046-b1c0-4ee8a158a0d9.png">
Network Load Balancer を選択

### NLBの基本設定

<img width="1409" alt="Screen Shot 0029-12-04 at 7.23.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/96ac9ad1-2667-5641-d908-205284db2412.png">
Nameには任意の名前を設定。
Schemeは、VPC内でのみ使用するのであれば internalを選択。

Listenerは、Aurora(MySQL)を対象とするので 3306/TCP

Availability Zoneでは使用するVPCを選択し、エンドポイントを置くサブネットを選択する。

### ルーティングの設定
<img width="689" alt="Screen Shot 0029-12-04 at 7.24.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/dc5a1cf6-40e6-dbf8-2cfb-45d93753745e.png">

ALBと同じようにターゲットグループを作成する。
AuroraのReplicaをターゲットとする場合には、3306/TCP、Target typeは ip とする。

### ターゲットの登録
<img width="1415" alt="Screen Shot 0029-12-04 at 7.25.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/5d2cd914-43c9-f62f-75c7-518bae047cb7.png">

ターゲットとして、ロードバランシングの対象としたいReplicaインスタンスのIPアドレスを登録する。
IPアドレスはReplicaインスタンスのDNS名をnslookupやdigで引いて調べる。

### Security Groupの設定
<img width="1165" alt="Screen Shot 0029-12-04 at 7.35.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/a9d87c92-6e53-d6f0-4236-913aee04cbda.png">

NLBにはSecurity Groupを設定できない。
なので、NLBのAvailability Zoneに設定したサブネットのネットワークアドレスを許可するよう、RDSのSecurity Groupに設定をする。

### 疎通確認

<img width="793" alt="Screen Shot 0029-12-04 at 8.07.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/13038/ae4f06d9-83da-16a0-28c2-843f9f784795.png">

アプリケーションサーバから接続可能なことを確認する。

## 最後に

今のところ、弊社では開発環境にのみ導入をし、試験運用を行なっております。
特に動作にが問題なく有用そうであれば、本番環境への導入を進めていきたいと思っています。
意識の低いSRE SREに取り組む前の話

# 意識の低いSRE SREに取り組む前の話

## 前置き

![グラフ：目標レベル](https://qiita-image-store.s3.amazonaws.com/0/213982/e846b935-551f-b1d5-bce2-a9bc6ff27649.png)

|目標レベル|レベル0<br>技術負債山<br>(地盤沈下中)|レベル1<br>高尾山|レベル2　　　<br>富士山|レベル3　　　<br>エベレスト山|レベル4　　　<br>オリンポス山<br>(火星)|
|---|---|---|---|---|---|
|段階|オンプレで<br>LAMP構成|クラウド化|マイクロサービス化|パブリッククラウド<br>フル活用|世界中に<br>自社データセンターや<br>海底ケーブル|
|例|10年前に<br>作った<br>システムのまま|ここ数年で<br>作った<br>システム|2014年の<br>クックパッドの<br>報告が有名|Netflix,<br>Pokemon GO,<br>...|Amazon,<br>Microsoft,<br>Google,<br>facebook,<br>...|

レベル０のプロジェクトを、レベル２に持って行くには、まずレベル１をクリアする必要がありますよね、の話です。

オンプレでLAMP構成な人向けです。

## 本題

### １．あなたのプロジェクトは、どのレベルにありますか？

|SREで捨てるもの|SREで取り入れるもの|
|---|---|
|ウォーターフォール|アジャイル|
|片手間に改善|開発作業の半分は改善|
|オンプレ|クラウド|
|XX専用サーバ、KVM|docker|
|サーバのupdate|サーバは使い捨て(式年遷宮/Blue-Green Deployment)|
|Apache|Nginx|
|php 5.4|php 7.x|
|MySQL 5.5/MariaDB 5.5|MySQL 5.7/MariaDB 10.x|
|手動デプロイ|自動デプロイ|
|subversion|git|
|手動テスト|自動テスト|
|モノシリックなシステム|マイクロサービス|
|ぐだぐだなセキュリティ体制|PCI DSS準拠のセキュリティ体制|
|共有ID/パスワード|個人別ID/パスワード|
|思い込みで作業順を決める|計測結果で作業順を決める|
|...|...|

2017-08-24 [「hbstudy＃76 SRE大全: XFLAG スタジオ編」で発表しました](https://xflag.com/blog/hbstudy76_sre_xflag.html)
で、「**SREとは、確実に古いシステムを捨てていく事**」という名言がありました。

### ２．より深刻な問題は何ですか？

[80対20の法則](https://www.amazon.co.jp/dp/B00CPKUY7C) 等で言われているように、より深刻な20%の問題から取り組みましょう。  
残り80%は当面現状維持、後回しで良いのです。

大部分のプロジェクトでは、

- セキュリティ問題
- 負荷上限が低い
- 冗長化が無い（不足）

が３大問題で、あとは小さな問題(フレームワーク使ってない、とか)の可能性が高いです。

### ３．作業順

レベル０をレベル１にする時の作業順です。

1. 右から左（シフト＆リフト）でクラウドに持っていく
1. 深刻な不足リソース(CPU,memory,disk等)は増やす
1. docker化する（これで、php5.4/php7.xの複数バージョン共存が可能になる）
1. OS,php,MySQL等を最新にする(セキュリティ)

いわゆる普通の「クラウド移行案件」って感じですね。

### ４．その後の作業見通し

レベル１をレベル２にする時の作業順です。

1. ソースコードをgit管理する
1. CIツールを導入する
1. CIツールの制約に合わせた形で自動デプロイ化する
1. 自動テストを作成する
1. CIツールで自動テストが動くようにする
1. ログサーバ作る
1. ログをfluentdでnginx→ログサーバ→bigquery転送する
1. BIツール入れる
1. BIツールの使い方を研究する（遅い箇所の探し方）

## 結論

SREに取り組む前に、まずクラウド化してくださいねー
自分が書いたRubyプログラムをirb上で読み込む方法


## はじめに

この記事は書籍「[プロを目指す人のためのRuby入門](http://gihyo.jp/book/2017/978-4-7741-9397-7)」に掲載できなかったトピックを著者自らが紹介するアドベントカレンダーの4日目です。
本文に出てくる章番号や項番号は書籍の中で使われている番号です。

今回は自分が書いたRubyプログラムをirb上で読み込む方法を説明します。

### 必要な前提知識

「プロを目指す人のためのRuby入門」の第5章まで読み終わっていること。

## 自分が書いたRubyプログラムをirb上で読み込む方法

「プロを目指す人のためのRuby入門」では、各章に例題があり、その例題をMinitestを使ってテスト駆動開発（TDD）で実装しています。

たとえば以下は第5章の例題で作成するプログラムとテストコードです（問題やコードの説明は[サンプルページ](http://gihyo.jp/book/2017/978-4-7741-9397-7)のPDFを参照）。

```ruby
# lib/convert_length.rb
UNITS = { m: 1.0, ft: 3.28, in: 39.37 }
def convert_length(length, from: :m, to: :m)
  (length / UNITS[from] * UNITS[to]).round(2)
end
```

```ruby
# test/convert_length_test.rb
require 'minitest/autorun'
require './lib/convert_length'

class ConvertLengthTest < Minitest::Test
  def test_convert_length
    assert_equal 39.37, convert_length(1, from: :m, to: :in)
    assert_equal 0.38, convert_length(15, from: :in, to: :m)
    assert_equal 10670.73, convert_length(35000, from: :ft, to: :m)
  end
end
```

TDDで実装していくのも楽しいのですが、完成したプログラムをirb上であれこれ引数を変えながら動かすのもまた面白いです。

自分で書いたプログラムをirb上で動かすのは難しくありません。
次のように自分が書いたコードをrequireすれば、irb内でも自作のクラスやメソッドが利用できるようになります。

```
$ irb
irb(main):001:0> require './lib/convert_length'
=> true
irb(main):002:0> convert_length(1, from: :m, to: :in)
=> 39.37
irb(main):003:0> convert_length(15, from: :in, to: :m)
=> 0.38
irb(main):004:0> convert_length(35000, from: :ft, to: :m)
=> 10670.73
```

### requireで指定するパスに注意する

2.12.7項でも説明したとおり、自分で書いたプログラムを読み込むときはRubyを実行しているディレクトリからの相対パス（または絶対パス）を指定する必要があります。

パスが間違っていたり、`./`で書き始めていなかったりすると読み込みに失敗します。

```ruby
# 相対パスの指定が間違っているケース
require './convert_length'
#=> LoadError: cannot load such file -- ./convert_length

# "./"で書き始めていないケース
require 'lib/convert_length'
#=> LoadError: cannot load such file -- lib/convert_length
```

### プログラムを書き直したらloadする

irb上で自分が書いたプログラムを動かす場合、単純に書き直すだけだったり、再度requireしたりしても、プログラムの変更内容はirbには反映されません。

プログラムをもう一度読み込み直すときは`load`メソッドを使います。

```ruby
load './lib/convert_length.rb'
```

詳しくは「2.12.8 load」を参照してください。

## 次回予告

次回はMinitestでテストをスキップする方法を紹介します。
dictで一つのキーに複数の値を持ちたい時の実装方法

この記事は [Pythonのコードを短く簡潔に書くテクニック Advent Calendar 2017](https://qiita.com/advent-calendar/2017/python-short-code) の4日目です。

# はじめに

dictで一つのキーに複数の値を持つために値をリストにすることがあります。
この時、データを挿入していくには既に値があるかチェックし、なければ空のリストを挿入する、という操作が必要になります。

こういった操作をするのに便利なやり方をいくつか紹介します。

[dict.setdefault()]:https://docs.python.jp/3/library/stdtypes.html#dict.setdefault
[collections.defaultdict]:https://docs.python.jp/3/library/collections.html#collections.defaultdict
[itertools.groupby]:https://docs.python.jp/3/library/itertools.html#itertools.groupby

# 例題

単語が入ったリストから、頭文字をキーとしたdictに格納する処理を考えてみます。

```py3:元データの単語リスト
words = ['apple', 'orange', 'banana', 'alpha', 'beta']
```
↓

```py3:欲しい結果
results = {
    'a': ['apple', 'alpha'],
    'b': ['banana', 'beta'],
    'o': ['orange'],
}
```


# 普通に書いた場合

```py3
results = {}
for word in words:
    key = word[0]
    if key not in results:    #1
        results[key] = []     #2
    results[key].append(word) #3
```

普通に書くと、1.キーの存在チェック、2.空リストの作成、3.リストに単語を格納、の３回もdictにアクセスしなければなりません。
コードも長くなります。

# [dict.setdefault()]を使う

setdefault()はdictから値を取得する際に指定のキーがなければデフォルト値を設定してくれます。

```py3
results = {}
for word in words:
    results.setdefault(word[0], []).append(word)
```

これを使うとコードがスッキリする上に、dictへのアクセスが1回で済むようになります。

# [collections.defaultdict]を使う

defaultdictでも同じようなことができます。
コンストラクタでデフォルト値を作成する関数を指定します。
`[]`でキーを参照したときに、なければデフォルト値が設定されます。

```py3
from collections import defaultdict

results = defaultdict(list)
for word in words:
    results[word[0]].append(word)
```

# [itertools.groupby]を使う

groupbyを使うとリストを任意のキーでグルーピングできます。
この結果で辞書を作成すれば目的の結果が得られます。
ただしgroupbyに渡すリストは事前にソートする必要があります。

```py3:
from itertools import groupby
from operator import itemgetter

results = {k: list(v)
           for k, v in groupby(sorted(words), key=itemgetter(0))}
```

# 参考

- Python3 ドキュメント
    - Python標準ライブラリ
        - [dict.setdefault()]
        - [collections.defaultdict]
        - [itertools.groupby]
- Qiita
    - [以外と知られていない!? Python標準ライブラリの関数groupby](https://qiita.com/tag1216/items/9aecc6816371ee35215e)
Redmineのインポートページに自動ボタンを設置する

# やったこと
インポートページで、トラッカーなどを指定する処理を自動化するボタンを設置しました。
![ttt.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/150778/c907d9b9-1657-b263-9d90-4c054ccae9b2.jpeg)

#背景
標準機能にインポート機能が入って誰でも使える様になってとても便利です。
しかし、今まで使っていた人達から、各項目を手動で選択しなければいけなくなったので、手間が増えてしまったと言われてきました。
自動ボタンを押したら、選択処理を自動で行う様にしました。
ViewCustomizePluginで実装しました。

#結果
自動ボタンを押すと、自動で選択されます。
![インポートページに自動ボタン.003.jpeg](https://qiita-image-store.s3.amazonaws.com/0/150778/cfeb78c4-73a9-924a-c84d-64a9dae03a59.jpeg)

作成されたチケットはこちら。
![インポートページに自動ボタン.004.jpeg](https://qiita-image-store.s3.amazonaws.com/0/150778/3a201080-a8f2-64b4-1718-9c2c01947c46.jpeg)

#ソース

##Path pattern:
```
/imports/.+/mapping
```
##Type:
```
JavaScript
```
##Code:
ここのソースは全ての項目ではなくて、
トラッカー、ステータス、題名、説明、担当者、対象バージョンを自動選択する処理です。

```js
$(function() {
 var target = $("#content").find('fieldset.box.tabular');
 var button = $('<input type="button" value="自動A"/>');
 
 button.on('click', function() {
  /* トラッカー */ 
  target.find('select#import_mapping_tracker').val(1);
  
  /* ステータス */
  target.find('select#import_mapping_status').val(2);
  
  /* 題名 */
  target.find('select#import_mapping_subject').val(3);
  
  /* 説明 */
  target.find('select#import_mapping_description').val(4);
  
  /* 優先度 */ 
  /* import_mapping_priority */
  
  /*カテゴリ */
  /* import_mapping_category */
  /* 存在しない値は新規作成 */
  target.find('input[type=checkbox]#import_settings_mapping_create_categories').prop("checked", true);
  
  /* 担当者 */
  target.find('select#import_mapping_assigned_to').val(5);
  
  /* 対象バージョン */
  target.find('select#import_mapping_fixed_version').val(6);
  /* 存在しない値は新規作成 */
  target.find('input[type=checkbox]#import_settings_mapping_create_versions').prop("checked", true);
  
  /* プライベート */
  /* import_mapping_is_private */
  
  /* 親チケット */
  /* import_mapping_parent_issue_id */
  
  /* 開始日 */
  /* import_mapping_start_date */
  
  /* 期日 */
  /* import_mapping_due_date */
  
  /* 予定工数 */
  /* import_mapping_estimated_hours */
  
  /* 進捗率 */
  /* import_mapping_done_ratio */
  
  setTimeout(function(){
   /* プロジェクトは手動選択してもらう為アラートで促す */
   alert("プロジェクトの選択が正しい事を確認しましょう！");
  },200);
 });
 
 target.before(button);
})
```
※アラート表示のタイミングは、タイマーにしました。（手抜きですみません）

#参考記事
↓ Enjoy*Study (onozatyさん) ↓ 
[View customize plugin](http://blog.enjoyxstudy.com/archive/category/Redmine)
コンピュータの動作原理（０）

これからぼちぼちコンピュータの動作原理についての解説をして行くのですが、原理の解説の前に大切な事を２つ。

１つは、コンピュータはスイッチのON/OFFの連鎖だけで出来ている事。
２つめは、コンピュータはそれが全て誰かが決めた事だけで成り立っている事。

　コンピュータの動作原理について調べようと思って検索すると、だいたいPC本体とディスプレイとキーボードと、のような解説が出てきます。すこしマシなのは、PCのフタをあけた絵があって、これがマザーボードでCPUとメモリです、のような解説です。しかしこれらはコンピュータの「仕組み」の話で、動作原理ではありません。

　それからもう少し調べると、加算だけとか、引き算が苦手とか、論理演算しか出来ないとか、そういう解説が出てきます。
　たぶん、苦手なのは解説してる人です、コンピュータには苦手も得意もありません。コンピュータに出来る事、出来ない事～　のような解説もアテにしないでください。擬人化は理解の妨げになるだけです。
　コンピュータにはヒトがするような、「考える」ような機能は一切ありません。
 
 **コンピュータはただ単にON/OFFの連鎖だけで出来ています。コンピュータは計算などしていないのです。**

　この連鎖は例えば、「あっちの３つのスイッチが全部ONの場合だけ、こっちのスイッチをOFFにする」のような条件を、**スイッチ同士をつなぐ配線をどうするかで設定**出来ます。
　これがコンピュータの動作の全てです。

　では、連鎖の始まりはどこから来るのでしょう？
　その代表的な例がキーボードです。あなたがキーを押します。するとキーには接点があって、キーボードの中の配線のうちのどれかがつながります。例えばこれは片方はコンピュータに、もう片方は電源につながっていて、キーを押したときだけ電気が流れるようになっています。
　コンピュータの中ではこの電気の流れでスイッチの連鎖に変化がおこります。電気の流れに変化があるとソフトウエアの処理に変化がおこります。そうしてあなたが見ている画面に文字が出てくるまでの一連の連鎖となります。

　もうひとつについて。１＋１を入力したら３が出てくるシステムがあったとします。それを設計・実装した人の思った事と入力した人の期待とは合っていないでしょう。しかし、設計したヒトがそういう動作だと決めただけで、コンピュータが何か間違った訳ではありません。何か間違いがあるとしたら、間違ったのは設計した人か実装したひとです。
　コンピュータはそれを設計・実装した人の決めた通り、作った通りの動作をします。そしてその 「動作」 とは、スイッチのON/OFFの連鎖だけなのです。計算とか判定とか、そのようなモノはありません。

　私の作った[引き算回路](http://qv80.cocolog-nifty.com/blog/files/SUB_ADD.circ)([Logisim](http://www.cburch.com/logisim/)用のドキュメント)は、それを引き算だと思っているのは私で、その回路は引き算とは何の関係もありません。中身はトランジスタと配線ですから。それは、私がそれを 「引き算回路として設計した」 というだけで、それを利用した人が 「引き算だと思う」 だけです。

　そして**コンピュータが何かしているように見せかけるのは、ソフトウエアの演出**です。
　「どういう動作にするかをヒトが決めて配線」し、それを利用した結果「それがいったい何なのか考えるのもヒト」なのです。

　繰り返しますが、コンピュータの動作は、スイッチのON/OFFの連鎖だけです。
　これからそれを順を追って見ていきましょう。

リスト
----
[コンピュータの動作原理（１）概要](https://qiita.com/niQSun/items/2db8859b89f57ab5c019)
[コンピュータの動作原理（２）論理GATEを作る ーMOSFETの動作ー](https://qiita.com/niQSun/items/251e5824c70724a7d2c0)
[コンピュータの動作原理（３）真理値表と論理回路](https://qiita.com/niQSun/items/5502286ce77ceb0c2d88)
[コンピュータの動作原理（４）減算回路](https://qiita.com/niQSun/items/220215cbc3d298e07487)
[コンピュータの動作原理（５）順序回路](https://qiita.com/niQSun/items/8d5959f83a44b16d9cd4)
[コンピュータの動作原理（６）8ビットプロセッサP08：前編](https://qiita.com/niQSun/items/4d92eab8cce210db4b77)
[コンピュータの動作原理（７）8ビットプロセッサP08：後編](https://qiita.com/niQSun/items/f4b54136e8b65a32ffb0)
[コンピュータの動作原理（後書き）](https://qiita.com/niQSun/items/038e7a0e7f56eb81aaf9)

おまけ
[二進数の二の補数について](https://qiita.com/niQSun/items/a3d5e9e7e1fe7b3465b9)

[^1]: まだソフトウエアの話は出てきていませんから、この場合 1 + 1 の順にボタンを押したら、のように考えてください。
WineのソースコードをEclipseで開く(備忘録)

※CDT(Eclipse C/C++ Development Tools)は別途インストールすること
[EclipseにCDTを追加する手順 | 慶應義塾 理工学ITC](http://www.st.itc.keio.ac.jp/ja/faq_linux_eclipse_add_cdt_st.html)

**ブラウザでWineのソースコードをダウンロードする**
https://dl.winehq.org/wine/source/2.x/
今回は最新の wine-2.22.tar.xz をダウンロード

**ソースファイルを解凍する**
ファイルマネージャで Download ディレクトリを開き、wine-2.22.tar.xz のコンテキストメニューから [Extract Here] をクリック
Wine-2.22 ディレクトリにソースが解凍される

**ターミナルを開きソースディレクトリへ移動する**
``cd ~/Downloads/wine-2.22``

**ソースからインストールする場合と同じように予め xorg-dev と libx-dev をインストール**
``sudo apt-get install xorg-dev libx11-dev``

**configureを実行してMakefileを作成する**
``./configure --enable-win64``
「configure: Finished.」と表示されたら成功。

**EclipseでC/C++プロジェクトの読み込み**
Eclipseを開き、[File]->[New]->[Project...]
[C/C++]->[Makefile Project with Existing Code] を選択し [Next>]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/102207/6ef67db0-a6ea-40e4-40ee-3d0b74835daa.png)


[Browse...]をクリックしソースコードのディレクトリを指定
下の[Toolchain for Indexor Settings]で[Linux GCC]を指定(noneでもべつにおｋ)
[Finish]を押下
![image.png](https://qiita-image-store.s3.amazonaws.com/0/102207/40dbc652-9093-79aa-e53a-1c2713ba6091.png)

**ビルド確認**
[Project]->[Build All]
かなり時間がかかる
「Wine build complete.」が表示されれば成功。
EchoでSessionを利用したテストを行う

セッション機能の導入はこちらを参考に
https://qiita.com/to-hutohu/items/740ee30aa996c0bd8d7e

## 環境
* Go1.9
* echo 3.2.3
* srinathgs/mysqlstore


## 流れ
1. テストを行う前にセッションストアにデータを入れておく
2. ミドルウェアを通してハンドラを返す
3. 後は通常通り


## 例

``` Go:example.go
func Handler(c echo.Context) error {
	sess, err := session.Get("sessions", c)
	if err != nil {
		return fmt.Errorf("Failed to get session: %v", err)
	}

	var userId string
	if sess.Values["userId"] != nil {
		userId = sess.Values["userId"].(string)
	}
	// 処理
}
```

## テストコード(抜粋)

``` Go:example_test.go
func beforeTest(t *testing.T) (*echo.Echo, *http.Cookie, echo.MiddlewareFunc) {
	e := echo.New()

	store, err := mysqlstore.NewMySQLStore(endpoint, 
					"sessions", "/", 60*60*24*14, []byte("secret"))

	if err != nil {
		t.Fatal(err)
	}

	// セッション情報をあらかじめストアに保存しておく
	req := httptest.NewRequest(echo.GET, "/", nil)
	rec := httptest.NewRecorder()
	sess, err := store.New(req, "session")
	sess.Values["userId"] = "testUser"

	err = sess.Save(req, rec)
	if err != nil {
		t.Fatal(err)
	}

	// セッションIDを取得して使いまわせるようにしておく
	cookie := parseCookies(rec.Header().Get("Set-Cookie"))["session"]
	mw := session.Middleware(store)

	return e, cookie, mw
}

func TestGetChannelsHandler(t *testing.T) {
	e, cookie, mw := beforeTest(t)

	// ミドルウェアを通してハンドラの設定
	rec := request(e, t, mw(Handler), cookie)
	// レスポンスのチェック
}


func request(e *echo.Echo, t *testing.T, handler echo.HandlerFunc, cookie *http.Cookie) *httptest.ResponseRecorder {
	req := httptest.NewRequest("GET", "http://test", nil)

	req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)

	// クッキーに設定しておく
	if cookie != nil {
		req.Header.Add("Cookie", fmt.Sprintf("%s=%s", cookie.Name, cookie.Value))
	}
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	err := handler(c)

	if err != nil {
		t.Fatal(err)
	}

	return rec
}

func parseCookies(value string) map[string]*http.Cookie {
	m := map[string]*http.Cookie{}
	for _, c := range (&http.Request{Header: http.Header{"Cookie": {value}}}).Cookies() {
		m[c.Name] = c
	}
	return m
}
```

複数のエンドポイントをテストする場合には上のようにリクエスト部分をある程度まとめておくと、コードが簡潔になりそうです。
ランダムランチの組み合わせアルゴリズムを考えて実装した

この記事は Livesense - 自 Advent Calendar 2017 4日目の記事です。
テーマ「関」というわけで、組織内で関係を作るためのランダムランチについて書きます。

## ランダムランチとは？

社内交流の取り組みの一つで、社員をランダムなグループを作ってランチに行くというイベントです。シャッフルランチという呼び方もされるようです。
組織が大きくなってくると、全く話さない部署の人が出て来るものです。また、いつも同じメンバーでランチに行っていると安心感はあるのですがマンネリ化もします。
ランダムランチをすることで離れた部署のメンバーと交流ができ、これが社内の[弱い紐帯](https://www.google.co.jp/search?q=弱い紐帯)を育むのです。素晴らしい！

弊社でもランダムランチを行うときがあります。
全社員職種問わずであったり、エンジニアの有志（ほぼ全員が参加）であったり、部署の一部メンバーで行ったり、その時々です。

そこで難しいのは組み合わせです。
数回繰り返した時に過去の開催結果を考慮しなくてはいけない、かつ、その組み合わせで良いという明確な答えが無いため、手動でやると頭が爆発しそうになります。
単純にランダムでグループを作ると、よく話す同じチームの人であったり、前回のランダムランチで一緒だった人とまた同じグループになってしまいます。

こんなときこそコンピュータの力を使って自動化しましょう！

## gemを作りました
私のプログラミングにおける母国語はRubyであるためgemにしました。
[GroupMixer](https://rubygems.org/gems/group_mixer)と名付けました。
計算量は参加者数の2乗になります。
数万の組織でランダムランチをすることは無いと思うので、とりあえず大丈夫だと思います。

以下、その解説となります。

## 問題を定義する
どのようにグループを分ければ良いか。要求としては以下のようになります。

- できるだけ普段交流が無い人と組み合わせる。
- できるだけ過去に一緒になった人は組み合わせない。
- それなりにランダム。

できるだけ、というのがポイントで２０人ぐらいの組織で毎週やればそのうち同じ人に当たるのは必然だからです。

## 既存のアルゴリズムを探してみる
逆、つまりクラスタリングにはいくつも定番アルゴリズムがあります。
今回の問題は、全体ができるだけ離れた人の組み合わせになるように分けなくてはいけません。
（クラスタリングして分かれた各組から一人ずつランダムに選ぶ、という方法でもそれなりにいけそうだなと書いていて思いつきました）

昔からやってみたかった[巡回セールスマン問題](https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E3%82%BB%E3%83%BC%E3%83%AB%E3%82%B9%E3%83%9E%E3%83%B3%E5%95%8F%E9%A1%8C)などを解くのに使われる[蟻コロニー最適化](https://ja.wikipedia.org/wiki/%E8%9F%BB%E3%82%B3%E3%83%AD%E3%83%8B%E3%83%BC%E6%9C%80%E9%81%A9%E5%8C%96)も良いかなと思ったのですが、実装が面倒で採用しませんでした。

## 今回作成したアルゴリズム
アルゴリズムと呼ぶにはおこがましいぐらいですが、ぱっと思いついたのは以下のような手順です。

1. 過去のランダムランチの組み合わせや所属している組織などから、個々人の関連度を出す
    1. 関連度とは関わった人の数と考えてください
    1. 多くの組織に所属したことがあったり、社内で顔の広い人は大きな関連度を持つことになります
    1. 逆に新しく入社した人は関連度は少なくなります
1. 関連度が大きい人から、グループに割り当てていく
1. 割り当てられるグループは以下のように選ぶ
    1. 割り当てられる時点で、最も関連度の合計が低くなるグループ
    1. 最も関連度の合計が低くなるグループが複数ある場合、最も人数の多いグループ
    1. 上記２つの条件を満たすグループが複数ある場合は、その中からランダムに選ぶ

2の順番でメンバーを割り当てることの意味は、関連度の小さい人を後で配置したほうが全体の関連度を下げられるからです。
（今日会社に入ったばかりの新メンバーはどのグループに配置しても関連度は０）
3の2で最も人数の多いグループを選ぶのは、関連度が大きい人をまとめておいたほうが後から配置される人との関連度を下げられるからです。

厳密な意味で最適な解では無いですが、これでそこそこの結果が得られると思います。

## 今後の展望
現状だと少なくともRubyを触れる人にしか使えないので、Webサービス化も検討しております。
すでにそれっぽいツールもあるようですが、理想としては[調整さん](https://chouseisan.com/)のように登録せずともやりやすいサービスにしてみたいです。

更に機能として検討しているのは、

- 初回データを作る方法（参加者が入れられるようにする、など）
- 参加者を入力する、または募集する画面
- なんらかの方法で組み合わせの良さを数値化して表示
- ある人とある人を絶対同じグループに入れる
- ある人とある人を絶対に同じグループに入れない

みたいな感じです。
echoでmysqlを使ったセッション管理

golangの軽量・高速なWebフレームワークで[echo](https://echo.labstack.com/)と言うものがあります。

そこでmysqlを使ったセッション管理を実装したのでメモ

## 環境
* Go1.9
* echo 3.2.3
* srinathgs/mysqlstore
* Mysql5.7.20

## やること
[公式サイトのガイド](https://echo.labstack.com/middleware/session)を見ると、echoではgorillaのセッション管理機能を使用することを推奨しているようです。
それを使用することでgorillaコミュニティで開発されたセッションストアを流用することができるからですね。

必要なパッケージをインストールします。
```go get github.com/srinathgs/mysqlstore```
```go get github.com/labstack/echo-contrib/session```


以下のようにコードを追加します。

``` Go
package main

import (
	"net/http"

	"github.com/labstack/echo"
	"github.com/labstack/echo-contrib/session"
	"github.com/srinathgs/mysqlstore"
)

func main() {
	e := echo.New()
	store, err := mysqlstore.NewMySQLStore("<user>:<pass>@<host>:<port>/<db>?parseTime=true&loc=local", "sessions", "/", 60*60*24*14)
	if err != nil {
		panic(err)
	}
	e.Use(session.Middleware(store))

	e.Logger.Fatal(e.Start(":9000"))
}
```

`mysqlstore.NewMySQLStore`の第二引数はセッション情報を保存するテーブルの名前、第三引数はクッキーで指定されるPath、第四引数はクッキーのmaxAgeとなります。

xormやgormなどですでにDBとの接続を確立している場合は`mysqlstore.NewMySQLStoreFromConnection`を使うこともできます。

``` Go
var engine *xorm.Engine

store, err := mysqlstore.NewMySQLStoreFromConnection(engine.DB().DB, "sessions", "/", 60*60*24*14)

```

## 注意する点
ここを書きたいために記事を書いたくらいなのですが、**mysqlのエンドポイントを指定する箇所でオプションとして`parseTime=true`を指定しないと正常に動作しません。**
さらに、エラーなども全く出ないまま動かないためこれでだいぶ時間を溶かしてしまいました。

[issue](https://github.com/srinathgs/mysqlstore/issues/10)は立てられているようです。

## ハンドラでセッション情報を使用する
アクセスされる度にカウントを増やしてみます

```Go
type Count struct {
	count int
}

func Handler(c echo.Context) error {
	sess, err := session.Get("sessions", c)
	if err != nil {
		c.Error(err)
		return err
	}
	if sess.Values["count"] == nil {
		sess.Values["count"] = 0
	}
	count := sess.Values["count"].(int)
	count++
	sess.Values["count"] = count
	sess.Save(c.Request(), c.Response())
	c.JSON(http.StatusOK, Count{count})
	return nil
}
```
Qiitaの画像アップロード上限を増やしたい

Qiitaは投稿件数が０の場合、画像などのアップロード上限が2MBしかありません。
１件でも記事を投稿すれば、アップロード上限が１００MBまで引き上げられるそうです。
つまりこれはQiitaのアップロード上限を上げたいがための記事です。
Rubyで呼び出された変数名を取得する

```ruby
できなかった = Class.new do
  def method_missing(method)
    top_variales = eval('instance_variables', TOPLEVEL_BINDING)
    called_variable = top_variales.each do |v|
      variable = eval(v.to_s, TOPLEVEL_BINDING)
      break v if self == variable
    end
    puts "#{called_variable}を#{method}ことはできなかった"
  end
end

@悪魔 = できなかった.new
@悪魔.倒す # => @悪魔を倒すことはできなかった
@悪魔.叩く # => @悪魔を叩くことはできなかった
```

# Kernel#eval
は文字型を評価できます

```ruby
array = [10, 20]
element = 30
eval('array << element') # => [10, 20, 30]

num = 10
eval('numbers'.delete('bers')) # => 10
```

#Kernel#binding
スコープをオブジェクトにまとめたものです。`Kernel#eval`の第二引数に渡せばそこで評価されます。
また、Rubyには事前に定義された定数`TOPLEVEL_BINDING`が用意されており、トップレベルのスコープのBindingになっています。

```ruby
class MyClass
  def my_method
    @x = 1
    binding
  end
end

b = MyClass.new.my_method

eval '@x', b # => 1
```

# obj.instance_variables
定義済みのインスタンス変数の一覧をハッシュになって配列で返します

```ruby
@a = 1
@b = 2
instance_variables # => [:@a, :@b]
```
これから情報処理技術者試験を受ける人たちに向けて

# はじめに
HAL東京高度情報処理学科のおりばーです。
最近Qiitaにアカウントを登録し、友人から「HAL Advent Calendar 2017」があると紹介されたので、参加させていただきました。
今回はIPAが行なっている情報処理技術者試験に関して記事を書こうと思います。

# 経歴
私はIT系の勉強は入学まで全くやってなく、毎日ニコニコ動画を見てたぐらいでした。
だけどパソコンが好きだったので、プログラムを学ぼうと思いHALに入学しました。
今までに取得した資格は以下の通りです。

- ITパスポート(2015年3月取得)
- 情報検定 情報活用試験 １級,２級
- 情報検定 情報システム試験 プログラマ認定,システムエンジニア認定
- 基本情報技術者(2015年秋取得)
- 応用情報技術者(2016年春取得)
- ネットワークスペシャリスト(2016年秋取得)
- データベーススペシャリスト（2018年春取得）

# 資格取得について
HALではIPAの行なっている情報処理技術者試験にみんな申し込んで受験します。
特に基本情報技術者試験に力を入れており、取得に向けてみんな頑張って勉強していると思います。
先生の中には「資格は必要！持っているのと持っていないとじゃ就活に雲泥の差が出る！」だとか、学生間では「基本情報技術者とか余裕だろ」とか最近耳にするようになりました。こういう話を聞くたびにうんざりしますし、残念に思います。

そこで、就活の時期において、資格が自分にどのように作用したのかを書いていこうと思います。

# 資格取得の為にやったこと
経歴を見ての通り、ITパスポートから自分は取得しています。
これはとても重要なことだと私は思っています。
**段階を踏む**というのが私のスタンスで、このおかげでそれぞれの資格勉強に対する負担を軽減できたと思っています。
学校では急に基本情報技術者から受けさせられますが、これは中々厳しいと私は思っています。
基本情報技術者試験はネットの意見とかよく見ると余裕だとか、実際煽ってくる人は現実にも結構います。
大事なのは**難しさは人それぞれで、得意不得意はどの人にもあるもの**です。
自分は難しいと感じたので、段階を踏んで取得しようと思っただけです。
ぜひ基本情報技術者試験が難しいと思っている皆さんは段階を踏んで受験してみてください。

## 学生時代に資格はそもそも必要なのか
結論から申しますと、私の意見は**「学生の間は作品をどんどん作れ」**です。
現在の自分が一番後悔して入るのが資格に力を入れすぎて作品をあまり作ってこなかったことです。
入学当時の私は**「資格を取得してからがスタート地点」**だと思っていたのですが、それは方向性が間違っていたと今は思います。
基本情報技術者試験の前身である第二種情報処理技術者試験の「経験」の部分にはこのように書かれています。
> 高度情報処理技術者を目指し、情報システムの開発、保守又は運用の業務について、１年程度の実務経験があることを想定する。

まさにこの通りで、経験を積んだ人が資格を取得する。という流れになって入るわけです。
応用情報技術者やネットワークスペシャリストはもっと経験年数が必要でしょう。
「まずは手を動かして作品を作ろう。ある程度知識がついたら資格の勉強をすれば良い。」っていうのが今の私の意見です。
実際、私が外部の人と関わって行く中で、資格を取得している人は少なかったかのように感じます。
特に大学生で取得している人とあまり出会いませんでした。それでも明らかに自分自身より知識があったので、実際に手を動かして知識をつけたんだと思います。専門学生は相対的に見て、多くの人が資格取得していますが。

資格取得にメリットはもちろんあります。私がネットワークスペシャリストまで取得して感じたメリットは以下の通りです。

- ITに関する幅広い知識が身につく
- その分野に関する基本的な知識が身につく

就活に役立つ云々は次の項目に任せるとして、資格取得のメリットは知識が身につくことです。
すなわち、合格したしていないに関わらず知識が身につくのはどの人も同じです。
ネットワークに関する実務経験なし、機械も持っていない、触ったこともほぼない私がネットワークスペシャリストに合格して、本当にスペシャリストなのかと感じることはあるのですが、ネットワークに関する基本的な知識は身についたと感じ、その面ではとても良かったと思っています。

この項のまとめとして、決して資格が必要ではないということを言っているわけではありません。
「資格を取得する前にやるべきことがあるのではないのか？」と言っているだけです。
**資格は社会人になってからでも取得できるのです。必要になった時に取ればよい**と私は思います。

## 資格は就活に役立つのか
これはケースバイケースです。実際私に関していえば、今のところ役だった形跡はありません。
おそらくこれは目指す所によって変わってくると思います。
自分はベンチャー系の会社を目指しているので、そういう会社は**資格よりもその人が何を作ってきたか**に重きを置いているように感じました。
特に最近はGitHubのコードを見られるケースが増えていると思います。その人がどのような作品を作って、どのようなコードを書いているのかとても重要な判断材料です。ベンチャー系を目指す人は意識して置いた方が良いと私は思います。

大きな企業に関してはすみませんが分かりません。書類通過云々の観点では取得して置いたほうが良いとは思います。それぐらいしか言えません。

# まとめ
資格取得は体力も時間も使います。決して楽な戦いではありません。
学生である時間は有限です。インプットだけではなくアウトプットも積極的に行なっていきましょう。
次回の記事は基本情報技術者からネットワークスペシャリスト取得まで行なってきたことを詳しく書いていこうと思います。よろしくお願いします。

ホームページ:[https://minakawadaiki.com](https://minakawadaiki.com)
pythonで手軽にチャットアプリ

こんにちは！今年に入ってqiitaの記事をずっと作成していましたが、調べたことが頭に入るし、やってみるもんだなと思いました。これまでに投稿した記事は８件ですが、その中でも特に多く投稿したのがPython関連のネタです。今年はPyconに参加したり、卒業研究にもPythonを使い、Pythonにどっぷり浸った1年でした(何回Pythonって言ってるんでしょうね（笑）)
というわけで今回はその集大成としてPythonでアプリケーションを作ってみたので、ご紹介します。
#今回作るもの
今回は機械学習のAPIを使用したチャットボット形式のアプリを作ります。イメージ的にはL○NEのりんなちゃんみないなものを作ってみたいと思います。
#使用言語、フレームワークなど
- python3.6
- tkinter
- a3rt

この中にある「a3rt」とは、今年リクルートがリリースした機械学習のAPIです（[参考](https://a3rt.recruit-tech.co.jp/)）。Pythonで使用するには[pya3rt](https://github.com/nocotan/pya3rt)というライブラリを使用します。a3rtは使用するサービスによって無料のAPIキーを発行する必要があります。今回はtalkAPIを使用します。
#作成したソースコード
```python
#-*- coding: utf8 -*-
import sys
import tkinter as tk
import tkinter.messagebox as tkm
import pya3rt

apikey = "YOUR_API_KEY"
client = pya3rt.TalkClient(apikey)

root = tk.Tk()

# ウインドウのタイトルを定義する
root.title(u'Seri')

# ここでウインドウサイズを定義する
root.geometry('400x300')
# ボタンが押されたらリストボックスに、Entryの中身を追加
def addList(text):
    mysay = 'you: ' + text
    print(mysay)
    ListBox1.insert(tk.END, mysay)
    Seri = 'Seri: ' + talk(text)
    Entry1.delete(0, tk.END)
    addRep(Seri)

def addRep(Seri):
    ListBox1.insert(tk.END, Seri)

def talk(say):
    if say == 'end':
        return('ではまた')
    else:
        ans_json = client.talk(say)
        ans = ans_json['results'][0]['reply']
        return(ans)

# ラベルを使って文字を画面上に出す
Static1 = tk.Label(text=u'▼　Seriに話しかけよう!　▼')
Static1.pack()


# Entryを出現させる
Entry1 = tk.Entry(width=50)                   # widthプロパティで大きさを変える
Entry1.insert(tk.END, u'こんにちは')        # 最初から文字を入れておく
Entry1.pack()


# Buttonを設置してみる
Button1 = tk.Button(text=u'送信', width=50, command=lambda: addList(Entry1.get()))        # 関数に引数を渡す場合は、commandオプションとlambda式を使う
Button1.pack()


# リストボックスを設置してみる
ListBox1 = tk.Listbox(width=55, height=14)
ListBox1.pack()

root.mainloop()
```
#実際に使ってみた
![スクリーンショット 2017-12-04 1.59.54.png](https://qiita-image-store.s3.amazonaws.com/0/170520/f2c4ef32-0b53-2ffb-b839-4df5e417277d.png)
なかなかそっけない対応でS○riっぽかったので名前はSeriにしました（笑）
#問題点・改良したい点
windowsやLinuxで実行すると、日本語入力はできますが、Macなぜかできないので別のテキストファイルで入力したものをコピペするというめんどくさい作業をして動作を試しています（苦笑）。テキストを入力した後に入力したテキストを先に表示されてその返答が後から表示されるようなL○NEのような感じにしたかったのですが、テキストと返答が同時に出力されてしまいます。
本当は【end】と入力したらウィンドウを閉じるようにしたかったのですが、時間がなくて実装できませんでした…いつかまた改良したいと思います。
エラーをユーザーへ伝えるVue.jsコンポーネント作りました

こんな感じで `this.$teller` を `catch` に渡せば、ユーザーへエラー内容を伝えてくれるコンポーネントが欲しいと思い書いてみました。

```js:Promise
SomePromiseTask()
  .then()
  .catch(this.$teller)
```

```js:AsyncAwait
clickedBtn () {
  this.handleTasks()
    .then(()
    .catch(this.$teller)
},
handleTasks: async function () {
  await this.taskA()
  await this.taskB()
  await this.taskC()
  await this.taskD()
},
```

![9e2564bc5e43f12c8a196732fc7733bf.gif](https://qiita-image-store.s3.amazonaws.com/0/62259/ba4f5140-84be-2757-12f5-f2a67174f1f7.gif)

- [Github](https://github.com/akifo/vue-teller)
- [Demo](https://akifo.github.io/vue-teller/)

## Argument の種類

３種類の形式を想定しています。

- String
- Error
- Object

```js:String
this.$teller("message")
```

```js:Error
this.$teller(new Error("message"))
this.$teller(new SyntaxError("message"))
```

```js:Object
this.$teller({
  "type": "error",
  "title": "title",
  "message": "message",
  "duration": 3000,
  "position": "top-right"
})
```

## ざっくりコード解説
1. コンポーネントを `Vue.extend` で読み込む
2. `new` を使って新しいインスタンスを作る
3.  `$mount` でマウントする
4.  オプションなどを設定して、DOMへ表示させる

```js:コード適当に抜き出し
const ErrorMessageConstructor = Vue.extend(ErrorHMessageComponent)
const instance = new ErrorMessageConstructor()
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
```


## 参考にしたリポジトリ
### [Element](https://github.com/ElemeFE/element) 

awesome-vue にある notification（toast） 系のコードを全て読んだ結果、この [Element](https://github.com/ElemeFE/element) が一番参考になりました。コードの書き方が洗練されていますし、本当に考えられて書かれているUIツールキットです。コンポーネントの作り方を学習されたい方にオススメしたいです。

### [Vue.js本体の util.js](https://github.com/vuejs/vue/blob/dev/src/shared/util.js)

JavaScript の変数の型判定をするコードがたくさんあります。例えば「本当にObjectか？」「正規表現か？」など。



## vue-teller 使用上の注意

破壊的な変更を伴う修正を行う予定ですので、issueなどご確認いただきながらご利用頂ければと思います。

※ この記事・コードは JavaScript 的に、よろしくない可能性があります。田舎のフリーランスでして、詳しい人に聞くことができないため、公開コードを書くことで正しい手法なのか確認も兼ねていますことをご了承ください。お気軽にご指摘頂けますと嬉しいです。（2018年に、このコメント消します）


## まとめ

- vue は簡単だけど、webpack や rollup が難しい
- ElementUI のコードがかっこいい
2011-2016までのadvent calendarの完走率を調べる

誰もいなかったら私が埋めます！って言ってカレンダー作ったはいいのですが、完走が厳しくなってきたので、言い訳のために調べました。

2015年からカテゴリーができて、ちょっとめんどくさかったです :(

#結果
```shell-session
{'ratio': 100.0, 'finish': 1, 'year': 2011, 'total': 1}
{'ratio': 55.2, 'finish': 16, 'year': 2012, 'total': 29}
{'ratio': 43.9, 'finish': 36, 'year': 2013, 'total': 82}
{'ratio': 43.9, 'finish': 94, 'year': 2014, 'total': 214}
{'ratio': 49.87, 'finish': 188, 'year': 2015, 'total': 377}
{'ratio': 56.51, 'finish': 282, 'year': 2016, 'total': 499}
Advent calendar completion rate :51.33
```

2011-2016年までのqiita advent calendarの完走率(25日全て埋まっている割合)は約51%でした。
ちなみにこの完走とは`.adventCalendarList_recruitmentCount`タグを取ってきているのですが、書かなくても参加登録しただけでインクリメントしてしまうようなので、厳密にいうと完走率はもっと低くなりそうです...。
結果として完走率が50%超えているのは2016年のみなので(2011年は見えない)意外と少ない、といった印象なのですがどうでしょうか。
というわけでこのadvent calendarが完走する可能性も半々です:santa:

最後にソースを載せて終わろうかと思ったのですが、そこそこ長くなってしまったのでgistにあげます :)

[ここだよ！](https://gist.github.com/anapple07/5e1337725b224ab052b7cb2063a81b2c)
GAS スプレッドシートで意図した日時にならない?!そんな時はタイムゾーンの設定が必要です！

自分でスプレッドシートを新規作成した場合は大体問題にならないかと思いますが、他人が作ったエクセルをスプレッドシートとして開き、それに対してプロジェクト（スクリプトエディタ）でスクリプトを書いた場合に、問題は起こるかもしれません。。（私はこれでハマりました）

## サンプル

以下、「A1」のセルに現日時を書き込み、その隣のセルに時を書き込む処理。

```js
function myFunction() {
  var range = SpreadsheetApp.getActiveSheet().getRange('A1');
  range.setValue(new Date);
  
  var date = range.getValue();
  range.offset(0, 1).setValue(date.getHours());
}
```

スプレッドシートのタイムゾーンと、プロジェクトのタイムゾーンが一致していれば、何も問題ありません。
「A1」のセルに書き込まれた日時が「2017/12/03 8:03:16」だとすると、その隣は「8」になります。

ところが、スプレッドシートのタイムゾーンと、プロジェクトのタイムゾーンが不一致だと当たり前ですが上記の通りにはなりません。
例えば、スプレッドシートのタイムゾーンが「(GMT+08:00)香港」で、プロジェクトのタイムゾーンが「(GMT+09:00)東京」の場合、「A1」のセルに書き込まれた日時が「2017/12/03 8:03:16」だとすると、その隣は「9」になります。


## タイムゾーンを設定するには

例として日本時間を設定する場合。

### スプレッドシート

1. 画面上部のメニューバーから「ファイル」＞「スプレッドシートの設定」を選択
2. 「全般」タブの「タイムゾーン」の項目を「(GMT+09:00)東京」に設定

<img width="627" alt="スプレッドシートの設定" src="https://qiita-image-store.s3.amazonaws.com/0/25283/0656375b-62f1-a74d-9f3d-72eeb5906b93.png">

### プロジェクト

1. 画面上部のメニューバーから「ファイル」＞「プロジェクトのプロパティ」を選択
2. 「情報」タブの「タイムゾーン」の項目を「(GMT+09:00)東京」に設定

<img width="697" alt="プロジェクトのプロパティ" src="https://qiita-image-store.s3.amazonaws.com/0/25283/e6c61557-b217-13da-7ed5-79f44f9b94e2.png">

以上になります。
Rustで簡易HTTPサーバーを作成してみる

Qiita初投稿がAdventCalendarで大変恐縮ですがよろしくお願いします。
最近HTTPサーバーの仕組みについて勉強したいと思っておりC言語で実装してみています。
また、Rustにも興味がありましたので、この機会にRustで簡易的なHTTPサーバーを作成してみましたのでそのご紹介をさせていただきます。

## 実行環境

ArchLinux
rustc 1.22.1 (05e2e1c41 2017-11-22)

## 実装

まずmainの実装は以下のようになりました。

```Rust:main()

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                thread::spawn(move || {
                    handle_client(stream)
                });
            }
            Err(_) => { panic!("connection failed") }
        };
        
    }
}

```

TCPの接続周りはstd::netモジュールを使用しました。TcpListener.bindでipアドレスとポート番号を割り当てたTcpListenerを作成します。
incoming()はloop~acceptと同様の動きをしているらしいのでそれによって、接続をループで待ち受けます。
接続が来た場合、スレッドを作成し、handle_clientに処理を任せます。

handle_clientの処理は以下のようになりました。(2017/12/04 ご指摘いただいた部分修正させていただいております。@ubnt_intrepidさん、ありがとうございます)

```Rust:handle_client()

fn handle_client(stream: TcpStream) {
    let mut stream = io::BufReader::new(stream);

    let mut first_line = String::new();
    if let Err(err) = stream.read_line(&mut first_line) {
        panic!("error during receive a line: {}", err);
    }

    let mut params = first_line.split_whitespace();
    let method = params.next();
    let path = params.next();
    match (method, path) {
        (Some("GET"), Some(file_path)) => {
            get_operation(file_path, stream.get_mut());
        }
        _ => panic!("failed to parse"),
    }
}
```

ここではstreamをBufReaderでラップしたものを使用して、送られてきた情報を読み取り分割していっています。
BufReaderのread_lineを使用して一行目だけを取得し `split_whitespace()` でスペースごとに分割しています。
接続側で`curl localhost:8080 -v` を実行したとすると

```
> GET /test.html HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.1
> Accept: */*
```

このリクエストの情報のうち `GET /test.html HTTP/1.1` が空白区切りでparamsに入ったことになります。
先頭の値(メソッド)がGETの場合get_operationを実行するようになっています。(2017/12/04 こちらもご指摘いただいた部分修正させていただいております。@ubnt_intrepidさん、ありがとうございます)

```Rust:get_operation

fn get_operation(file_name: &str, stream: &mut TcpStream) {
    let path = PathBuf::from(format!("./www{}", file_name));
    let mut file = match File::open(&path) {
        Err(why) => {
            panic!(
                "couldn't open {}: {}",
                path.display(),
                Error::description(&why)
            )
        }
        Ok(file) => file,
    };
    let len = file.metadata().map(|m| m.len()).unwrap_or(0);

    writeln!(stream, "HTTP/1.1 200 OK").unwrap();
    writeln!(stream, "Content-Type: text/html; charset=UTF-8").unwrap();
    writeln!(stream, "Content-Length: {}", len).unwrap();
    writeln!(stream).unwrap();

    io::copy(&mut file, stream).unwrap();
}

```

get_operationでは、streamを使ってresponseのヘッダー行を固定で出力してしまっています。(どのバージョンのHTTPリクエストが来ても1.1で返してしまっています)
あとはパス指定されたファイルをreadで読み取り、streamに書き込んでいっているだけとなっています。

## まとめ

今回のHTTPサーバーはGetしか実装していませんし、レスポンスも固定ですが、簡易サーバーなのでご了承ください。
コードの全文等は以下においてありますので、ご興味がある方はご確認ください。
何か間違いや改善点などございましたらご指摘いただければ幸いです。

https://github.com/worldcreate/simple-httpd

## 参考

+ [Rust Echo Server Example](https://avacariu.me/articles/2015/rust-echo-server-example)
+ [Rust TCP接続](http://gassan.hatenablog.jp/entry/2015/06/12/211109)
ブロックチェーンにおける合意形成方法について

今回はブロックチェーンにおける**合意形成の方法**について紹介します。
できる限り「Short & Simple」を心がけます。
なお、私もブロックチェーン初学者なので、内容に誤り等ありましたらご指摘いただけると幸いです。

## ブロックチェーンにおける合意形成とは

- ブロックチェーンネットワークでの**取引の正当性を確認する作業**
- 主に**改ざんや二重使用がないか**を検証する
- ブロックチェーンは基本的に中央集権的な仕組みを持たないため、ネットワークの**全参加者がそれぞれ承認作業をおこなう**

## 合意形成の流れ
ブロックチェーンにおける合意形成は以下のような流れとなる。

1. トランザクションの検証
2. ブロックへのトランザクションの集積、マイニング
3. 新規ブロック検証とブロックチェーンへの埋め込み
4. ブロックチェーンの選択

いろいろな文献を見ていると、「合意形成」の説明対象が上記１〜４全体のものや、上記２のみのものが混在しているようである。
「合意形成方法＝Proof of Work」などのように書いているものは、おそらく上記２について説明していると思われる。
以降ではその上記２で使われる手法について簡単に紹介する。

### Proof of Work（PoW）
#### 概要
＜事前作業＞
トランザクションプールに蓄積されている取引データを集積し、「直前のブロックのハッシュ値（ブロックヘッダのハッシュ値）」「新規ブロックのタイプスタンプ」「集積した取引データのハッシュ値（マークルツリーのrootハッシュ）」などでブロックヘッダを構築する。

＜ここからがPoW＞
構築したブロックヘッダに含まれる「Nonce（ノンス）」に適当な値を入れながらブロックヘッダのハッシュ値を計算し、そのハッシュ値の先頭に所定の数だけ「0」が並ぶようなノンス（値）を発見する作業。

#### 特徴
- 膨大な計算を行うため、「時間」「マシンパワー」「電力」が必要
- 悪意ある参加者が計算処理能力の約51%以上を掌握すると改ざんが可能となる


### Proof of Stake（PoS）
#### 概要
通貨所有者が利付担保のように通貨の「所有を主張（stake）」することができる。ネットワーク参加者は保有している通貨の一部を使わずに預けることで、新しい通貨またはトランザクション手数料という形で投資のリターンを得ることができる。
比較的新しめのパブリックブロックチェーンでは、PoW系よりもPoS系を採用することが多い

#### 特徴
- PoWに比べてエネルギー消費が少ない
- PoWに比べてブロック生成時間が短い

## 参考文献
- [いちばんやさしいブロックチェーンの教本](https://www.amazon.co.jp/いちばんやさしいブロックチェーンの教本-人気講師が教えるビットコインを支える仕組み-「いちばんやさしい教本」シリーズ-杉井靖典-ebook/dp/B075CFG2TY/ref=sr_1_1?ie=UTF8&qid=1511787155&sr=8-1&keywords=いちばんやさしいブロックチェーンの教本)
- [Mastering Bitcoin](https://www.amazon.co.jp/ビットコインとブロックチェーン-アンドレアス・Ｍ・アントノプロス-ebook/dp/B072JJL66R/ref=sr_1_2?s=digital-text&ie=UTF8&qid=1511787188&sr=1-2&keywords=mastering+bitcoin)
- [ブロックチェーンのコンセンサスアルゴリズム（合意形成）とは？ビットコインのProof of Workを解説！](http://moblock.jp/articles/17182)