OmniAICreator/Qiita-1.07M huggingface dataset:
WindowsでChainer環境を整える

## はじめに
近年話題のDeepLearning。CaffeやTensorFlowなど様々なフレームワークがありますが、私はもっぱらChainer派です。
普段はUbuntu14.04を使用しているのですが、先日Windowsマシン上でChainerを扱わなければならないことが有り、Ubuntuの時のようにスムーズにChainerが導入できず、かなり手間取ってしまいました。
レアケースだとは思うのですが、引っかかったところとその解決方法をまとめてみました。

## 環境

- Windows 10
- Python 2.7

PythonやGitの導入に関しては割愛させていただきます。
ちなみにCPU環境だったのでCUDA等に関しては説明できません。

## 引っかかったところ

### モジュールが入らない！

chainerはnumpy, scipy, h5pyの3つがインストールされていなければ、インストールできないようです。

これらのモジュールをインストールする際に、いきなり「pip install numpy」のようにしてもインストールできません。
どうやらwhlというコンパイル済みのファイルからインストールする必要があるようです。
[こちらのサイト](http://www.lfd.uci.edu/~gohlke/pythonlibs/)に様々なwhlファイルがありますので、こちらからダウンロードしましょう。必要なwhlファイルをダウンロードしたら、そのファイルを使ってpip installします。下記はnumpyの例です。

~~~
cd [whlファイルがあるディレクトリ]
pip install numpy-1.11.1+mkl-cp27-cp27m-win_amd64.whl
~~~

scipy, h5pyも同様にwhlファイルからインストールしましょう。

※プロキシ環境の場合

~~~
$ pip install [モジュール名] --proxy=[user]@[proxy]:[port]
~~~

## chainerのwhlファイルがない！

さて、先ほどのサイトですがchainerのwhlファイルはありません。(2016/06/30現在)
なのでGitHubからコードをcloneして、ビルドしましょう。

~~~
$ git clone https://github.com/pfnet/chainer.git
$ cd chainer
$ python setup.py install
~~~

## setup.pyの実行が途中で止まってしまう

エラーメッセージにも出てくると思いますが、Visual Studio C++が必要みたいです
[ここ](https://www.microsoft.com/en-us/download/details.aspx?id=44266)からダウンロードしてインストールしましょう

## 確認

これでやっとインストールできるはずです。

ちゃんとChainerがインストールできたか確認する為、ExampleのMNISTの認識をしてみましょう。
git cloneしてきたディレクトリで下記を実行してみてください。

~~~
$ python examples/mnist/train_mnist.py
GPU: -1
# unit: 1000
# Minibatch-size: 100
# epoch: 20
Network type: simple

load MNIST dataset
epoch 1
graph generated
train mean loss=0.190369202715, accuracy=0.941016668603, throughput=994.727940618 images/sec
test  mean loss=0.0899474363861, accuracy=0.970900004506
epoch 2
・
・
・
~~~

CPU環境なので私は10分くらいかかりました

# おわりに

Windows10にbashが導入されるらしいですので、今後はこのように面倒な手順を踏まなくても良くなると思います。
「導入されるまで待てない！」という方は今回の方法を試してみてください。
sensor / difference > Link > MPU-9150 / MPU-9250 > AD0ピン / CSピン

傾斜計に使うICのMPU-9150とMPU-9250の違いについては、Strawberry Linuxさんの以下のページに詳しい。
https://strawberry-linux.com/support/12250/1703808

AD0ピンとCSピンの考慮が必要とのこと。
Mithril.jsとC3.js(d3.jsベースのチャートライブラリ)を組み合わせて使う


Mithril.js http://mithril.js.org/
C3.js : http://c3js.org



``` 線チャートコンポーネント
// 線チャートコンポーネント
var SequenceChart = {
  controller: function() {
    var ctrl;
    ctrl = this;
    
    ctrl.renderChart = function(data, element, isInit, context) {
      // 初期化されていないなら、チャートを初期化
      if(!isInit) {
        ctrl.initChart(element, data);
      }
    };
        
    ctrl.initChart = function(element, model) {
      var chart, options;
      options = {
        data: {
          columns: model
        }
      };
      options.bindto = element;
          
      chart = c3.generate(options);
    };
  },
  view: function(ctrl, model) {
    return m('div', {
      // config属性でチャートを出力
      config: ctrl.renderChart.bind(ctrl, model)
    });
  }
};
```

``` 使う
var model = [
  ['labelA', 10, 20, 30],
  ['labelB', 20, 30, 40]
]

m.mount(document.body, SequenceChart(model));
```
sensor > Link > MPU-9150 @ cubic9さん > MPU-9250の参考に

傾斜を測定するためのICとしてMPU-9250を購入した。

以下のリンクは参考になりそう。
[MPU-9150 @ cubic9.com](http://cubic9.com/Devel/%C5%C5%BB%D2%B9%A9%BA%EE/Arduino/%A5%E2%A1%BC%A5%B7%A5%E7%A5%F3%A5%BB%A5%F3%A5%B5/MPU-9150/)

Arduino Unoで実装している。
そして、MPU-9150からの数値を使ってUnityソフトを動かしている。
一ヶ月、若手社員に送った記事（6月編）

# いきさつ

請負開発だった案件に問題があって、終いには人質的に派遣に出されてしまった若手がいる。
一人ぼっちで関わりが無いままなのは余りに可哀想なので、派遣先を退勤するときにはSlackで連絡を入れるようにしてもらっている。で、単におつかれーと返すだけでは味気ないので、その返信には「これ読んでみてね～」的な記事を送ることにした。

請負案件のときには既に疲弊していたので、仕事や開発者としての振る舞いに関する記事から、改善プロセスの記事、開発の原則的な記事を送ってみた。
こういう情報は、目を通してすぐに何かというわけにはいかないですね。頭の片隅に留めておいて、そういえばあんな話があったな～とか、問題解決にTOCを使ってみるか～とか思ってくれれば良いかなと。技術者たるものアンテナを立てていかないといけないですから。


# 記事一覧

“仕事が面白くない”症候群とたたかう三つの方法
http://brevis.exblog.jp/23726856/

学ぶ時間をどうつくるか
http://brevis.exblog.jp/24292367/

今さら聞けない！ 3分で分かる「7つの習慣」まとめ
http://www.itmedia.co.jp/bizid/spv/1405/07/news028.html

今日から始める生産性アップ術。ポモドーロ・テクニック再入門ガイド
http://www.lifehacker.jp/2014/07/140714pomodoro.html

あなたの行動を制約しているのは“ジレンマ”だ
http://monoist.atmarkit.co.jp/mn/spv/0806/12/news130.html

社内の対立を解消するツールとその使い方を伝授
http://monoist.atmarkit.co.jp/mn/spv/0806/24/news120.html

芋づる式に問題の根本を発見し解決するツール
http://monoist.atmarkit.co.jp/mn/spv/0807/04/news143.html

ジレンマを解くツールの使い方を詳細に学ぼう
http://monoist.atmarkit.co.jp/mn/articles/0807/16/news142.html

“それができれば苦労しないよ”と決め付けないで
http://monoist.atmarkit.co.jp/mn/articles/0808/06/news129.html

“空飛ぶブタ”を地上に引きずり降ろして勝利宣言
http://monoist.atmarkit.co.jp/mn/articles/0808/25/news114.html

マジカ！
http://www.magicaland.org/?mobile=1

オブジェクト指向設計原則 - Strategic Choice
http://d.hatena.ne.jp/asakichy/20090122/1232879842

リーダブルコード - Strategic Choice
http://d.hatena.ne.jp/asakichy/20140620/1403215047

コードの臭い・落穂拾い・Clean Code編 - Strategic Choice
http://d.hatena.ne.jp/asakichy/20121009/1349733590

ソフトウェアのバグをなくすには？--プログラミングの際に避けるべき10の失敗
http://japan.zdnet.com/article/35083529/?tag=mcol;relArticles

新人プログラマが知るべきプログラミングの原則６選！
http://qiita.com/ryotanatsume/items/018cae5c5be8faba367a
Cloud9 で bin/rails xxx が動かなくなったので


## 事の起こり
新しいターミナルを立てて何かしようとしたりすると下記のように言われはじめてあれれ？という感じになってしまった。スクリーンキャスト撮っている最中だったのに...

```terminal
ubuntu@xxxx-yyyy-9999999:~/workspace$ bin/rails s -p $PORT -b $IP                          
/usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler (LoadError)
        from /usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /home/ubuntu/workspace/bin/spring:8:in `<top (required)>'
        from bin/rails:3:in `load'
        from bin/rails:3:in `<main>'
```

## 調査

同じような感じになっているスレッドを発見した。6日前くらいから起きているらしい。

https://community.c9.io/t/new-ruby-on-rails-projects-unrunnable/6809/14

## 検証

rvm周辺っぽいことは想像ついていたのだけどよくわからず。

```terminal
ubuntu@xxxx-yyyy-9999999:~/workspace$ rvm list
Warning! PATH is not properly set up, $GEM_HOME is not set,
         usually this is caused by shell initialization files - check them for 'PATH=...' entries,
         it might also help to re-add RVM to your dotfiles: 'rvm get stable --auto-dotfiles',
         to fix temporarily in this shell session run: 'rvm use ruby-2.3.0'.

rvm rubies

 * ruby-2.3.0 [ x86_64 ]

# => - current
# =* - current && default
#  * - default
```

## 解決

どうやら`current`に対応するバージョンの指定がないみたい。なので

```
rvm use ruby-2.3.0
```

を打ってみる。すると`bin/rails c`できた！

## 再発防止

上記を毎回やるのは面倒なので

```terminal
echo "rvm use ruby-2.3.0" >> ~/.bashrc
```

してこちらではOK。
zsh+pyenv+awscli環境でタブ補完を設定する際のメモ

# 事象
* `pyenv` を入れた状態で `aws_zsh_completer.sh` を有効にしようとするとターミナルごと落ちる

# 環境
* Mac OSX 10.11.5
* `Homebrew` で `pyenv` をインストールしている
* `pip` で `awscli` をインストールしている

# 設定
* `.zshrc` の末尾に以下1行を追加

```sh
source "$(pyenv which aws_zsh_completer.sh)"
```

# 参考
* https://gist.github.com/n0ts/6317641
大学との共同研究についての注意点

# 記事の目的
これまでさんざん大学との共同研究で失敗してきたので注意点をまとめておく。
なお、情報系以外の世界はよくわからないので、多分当てはまらないと思う。

# １．基本教授は研究してくれない
* 教授は基本的に忙しい。予算を獲得するために国の会議に出たり、授業をしたり、教授会に出たり。実質研究していない教授も多い。
* そこで、実際には教授のネームバリューより担当する学生の質によって共同研究の成否が決まる
* 採用してもいいと思える学生が見つかるかどうかがカギ
* あるいは新進気鋭の助教とか研究員がいれば可能性はある
* 学生はやはり学生なのでプロジェクトマネジメントは結構困難
* 遠隔地から知らないおっさんに指示を出されてもだいたいやってくれない。チームとして入り込むレベルでかかわることが必要

# ２．共同研究は開発の外注契約というよりはコンサルティング契約に近い
* 通常の開発の外注なら契約を結んで仕様通りに作らせればよいが、研究は思った通りに行かない
* 事前にできると思ったことができなかったりすることはざら。
* 発注している側のほうが知識がない場合が多いこともあり、「XXXという理由でできません、XXXにしたほうがいいですよ」と言われたときに、「いや、最初に決めた通りやれ」ということも難しい
* 担当者が共同研究相手にほれ込んでいるかどうかがカギ。「○○先生が言うことだからきっと一理あるんだろう、私も勉強してみよう」と思えるかどうか
* 逆に担当者が「なんでこの人に（あるいはこのテーマを）頼んでいるんだろう」と思ってしまうようでは絶対にうまくいかない
* 共同研究相手は実施の有無の決定権を含めて実際にプロジェクトマネジメントを行う担当者が選べるようにしなければいけない

# ３．大学だから論文書ければいいんでしょというスタンスでもない
* 最近は大学も変わってきている。論文にならなくても社会的意義のために引き受けてくれることもある
* 一方で大学TLO(Technology Licensing Organization)という知財を扱う組織も一般的になり、あとから特許権を主張される可能性もある
* TLOとは事前によく話し合うことと、権利を安く買いたたけるという考えは捨てるべし

# ４．時間のレンジはやっぱり違う
* 企業は1年後にはものになるかなみたいなイメージでいても、大学は5年後かなと思っていることはままある
* 最近はそれなりに考えの差は埋まってきたがそれでも依然差はある

# ５．敵は内部にいる
* 社長や経営陣お気に入りの"先生"と付き合うときは注意が必要
* 担当者は失礼なことはできないので、対等な契約にならない。成果が出なくてもやめられない
* はじめはトントン拍子で進んだりもするが、お互いの担当者が出てきて、さて何をやろうみたいな感じになったり時間を無駄にすることもある

# じゃあどうすればいいの？
* 本気でやる。学生を一人採用するレベルで社内に招くか、社員一人に博士号を取らせるレベルで大学に派遣するか
* 少額のコンサルティング契約にとどめる。あくまでも主体は自分たちで、隔週で意見を聞くなど
* いずれにしても自分たちが何もしなくてもやってくれるという考えは捨てる。基本自分たちでやらないと仮にうまくいっても技術が残らないし、うまくいかなくても技術は残る
* 大学発ベンチャーを当たってみる。彼らは社会人なので社会人的常識が通用する
* 大学以外の研究機関も視野に入れる。統計数理研究所とかNIIとか
ファイルのパス一覧からファイル名のみを抽出（小ネタ、読了に要する時間：推定約３０秒）

とある開発作業(CakePHPがらみ)をしている日常で出くわした、ちょっとした問題の解答をメモとして残します。

## 環境
MacBook Air(Early 2015), OS:10.11.4
## お題
以下のような内容のファイル files-list.txt があります。
（何かの作業で改修したファイル一覧みたいなもの。）

[ykt68@MacBook work] cat files-list.txt
app/Controller/Component/DivisionComponent.php
app/Model/Order.php
app/Controller/OrderController.php
app/View/Themed/Sp/Top/index.ctp
app/View/Elements/sp/footer.ctp
app/View/Elements/sp/header.ctp
app/View/Elements/sp/parts/topics.ctp
app/webroot/js/uploader.min.js
app/webroot/css/sp/layout.css
[ykt68@MacBook work]

上記から、**なるべく手間をかけずに**、ディレクトリパスを除いたファイル名だけの一覧が欲しい。

## 答え
以下でOKでした。

[ykt68@MacBook work] cat files-list.txt | **sed -E "s/^.+\/([^/]+)$/\1/"**
DivisionComponent.php
Order.php
OrderController.php
index.ctp
footer.ctp
header.ctp
topics.ctp
uploader.min.js
layout.css
[ykt68@MacBook work]


以上
ローカルでもMarkdownで技術ノウハウを残すメリット

私はテキスト形式で、dropboxにノウハウをメモするようにしてきました。
Qiitaデビューするにあたって、私と同じようにテキスト形式でノウハウを残している方も今後は、Markdown形式に移行するきっかけになればうれしいです。

# もしも、下記のような書き方でノウハウを貯めている方がいらっしゃったらぜひオススメです♪

```text:ノウハウ.txt
■○○の構築方法
・http://～からダウンロードしてくる
・コマンドプロンプトで○○を実行して、△△を生成
```
↓↓↓↓↓↓↓Markdown形式↓↓↓↓↓↓

```text:ノウハウ.txt
# ○○の構築方法
- http://～からダウンロードしてくる
- コマンドプロンプトで○○を実行して、△△を生成
```

## Markdownは下記のようにプレビューできます
![image](https://qiita-image-store.s3.amazonaws.com/0/131565/4728b82f-e594-6c60-8fac-bc22e88b1f19.png)


# Markdownのメリット
- ノウハウを残す文章のルールを考えなくていい
- Qiitaにそのまま移行できる
- 書いたMarkdownをブラウザでプレビューすることでより見やすい表示形式になる（sublime textのプラグインOmniMarkupPreviewerなど）
- 書くのに慣れているとgitのリポジトリの説明などスムーズに書きやすくなる
- 困っている同僚にノウハウのテキストを送ってあげると喜ばれるかも？
PythonでLANG=Cのときのエンコーディングの注意

とあるPythonスクリプトを動かす環境のLANGがja_JP.UTF-8からCに変わったらエラーが出るようになったのでそのあたりの対処をメモ。

```py3
#!/usr/bin/python3
# -*- coding: utf8 -*-

import sys

from logging import getLogger, StreamHandler, DEBUG

handler = StreamHandler()

logger = getLogger(__name__)
logger.setLevel(DEBUG)
logger.addHandler(handler)


str = "ほげ"
tf = open('utf8.txt')
s = tf.read()

print(str)
print(s)

logger.debug(str)
logger.debug(s)
```
これをLANG=ja_JP.UTF-8で動かすのは大抵問題がない。これは大抵起動時にLANGを見て入出力のデフォルトエンコーディングを変更するようにPythonが設定されているからである。なのでこれをLANG=Cに持っていくとUTF-8をASCIIとして解釈しようとして例外を出すようになる。

まずファイルの読み込みにエンコーディングを指定する。

```py3
tf = open('utf8.txt', encoding='utf8')
```

printで使う sys.stdout の出力先がUTF-8であると指定する。

```py
sys.stdout = codecs.getwriter("utf8")(sys.stdout.detach())
sys.stderr = codecs.getwriter("utf8")(sys.stderr.detach())
```

loggerはこのままでも動くがエスケープされた出力となってしまうので変更したsys.stderrを使うようにする。

```py
handler = StreamHandler(sys.stderr)
```

まとめるとこうなる。

```py
#!/usr/bin/python3
# -*- coding: utf8 -*-

import codecs
import locale
import sys


from logging import getLogger, StreamHandler, DEBUG, Formatter

sys.stdout = codecs.getwriter("utf8")(sys.stdout.detach())
sys.stderr = codecs.getwriter("utf8")(sys.stderr.detach())

handler = StreamHandler(sys.stdout)

logger = getLogger(__name__)
logger.setLevel(DEBUG)
logger.addHandler(handler)



str = "ほげ"
tf = open('utf8.txt', encoding='utf8')
s = tf.read()

print(str)
print(s)

logger.debug(str)
logger.debug(s)
```
# 参考
* http://stackoverflow.com/questions/4374455/how-to-set-sys-stdout-encoding-in-python-3
Amazon EFSを試してみた


## ドキュメント等からわかったこと

### mount target

* アベイラビリティゾーン毎にmount targetが作成される
* mount targetはアベイラビリティゾーン毎に1つだけ
* デフォルトはすべてのアベイラビリティゾーンに作成するが選択することもできる
* mount targetを作成するサブネットは選択できる
* mount targetのIPアドレスは指定することもできる
* mount targetには最低1つセキュリティグループを関連付ける必要がある
* mount targetに関連付けられるセキュリティグループは5つまで
* File systemの作成後にmount targetの削除、再作成が可能


### ネットワーク

* TCP 2049番ポートを使うのでセキュリティグループで許可する必要がある
    * EC2に関連付けているセキュリティグループはOutboundを許可する
    * mount targetに関連付けているセキュリティグループはInboundを許可する
* mount targetとは別サブネットのEC2からFile systemをマウントすることができる
    * Network ACLでTCP 2049番ポートの通信が制限されていないかに注意 (NACLはステートレスなので戻りの通信も)
* mount targetはPublic IPを持てない
* Direct Connect, VPNやVPCピアリング等のVPCの外からのマウントはできない


### NFS

* NFSv4.0/NFSv4.1に対応しているが、NFSv4.1を推奨
* Amazon Linux AMI 2016.03.0 ならNFSクライアント(nfs−utils)がインストール済みなので、改めてのインストールは不要

```
$ cat /etc/system-release
Amazon Linux AMI release 2016.03

$ sudo yum -y install nfs-utils  
読み込んだプラグイン:priorities, update-motd, upgrade-helper
amzn-main/latest                                                                                        | 2.1 kB     00:00     
amzn-updates/latest                                                                                     | 2.3 kB     00:00     
パッケージ 1:nfs-utils-1.3.0-0.21.amzn1.x86_64 はインストール済みか最新バージョンです
何もしません
```

* File systemはDNS名でもIPアドレスでもマウント可能
    * DNS名を使うメリットは次の2つ
        * DNS名は変わらないため、mount targetを削除しても同じアベイラビリティゾーンで再作成すれば、そのままマウントできる
        * DNS名はマネジメントコンソールやスクリプトで生成することができ、これを使うことで、間違ったアベイラビリィゾーンでマウントすること(EC2とmount targetが異なるアベイラビリティゾーンになること)を防ぐことができる(IPアドレスだとパッと見でどのアベイラビリティゾーンなのかがわかりにくいので間違いやすいのかも)
    * VPCのDNS hostnamesを無効にしているなど名前が引けないような環境ではIPアドレスでマウントする


## マウント手順

※ North Virginiaリージョン、AMI release 2016.03 を使用

* 下ごしらえ

```
$ REGION=us-east-1
$ AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
$ EFS_FSID=fs-xxxxxxxx
$ MOUNT_POINT="/mnt/efs/${EFS_FSID}/${AZ}"
```

* mount targetに疎通確認

```
$ sudo traceroute --tcp -p 2049 ${AZ}.${EFS_FSID}.efs.${REGION}.amazonaws.com
```

* マウントポイント作成

```
$ sudo mkdir -p ${MOUNT_POINT}
```

* マウント

```
$ sudo cp -pi /etc/fstab /etc/fstab.$(date "+%Y%m%d")
$ echo "${AZ}.${EFS_FSID}.efs.${REGION}.amazonaws.com:/    ${MOUNT_POINT}   nfs4    defaults" | sudo tee -a /etc/fstab
$ sudo mount ${MOUNT_POINT}
```

* おまけ  
  容量8エクサバイト！？

```
$ df -Ph ${MOUNT_POINT}
ファイルシス                                         サイズ  使用  残り 使用% マウント位置
us-east-1b.fs-xxxxxxxxx.efs.us-east-1.amazonaws.com:/   8.0E     0  8.0E    0% /mnt/efs/fs-xxxxxxxx/us-east-1b
```


## 参考

* https://docs.aws.amazon.com/ja_jp/efs/latest/ug/security-considerations.html#network-access
* https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs.html
* https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html
* https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs-mount-cmd-ip-addr.html
* https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mount-fs-auto-mount-onreboot.html
データ収集：OCTOPARSE


# **A Crawling System Is Now Available! No Programming Required**



####**Perhaps you’ve never heard of [Octoparse](http://www.octoparse.com/) before. It doesn’t matter. You just need to trust we’re here now. [Octopars 6.0](http://www.octoparse.com/), a complete, powerful version, which we’ve been working on it for three years.** 
![Screenshot 1 Our website .jpg](https://qiita-image-store.s3.amazonaws.com/0/130932/bf35a1a6-dd54-54e8-92a4-ac9281eebd6d.jpeg)



Probably you’ve heard of import.io or Mozenda already. But now, you know [Octoparse](http://www.octoparse.com/) too. [Octoparse](http://www.octoparse.com/) is an [web scraping tool](http://www.octoparse.com/).  It’s capable of converting information from World Wide Web into useful and structured data and it also supports to make an API request to get the data extracted from [Octoparse](http://www.octoparse.com/).

 
[Octoparse](http://www.octoparse.com/) compatibles with the vast majority of websites. It’s also capable of handling a variety of complex static or dynamic web page structures, including data extraction, pagination, AJAX, regular expression, XPath positioning and many other powerful features. Octoparse even has cloud hosting your collection tasks to cloud server 7*24 hours a day so that you can pay more attention to business instead of tedious data collection.
![Design workflow  interface 1 .png](https://qiita-image-store.s3.amazonaws.com/0/130932/e2f83521-c4b9-72f5-cb0f-b56e72c97d7d.png)
 

In the past, if you want information from the Internet, you need to develop your own crawlers by programming. Thus, expensive cost of technology is inevitable because the internet webpages changes constantly. Just a little change on HTML page would make you to re-modify the program. This is obviously not a good solution. Long-term maintenance costs would probably make you not be able to focus on the most important part.

![Design workflow  interface2.png](https://qiita-image-store.s3.amazonaws.com/0/130932/3d8e9eca-41d8-bb9f-26a8-adf00d8c5c21.png)

But you have Octoparse now, a totally free software. We believe that to our 10K users, compared with 100K users, the cost of technology is the same and is ever getting lower down. We won’t charge any fee here. But we provide powerful cloud hosting service that is used for cloud data collection, which may cost you a little and we get profit from. Although [Octoparse](http://www.octoparse.com/) may not be the cheapest web scraping tool, we believe it is hard to find one that is cheaper than us. And you can [DOWNLOAD](http://http://www.octoparse.com/download/) it now!
![Export data extracted.png](https://qiita-image-store.s3.amazonaws.com/0/130932/bacde7f8-4216-0feb-3756-3452cd266464.png)

We’ll be very appreciated if you can join us. If you’ve already used Octoparse to configure collection tasks and want to experience the cloud gathering function , please EMAIL me at support@octoparse.com.
Macで簡易ローカルサーバーをたてる


普段、gulpとBrowser-Syncを使って構築をしていますが、
わざわざ、Browser-Syncの環境を作る必要のない時などに、サクっとローカルサーバを立てたい時の方法です。

## ローカルサーバをたてる

```
1. ターミナルを開く
2. ドキュメントルート(表示させたい)にcdで移動
3. [python -m SimpleHTTPServer 8888]を実行
4. [http://localhost:8888/](http://localhost:8888/)
```
pythonコマンド、一行だけ。これだけです。超簡単。
サルでもできますね。(私はサル以下ですが。。)

ちなみにポートは変更可能です。 (例) 8888 → 7777

## サンプル

### サンプルのファイルを用意する。

(ドキュメントルート)
/Users/(ユーザー名)/sample/index.html

用意したファイル

```
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>hogehoge</title>
</head>
<body>
  <h1>pythonコマンドで簡易ローカルサーバーをたてる</h1>
  <p>サルでもできる。</p>
</body>
</html>
```

### ターミナルでドキュメントルートへ移動

```
$ cd /Users/(ユーザー名)/sample
```

### pythonコマンド実行

```
$ python -m SimpleHTTPServer 8888
```

### ブラウザ確認

```
[http://localhost:8888/](http://localhost:8888/)
```
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/55848/fdbd9983-1cfc-add8-d3f1-460ae01eabc4.jpeg)

* * *
### サーバーを停止する

```
[control] + [c]
```
Slickなるものを使ってみよう(mysql)

こんにちは世界とロギング関連が終わったら次はDB回り。
いつSparkに手ェつけんだって話だけども、Sparkに渡したいデータ元がDBだからしょうがないんだよと言い訳しとこう。

■build.sbt
基本的に前回記事とかに追記してるものと思いねぇ。

```
"com.typesafe.slick" %% "slick" % "3.1.0-M2",
"com.typesafe.slick" %% "slick-codegen" % "3.1.0-M2",
"mysql" % "mysql-connector-java" % "5.1.34",
```

codegenはテーブル構成からmodelクラスにあたるものを作ってくれるのかね。
今回使わないけど今後の要件でなんか使いそうな気はするから入れておこう。
後で消すかもだけど

■scala
参考：http://www.mwsoft.jp/programming/scala/slick3_1.html

```
import slick.driver.MySQLDriver.api._
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.duration.Duration
```

まずimportにこいつら追加。concurrentはとりあえず非同期処理やスレッド回りに関連する連中って理解。詳しくは後々もっとちゃんと追う。今回はとにかく動かす。

```
    val db = Database.forURL("jdbc:mysql://localhost/scaladevdb", driver="com.mysql.jdbc.Driver", user="scala", password="scala")
    val query = sql"SELECT id, name FROM test".as[(Int, String)]
    val f:Future[Vector[(Int, String)]] = db.run(query)
    Await.result(f, Duration.Inf) foreach println
```

※mysqlそのものの設定やらは準備は既に出来ている前提です

とりあえずこれでDBアクセスと結果吐き出しは出来た。

・Future、Await,Durationとはなんぞや
・Vector型ってなんぞや
・scalaのシンタックス(Await.resultの行)がまだぜんぜんわからん

課題やまづみ
サービスが急成長してRDSで困ってる君へ8000万件のテーブルをダウンタイム1時間でALTERするよ!

サービスの急成長は嬉しいお知らせですが、その反面機能追加時のALTERがどんどん大変に。普通にALTERを行うと、メンテナンス時間何時間とったら、良いのかわからないですよね。１時間程度のメンテナンス時間で、RDS上のデカイテーブルをALTERする方法を紹介します。

#戦略
1.リードレプリカを追加する
2.オンラインでリードレプリカにALTER文を実行
3.レプリケーションがおいつたタイミングで、アプリケーションの向き先をリードレプリカに変更
4.リードレプリカをマスターに昇格させる

#手順
### 1.リードレプリカに書き込み権限を与える

デフォルトの状態では、「Parameter Groups」のread_onlyが{TrueIfReplica}になっているので、これを「0」にします。この変更は再起動なしで各インスタンスに適用されるのでで、**間違って「1」にしてMasterへの書き込みが止まらないよう**に注意しましょう。

## 2.リードレプリカを作成
AWSコンソールから、マスターとなるインスタンスを選択し、インスタンス操作から、リードレプリカを作成をクリックします。マスターを作成する時と同じように、インスタンス、SSDの容量等を入力します

## 3.ALTER文実行
リードレプリカに対して時間のかかるクエリを実行します

## 4.レプリケーションの同期を待つ
スレーブにし対して、「SHOW SLAVE STATUS」を実行し、「slave behind master」が0になるのを待ちます。

##5. メンテナンス & マスター切り替え
レプリケーションが追いついたら、メンテナンスに入れてアプリケーションの向き先を、リードレプリカにします。

##6. マスター昇格
・AWSコンソールから、スレーブを選択し、「Promote Read Replica」を選択します。
・確認画面の後の画面でバックアップを無効にします。
(無効にしないと、昇格の時にバックアップが実行され、ひたすら待たされます)

##7. Muti-AZ有効に
マスター昇格が終わったら、MultiAZを有効にします。検証した感じでは、ダウンタイムなしでできますが、メンテ中に行うと安心です

##8. メンテナンスを開ける

Muti-AZが有効になったら、メンテナンスをあけましょう

##9. バックアップを戻す
バックアップの設定を戻します。おそらくバックアップが実行されます
以上でおしまいです、おつかれさまです。
新人プログラマーの軌跡　#5　正規表現チートシート

この2週間は
テストサイトの作成、ローカル開発環境・データベース・正規表現のお勉強を主にしていました。
テストサイトの作成は実務で、
[ローカル開発環境](http://dotinstall.com/lessons/basic_localdev_win)[MySQL](http://dotinstall.com/lessons/basic_mysql_v2)[正規表現](http://dotinstall.com/lessons/basic_regexp)はドットインストールで主に学習をしました。

ローカル開発環境やMySQLはまだ混乱している部分が多いので、~~もう少し時間を頂戴すべく~~
今回は**正規表現の基本をまとめよう**と思います。

#**正規表現**
正規表現とは、数字などとメタ文字を用いた表現方法の１つです。
それを利用して、検索対象の文字列から目的の文字列を探し出します。
門戸は広そうであるが掘ればなかなか難しそうな正規表現について、見ていきます。

##**文字指定**

| 文字指定 | 意味 |
|:-----------:|:------------:|
|　**.**|任意の一文字　\nを除く|
|\n|改行|
|\t|タブ|
|\　|メタ文字の前に置くとメタ文字をエスケープする|
|\w|すべての半角英数字とアンダースコア|
|\W|半角英数字とアンダースコア以外すべて|
|\d|すべての半角数字|
|\D|半角数字以外すべて|
|\s|空白文字(半角スペース、\t、\n、\r、\f)すべて|
|\S|空白文字(半角スペース、\t、\n、\r、\f)以外すべて|

###例①
```
aaaaaaaaaa

bbbbbb
cccc

ddddddd
```

``^\n　⇒　　``　や　``\n\n　⇒　\n``　とすると

```
aaaaaaaaaa
bbbbbb
cccc
ddddddd
```
と空行が消えてくれます。
　　　
###例②
```
〒123-4567
```
に
``\d\d\d-\d\d\d\d``　や　``\d{3}-\d{4}``
と指定すると、郵便番号にマッチします。
また{}を使った方法については後述します。

##**量指定子**
同じパターンが何度も繰り返す場合に使えます。

| 量指定子 | 意味 |
|:-----------:|:------------:|
|+|前の文字を1回以上繰り返す|
|*|前の文字を0回以上繰り返す|
|?|前の文字を0or1回繰り返す　量指定子の後に置くとマッチパターンが最小になる|
|{m}|m回繰り返す|
|{m,}|m回以上繰り返す|
|{,n}|n回以下繰り返す|
|{m,n}|m回以上n回以下繰り返す|

###例①
```
Google
Gogle
Gooooooooooooogle
Gooooooooogle
Ggle
Goooogle
```
o の数がめちゃくちゃな文字列に
``Go*gle　⇒　Google``　や　``Go{0,20}gle　⇒　Google``
とすると

```
Google
Google
Google
Google
Google
Google
```

元通りになりました。



##**グループ指定**
| グループ指定 | 意味 |
|:-----------:|:------------:|
|[ ]|[ ]内のいずれか一文字|
|[^ ]|[ ]内に含まれないいずれか一文字|
|?:|( )の初めに使うとキャプチャは行わず、グループ化のみ行う|
|( )|( )内を$1に格納　( )は複数設置可能|
|$1|( )に格納された文字列 ※置換後の文字列中で使用可能|
|\1|( )に格納された文字列 ※検索の文字列中で使用可能|

###例①
```
ぶるんる ぶるんる ぶるんる
はるちるがる とるぶる
おるいるけるのる まるわるりるにる
のるばるらるがる さるいるたるよる
ぶるんる ぶるんる ぶるんる
はるちるがる とるぶる
```
昔よく遊んで歌いましたね。だが、「る」が入っていて見づらい。
ならば「る」を抜きましょう。

そこで
``(.)る　⇒　$1``
とすると、おなじみの

```
ぶん ぶん ぶん
はちが とぶ
おいけの まわりに
のばらが さいたよ
ぶん ぶん ぶん
はちが とぶ
```

が現れました。

##**アンカー**
| アンカー| 意味 |
|:-----------:|:------------:|
|^|行頭にマッチする|
|$|行末にマッチする|

###例①
```
aasooijgesreoihj@gmail.jp
```
ドメインが変ですね。

そこで
``jp$　⇒　com``
とすると

```
aasooijgesreoihj@gmail.com
```

になります。行末がjpの部分にマッチしたのですね。

##**前後読み**
| 前後読み | 意味 |
|:-----------:|:------------:|
|(?<=hoge)|左側にhogeが存在する箇所|
|(?<!hoge)|左側にhogeが存在しない箇所|
|(?=hoge)|右側にhogeが存在する箇所|
|(?!hoge)|右側にhogeが存在しない箇所|
言語によってはサポートしていないツールがあるので、注意が必要です。

###例①
```
出発地：東京都　→　目的地：京都
```
ここで、目的地を宮崎に変更したいと思い
``京都　⇒　宮崎　``と変換すると、

```
出発地：東宮崎　→　目的地：宮崎
```

となってしまいます。
東京都の京都にもマッチングしてしまったのですね。

そこで
``(?<!東)京都　⇒　宮崎``
とすると

```
出発地：東京都　→　目的地：宮崎
```

と見事、変換成功です。京都の左が東出ない場合にマッチしたのですね。

##**オプション**
オプションはまだ把握しきれていないですが・・・

| オプション | 意味 |
|:-----------:|:------------:|
|i|大文字小文字の区別をしない|
|g|一致した部分すべてに適応|
|m|複数行に対応|


#まとめ
最初は気難しそうに見えた正規表現だが、まとめてみるとそんなに量もなくルールを知らないだけだったのかもしれません。
あとは時間がかかっても辛抱強く正規表現を使い、どれほど便利なのかを身に沁みさせる必要があります。
また言語の違いにより表記方法が変わってくるので、そこはその都度対応しなければなりません。

だけど今後、どんなことが出来るようになるのか楽しみです。

#参考文献
正規表現クイズ
(http://www.nurs.or.jp/~lionfan/reg2/)
サルにもわかる正規表現入門
(http://www.mnet.ne.jp/~nakama/)
手を動かしながら覚える正規表現
(http://doc.mas3.net/regexp/)
bespoke-pdfを利用しプレゼンをPDFに出力するときの注意点

`Bespoke.js` を利用しプレゼンを作成しオンライン閲覧はとても便利ですが、ときときPDFに出力し回覧するケースも考えられます。

PDFに出力するのは `bespoke-pdf` の利用は定番ですが、私のケースでは変なPDF（文字化けっぽい）が作成されました：

<img width="530" alt="Screen Shot 2016-06-30 at 17.08.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/2179/b6a7d50d-a25b-53bf-a7dd-520383fcea65.png">


１ページ目はプレゼンが始まる前に表示されるHTMLページです。２ページ目は２つのSlideが重ねっています。

PDFを生成するために、ロカールにHTTPサーバを立たなければなれいませんし、プレビュー画面が開く途端に画面をキャプチャーしようとすると、上図のような変なページが取られます。

プレビューページが開いてから１秒ほど待たせてからPDFを作成するのがこの問題を回避するできるかもしれません。

いする調べたところ、 `bespoke-pdf` に `delay` というオプションがあります。 `main.js` を下記に修正：

```js
// Bespoke.js
bespoke.from('article', [
  ...
  pdf({
    delay: 10
  }),
  ...
  ]);
```

`delay`　オプションをついてから `gulp pdf` を実行して、今回はPDFファイルを正しく作成されました。
【Android】アプリ内で操作音を鳴らしたくない

Androidでは端末の設定で「タッチ操作音」をONにしていると、
アプリ内のボタンやリストのセルをタップした時に操作音が鳴るようになる

もし何も対応しないまま、アプリ内のボタンに独自のタップ音をつけた場合、
２重でタップ音が聞こえてしまったり、アプリ内の独自ボリュームはミュートにしているのに端末の操作音が聞こえてしまって、
ユーザーからしたら不具合と思われてしまう可能性がある

そのようなことを回避するために、今回は自分のアプリ内では端末の操作音が鳴らないようにする設定方法の紹介

# 鳴らないようにする設定方法
設定にはxmlでやる方法とコードでやる方法がある

## xml
設定したいボタンやリストに対して `soundEffectsEnabled=false`を追加すれば良い

```xml
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:text="button"
    android:soundEffectsEnabled="false"
    />
```
  
また、使っているテーマの`soundEffectsEnabled`に対して`false`を設定すると、
アプリ内全体で操作音が鳴らないように一括設定することもできる

```xml
<style name="AppTheme" parent="@style/AppBaseTheme">
    <item name="android:windowNoTitle">true</item>
    <item name="android:soundEffectsEnabled">false</item>
</style>
```
特にこだわりがなければテーマにさえ設定しておけば良い

## コード
コードでやる場合には以下のようにすれば設定できる

#### java
```java
Button button = (Button) view.findViewById(R.id.btn);
button.setSoundEffectsEnabled(false);
```

#### kotlin
```java
var button = view.findViewById(R.id.btn) as Button
button.isSoundEffectsEnabled = false
```

xmlを使ってレイアウトを作っていないダイアログ内のボタンなどに対してはこの方法でやることになる
ORA-00932: データ型が一致しません: NUMBERが予想されましたがBINARYです。 でハマっているJavaerの皆様へ

```sql
SELECT
  *
FROM
  HOGE
WHERE
(:startDate IS NULL OR START_DATE >= :startDate) AND
(:endDate IS NULL OR START_DATE >= :endDate)
```

みたいなSQLをEntityManagerから作ったQueryに食わせて

```java
EntityManager em = YourEntityManagerFactory.create();
Query query = em.createNamedQuery("yourQuery.Name");
query.setParameter("startDate", condition.getStartDate());
query.setParameter("endDate", condition.getEndDate());
List<YourEntity> entities = query.getResultList();
```

したら

```
Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: データ型が一致しません: NUMBERが予想されましたがBINARYです。
```

出てほげーーーーーってなった人へ。


```java
query.setParameter("startDate", condition.getStartDate(), TemporalType.DATE);
// query.setParameter("startDate", condition.getStartDate(), TemporalType.TIME);
// query.setParameter("startDate", condition.getStartDate(), TemporalType.TIMESTAMP);
```

（　◜◡‾）（‾◡◝　）
REST API のテストにcurlとか使ってる？便利なのあるよ

## ことのはじまり
僕の周りにREST APIのテストにcurlを使ってる人がけっこういました。
Chrome ExtensionのREST Clientを教えてあげたら、みんな喜んでいました。
そこで本記事を書こうとなりました

## おすすめ REST Client  （Chrome Extension）
- [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop) 
- [Advanced REST client](https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo)

## 使い方
GUIなので簡単に使うことができます
<img width="1270" alt="スクリーンショット 2016-06-30 16.51.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/47508/9193a705-1868-8b1e-bf76-346f9be91d72.png">

**※以下はPostmanでの例です**

1. GET, POSTを選択し、APIのURLを入力します
JSONデータを送る場合は、以下のようにHeaderにセットしましょう
` Content-Type: application/json `
<img width="1047" alt="スクリーンショット 2016-06-30 16.32.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/47508/f9ca1d86-80f1-00b0-dd00-932e7adc22cc.png">  

 
2. BodyにJSONデータをセットします
<img width="1049" alt="スクリーンショット 2016-06-30 16.32.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/47508/ea97239c-e2e1-589c-9ccb-c5cd0cac9abb.png">

3. Send
4. レスポンスがこんな感じで返ってきます
<img width="1045" alt="スクリーンショット 2016-06-30 16.49.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/47508/8dbb02c5-56a3-032d-af35-f7a0aa9588f6.png">


## おまけ
OAuthなどのテストもできます。
<img width="265" alt="スクリーンショット 2016-06-30 16.33.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/47508/e06b8c48-9e01-d392-1206-50bd2c026a01.png">

## 最後に
間違っているところや、意見があればどしどしコメントください！！！
ruby code gold

http://idiosyncratic-ruby.com/27-golfing-basics.html


```rb
vagrant@precise64:~/data/boot$ pry
[1] pry(main)> @a = 12
=> 12
[2] pry(main)> "lala #@a"
=> "lala 12"
[3] pry(main)> $b = 13
=> 13
[4] pry(main)> "lala #$b"
=> "lala 13"
[5] pry(main)> @@c = 14
=> 14
[6] pry(main)> "lala #@@c"
=> "lala 14"
```
マイクロサービスのテスト作成方針


マイクロサービスをつくった。
[一からマイクロサービスの開発フローを作った話
](http://qiita.com/tomoyamachi@github/items/0f049c87bfdef4aa6ad9)

そこで、実際にどのように開発していたかを共有する。

今後、おおまかに分けて以下の3つのカテゴリで書いていく。

- テスト
- ドキュメント作成
- エラー/負荷対策

今回はテストに関してだけで、結構な量になったので、ドキュメント作成とエラー/負荷対策については、今後記載する。

# テスト
各サービスごとに単体テストと結合テストを作成した。
## 方針

- テストコードを先に書く
- 優先度は「結合テスト > 単体テスト」

## テストツール

- 単体テスト : PHPUnit
- 結合テスト : Cucumber (ruby)

結合テストはサービスのプロジェクトとは独立して作成しておき、新しいプロジェクトとして作りなおす場合でも利用できるようにした。(将来的には、Go言語で作り直したい)


## テストを書くまでの手順

だいたい以下のようなフローで行った。
![platform_dev_env.png](https://qiita-image-store.s3.amazonaws.com/0/14275/edc64433-8abf-39a5-2103-a796d85adaf1.png "platform_dev_env.png")

さらに詳細に書くと以下のようになる。

### endpointのURLと、正常系のテストで何をすべきか洗い出す

まずはやりたいことを整理して、
引数と、どのようなが必要かまとめる。
先にチェックリストをつくり、本当に実装できているかを最後に確認することで、自分の中でダブルチェックができる。


### 正常系の結合テストを書く

json-schemeを使い、返り値の型もチェックする。
このjson-schemeはのちほどAPIドキュメントを自動作成する場合にも利用する。


### 異常系の結合テストを書く
不正なURL, 不正なHTTP METHOD, 不正な引数は最低限チェック。

数値を引数とする場合は、
正負の数, 0, データの境界値(最小 / 最大値), 小数点は最低限チェックする。 
これら、必ずテストするものは、1行で呼び出せるよう自動化しておく。

### 結合テストを通過するようにコードを書く

書いてある通り。

### 動作を保証したい/テストパターンが多いようであれば単体テストを書く

今回のプロジェクトでは、各メソッドごとにテストを書いたりしていない。条件分岐がとても多い場合以外は、結合テスト側で各パターンを作ってチェックしている。

理由としては、今後、別の言語でつくるときなどに、再利用できるという点。

逆に、単体テストを作ったのは以下のようなパターン。

- メールアドレス/書き込み内容など、入力されるデータの正当性チェック
- 確率で成功したり、失敗するもの


### コードチェック
作成したコードが規約に則っているか、自動でコードチェック。
PHPの場合は、以下のチェックツールを使う。

- PHP Linter
- PHP Code Sniffer
- PHP Mess Detecter

### pull request

Pull request時に、Circle CIで、自動テストを行う。
Circle CIのサーバで、localhostにwebサーバを作成し、単体テスト/結合テストを行う。

複数のプロジェクトで相互に通信を行う場合は、
テストの度にすべてのプロジェクトをcloneし、circle ci環境内でポートを分け、webサーバを立ち上げる。

## CucumberでAPIでのテストを楽にする
前述のとおり、今回、APIの結合テストでCucumberを利用した。
デフォルトのCucumberでは、テストが書きづらそうだったので、
以下のgemを改良させて使わせていただいた。
https://github.com/hidroh/cucumber-api

基本、ほぼそのまま利用しているが、以下の点を自分のやりたいことに合うように変更した。

- APIリクエスト対象を、特定のドメインで固定する
	- http://sampleapi.com/v1/ の部分は省略する
- セッションを保持したまま、リクエストを送れる
	- ログインしたアカウントでしかできないことなどをチェックする

変更したコードはこちら。
https://github.com/tomoyamachi/cucumber-api
Rubyで２次元配列をハッシュに変換するときキーが重複していたら値を足したい

文章にするとわけわからんけど要は、Rubyでこのを２次元配列を

```rb

[[tanaka, 1], [yamada, 2], [sato, 3], [tanaka, 4]]
```

こう変換したいとき

```rb

{
  "tanaka": 5,
  "yamada": 2,
  "sato": 3
}
```

どうするかという話。

結果は簡単でeach_with_objectを使えば終わり。

```rb

arr = [[tanaka, 1], [yamada, 2], [sato, 3], [tanaka, 4]]
arr.each_with_object(Hash.new(0)) {|(k, v), h| h[k] += v}
```

１行でできるのすごい。

## 元ネタ

- [Convert Array to Hash removing duplicate keys and adding values at the same time](http://stackoverflow.com/questions/27735384/convert-array-to-hash-removing-duplicate-keys-and-adding-values-at-the-same-time)
HTML5 における CORS について

HTML5のCORSについて調べる機会があったので纏めました。
(誤りなど有りましたらコメントいただけると幸いです)

# 同一オリジンポリシー (Same-Origin Policy)

## 同一オリジンポリシーとは
同一オリジンポリシー (Same-Origin Policy) とは、リソースの保護範囲を決定する取り決めである。
セキュリティ上の理由から、ブラウザは異なるオリジンへのリクエストを送信できないように制限している。

※ 備考：なぜ制限する必要があるのか
具体例として、ブラウザから悪意ある攻撃者のサイトにアクセスし、ページのJavaScriptが実行されるとする。
同一オリジンポリシーが無いと、JavaScript から異なるオリジン (例えば file://127.0.0.1/ など) にアクセスできてしまう可能性がある。
すると攻撃者のサーバーへデータを漏出させることが容易となってしまう為、許可しない限りは異なるオリジンへの通信を制限すべきである。

## 同一オリジンとは
リソースのURLのうち「スキーム、ホスト、ポート」の組み合わせをオリジンと呼ぶ。
閲覧中のWebページとリソースのオリジンが一致していれば同一オリジンとみなす。

具体例として http://www.example.com に対しては、

- http://www.example.com/example.png // 一致
- https://www.example.com/example.png // スキーム不一致
- http://www2.example.com/example.png // ホスト不一致
- http://www.example.com:3000/example.png // ポート不一致

となる。

※ 備考：InternetExplorer の例外
IE に於いては以下の例外があるため注意が必要

- 信頼済みサイト(IE独自機能)に登録されているサイトは同一オリジンとみなす
- 異なるポートでも同一オリジンとみなす

## 同一オリジンポリシーによる制約
以下の WebAPI は同一オリジンポリシーの制約を受ける。

- XMLHttpRequest
- Canvas
- Web Storage
- X-Frame-Options

また以下のHTML要素などによる異なるオリジンからのリソース取得については制約を受けない。

- script // スクリプト
- img, video, audio // メディア
- object, embed, applet // プラグイン
- frame, iframe // 別サイトのコンテンツ
- link, CSS(font-face): // CSS、Webフォントなど

# CORS (Cross-Origin Resource Sharing)

## CORSとは
CORS (Cross-Origin Resource Sharing) は異なるオリジン間でデータをやり取りするための決まり。
CORSによって異なるオリジンから読み出されたリソースも、同じオリジンから読み出されたリソースと同じように扱うことができる。

例えば XHR (XMLHttpRequest) を利用すれば Ajax で異なるオリジンのリソースを取得することが出来る。
しかし XHR は同一オリジンポリシーに従うため、異なるオリジン間へのリクエストが制限されている。
CORSを行うためには、サーバーとクライアント双方で適切なヘッダーを付与する必要がある。

## CORSに関連するリクエストヘッダ
リクエストヘッダーはブラウザが自動的に付与してくれる。

- Origin: オリジン情報(必須)
- Access-Control-Request-Method: HTTP メソッドの種類
- Access-Control-Request-Headers: リクエストヘッダの種類

## CORSに関連するレスポンスヘッダ
レスポンスヘッダーは必要に応じて付与する必要がある。

- Access-Control-Allow-Origin: 許可するオリジン(必須)
- Access-Control-Allow-Credentials: 認証情報を含むリクエストの許可
- Access-Control-Allow-Methods: 許可する HTTP メソッドの種類
- Access-Control-Allow-Headers: 許可するリクエストヘッダの種類
- Access-Control-Expose-Headers: 要求するリクエストヘッダの種類
- Access-Control-Max-Age: プリフライトリクエスト(OPTION)の有効期限

# crossorigin 属性 と Canvas 要素

## crossorigin 属性とは
HTML5 では以下の HTML 要素が crossorigin 属性に対応している。

- img
- audio
- video
- link
- script

これらの HTML 属性に crossorigin 属性が付与すると、リソース取得時のリクエストヘッダーが変化する。

- なし: CORSに対応しない
- crossorigin (値指定なし): anonymous と同一
- crossorigin="anonymous": 認証情報を付与しない
- crossorigin="use-credentials": 認証情報を付与する

## Canvas 要素の機能制限
異なるオリジンのリソースを Canvas 要素で読み込んだ場合、同一オリジンポリシーによる 制約によって、以下の関数などが実行できなくなってしまう。
上述の crossorigin 属性を指定することで、これらの関数を利用することができるようになる。

- toBlob() // 描画内容からblobオブジェクトを生成
- toDataURL() // 描画内容からbase64を生成
- getImageData() // 指定範囲のImageDataオブジェクトを取得

# 資料
- 同一オリジンポリシー
  - https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy
- HTTP アクセス制御 (CORS)
  - https://developer.mozilla.org/ja/docs/HTTP_access_control
- CORS 設定属性
  - https://developer.mozilla.org/ja/docs/Web/HTML/CORS_settings_attributes
- CORS Enabled Image
  - https://developer.mozilla.org/ja/docs/Web/HTML/CORS_enabled_image
ListViewの内容を動的に更新したい場合はObservableCollectionを利用する


例えばこんなView（ChatPage.xaml）があって、

```xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MessageApp.Views.ChatPage">
	<ContentPage.Content>
		<StackLayout>
			<ListView x:Name="messagesView" VerticalOptions="FillAndExpand"></ListView>
			<StackLayout Orientation="Vertical" VerticalOptions="End">
				<Entry x:Name="message" Placeholder="Write something here..." Keyboard="Chat" />
				<Button Text="Send" WidthRequest="80" Clicked="OnSendTapped" />
			</StackLayout>
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

```

こんな動作を期待しているときに、

![iPhone_6s_-_iPhone_6s___iOS_9_3__13E230_.png](https://qiita-image-store.s3.amazonaws.com/0/5877/a0dea4f0-fb56-71a8-a3ac-20e7e587281c.png "iPhone_6s_-_iPhone_6s___iOS_9_3__13E230_.png")

こんな風なView（ChatPage.xaml.cs）を書いても期待した動作にはならない。

```csharp
using System;
using System.Collections.Generic;
using Xamarin.Forms;

namespace MessageApp.Views
{
	public partial class ChatPage : ContentPage
	{
		private List<string> messages = new List<string>();

		public ChatPage()
		{
			InitializeComponent();
			Title = "Message";
			messagesView.ItemsSource = messages;
		}

		void OnSendTapped(object sender, EventArgs args)
		{
			messages.Add(message.Text);
			message.Text = "";
		}
	}
}

```

ListのオブジェクトをItemSourceとして指定しても、ListView側が変更を検知できないので、変更を検知させたい場合はObservableCollectionを利用する必要がある。修正後のコードがこちら。

```csharp
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace MessageApp.Views
{
	public partial class ChatPage : ContentPage
	{
		private ObservableCollection<string> messages = new ObservableCollection<string>();

		public ChatPage()
		{
			InitializeComponent();
			Title = "Message";
			messagesView.ItemsSource = messages;
		}

		void OnSendTapped(object sender, EventArgs args)
		{
			messages.Add(message.Text);
			message.Text = "";
		}
	}
}
```

参考：[ListView Data Sources: Data Binding](https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/data-and-databinding/#Data_Binding)
プロジェクト管理 請負契約


■著作権の帰属
A社からB社に対して､請負契約を発注した｡
契約書上は取り決めをしていなかった場合､プログラム著作権の原始的帰属はB社に帰属する｡

■契約のゴール
注文者は結果に対し報酬を支払う｡請負人は仕事の完成を約す｡

■瑕疵担保責任
瑕疵担保条項は強行規定ではないので､ビジネス契約では当事者の合意により異なった定めの設定が可能｡なので売買契約であると認定されないよう､契約書で瑕疵の補償の仕方についてできるだけ具体的に定める｡

■注意点
下請代金､またはその算出方法を明確に記載しておく｡
所有権､知的財産権の移転と時期については､返還の必要が生じる場合も鑑み､設定する｡
[作ってみた] たばこの売れ行き変遷 見えるくん

#何をつくったか
たばこの主要各銘柄の売れ筋が1998年からどう変わっていったのかを可視化するソフトです！

![Cigarette_market_transition.gif](https://es-project.qiita.com/files/dc864123-13f9-70a5-5d58-59ad73e52a76.gif)

#Features
- シェア、タール、価格の中から自由にタテヨコ軸を設定して、1998年から2014年までの主要銘柄の変遷が見れます
- 各銘柄の円の面積が、その銘柄の本数ベースの売り上げに比例しています。
- 表示画面下のバーの任意の場所をクリック&ドラッグすることで年の遷移もできますが、キーボードの左右矢印キーを押すことでも移動できます<img width="254" alt="スクリーンショット 2016-06-22 8.35.52.png" src="https://es-project.qiita.com/files/cbe1ba2a-ff8d-629a-a497-ff7df2a33151.png">
- 右側のチェックボックスを使うことで、特定の銘柄にフォーカスすることができます<img width="670" alt="スクリーンショット 2016-06-22 8.36.31.png" src="https://es-project.qiita.com/files/4f85f6db-7c8c-4d8c-3ce7-0e32d9055ff7.png">
- フォーカスした銘柄は、変遷の記録が強調されて見やすくなります(上図
- キーボードのSpaceキーを押すと、全銘柄の選択/解除ができます

#使い方

1. GitHubに置いといたので、https://github.com/lucas29/cigarette_market_transition ここからClone or download (緑色のボタン) <img width="882" alt="スクリーンショット 2016-06-22 8.28.12.png" src="https://es-project.qiita.com/files/9b2771e4-14f7-25de-bcef-ebc0fc5655f6.png"> (ソースコードもここで見れます)
2. downloadしたzipを展開 (解凍って今の若いコは言わないらしい…)
3. OSに合わせて、例えばWindows 32bitの場合は "application.windows32" 内の実行ファイルを実行

#参考情報
- 売り上げデータはTIOJが一般に公開している "上位20銘柄推移.pdf" とかいうファイルより

#改善点の依頼
改善点の依頼は本記事へのコメントで！
暇だったら取り込んで更新します。
SwiftでPreprocessor Macrosを使う

ハマったのでメモ。

## Preprocessor Macrosとは

`Build Settings` にある `DEBUG` などのフラグの設定です。

![macros.png](https://qiita-image-store.s3.amazonaws.com/0/8093/7dd6f841-a974-93b0-88ca-15a7eab41a29.png)

## SwiftからPreprocessor Macrosを使用するには

`Other Swift Flags`に `-D{フラグ名}` を設定します。

![swift.png](https://qiita-image-store.s3.amazonaws.com/0/8093/1d209464-5580-25d3-f57f-496d10868082.png)


コードから以下のように使用することができます。

```
var baseURL: NSURL {
    #if STAGING
        return NSURL(string: "https://hogehoge.stg.piyopiyo")!
    #else
        return NSURL(string: "https://hogehoge.piyopiyo")!
    #endif
}
```

## 参考

[ios - #ifdef replacement in swift language - Stack Overflow](http://stackoverflow.com/questions/24003291/ifdef-replacement-in-swift-language)
Bigqueryで使ったクエリまとめ

## About
久しぶりにSQL触ったので、サンプルとして置いておきます。間違っていたら教えて下さい。。。適宜追加予定です。


### UTC -> JST変換

```sql
SELECT
  create_time
  , STRFTIME_UTC_USEC(TIMESTAMP_TO_USEC(create_time) + 32400000000, "%Y/%m/%d %H:%M:%S") AS create_time_jst
FROM
  [test.access_log]
LIMIT
  1
```

http://itnote-ichi5.com/post-bigquery-utc-jst/


### テーブルの結合

```sql
select 
*
from 
(
  table_date_range(dataset.tablename,
  TIMESTAMP('2016-06-01'),
  TIMESTAMP('2016-06-30')))
  limit 100
```

### ある期間内で曜日ごとに集計する

```sql
SELECT CASE
           WHEN DAYOFWEEK(time) = 1 THEN 'Sun'
           WHEN DAYOFWEEK(time) = 2 THEN 'Mon'
           WHEN DAYOFWEEK(time) = 3 THEN 'Tue'
           WHEN DAYOFWEEK(time) = 4 THEN 'Wed'
           WHEN DAYOFWEEK(time) = 5 THEN 'Thu'
           WHEN DAYOFWEEK(time) = 6 THEN 'Fri'
           WHEN DAYOFWEEK(time) = 7 THEN 'Sat'
           ELSE 'none'
       END AS week,
       count(time) as count
       from ( table_date_range(dataset.tablename, TIMESTAMP('2016-06-01'), TIMESTAMP('2016-06-30')))
WHERE context LIKE '%XXX%'
GROUP BY week
```

6月の期間内で曜日ごとのデータを集計してます。`DAYOFWEEK` 関数だと数値が取れますが、そのままだとわかりにくいので、`CASE` 文を使って、英語に修正しています。

### 文字列を区切り文字で分割して取得する
|time|data|
|---|---|
|2016-07-04 02:30:00 UTC| aaa bbb ccc |
|2016-07-04 03:30:00 UTC| ddd eee fff |

上記のようなテーブルがあった際にdataの中からspaceを区切り文字として、それぞれの値を取りたいとします。

```sql
SELECT time, 
  FIRST(SPLIT(data, ' ')) as col1,
  NTH(2,SPLIT(data, ' ')) as col2,
  NTH(3,SPLIT(data, ' ')) as col3
FROM test
```

とすると

|time|col1|col2|col3|
|---|---|---|---|
|2016-07-04 02:30:00 UTC|aaa|bbb|ccc|
|2016-07-04 03:30:00 UTC|ddd|eee|fff|

というようになります。

### 今月のテーブルを対象にクエリを発行する
テーブルを日付単位で分ける構成を取っているところもあると思います。そんなときに今月の情報を横断的に見たいというときの方法です。

```sql
select * from 
(TABLE_QUERY(<dataset_name>,
  'REGEXP_MATCH(table_id, r"^<table_prefix>") AND
   table_id CONTAINS STRFTIME_UTC_USEC(NOW(), "%Y%m")'))
```

TABLE_QUERYを使って対象月のテーブルを全て取得して、クエリを発行します。

### TOP10を出力する

```sql
SELECT TOP(ua,10) as ua,
       COUNT(*) AS COUNT 
FROM (TABLE_QUERY(<dataset_name>, 'REGEXP_MATCH(table_id, r"^<table_prefix>") AND table_id CONTAINS STRFTIME_UTC_USEC(NOW(), "%Y%m%d")'))
```

uaというカラムのカウントが多い順TOP10を出力します。

### 先月の最終日を出力する

```sql
SELECT DATE(DATE_ADD(CURRENT_DATE() , -DAY(CURRENT_DATE()), "DAY"))
```

http://stackoverflow.com/questions/38207702/the-last-day-of-the-previous-month-bigquery

## リンク
- https://cloud.google.com/bigquery/query-reference#select-syntax
- http://qiita.com/hakobera/items/cdc6fd41b68a31821c96
ApacheでDNSのワイルドカードレコードに対応するVirtual Hostの記述方法(For Rails)

前回投稿した
[ApartmentGemを使ってテナント型Webアプリケーション構築のサンプル (PostgreSQL版)](http://qiita.com/Syn256/items/82044d86329b46864d2c) 
にてワイルドカードレコードを作ってApartmentのCreateを呼び出せばOKと書いていましたが、
Virtual Hostの設定が抜けていたので片手落ちでした。


``` /etc/httpd/conf.d/multi_tenant.conf
# ファイル名は適当です。
<VirtualHost *:80>
    ServerAdmin admin@example.com
    ServerName www.example.com
    ServerAlias *.example.com # ここ重要。ここでxxx.example.comのアクセスを受ける宣言をしている。
    DocumentRoot /path to your rails app/public
    <Directory "/path to your rails app/public">
      AllowOverride All
      Options FollowSymLinks Includes
      Require all granted
    </Directory>
</VirtualHost>
```

上記を設定すると、定義されていないサブドメインのアクセスがすべて上記VirtualHostに寄せられます。この仕組みを使うことでマルチテナントなアプリケーションを構築することが簡単になります。
Facebook SDK for .NETで、アプリのアクセストークンを取得する方法


# 概要

Facebook Graphにアクセスするようなアプリのユニットテストしようと思ったときに、アプリのテスト専用ユーザーの[ユーザーアクセストークン](https://developers.facebook.com/docs/facebook-login/access-tokens#usertokens)をユニットテストの中で参照したいと言うことがあると思います。
（例えば、テストユーザーとしていいねしたり投稿したりするなど）。

C#のFacebook SDKを使って簡単に実装できたので紹介します。


# 実際のコード

コードのステップとしては、次のようになっています。

1. まずは、[Facebookアプリのアクセストークン](https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens)を取得
2. アプリのアクセストークンを元に、アプリに属しているテストユーザーのアクセストークン等を含むデータを読み出し
3. 2で取得したテストユーザーのユーザーアクセストークンを使って、投稿したりいいねしたりするなど、ユニットテストで必要な動作を行う

```csharp

// まずはアプリアクセストークンを取得する
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new
{
	client_id = appId, //FacebookアプリのID
	client_secret = appSecret, //FacebookアプリのSecret
	grant_type = "client_credentials"
});

//取得したアプリアクセストークンを使うようにFacebookClientに設定
fb.AccessToken = result.access_token;


//次にアプリに属すテストユーザーのデータを読み出す
dynamic testUsers = fb.Get($"/{appId}/accounts/test-users");


//最後に、テストユーザーのID(例えば"123455555")を元に、ユーザーアクセストークンを取り出す
var userToken = ((IEnumerable<dynamic>)testUsers.data).FirstOrDefault(_ => _.id == "123455555").access_token;


// 後は、ユーザーアクセストークンを元に投稿するなどする
fb.AccessToken = userToken;
fb.Post("/me/feed", new { message = "hello from unit test" });
```

# 備考

上の例ではdynamic型でSDKの戻り値を受けていますが、[Facebook SDK for .NETの戻り値で型付けを利用する](http://qiita.com/katz/items/82e7fe823c3a18aeb71d) を参考に、戻り値を型付けした状態で使うのもありです。


# 参考情報

- [How to get an access token using C# SDK](http://stackoverflow.com/a/9915048)
- [Facebookドキュメント - アクセストークン](https://developers.facebook.com/docs/facebook-login/access-tokens)
ASP.NET開発でもユニットテストがしたい

# 概要

.Net Core（最近1.0がリリースされましたね）より昔のASP.NETは、IISとがっつり手を握り合っていて、スタティックなオブジェクトがいっぱいあります。

そんなスタティックなオブジェクトを使っていると、ユニットテストを書けません（書いてもぬるぽです）。

それをどうにかしようというのがこの記事です。

----

# HttpContext

----

リクエストやレスポンスが入っている肝心かなめのオブジェクトです。

HttpContextBaseという抽象クラスがありますが、なんとHttpContextはこれを継承していません。 :open_mouth: 

----

# HttpContextの解決策

----

HttpContextBaseとHttpContextWrapperを使いましょう。

```vbnet:Injectee.vb
Public Sub New (httpContext As HttpContextBase)
```

```vbnet:Injector.vb
New Injectee(New HttpContextWrapper(HttpContext.Current))
```

----

# FormsAuthentication

----

Form認証にしたときに使うやつです。

----

# FormsAuthenticationの解決策

----

用意されているラッパはないので、自前でラッパを用意しましょう。

```vbhet:IAuthenticationWrapper.vb
Public Interface IAuthenticationWrapper
    Sub SetAuthentication(userName As String, isPersistent As Boolean)
End Interface
```

```vbnet:AuthenticationWrapper.vb
Public Class AuthenticationWrapper
    IAuthenticationWrapper

    Sub SetAuthentication(userName As String, isPersistent As Boolean) Implements IAuthenticationWrapper.SetAuthentication
        FormsAuthentication.SetCookeiAuthentication(userName, isPersistent)
    End Sub
End Class
```    

----

# まとめ

---

ASP.NETでユニットテストしたいときは、

とにかくラッパ！！

:stuck_out_tongue_closed_eyes:
docker で Ctrl-p ２回押し問題 (detach-keys の問題) を解決するには

http://qiita.com/YutakakINJO/items/eeb579f75feb50fa18ae で言及されている問題が、もうすでに解決されているのでメモしておく。

# 問題(再確認)

デフォルトでは `Ctrl-p` は、detachKeys の一部として認識されていて、コンテナにこのキーを送るには、 `Ctrl-p` を２度押しする必要があった。

# 解決方法

docker v.1.10.0 から、 detachKeys を変更する機能が実装された。ので、普段使わないキーに、この detachKey を配置してやればよい。

以下のファイルを `~/.docker/config.json` に配置する。

```json:~/.docker/config.json
{
    "detachKeys": "ctrl-\\"
}
```
React Nativeでnode moduleを使おうとしたらエラーでた。

タイトルの通りなんだけどエラーでた。
モジュールの解決に失敗している様子。

## 原因
対処法的なの一通りしたところで気がついた。

Node.jsのeventsモジュールが無くてエラー出てることに・・・
実はエラー文にちゃんと書いてあった。

React NativeはJSのエンジンとしてJavaScriptCoreを使っているので、Nodeのnativeなモジュールを使っているようなモジュールは読み込めないのだった。

## 反省
思い込みカッコ悪い。
Spring Bootで作ってるWebアプリケーションをHTTPS接続に対応させる。

# 三行で

コマンドプロンプトのkeytoolでSSL証明書作って　
Spring Bootのフォルダに証明書突っ込んで　
application.propertyに書き込めばいいよ

## cmdで証明書作成する
以下のコマンドを実行すると、C:\Users\Nameにkeystore.p12が生成される。
cygwinとかを使用しなくても可能でした。

```
C:\Users\Name>keytool -genkey -alias taka 
-storetype PKCS12 -keyalg RSA -keysize 2048
 -keystore keystore.p12 -validity 3650

キーストアのパスワードを入力してください:rootdb
新規パスワードを再入力してください:rootdb

（中略）

CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknownでよろしいですか。
  [いいえ]:  はい
```

## HTTPSを有効化する
生成されたkeystore.p12をプロジェクトの一番浅いディレクトリに置く。（どこでもいいらしい）
そして、application.propertyに以下の記述を追加する。

```
# SSL Setting
server.port: 8443
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: rootdb
server.ssl.keyStoreType: PKCS12
server.ssl.keyAlias: taka
```

## アクセスする
`https://localhost:8443/`　にアクセスすえればOK。
PlayFramework 2.5.2 からRangeRequest対応した！

# 0. 前置き

とあるサービスにてiPhoneで動画再生するようにしたいという要求がありました。
それで、コンテント返せばいいやってことで以下のように書いてました。

```scala

def getMovie() = Action { implicit request =>
   val sendFile = new File("/sendFilePath/example.mp4")
   val fileContent: Enumerator[Array[Byte]] = Enumerator.fromFile(sendFile)
   val source = Source.fromPublisher(Streams.enumeratorToPublisher(fileContent)).map(ByteString.apply)
   val entity = HttpEntity.Streamed(source, Some(file.length), Some(contentsType))
   Result(
      header = ResponseHeader(200),
      body = entity
   ).as("video/mp4")
}
```
ところがどっこい、動画再生されないじゃありませんか…(´・ω・｀)

https://gist.github.com/uupaa/ad00a1912b5770b0023d

あ、iPhoneとかAndroidって動画再生RangeRequestしてるんだ。
ってことでPlayFrameworkでRangeRequestに対応することに。

# １.PlayFrameworkではRangeRequestは今までめんどくさかった。

http://qiita.com/upopo21/items/ae43f0b61b0b7de22183
上記の方が記事を掲載していただいてるように、RangeRequestめんどくさかったです。

で、本題、Play2.5.2からRangeRequestが公式に対応しましたヽ(=´▽`=)ﾉ
https://github.com/playframework/playframework/pull/5995

# 1.これからは

公式対応したので、これからは以下のような感じでかけます。
非常に簡単ですね。

```scala
import play.api.mvc._

def getMovie() = Action { implicit request =>
   val sendFile = new File("/sendFilePath/example.mp4")
   RangeResult.ofFile(sendFile, request.headers.get("Range"), Some("video/mp4"))
}
```

Play使いでiPhone動画再生させたくて困っている方の足しになれば！
あ、Play2.4とかなら上司に2.5にしていいですか！？っていう口実にもなりますね。
Golangのrevelをインストールしてみる

# revelフレームワークのインストール
参考）https://revel.github.io/tutorial/gettingstarted.html

Git,HGがインストールされていたからか、これだけです
```$ go get github.com/revel/revel```

# コマンドラインツールのインストール
こちらも簡単です。
```$ go get github.com/revel/cmd/revel```

```~/.bashrc
export PATH="$PATH:$GOPATH/bin"
```

 ヘルプを見ることで何ができるようになったか、なんとなくわかりますね

```
$ revel help
~
~ revel! http://revel.github.io
~
usage: revel command [arguments]

The commands are:

    new         create a skeleton Revel application
    run         run a Revel application
    build       build a Revel application (e.g. for deployment)
    package     package a Revel application (e.g. for deployment)
    clean       clean a Revel application's temp files
    test        run all tests from the command-line
    version     displays the Revel Framework and Go version

Use "revel help [command]" for more information.
```

# revelで画面を表示してみる
## コマンドでプロジェクトを作成する
これでrevelを利用するために必要な雛形ができあがります
```$ revel new revelSample```

出来上がったディレクトリを見てみましょう

```
$ find . -type d
./app
./app/controllers
./app/views
./app/views/App
./app/views/errors
./conf
./messages
./public
./public/css
./public/fonts
./public/img
./public/js
./tests
```
だいたいイメージがつきますね

## 作成したプロジェクトを起動してみる

```
$ revel run revelSample
```
はい。これでOKです。

## ブラウザで確認してみる
サーバーを起動した状態で以下にアクセスする
http://localhost:9000/
「It works!」とブラウザで表示されれば完了です

非常に簡単ですね。