OmniAICreator/Qiita-1.07M huggingface dataset:
改行とかのある文字列をエスケープしないで書きたい

AAなどの文字列はエスケープすると超絶見難くなるのでそのまま書きたくなった。

```d:エスケープされ見るも無残な姿になってしまったD言語くん
string dman = "      ____\n      L__L|\n      /    \\\n    /        \\\n  / _______    \\\n  \\ \\#/  \\/ \\  /\n   \\|#| O| O|#\\\n    |#L _L__ #|\n    |###|  |##|\n    /###/  /##|\n   /###/   /##|\n  /###/___/###/\n /###########/\n /##########/\n    /     \\\n    \\     /\n   _ \\   /__\n  |__/  |__/";
```
[^1]

Delimited Stringsというものがある。[^2]デリミタ、文字列の終了を表す記号のある文字列である。それを使って以下のように書ける。

```d
string s = q"/123"\n\n"/";//string dman = "123\"\\n\\n\"";
writeln(s);
```

```text:このように出力される
123"\n\n"
```

通常エスケープしなければならない`"`がそのまま出力され、改行を表すはずの`\n`がそのまま出力されている。うれしい。この場合`/`がデリミタとなって、それに囲まれた部分で自由に書ける。ただしデリミタである`/`は書けない。

```d
string s = q"/a/a/";//エラーになる
```

ただしNesting Delimiterという特殊なデリミタもある。

```d
string s1 = q"((a)())";//(a)()
string s2 = q"(a(a)";//これはだめ
```

たくさんのカッコで囲まれた文字列とかを書くときに必要かもしれない。

好きな言葉をデリミタに使うこともできる。その場合デリミタのすぐ後に改行を入れる必要がある。

```d:ソースコード中に降臨できてご満悦のD言語くん
string dman = q"DmanisGod
      ____ 
      L__L|
      /    \
    /        \
  / _______    \
  \ \#/  \/ \  /
   \|#| O| O|#\
    |#L _L__ #|
    |###|  |##|
    /###/  /##|
   /###/   /##|
  /###/___/###/
 /###########/
 /##########/
    /     \
    \     /
   _ \   /__
  |__/  |__/
DmanisGod";
writeln(dman);
```

```text:出力
      ____
      L__L|
      /    \
    /        \
  / _______    \
  \ \#/  \/ \  /
   \|#| O| O|#\
    |#L _L__ #|
    |###|  |##|
    /###/  /##|
   /###/   /##|
  /###/___/###/
 /###########/
 /##########/
    /     \
    \     /
   _ \   /__
  |__/  |__/

```

最後に改行ができてしまうため注意が必要である。

---

## 追記

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://t.co/vx1HqYqmqd">https://t.co/vx1HqYqmqd</a><br>`` リテラルでいいんじゃない？と思うんだけど、デリミタの指定込みのネタかな</p>&mdash; 黄前久美子さんと高坂麗奈さんの距離感 (@shitsyndrome) <a href="https://twitter.com/shitsyndrome/status/806079495685828608">2016年12月6日</a></blockquote>

```d:``リテラルを知らなかったことに死ぬほどキレてるD言語くん
string s =
`      ____
      L__L|
      /    \
    /        \
  / _______    \
  \ \#/  \/ \  /
   \|#| O| O|#\
    |#L _L__ #|
    |###|  |##|
    /###/  /##|
   /###/   /##|
  /###/___/###/
 /###########/
 /##########/
    /     \
    \     /
   _ \   /__
  |__/  |__/`;
```

[^3]

こっちのほうがいいですね……

[^1]: http://qiita.com/kotet/items/a04955c206a2f56e16d8
[^2]: http://dlang.org/spec/lex.html
[^3]: https://twitter.com/SagafroKichigai/status/805188096769736704
mac で microsoft dotnet をつかって webapp を scaffold する

# mac os x で dotnet run したい

```shell-session
brew install Caskroom/cask/dotnet
exec $SHELL -l
mkdir hoge
cd hoge
dotnet new -t web
dotnet restore
dotnet run
```

```shell-session
Project hello (.NETCoreApp,Version=v1.1) will be compiled because expected outputs are missing
Compiling hello for .NETCoreApp,Version=v1.1
/Users/amano/pj/cs/hello/project.json(5,30): warning NU1007: Dependency specified was Microsoft.NETCore.App >= 1.1.0-preview1-001153-00 but ended up with Microsoft.NETCore.App 1.1.0.

Compilation succeeded.
    1 Warning(s)
    0 Error(s)

Time elapsed 00:00:03.3512061


info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
      User profile is available. Using '/Users/amano/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /Users/amano/pj/cs/hello
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
```

できた
Cloud9でVagrantを使ってみる

# 概要
元々ローカルでVagrant使っていたのですが、何か動作もっさりしてて。。
クラウドIDEとかなら何か変わるのかな、と妄想して試すためのメモ

# 前提
* Vagrantをローカルで動かしたことがある
* Cloud9が何者かを知っている

# やってみること
Vagrantで、作った仮想環境でGitLabとRedmineの連携を試してみたいと思います。

# やります
## 1.Cloud9はこれ選んだ
![1.png](https://qiita-image-store.s3.amazonaws.com/0/117615/8e08903d-fa21-a1b6-abe4-8b1e8390e8b1.png)

## 2.環境上にVagrantダウンロードした
### まずは自分の環境確認
```
cat /proc/version
->Linux version 4.2.0-c9 (root@b197fb11a5c1) (gcc version 4.9.2 (Debian 4.9.2-10) ) #2 SMP Thu Oct 20 09:52:05 UTC 2016
```
（うわ、CentOS以外触ったことない。。なにこれ。。）

```
uname -a
->Linux ksyun-exp-4094368 4.2.0-c9 #2 SMP Thu Oct 20 09:52:05 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
```
### Vagrantのダウンロードページをみる
あったこれか
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/117615/aa3f79de-7d8e-17fe-4a73-c7478bceb64b.png)

### とりあえずwgetしてインストールする
```
wget https://releases.hashicorp.com/vagrant/1.9.0/vagrant_1.9.0_x86_64.deb
```

```
sudo dpkg --install vagrant_1.7.2_i686.deb
```
できたっぽい

```
vagrant -v
->Vagrant 1.9.0
```

## 3.VirtualBoxをダウンロードする
[公式サイト](https://www.virtualbox.org/wiki/Linux_Downloads)にはこんなことが書いてあるようだったので実行

```
sudo vi /etc/apt/sources.list
 
#最後に以下を追加
deb http://download.virtualbox.org/virtualbox/debian raring contrib
 
sudo wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
sudo apt-get update
sudo apt-get install virtualbox
```

なんかうまくいったよう

# 動かして確認してみる
## `vagrant init --minimal`
Vagrantfileとかができてる。やった

## Vagrantfile修正して`vagrant up`
```
VirtualBox is complaining that the installation is incomplete. Please
run `VBoxManage --version` to see the error message which should contain
instructions on how to fix this error.
```
すんげえ怒られた

### `VBoxManage --version`
何かこのコマンド叩けと言われてるようだったので

```
WARNING: The character device /dev/vboxdrv does not exist.
         Please install the virtualbox-dkms package and the appropriate
         headers, most likely linux-headers-.

         You will not be able to start VMs until this problem is fixed.
4.3.36_Ubuntur105129
```
はい、怒られるのはわかってましたよ。

教えてぐーぐる先生！
[Ubuntu: Virtualbox を起動しようとしてエラーが出る](http://www.lifewithunix.jp/notes/2015/05/20/ubuntu-the-character-device-dev_vboxdrv-does-not-exist/)
>virtualbox コマンドを発行した時に表示されていたエラーメッセージの中にある”linux-header”と関係があることが判明しました。つまり、カーネルの中にvirualboxが必要とするヘッダーが含まれていないという事。厳密には、カーネルと完全に同一バージョンのヘッダーパッケージが入っている必要があるという事のようです。確かに、3.13.0-51-lowlatency のヘッダーが出てきません。

なるほど・・（よくわかってない）

>aptitude コマンドで、3.13.0-51 をキーワードを検索して、ヘッダーをインストールしました。

なんか`aptitude`とかいう何かで検索してインストールすれば良いのかな？？！！

```
aptitude search 4.2.0-c9
->bash: aptitude: command not found
```

諦めへんで

```
sudo apt-get install aptitude
```
検索できるようになったみたい

```
aptitude search 4.2.0-c9
->
```
なんと、検索結果ゼロ。。。<br>
`aptitude search 4.2.0`これなら少しは出てきた。。。でもよくわからん


### もうやだ、わからん

すんません、、解決手段わかれば追記します。。

# 追記：ダメでした

https://docs.c9.io/docs/software-we-do-not-support

公式で確認したところ、VM系のツールはすべてサポートされていないようでしたｗ
vue.jsでfile postする例

vue.jsでfile postする例です。
何かのご参考になれば。

```
template#file_new
  = file_field_tag :files, multiple: true, 'v-on:change' => 'fileInputChange'
  = submit_tag 'Upload', 'v-on:click.prevent' => 'fileUpload'
```


```coffeescript
$ ->
  Vue.component 'file-new',
    template: '#file_new'
    data: ->
      file_input: undefined
      files: undefined
    methods:
      fileInputChange: (e) ->
        @file_input = e.target
        @files = @file_input.files
      fileUpload: ->
        return if @files.length <= 0
        $.each Array.prototype.slice.call(@files, 0), (i, file) =>
          @_handleUpload(file)
        @file_input.value = ''
      _handleUpload: (file) ->
        form = new FormData()
        form.append('Content-Type', file.type || 'application/octet-stream')
        form.append('file', file)

        $.ajax
          url: "/api/hoge.json"
          type: 'POST'
          data: form
          cache: false
          contentType: false
          processData: false
        .done (response) =>
          console.log response
        .fail (response) =>
          console.error response
```
CodeIgniterの日本語情報源

この記事は<a href="http://qiita.com/advent-calendar/2016/code_igniter" target="_blank">CodeIgniter Advent Calendar 2016</a>の6日目です。

当初の予定では「CodeIgniterの情報源について。日本語および国外の記事を探してみた話。」と題していたのですが、後半部分がまとめ切れないので、そこは切り分けてまたの機会にします。

CodeIgniter2の頃に開発が停滞していた影響か、Google検索では日本語の情報がなかなか見つけにくい現状ですが、ピンポイントで探せば意外と情報を見つける事が出来る様です。
この記事ではCodeIgniterの日本語情報がどこに潜んでいるかを紹介します。

## [teratailのCodeIgniterタグ](https://teratail.com/tags/CodeIgniter)
先日の[CodeIgniter Night](https://codeigniter-talk.doorkeeper.jp/events/52872)に参加されていた方に教えて頂きました。まったくアンテナを張っていない世界でびっくりしました。
teratailのサービス上の性質からか具体的なコードの話が多く、かつ投稿も新しい物が見られます。
おそらく僕が今知っている中では一番活発に情報が流れている所だと思います。
最近では[徳丸氏](https://teratail.com/users/ockeghem)がteratailで[PHPのセキュリティに関する話題](http://a.hatena.ne.jp/ockeghem/)を[観測](https://twitter.com/ockeghem/status/802501733154856961)し[続け](https://twitter.com/ockeghem/status/802502829948616704)て[いる](https://twitter.com/ockeghem/status/805575391582646272)様なので、実は僕が知らないだけで有名なのかもしれません。

## [QiitaのCodeIgniterタグ](http://qiita.com/tags/CodeIgniter)
この記事自体Qiitaに書いているので説明不要ですね。
[CodeIgniter3]のタグもあるのですが、14投稿中11件が[CodeIgniter]のタグも付いているので、基本的には[CodeIgniter]のタグで良いでしょう。

## [CodeIgniter Talk - Facebookグループ](https://www.facebook.com/groups/654414737905980/)
参加せずとも見る事が出来ますが、Facebookのログインが必要です。
Google検索に引っかからないのがもったいない所です。

## [codeigniter lang:ja - Twitter検索](https://twitter.com/search?q=codeigniter%20lang%3Aja&src=typd)
単純にTwitter上を[CodeIgniter]という単語で検索するだけですが、たまにブログ記事のTweetなどが引っかかります。
常時監視するのは面倒すぎるので、[YahooのmyThingsアプリ](https://mythings.yahoo.co.jp/)（日本語版IFTTTのようなもの）を使ってはてなブックマークへ保存しています。
もしmyThingsをお使いの方がいれば、レシピはこちらですのでどうぞ
https://mythings.yahoo.co.jp/?share_id=mmW3G02fAigAUNwhFT5qpeE-

## [Asakusa.php](https://asakusaphp.doorkeeper.jp/)
東京の浅草で @NEKOGETさんが主催されている勉強会です。
別にCodeIgniterに限らず、やることを決めて作業をしたりお話をしたりする会です。
でもCodeIgniterについてお聞きすると無限に話を聞くことが出来ます。
余談ですが、僕はこの勉強会で @NEKOGETさんや今の職場のCTOの @hiro_y さんに初めてお会いしました。
色々勉強になる事が多い素敵な会です。

---

以上がGoogle検索以外での、僕のCodeIgniterの情報源です。
明日はkenjisさんの記事が予定されています。
iPhone系&Androidとそれ以外で分岐させる姑息技

#いきさつ
某メディアの広告をJSで表示しているんですけど、そもそもPCには対応していないため、PCで見るとコンソールにずっとエラーが出ていた。
某メディア担当者曰く「仕様です（キリッ）」とのこと（笑）

本来ならVIEW側でやるべきじゃないのとは思うんですけど、エンジニアの手を煩わすのもアレなんで暫定処理として調べた。

キレッキレのRailsエンジニアさんからの苦情は受け付けませんので予めご容赦くださいw

#作業内容

```hoge.haml
= render '*******/*******/*******_***'
```

問題のJSコードはパーシャルで読み込んでいる。
なので、そのパーシャルを呼び出しているコードに分岐処理を追加。


なんと！
request.env['HTTP_USER_AGENT']
または
request.user_agent
でアクセスしたUAがわかるらしい。ステキ！

僕の場合はPCの時はパーシャルを読み込ませたくない。
逆にいうとモバイルでは表示させたいとなる。
で、以下のコードになった。

```hoge.haml
- userAgent = request.user_agent
- if(userAgent.include?('Mobile')||userAgent.include?('Android'))
  = render '*******/*******/*******_***'
```

userAgentに代入された文字列に「Mobile」や「Android」が含まれているものが対象になっているので、厳密には正しい分岐処理ではない。
なので姑息技ということ。
ただ、この条件であれば、iPhone、iPad、iPod touch、Androidを網羅できるので、その他の少数端末は無視してもOKって場合は使ってもよいかな〜ってF.E.E.さんはどうぞ〜w

#追記2016/12/08

エンジニアさんに以下のgemを使うように言われた（笑）

[rack-user_agent](https://github.com/k0kubun/rack-user_agent)

##手順は簡単！
``` Gemfile.
gem 'rack-user_agent'
```

``` console.
#bundle install
```
あとはhamlの任意の箇所に取得できるデータを読み込むなりして使うだけ

僕の場合はスマートフォンからのアクセスならば処理を実行させたいので以下のようになった

``` sample.haml
- if request.from_smartphone?
  処理
```
Wordpressのheadは4行で

先にhead内に記載する内容を記述します

```html:header.php
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<?php wp_head(); ?>
```
head内はこれだけでいいです。

## タイトルタグを出力
```php:function.php
<?php
function title_setup(){

  // タイトル
  add_theme_support( 'title-tag' );

}
add_action( 'after_setup_theme', 'title_setup' );
?>
```
これでタイトルタグが出力されます。
ホームでは「サイトタイトル - デスクリプション」、それ以外は「ページタイトル - ページタイトル」
また、header.phpにタイトルタグを記述した場合はそちらが優先されます。
これをつかって、特定のページのみ、任意のタイトルタグにすることも可能です

## css, jsの読み込み
```php:function
<?php
function original_enqueue_scripts() {

  // cssの読み込み
  wp_enqueue_style(
    'style', // システムで使う名前
    get_stylesheet_uri(), // style.cssを読み込む
    array('before_style'), //  読み込む前に読み込まれるべきスタイル。システムで使う名前を入れる
    filemtime( get_stylesheet_directory() . '/style.css' ) // バージョンの自動生成
  );


  // jsの読み込み
  バージョン
  wp_enqueue_script(
    'bundle', // システムで使う名前
    get_template_directory_uri() . '/js/bundle.js', // 読み込むjavascript
    array( 'jquery' ), // 先に読み込むjavascript
    '1.0.0', // バージョン
    true // trueなら</body>の前に、falseならhead内に出力する
  );

  // 決まり文句として入れておこう
  if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
    wp_enqueue_script( 'comment-reply' );
  }
}
add_action( 'wp_enqueue_scripts', 'original_enqueue_scripts' );
?>
```
これで管理できます。wordpress自身が読み込むファイルとの順番などが調整できます。

## キーワード、ディスクリプション、OGPなど
プラグインをつかおう！
ページごとに変えたほうが良いみたいだし、そんなの作ってたら大変だよ( ´Д`)

## ファビコン
管理画面 > 外観 > カスタマイズ > サイト基本情報 > サイトアイコン
にいれたら、それがファビコンになります。
なにも設定いらないみたいですねぇ。

---

### まとめ
いままで私も静的にheader.phpに記載していましたが、管理面などをみても、
管理画面で管理できたり、動的に出力されると言うのはメリットが多いように思います。

ぜひ活用してみてはいかがでしょうか
RでSPSSファイルを読み込んだときにエラーが出る話

きぬいとです．
最近，Rのバージョンを3.3.2にしました．
それが原因かどうかすらわからないのですが，SPSSのデータセットをRで`data.frame`型に変換して読み込もうとするとエラーが出るようになりました．

対処はできたんですけど根本的な解決には至っていないので備忘録ついでに投下します．
自分が使っているデータセットの問題である可能性もあるのかもしれません．


```R:savfileError.R

#あらかじめ，開きたいsavファイルのあるディレクトリとかに移動したりしてください．
#install foreign package
install.packages("foreign")
library(foreign)

#データセットの読み込み
#use.value.labelsは変数の名前を用いるかどうか．Fにすると数値で返してくれます．
#to.data.frameは該当データをdata.frame型に変換してくれます．今回はここが変らしい．

X <- read.spss("hoge.sav", use.value.labels = F, to.data.frame = T)

#エラー内容
#In addition:...のほうは前から出ていたエラーで，分析する上では支障のない警告です．

Error in if (use.missings) for (v in names(rval)) { : 
  argument is not interpretable as logical
In addition: There were 50 or more warnings (use warnings() to see the first 50)

#とりあえず強引に回避することにします．
#savファイルのデータセットを読み込むとデフォルトではlist型のようなので，data.frame()
#を用いて外からdata.frame型に変換します．

X <- data.frame(read.spss("hoge.sav", use.value.labels = F))

```

「`read.spss()`関数内で回避できるよ！」等，知っている方は教えてください．
【自分用メモ】Windows10にTerm3を入れるのに手間取った話

#Windowsに統合開発環境をつくる
Windowsで競プロをやっていた身として、Windowsにも左半面にエディタ・右半面にコマンドラインが欲しかった。しかもHaskellも似た環境でプログラミングしたかったので、左半面にTeraPad・右半面にコマンドプロンプトというダサいやり方をしていた。
そこでAtomを使って自分のWindowsにも統合開発環境を作ることにした。

ここまでが建前。本音はkstmのアドベントカレンダーに参加することになったので何か記事を書くことを探していて少し前(2016/11月末)にこの件でハマってしまったのを思い出し、次Windowsをクリーンインストールした時のためのメモ書き。

#環境
Windows10 Pro

#手順
基本的には4Step
1. Python2.7系  のインストール (Pathも通す)
2. Microsoft Visual Studio のインストール (Pathも通す)
3. node.exe のインストール (Pathを2つ通して動いた)
4. atom のPathを通す (Pathも通す)

1と2でハマることは特にないが、クリーンインストールする度に3と4でハマったんだよなぁ。つらみ。

#1. Python2.7 のインストール
以下のurlからダウンロード&インストール (インストール時にPathを通すオプションがある)
https://www.python.org/downloads/
Python3系ではないので注意

Pathは システム -> システムの詳細設定 -> 環境変数 -> "Path"を選択して編集 から追加できる。
デフォルトでは C:\ 直下に Python27 が生成されるので 新規 -> "C:\Python27"と記入 -> OK でPathを通せる。

#2. Microsoft Visual Studio のインストール
以下のurlからダウンロード&インストール (ハマらなければこれが一番時間がかかる…)
https://www.visualstudio.com/ja/downloads/

Microsofrt Visual Studio の Path はシステム環境変数に登録が必要で
システム -> システムの詳細設定 -> 環境変数 -> システム環境変数 (下側) -> 新規
より、
変数名: GYP_MSVS_VERSION	
変数値: 2015
で OK を押す。

#3. node.exe のインストール
例のごとく下のurlからダウンロード。 ~~ただこれ、本当に必要なのか分からない~~
https://nodejs.org/en/#download
これ、自分のPCでは環境変数通ってなくて動かないはずなんだけど、念のため明記しておこうかな…
上にならって適当なところをPath通してください。

#4. Atomをインストール
Atomを入れていればダウンロード&インストールは必要ないですがまだの人は以下urlからどうぞ
https://atom.io/
あとは例のごとくPathを通してください。
人によってディレクトリは変わりますが自分の場合は
C:\Users\[自分のユーザ名]\AppData\Local\atom\bin
C:\Users\[自分のユーザ名]\AppData\Local\atom\app-1.12.6\resources\app\apm\bin
の2つです。

#5. AtomからTerm3をインストール
これでエラーが吐かれたら何が悪いんだろう…
自分はこれで出来たので、これでみんなが幸せになればいいですね (他人事)

今後、大量の加筆修正入ると思います ﾃﾍﾍﾟﾛ
間取リートビューを作ってみよう（設計編）

これは [日本情報クリエイト Engineers Advent Calendar 2016](http://qiita.com/advent-calendar/2016/njc) の11日目の記事です。

# はじめに
「入社1年目だから」というのは言い訳にはなりませんが、
諸先輩社員の皆さんのようにギークな内容を書く自信がないので、
とりあえず動くものを作って~~お茶を濁そう~~アピールしようと思い、
表題のとおり、ストリートビューならぬ「間取リートビュー」なるものを作ってみることにしました。

今回は設計編です。

# 目的
Google ストリートビューのような操作性で、家の中を歩き回れるアプリの作成が最終的な目標ですが、その前準備として、抽象的な表現の仕方を定義（モデル化）します。

# 思想
* 自分の中にあるもので本質的な仕組みを考えてみる（どんと来い、車輪の再発明）
* 手間を惜しむための手間を惜しまない（実装を楽にしたい）
* 古典的なアルゴリズムや数学的表現はどんどん活用する

# 設計
## 基本
* 家の中を歩くルート（道すじ）の表現には、無向グラフを使います。
* 無向グラフの各ノードは写真を撮るポイント（位置）に対応し、各エッジはノード間の移動可能な隣接関係を示します。
* また、各ノードには座標の情報を持たせます。（後々、何かと便利だとろうという算段です）
* すなわち、家の中を歩き回ることを、定義したグラフを辿ることで表現します。

<img width="367" alt="間取リートビュー グラフのイメージ" src="https://qiita-image-store.s3.amazonaws.com/0/112587/0c73233d-ac6c-5c0f-97ce-5c6e95ff9731.png">

やったー！意外に簡単じゃないですか。
これでブラウザ上で家の中を自由に右へ左へ…あれ？
グラフを俯瞰している状態では、どこにノードがあるのか一目瞭然ですが、
ペグマンのように自分がノード上にいる場合「今来た道に対して、どちらの方向か」という情報が欲しくなります。

すぐに思いつく解決策として、
各ノードに「隣接するノードの、今来た道に対する相対的な方角」を持たせる、
方法を思いつきましたが、それは非常に手間です。

ここで基本に戻りましょう。各ノードは自身の座標の情報を持っているのでした。
これを使わない手はありません。

## ノード間の位置関係の表現
ノード $\\mu, \\nu$ を例に考えます。
$\\mu$ から見た $\\nu$ の位置を表すには、
それぞれの座標ベクトル ${\\bf c}\_{\\mu}=(x\_{\\mu}, y\_{\\mu}), {\\bf c}\_{\\nu}=(x\_{\\nu}, y\_{\\nu})$ を使い、
${\\bf v}\_{\\mu\\nu} = {\\bf c}\_{\\nu} - {\\bf c}\_{\\mu}$ を計算すれば良さそうです。

## 画像の初期アングル
ある部屋に南から進入した場合、正面は北です。同様に南西から侵入した場合、正面は北東です。このように、どのノードから移動してきたかによって、画像のアングルを決めてあげなければいけません。
そのために、基準として東西を結ぶ線を $x$ 軸と決め、画像は常に東を向いて撮影することにしましょう。$\\mu$ の直前のノード $\\lambda$ とすると、 ${\\bf v}\_{\\lambda\\mu}$ と $x$ 軸のなす角度分だけ画像のアングルを回転させてやればOKです。

これで、必要最低限の情報を表現する方法が固まりました。（よかった、よかった）

# グラフを利用した効率的な撮影法（今後の課題）
本家ストリートビューを見ていると、本当に路地の隅々まで網羅的に撮影されていることに驚きます。
余談ですが、最近、筆者は自動車を購入しまして、燃費の何たるかが身に沁みている今日此の頃なのですが、
そこへいくとストリートビュー車は、さぞ効率的に道という道を走ってるんだろうと想像します。

前置きが長かったですが、間取リートビューでも家の中を効率的に（最短経路で）撮影したい！というだけの話です。これにより、次のようなメリットが考えられます。

* 広い家やビル、庭の撮影などのケースが出てきた場合に、短時間で撮影が可能に
* 大量の画像を撮影した際に、ノードと画像の対応付けが容易に（撮影順が決まるため）

要は「各ノードを1度だけ通る移動コストが最小なルートを求め」たいのですが、これはまさしく [巡回セールスマン問題](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)  と同じNP困難な問題です。全探索を行う場合のオーダーは $O(n!)$ となり、家の規模によっては容易に計算時間が宇宙の年齢を超えてしまいます。

…が、今回はこちらについては扱いません。。興味のある方は Let's google it!

# まとめ
* ストリートビューならぬ「間取リートビュー」を設計
* 家の中を歩き回るルートは無向グラフで表現
* 各ノードは座標を持ち、その位置関係はベクトルを計算することで表現
* 各ノードの巡回（撮影）順は今回は任意。

# あとがき
あとは実装するだけです。会社から [RICOH THETA S] (https://theta360.com/ja/about/theta/s.html)もお借りしてきました。

実は当初、ノード間の位置関係を表すために、もう2つ複雑怪奇な数式が出てきていたのですが、ノートにメモをとっているうちに、それらが不必要なのだと気づきました。手書きのアウトプットって大事ですね。

それから、もう少し説明の画を増やします。。（反省）
Jenkins + Apache で HTTPS対応したのに400-BadRequestになった

今更感の出尽くした感のある記事ですが、
意外にもググっても直接的な記事が出なかったので書いてみました。

# なにコレ
トラブルシュートの事例です。
Jenkins + Apache を使ってSSL化したのに、とあるリンクを踏むと `http` にリクエストを投げていて`400`エラーが発生した事例です。

# 環境
・Jenkinsを 1090(HTTP)ポートで起動している
・Apacheを  1081(HTTPS)ポート HTTP1080(HTTP)ポートで起動している
※1080は1081にリダイレクトしているだけなので今回の話には出てきません。

# 状況
上記設定の時に、
Jenkinsの管理 > システムの設定 > Jenkins URL の項目を `https` のURLに直して保存ボタンを押した所、

```
Bad Request

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.
```
が出てしまった。
戻るボタンで戻って、再度システムの設定にアクセスするとちゃんとJenkins URLは保存されている。
にもかかわらず、保存ボタンを押したら上記エラーになった。(それ以外にも設定のリロードやジョブの設定の保存でも同じくエラーになった。)

# 調査
調べてみると、 `保存` を押した時に呼び出しているURLが既に `http`  だった。
つまり、
`https://user_server:1081/` で作業していたのに、`保存`を押すと
`http://user_server:1081/` にリクエストを投げてしまっていたので400エラーが出ていた。

# 原因
原因は[これ](http://www.rarul.com/mt/log/2015/05/reverseproxyred.html)

同じ方法で
```
  ProxyRequests  Off
  Header edit Location ^http https
  ProxyPass / http://localhost:1090/
```
と記載する事で、事なきを得るに至った。
devise_error_messages!をbootstrap3で表示しつつrubocopの指摘も回避する

# やりたいこと
-  `devise_error_messages!` を bootstrap3 で綺麗に表示したい
- 下記の記事を参考に実装したが、昔の記事なので rubocop に怒られた
 - http://qiita.com/inodev/items/d61539b86968f1274ef8
 - ボタンにする必要はなかったので自分は `<ul>` と `<li>` タグで表示してます

# rubocopに怒られないように修正

```ruby:devise_helper.rb
module DeviseHelper
  def devise_error_messages!
    return '' if resource.errors.empty?

    html = []
    html << content_tag(:div, class: 'alert alert-danger', role: 'alert') do
      content_tag(:ul) do
        resource.errors.full_messages.each do |error_message|
          concat content_tag(:li, error_message.to_s)
        end
      end
    end

    safe_join html
  end

  def devise_error_messages?
    resource.errors.empty? ? false : true
  end
end
```

こんな感じでエラー表示 | 
--- | 
<img src="https://qiita-image-store.s3.amazonaws.com/0/37385/6d265663-3715-5dd3-9620-744f3a3ce19a.jpeg" width="900"/> |

# rubocop のエラーとその対処法
- http://www.rubydoc.info/gems/rubocop/0.41.0/RuboCop/Cop/Rails/OutputSafety
- `html_safe` ではなく `safe_join` を使いなさいと言われるので、 html変数を文字列から配列に変更
- htmlを直書き（or ヒアドキュメント）するのではなく `content_tag` を使い、タグを入れ子にしたいのでブロックで処理する
- ただし、 `<li>` タグは `concat` で対応

# 参考記事
- http://qiita.com/inodev/items/d61539b86968f1274ef8
- http://qiita.com/mnishiguchi/items/d7a225e89806666e48fc
rubyのArray#compact!でnilを返させない

#はじめに
rubyのArrayには`compact`と呼ばれる配列中のnilを消すメソッドが定義されていますが
**nilのある無いにかかわらず配列に対しての`compact`は「nilの無い配列」が返ります**
しかしながら破壊的メソッドである`compact!`では
**「nilのある配列」に対しての`compact!`は「nilの無い配列」が返りますが
「nilの無い配列」に対しての`compact!`は「nil」が返ります**
前回からの変更が無いときは例外を出す見たいな時は便利ですが
統一性が無いので思わぬ動作を引き起こしかねない気もします
ってことでこの記事では専用の関数を作ります
##(訂正)
「`compact`が統一性がない」という記述になってましたが
統一性がないのは「`compact!`」です
ご指摘ありがとうございました

#実例

```compact1.rb
a=[60,21,nil,'foo',nil,0,'']
p a.compact!
p a.compact!
p a
```

```text:実行結果
[60, 21, "foo", 0, ""]
nil
[60, 21, "foo", 0, ""]
```

このように気持ち悪い結果となります
そこでcompact2を定義してみました

```compact2.rb
class Array
  def compact2!
    delete_if{|item| item.nil?}
  end
end

a=[60,21,nil,'foo',nil,0,'']
p a.compact2!
p a.compact2!
p a
```

```text:実行結果
[60, 21, "foo", 0, ""]
[60, 21, "foo", 0, ""]
[60, 21, "foo", 0, ""]
```
いい感じですね
ついでなので空文字列も消しちゃいましょう

```compact2b.rb
class Array
  def compact2!
    delete_if{|item| item.nil? || item==''}
  end
end

a=[60,21,nil,'foo',nil,0,'']
p a.compact2!
p a.compact2!
p a
```

```text:実行結果
[60, 21, "foo", 0]
[60, 21, "foo", 0]
[60, 21, "foo", 0]
```
消えたことは消えたのですがdelete_ifの書き方が少し気持ち悪い気もします
blank?かempty?が使えればもっとうまく書けそうですが
文字列にしか使えない(Undefined Method Error)なので仕方なさそうです
(個人的には,正規表現によるフィルタなど,拡張しやすい形なので,それはそれでいいのではないかと思っています)
EasyRTCのデモをMacでサクッと試してみる

#[EasyRTC](https://easyrtc.com/ "EasyRTC")のデモをMacで動かした時のメモ
**EasyRTCはオープンソースの[WebRTC](https://ja.wikipedia.org/wiki/WebRTC "WebRTC")ツールキットです。
デモには、ビデオチャット、ボイスチャットなどがあります。**

Node.jsをインストール
https://nodejs.org/ja/

githubからソースを落としてくる
https://github.com/priologic/easyrtc/tree/master

EasyRTCのディレクトリに移動して、Node.jsのパッケージをインストール
```cd EasyRTCのディレクトリ```
```npm install```

サンプルのディレクトリに移動して、Node.jsのパッケージをインストール
```cd server_example```
```npm install```

デモサーバ起動
```node server.js```

サーバにアクセスする
http://localhost:8080/
GoogleMapsでマーカー群が全体に収まるようにカメラポジションをチェンジする

データベースやAPI経由でマーカー情報を取得してマーカーを配置後に全てのマーカーが収まるようにカメラのポジションを変更するにはどうしたらいいのか、そんな便利なもん用意されているはずが無いと思い自作していたのですが発見しました。ショックです。余白まで設定できるなんて素晴らしい。時間を返してほしいｗ

```Java:MainActivty.java

private LatLngBounds getLatLngBounds(HashMap<String,Marker> map) {
    LatLngBounds.Builder builder = LatLngBounds.builder();
    for (Map.Entry<String , Marker> entry : map.entrySet()) {
        builder.include(entry.getValue().getPosition());
    }
    return builder.build();
}

// 地図領域とマーカー群のpadding => 100
LatLngBounds bounds  = getLatLngBounds(mMarkerHashMap);
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds,100));

```
今更だけど・・・本当に今更なんだけどAjaxでerrorが出たときの対処法

コンソールに出して確認するのじゃ。

```js
$( function() {
  $( '#btn' ) .click(
  function() {
    $.ajax({
      url: '404.html',
      type:'POST',
      dataType: 'json',
      success: function(data) {
             alert("ok");
           },
      error: function(XMLHttpRequest, textStatus, errorThrown) {
             console.warn(XMLHttpRequest.responseText);
             console.warn(XMLHttpRequest.status);
             console.warn(textStatus);
             console.warn(errorThrown.message);
         },
      complete : function(data) {
             alert("finish");
         }
    });
  });
} );
```

こちらが解法としてベスト。ありがとうございます。
http://www.koikikukan.com/archives/2014/10/01-012345.php
書き方をアップデートしていかないとね。。。「対応してないブラウザがある」との却下は苦い夏の思い出。。。
http://www.koikikukan.com/archives/2012/10/02-005555.php
http://api.jquery.com/jQuery.ajax/
おぷすたディストリビューションビジネスは何処へ向かうのか

この記事は[OpenStackアドベントカレンダー 2016](http://www.adventar.org/calendars/1739)の12月6日のエントリーです。

#私はナニモノか
Hewlett Packard Enterprise の Asia Pacific & Japanリージョンで、IaaS/PaaSなどのクラウド技術の提案/設計/構築を行うチーム（Helion Professional Services）に所属しています。HPEは正直であることを最上の美徳としている会社でして、身分を明かさずになにか書くことを良しとしないので一応念のため。
以下は個人の意見であり、会社の見解ではもちろんありません。これも念のため。

#HPEとはナニモノか
サーバ/ストレージなどのHWベンダとしてはよく知られてますが、Helion OpenStackという自社ディストリビューションを持っていたり、けっこうクラウドにも力入れてるんだぜ。パブリッククラウド事業からは撤退しましたけど、オンプレのIaaS/PaaSとかハイブリッドクラウド作るなら全部任せろ、な会社です。愉快な仲間に囲まれて毎日ハッピーです。

#Rock'n'Roll is Dead?
今年の6月に、こともあろうかMirantisの公式ブログに["Infrastructure Software is Dead"](https://www.mirantis.com/blog/infrastructure-software-is-dead/)という衝撃的なタイトルの記事が掲載され、それを引用する形でRackSpaceの公式ブログにも["OpenStack Is Dead! Long Live OpenStack!"](http://blog.rackspace.com/openstack-dead-long-live-openstack)という記事が掲載されました。おぷすた界隈ではかなり話題になっていましたので記憶に新しいかと思います。
刺激的な表現ではありましたが、ざっくり言うと**「OpenStackは製品じゃねーだろ。大事なことはそれを使ってどんなクラウドを作り上げるかだ。」**ということを伝えているのだと思います。
私もプロフェッショナルサービスを生業とする身なので、**(わかる)**と思いました。「製品メーカーとして責任を取れ」系のお客さんとの噛み合わなさには日頃悩まされてますので・・・。

#ContributionとDistribution
自前のサービスを成立させるためにOSSを活用することはもはや企業の生き残りの条件と言っても過言ではないと思います。とはいえエンタープライズのOSSに対する理解はまだまだ浸透しておらず、ベンダー依存度が高いという状況が日本に限らず残っていると思います。まあ僕らそれで食ってるわけですが、OSSのサブスクリプションに対して「製品買ってるんだからタダで直せ」ってのが成立するわけもなく。
ぶっちゃけ、ガチなエンタープライズビジネスを主体にしているベンダー企業が、OpenStackに限らずOSSのディストリビューションビジネスを手掛けるってことは簡単じゃないんだなー、と実感しています。ていうかOSSのエンタープライズ向けディストリビューションをビジネスの中心に据えて成功している大企業ってRedHatとSUSEぐらいじゃないですか？
Contribution（投資）とDistribution（回収）をうまくバランスさせて、かつお客さんのわがままに振り回されず、エコシステムを確立しつつアップストリームとダウンストリーム両方の品質を向上していくってのは容易じゃないです。特にそれがOpenStackのような~~何でもあり異種格闘技バトルロイヤル闇鍋ちゃんぽんミックスジュース~~許容性の高いアーキテクチャの場合は。

#で、HPEさんどうなのよ
Helionのビジネス自体は好調な感じなのですが、["Watch your PaaS (and IaaS) – SUSE acquires OpenStack and Cloud Foundry technology from HPE"](https://www.suse.com/communities/blog/acquisition-news-suse-acquiring-iaas-and-paas-technology-and-talent-from-hpe/)という発表がまずSUSEからありましたね。HPEさんはこれ系のメディアアピールが~~ド下手~~控えめなので、公式は[こんなシンプルなニュースリリース](https://www.hpe.com/us/en/newsroom/news-archive/statement/2016/11/HPE-Partners-with-SUSE-to-Provide-Best-in-Class-Hybrid-Cloud-Offerings.html)にとどまってますが・・・
これだけ見て 

- ん？Helionなくなっちゃうの？
- HPEはOpenStackやめるの？
- あの人辞めるの？

みたいな憶測が一部で飛び交ってたりしますが、**全くそんなことはない**のでご安心を。もともとHPEとSUSEの親会社であるMicroFocusとの間でソフトウェア事業の統合/再編を行っており、その中での動きです。
あんま勝手なこと書くと怒られるので（それがなんぼのもんじゃいって感じではありますが）、ざっくり言うと

- OSSのアップストリームへのコントリビュートはSUSEに寄せる
- HPEはエンタープライズ市場への対応に注力する

って感じですね。Helion OpenStackもHelion Stackato(Cloud Foundry)も継続してHPEのディストリビューションとして販売/サポートを行います。OSSの開発者（コントリビューター）はSUSEに籍を移す人が多いですが、ディストリビューターとして必要な開発チームはHPEにも残ります。

#どういうことか
たぶん冒頭にあげたMirantisやRackspaceの言っていることはある意味真実で、「OSSプロジェクトのあるべき姿」と「それを使って作り上げるシステムのあるべき姿」は必ずしも一致するわけではないのです。
OSSの利点であり美点は、**「そこにソースコードがあるからなんだってできる」**ということだと思うわけです。それが、ユーザとして自社に必要な機能をカスタマイズすることであったり、エンタープライズ向けディストリビューターとして市場のニーズに合ったエコシステムを作り上げることだったり。そしてアップストリームへのコントリビューションはどんな立場からもできます。
なので、製品を作って売る、という単純な話ではなくて、それぞれの会社が得意なことをやる、という形に成熟してきたのかなと思います。

#まあ、なんだ
OpenStack面白いからもっと盛り上げていこうぜ。
メリークリスマス。
Homebrewでインストールしたmysqlのbind-addressを変更して外部のホストからアクセスできるようにする

ハマったのでメモ

Homebrewでmysqlをインストールするとデフォルトでは`bind-address=127.0.0.1`で起動しています。
`ps auxww|grep [m]ysqld`で起動中のmysqlのプロセスをオプション付きで確認できます(`--bind-address=127.0.0.1`となっている)。

この設定は`/usr/local/Cellar/mysql/5.7.16/homebrew.mxcl.mysql.plist`に記述されています！
`/etc/my.cnf`を変更しても変わりませんでした！！

```
<string>--bind-address=127.0.0.1</string>
```
を

```
<string>--bind-address=0.0.0.0</string>
```

に修正してサービスを再起動！

```
brew services restart mysql
```

これで`--bind-address=0.0.0.0`で起動します。

最後まで読んでいただいてありがとうございました。

参考: http://dba.stackexchange.com/questions/55958/cant-remote-access-mysql-server-running-on-mac-os-x
jQueryのwhenについて

#$.whenが同期処理されない時

```javascript
var hoge = {};
$.when(
  hoge = new CLASS()
).done(function(){
  console.log('即座に実行される');
});
```

hogeのコンストラクタでajaxをするインスタンスを生成した後で、もう一個同じインスタンスを作ろうとしたら、気づいた。
同じURLにajaxしてたんだけど、最初のajax通信でエラーが出た。
最初のajax中に次のajaxが始まるせいみたい。

なんでだろうと思ったら、
$.when()の中の処理は全部同期処理できるのかと思ったら、違うらしい。
whenの中でdeferredオブジェクトを返さないと、即座にdone()が実行される。
よく考えれば、当たり前ですね〜。
参照：https://api.jquery.com/jquery.when/

どっかのサイトに\$.when()の中に$().animate書いて同期処理できるって書いてあったけど、animate()はdeferredを返すのかな？

```javascript
こんな感じのを見た
$.when(
  $().animate(),
  $().animate()
).done(function(){
  console.log('アニメーション完了後に実行される');
});
```
（まとめ）エンジニアのためのリーンキャンバスを用いたサービスの作り方

こんにちは！

[株式会社LITALICO](http://litalico.co.jp/) CTOの岸田崇志です。
『[LITALICO Advent Calendar 2016](http://qiita.com/advent-calendar/2016/litalico)』6日目の記事となります！

今年のAdventcalenderではサービスの設計フレームワークを前編・後編に分けて紹介しています。

<TABLE><TD>
<a href="http://asagao.hatenablog.jp/entry/2016/11/30/220000">
<img width="200" alt="logo_1" src="https://qiita-image-store.s3.amazonaws.com/0/34936/39b56e5c-77a1-d13d-6f3d-b8f693bc913b.png"></a>
</TD><TD>
<a href="http://asagao.hatenablog.jp/entry/2016/12/06/170000">
<img width="200" alt="logo_1" src="https://qiita-image-store.s3.amazonaws.com/0/34936/fe45a558-a062-7d03-b9bc-f7894e117371.png"></a>
</TD></TABLE>





# リーンキャンバスを知ろう
[前編](http://asagao.hatenablog.jp/entry/2016/11/30/220000)ではリーンキャンバスやAARRRなどについて説明しています。
リーンキャンバスを各項目を埋めていくだけでなく、ポイントを抑えながら手順を追って記述していく方法をまとめています。

詳細は[サービス開発は9割が失敗する - 6つの診断パターンからみるサービス設計がうまくなるコツ(前編)](http://asagao.hatenablog.jp/entry/2016/11/30/220000)を御覧ください。

<img width="400" alt="スクリーンショット 2016-11-22 16.12.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/34936/f5642dcc-c5f6-a4ca-e6d1-eef0c46e361b.png">


# コンテンツを設計していこう

[後編](http://asagao.hatenablog.jp/entry/2016/12/06/170000)ではリーンキャンバスから具体的に機能に落としこんでいくプロセスを説明していきます。

![contents_item.png](https://qiita-image-store.s3.amazonaws.com/0/34936/34e2c01e-62af-fc0d-6bae-7275e3a74fea.png)

サービス全体はリーンキャンバスで設計すればよいのですが、そこから先どうやっていけばいいんだろう？という意見をよく耳にします。

そこで、前編で説明した「リーンキャンバス」に加え「遷移概要図」「モチベ天秤」について紹介します。

詳細は[サービス開発は9割が失敗する - 6つの診断パターンからみるサービス設計がうまくなるコツ（後編）](http://asagao.hatenablog.jp/entry/2016/12/06/170000)を御覧ください。

エンジニアの方も知っておくとサービス開発の際に役立つことが多いと思いますのでぜひご覧下さい。
幼女画像判定システムLolinco フロント編

この記事は、[SLP_KBITその２ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/slp_kbit2)の6日目の記事です。

# はじめに

**※ 私はロリコンではありません**

今回は、SLPで開催されたハッカソンで開発した、幼女画像判定システムLolincoについて説明したいと思います。
ソースコードはこちら (https://github.com/SLP-KBIT/Lolinco) にあります。
このシステムは、@uchiyuと一緒に開発したもので、記事も担当ごとに分割しています。

# Lolincoとは

Lolincoとは、タイトルにもある通り、**与えられた画像に幼女が写っているかどうかを判別するシステム**です。
色々と内部を解説する前に、まずはシステムの動作を見てもらいたいと思います。

## トップページ

Lolincoのトップページです。
「ファイルを選択」から判別したい画像ファイルを選択します。
「ロリ判定」ボタンを押すと、幼女が写っているかどうかが判別されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/152449/abea1ba3-c416-8b92-d6cd-26bb12564d8a.png)

## 幼女が写っていなかった場合

悲痛な表情とともに、結果が通知されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/152449/d2322e3e-e686-2d10-dca7-c2d17cd399c5.png)

## 幼女が写っていた場合

感極まります。

![image](https://qiita-image-store.s3.amazonaws.com/0/152449/beeb55e2-af9e-fc36-2109-cbb8dbf61a50.png)

## 複数の人物が写っていた場合

一人だけ……一人だけ写っていてもいいんです……それで満足なんです……
(変なものも顔だと認識されていますが気にしないように)

![image](https://qiita-image-store.s3.amazonaws.com/0/152449/d130b7b0-06fb-6372-a26a-42e38333b68c.png)


# Lolincoの開発

Lolincoを開発する上でのタスクは、以下のように分担しました。

- 教師データの作成(@gembaf)
- 教師データを基にした機械学習(@uchiyu)
- 任意の画像の判別(@gembaf)

ここからは、自分の担当分である、**教師データの作成**と、**任意の画像の判別**について解説していきます。

## 教師データの作成

教師データの作成手順は、大きく分けると以下のようになります。

1. 画像を収集
2. OpenCVを利用して、画像から顔を抽出
3. 抽出された顔画像を、**ロリ**と**その他**に分ける

![image](https://qiita-image-store.s3.amazonaws.com/0/152449/a794c024-7c3b-f51a-3b74-ddbd905f85c8.png)

画像から顔を抽出する部分は、以下のブログを参考にさせて頂きました。

- [OpenCVで顔認識を行い、顔の部分だけトリミングして保存する【Python】](http://famirror.hateblo.jp/entry/2015/12/19/180000)

## 任意の画像の判別

任意の画像の判別方法は、大きく分けると以下のようになります。

1. アップロードされた画像から顔を抽出
2. 学習済みのアルゴリズムにより、抽出された顔画像がロリかどうかを判別(@uchiyu担当分)
3. 判別された結果を基に、システムとして表示

# おまけ

教師データを作成するために、大量の画像を収集する必要があるのですが、今回はGoogleの画像検索を使いました。
と言っても、画像検索のページを、Googleが用意したAPIを使わずに、機械的に収集するのは、どうやら規約違反のようです。
そのため、長時間の開発でテンションが上っていたせいか、今回全て手作業で集めました。
その際に得られた知見もシェアしたいと思います。

## 検索ワード

教師データとしてのロリ画像を集めるために、最適な検索ワードを模索しました。
結果として、「(年齢) 女の子」で検索すると、いい感じの画像が出てきました。
今回は、5歳～12歳の女の子を対象に画像を収集しました。
もちろん、教師データにはハズレのデータも必要なので、そのあたりは適当に画像検索しました。

以下に、試行錯誤した結果をまとめます。

| 検索ワード | 所感 |
|---|---|
| (年齢) 女の子 | いい感じ |
| (年齢) 女の子 画像 | 上記と変わらない |
| (年齢) 少女 | 写ってはいるが、顔が判別しづらい物の割合が多い。<br />ニュースで出てくる「紛争地域の子供」みたいな画像が増える |
| ロリ 女の子 | ロリっぽく見える大人が増える。<br />二次元の画像も増える |
| ロリ 女の子 画像 | 二次元(R18)の画像がすごく増える |
| 女の子 ロリ 画像 | 三次元(R18)の画像がすごく増える |

とりあえず、**ロリ**と**画像**が組み合わさるとヤバイということが分かりました。

# おわりに

今回は、開発したWebアプリについてのお話でした。
具体的な機械学習の部分が気になる人は、明日の@uchiyuの記事を楽しみにしておいて下さい。
また、Lolincoは、教師データの数が少ないせいか、精度がそんなによくありません。
風景や服を、顔と認識してしまうこともよくあります。
ただ、機械学習や画像認識については、発想次第でまだまだ面白そうなものが作れそうなので、今後も興味を持っていたいと思います。
みなさんも、是非一度触れてみて下さい！
ビックデータ＠IoT

　製造現場の機器から、日常生活で使用するデバイスまで現在社会を支える様々なモノはインターネットとつながり実世界のデータは増えて続けています。IoTは、提供する価値によって
１.モノ型：「モノがネットワークに繋がること」自体に価値がある。
２.データ型：「集積されるビッグデータ活用」に価値がある
3.課題解決型：ITでは対応できなかった企業課題解決に価値がある
３種型に分けることができます。
![1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/153266/ee6098c7-3438-3446-3485-d005a6c90d0c.jpeg)

膨大なデータを価値にする
　IoTにより、収集された大量のデータを効果的に活用することに期待されています。それに応じるのが、ビッグデータ活用です。
株式会社日昇テクナロジーは長年、組み込み経験活用を支える見守りシステムに取り込んできました。そのゲートウェイ技術を活用したソリューションや、
画像処理ソリューション製品などのプラットフォーム製品を提供しております。これから、介護施設管理データ、患者の健康データによって介護施設と患者を支援します。
![bigdata.jpg](https://qiita-image-store.s3.amazonaws.com/0/153266/edc53f5d-56be-f47f-ec7b-b34623364229.jpeg)

活用事例：http://www.dragonwake.com/article/show/id/10.html
SwiftでiPhone、iPadなどのデバイス判定をする方法

iPhone、iPadなどのデバイス判定をしたいときはこんな感じでやれば判定できます。

```swift:Swift
if UIDevice.current.userInterfaceIdiom == .phone {
   // 使用デバイスがiPhoneの場合

} else if UIDevice.current.userInterfaceIdiom == .pad {
   // 使用デバイスがiPadの場合

}
```

ちなみに、Switch文で書くとこのような分岐になります。
iPhone、iPad以外の分岐もあわせて書いてみます。

```swift:Swift
switch UIDevice.current.userInterfaceIdiom {
case .phone:
    // iPhone、iPod touchの場合
    
case .pad:
    // iPad端末の場合
    
case .tv:
    // Apple TVの場合
    
case .carPlay:
    // CarPlayの場合
    
case .unspecified:
    // 上記以外の端末の場合
}
```

iOSシミュレーターを使用しても、この分岐を判定してくれるので便利ですね。

CarPlay用のアプリを作ることはなかなかないかとは思いますが、iPhone、iPad以外のデバイスで作成するときにはデバイス判定が役立つときがあるかもしれませんね。

参考：[UIUserInterfaceIdiom - UIKit | Apple Developer Documentation](https://developer.apple.com/reference/uikit/uiuserinterfaceidiom)

**2018/07/30 追記・修正：全体的に書き換え**
Reactレガシーブラウザ対応

Reactでコードを書くにあたり、モバイルのレガシーブラウザ対応に関する調査内容を記す。
なお、React経験1ヶ月もないので有識者ではない。

## 古い端末対応
i0S6, 7, android4系端末対応のため下記導入

```
npm install --save-dev es5-shim es6-shim babel-preset-es2015-loose
```

.babelrcに`es2015-loose`追記

```
{
  "presets": ["es2015-loose", "es2015", "react"]
}
```

## Promise

adnroid4系でPromise動かないからpolyfillいれる。
promiseがうごかないので下記の取得系のパッケージでバグる。ハマル。

- [axios](https://www.npmjs.com/package/axios "axios")
- [react-lazy-load](https://www.npmjs.com/package/react-lazy-load "react-lazy-load")


### パッケージ導入
下記をインストール

```
npm install --save es6-promise
```

インストール後、これをルートのjsxに入れればandroid4系の標準ブラウザでpromiseが動く。

```src/index.jsx
import 'es6-promise/auto';
```

詳細はここを参照
[stefanpenner/es6-promise: A polyfill for ES6-style Promises](https://github.com/stefanpenner/es6-promise "stefanpenner/es6-promise: A polyfill for ES6-style Promises")

## メモ
babelに下記を食わして、コードに影響を与えず対応したかったが、どうもまくいかなかった。

babel-plugin-es6-promise https://www.npmjs.com/package/babel-plugin-es6-promise

## 参考
- [react/08-working-with-the-browser.ja-JP.md at 67f8524e88abbf1ac0fd86d38a0477d11fbc7b3e · facebook/react](https://github.com/facebook/react/blob/67f8524e88abbf1ac0fd86d38a0477d11fbc7b3e/docs/docs/08-working-with-the-browser.ja-JP.md "react/08-working-with-the-browser.ja-JP.md at 67f8524e88abbf1ac0fd86d38a0477d11fbc7b3e · facebook/react")
- [axios not work on android 4.4.2 · Issue #188 · mzabriskie/axios](https://github.com/mzabriskie/axios/issues/188 "axios not work on android 4.4.2 · Issue #188 · mzabriskie/axios")
- [Can I use... Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=promises "Can I use... Support tables for HTML5, CSS3, etc")
- [[フロントエンド] Reactを古いブラウザに対応させようと色々と苦労したけど、なんとか対応できた話 - YoheiM .NET](http://www.yoheim.net/blog.php?q=20160704 "[フロントエンド] Reactを古いブラウザに対応させようと色々と苦労したけど、なんとか対応できた話 - YoheiM .NET")
- paulmillr/es6-shim: ECMAScript 6 compatibility shims for legacy JavaScript engines https://github.com/paulmillr/es6-shim
[Windows][git] gitデーモンをサービスとして動かす

Windowsでgitデーモンを動かし、git://プロトコルでアクセスできるようにする手順です。

クライアントがWindowsだけならば、ファイル共有へレポジトリを作ればよいのですが、Windows以外もいるのでこんな手順にしました。

# 準備

## Chocolateyをインストールする

いろいろ簡単にインストールするために、[Chocolatey](https://chocolatey.org/)をインストールします。

## Git for Windowsとnssmをインストールする

gitとnssmをインストールします。

nssmは任意のexeをサービス化できるツールです。

```
C:\> choco install git nssm
```


# gitデーモンを動かす手順

## 手順 1 レポジトリ置き場を作る

公開するレポジトリを置くディレクトリを作成します。

```
C:\> mkdir h:\export\repos
```

## 手順 2 gitデーモンをサービスとして登録する

```
C:\>nssm install git-daemon "c:\Program Files\Git\cmd\git.exe" "daemon --export-all --enable=receive-pack --base-path=h:\export\repos"
```

## 手順 3 ファイアウォールでポートを開放する

TCP 9418番ポートを開放してアクセスできるようにします。

# レポジトリを作成する手順

レポジトリに書き込みできるようにするためには、ちょっとひと手間必要です。

## レポジトリを作成

これはいつもどおりです。

```
C:\> git init --bare h:\export\repos\test.git
```

## 空ファイルを作成

このファイルがないとpushできないです。

```
C:\> echo > h:\export\repos\test.git\git-daemon-export-ok
```
[Homestead][PDOException]   SQLSTATE[HY000] [1862] Your password has expired. 

0. homestead環境を新規に作成して、新しいプロジェクトを作成したぜ
1. databaseファイルを作成したぜ
2. table作るぜ

```
$ php artisan migrate

  [PDOException]
  SQLSTATE[HY000] [1862] Your password has expired. To log in you must change it using a client that supports expired passwords.
```

3． ...なんじゃこりゃ

```
$ mysql -u homestead -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.7.9

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

4.入れるやないか！
5.試しにsqlを

```
mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
```

6.リセットしないといけないらしい。
7.リセット

```
mysql > ALTER USER 'homestead'@'localhost' IDENTIFIED BY 'Secret';
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
```

8.き、効かないだと！
9.どうやらこっちらしい

```
mysql> SET PASSWORD = PASSWORD('Listing');
Query OK, 0 rows affected, 1 warning (0.00 sec)
```

＃3~5を３回ループしました。

A. パスワードを変更して fire!!

無事完了。

[参考]
ver5.6〜入ってるみたいですね
https://dev.mysql.com/doc/refman/5.6/ja/password-expiration-sandbox-mode.html
iOS シュミレータ・実機からローカルの開発サーバに繋いで開発する

## iOS シュミレータの場合

iOS 側のAPI Endpoint を

- http://127.0.0.1:3000/

にすることで、ローカルの開発サーバに繋いで確認しつつ開発が出来る。サブドメインをつけたかったら lvh.me を利用する。

lvh.me は prefix に何をつけても、127.0.0.1 を返してくれる便利ドメイン。

- http://api.lvh.me:3000/ とか

## iOS 実機の場合

開発機と同一ネットワークに居る条件。ローカルの開発サーバの待ち受けをどの IP からも許可する。

例えば Rails なら以下で許可する。

```
$ rails s -b 0.0.0.0
```

続いて iOS 側の API Endpoint を変更する。まずはローカルのネットワークの IP を確認。

```
$ ipconfig getifaddr en0 # en0 は適切に変更する
192.168.0.10
```

API Endpoint に [xip.io](http://xip.io/) を使う。xip.io は 192.168.0.10.xip.io で名前を引くと、その IPアドレスを返してしてくれる便利ドメイン。Basecamp が運営してる。

```
$ dig 192.168.0.10.xip.io
; <<>> DiG 9.8.3-P1 <<>> 192.168.0.10.xip.io
(略)
;; QUESTION SECTION:
;192.168.0.10.xip.io.           IN      A

;; ANSWER SECTION:
192.168.0.10.xip.io.    253     IN      A       192.168.0.10
```

なので、それを利用して API Endpoint にセットする。

- http://192.168.0.10.xip.io:3000/ # 開発機の IP
- http://api.192.168.0.10.xip.io:3000/ # サブドメインこみ

なお、サブドメインをつけた場合、最初のアクセス時には名前解決に失敗する。数秒たつと成功する(裏側で何らかのDNSの設定を動的追加してるっぽい)ので注意。
AWKワンライナーメモ

# **はじめに**
あまりAWK使ったことないので使って便利だったワンライナー系のテクを書き溜めていこうというそういうmemo的なものです！

# **目次**
- ログから最大値を抜き出す
- ユーザー毎のCPU使用率を集計

# **ワンライナー集**
## ログから最大値を抜き出す
```text:/var/log/sa/sa16
23時00分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
23時10分01秒     all      0.19      0.41      0.34      0.24      0.00     98.82
23時20分01秒     all      0.19      0.62      0.45      1.78      0.00     96.96
23時30分01秒     all      0.20      0.34      0.41      0.77      0.00     98.28
23時40分01秒     all      0.20      0.24      0.39      0.22      0.00     98.94
23時50分01秒     all      0.19      0.26      0.30      0.25      0.00     98.99
.
.
.
たくさん
```

このログの中から`iowait`の最大値を抜き出したい場合

```shell-session
[root@centos ~]# sar -f /var/log/sa/sa16 | awk 'NR==1 {max=$6} {if($6 > max) max = $6} END {print max}'
10.61
```

## ユーザー毎のCPU使用率を集計
```shell-session
[root@centos ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  19352  1380 ?        Ss   11:30   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    11:30   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    11:30   0:01 [migration/0]
root         4  0.0  0.0      0     0 ?        S    11:30   0:01 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S    11:30   0:00 [stopper/0]
root         6  0.0  0.0      0     0 ?        S    11:30   0:00 [watchdog/0]
root         7  0.0  0.0      0     0 ?        S    11:30   0:00 [migration/1]
root         8  0.0  0.0      0     0 ?        S    11:30   0:00 [stopper/1]
root         9  0.0  0.0      0     0 ?        S    11:30   0:00 [ksoftirqd/1]
~~~省略~~~
```

`ps aux`の結果からユーザー毎のCPU使用率を集計する場合

```shell-session
[root@centos ~]# ps aux | awk '{ if(NR>1){p[$1] += $3; n[$1]++ }}END{for(i in p) print p[i], n[i], i}'
0 1 ntp
0 1 rpc
0 1 dbus
0 2 68
0 5 postfix
0 1 rpcuser
7.1 376 root
199.8 467 webmail
```

# **参考**
- https://hydrocul.github.io/wiki/commands/awk.html
- http://d.hatena.ne.jp/sleepy_yoshi/20110918/p1
- [実用 awk ワンライナー](http://qiita.com/b4b4r07/items/45d34a434f05aa896d69)
Railsでサービス構築するときは時間を制御できる仕組みを入れておくと大変はかどる

Rubyコードの開発中に、時間を変更するときには、`timecop` gem が便利である。

timecop - Github
https://github.com/travisjeffery/timecop

例えば、 `Timecop.travel(t)` を実行した時点で、そのRubyインスタンスの現在時刻が変わり、かつ、`t`の時点から時間が進む。
`Timecop.freeze(t)` を実行すると、現在時刻が`t`で固定となる。
などなど、いくつかのメソッドが用意されている。
（`t`はTimeクラスのインスタンス）
Railsと組み合わせると、開発チームが共用で使っている開発サーバの時間を変更・偽装・シミュレート出来て便利である。ちょっとしたサービスなら、時間をからめたテストが必要だったり、イベントやキャンペーンの確認に使えるだろう。
`Timecop.travel` を活用するためのちょっとしたスニペットをご紹介。

# ページを作ろう
`timecop`単体では、UIは提供していない。
ちょっとした規模のサービスやアプリケーションなら、開発用のデバッグページがあったり、管理用のページがあるだろう。
Viewから時間を変更できるような画面を作っておけば、開発者以外のチームメンバーでも簡単に時間を変えられる。
当然ながら、**本番環境では、本記事のスニペットは全部無効になるように実装しておくのが良い。**

```rb
class DebugController < ApplicationController
  def update_time
    if params[:time].present?
      Timecop.travel(Time.parse(params[:time]))
    else
      Timecop.return
    end
  end
end
```

# 例外に備えよう
とは言え、時間をごまかしたくない例外もある。
例えば、`aws-sdk`だ。aws-sdk を使ってS3にアクセスするとき、ほんとうの時間とリクエスト時のタイムスタンプのズレが大きいと、下記のようなエラーが出る。

```
The difference between the request time and the current time is too large. (Aws::S3::Errors::RequestTimeTooSkewed)
```

他にも、なにか外部サービスを利用していて時間をごまかしたくない時にどうするか・・・。aws-sdkにモンキーパッチを当てようにも、`Time.now` を参照している箇所が多すぎる。
下記のような黒魔術で、呼び出し元によって`timecop`を無効化させることができる。

```ruby
class Time
  class << self
    def now_wrap
      if (caller || []).first.match('aws-sdk')
        now_without_mock_time # return real time
      else
        mock_time || now_without_mock_time # return mock time or real time
      end
    end
    alias_method :now, :now_wrap
  end
end
```

- 現時点の`timecop`のバージョンでは、非公開APIだが内部的に `mock_time` メソッドと `now_without_mock_time` メソッドをTimeクラスに生やしているのでこれを利用して現実世界の正しい時刻を得る。
- Rubyの `Kernel#caller` を使ってコールスタック（呼び出し元）に`aws-sdk`が含まれるか判定する。呼び出し元によって暗黙的に動作を変えるのは、極悪と言っても良いプログラミングスタイルである。通常の状況でヤッてはいけない。

# 再起動に備えよう
`timecop`単体では、永続化機能は提供していない。ページを作るだけでは不十分で、デプロイ契機で揮発する。
ファイルシステムでも、DBでも、なんでも良いので、永続化させちゃえば良い。

### 設定するところ

```rb
# 入力値を保存
redis.set("timecop:travel_time", params[:time])
# 現在のリアル時刻も一緒に保存
redis.set("timecop:travel_started_time", Time.now_without_mock_time.to_s)
# アプリケーションサーバを再起動させる。下記コマンドは Unicornな想定。
system 'kill -s USR2 `cat /var/www/hogehoge-pj/shared/tmp/pids/unicorn.pid` &'
```
- 現代のアプリケーションは、マルチプロセスで動くことは当たり前である。Unicornもワーカープロセスの数を自由に設定できるし、開発環境でもマルチで動作検証しておくべきだろう。複数のプロセスに`timecop`を一気に適用させるには、再起動させるのが手っ取り早い。再起動の方法は環境に依存する。

### Rails起動時（application.rbとか）にやること

```rb
tt = redis.get("timecop:travel_time")
tst = redis.get("timecop:travel_started_time")
if tt && tst
  a = Time.parse(tt)
  b = Time.parse(tst)
  # ここで時間変更。設定した日次に、経過時間を加算する
  Timecop.travel(a + (Time.now_without_mock_time - b).to_i.seconds)
end
```
起動時に毎回同じ時刻に .travel するのではなく、差分計算をして経過時間をシミュレートしたほうが、非エンジニア的にはうれしい。

---

# まとめ

Ruby は標準のメソッドもばんばん書き換えられるので、たまに苦しめられるけど、楽しい。
今回は `timecop gem` を紹介したが、これを使わずにDIYするのも容易いと思う。
[iOS]MetalでGPUコンピューティング (3) MTLDevice


この記事は、Metal Advent Calendar2016の6日目の記事です。

以前にMetalのGPUコンピューティングについて解説記事を書きました。
[[iOS] MetalでGPUコンピューティング (1)](http://qiita.com/yuky_az/items/ece9b64befc635e89f1a)
[[iOS] MetalでGPUコンピューティング (2)](http://qiita.com/yuky_az/items/ce5920f28c08e743418b#_reference-cc4434da198d861bba61)
 本記事からは、何回かに分けてAppleが提供するGPUコンピューティングのサンプルコードの解説をしたいと思います。

Appleが提供するMetalのサンプルコードにMetalGameOfLifeというものがあります。
 [MetalGameOfLife](https://developer.apple.com/library/content/samplecode/MetalGameOfLife/Introduction/Intro.html)

![IMG_5933.PNG](https://qiita-image-store.s3.amazonaws.com/0/35297/fa9b4e62-91a6-83fb-c60c-3666fc44fdf1.png "IMG_5933.PNG")
（実行画面）

いわゆる[ライフゲーム](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0)のアプリですが、Metalの並列プログラミングについての良いデモとなっています。
今後このサンプルコードをベースに、Metalの並列プログラミングの解説を行います。

このサンプルコードは、主に以下のファイルで構成されています。

AAPLRender.h
AAPLRender.m
AAPLViewController.h
AAPLViewController.m
Sharder.metal

このうち、AAPLRender.mには並列コンピューティング及び描画のCPU側のロジックが、Shader.metalには頂点シェーダー、フラグメントシェーダー、GPUコンピューティング用のシェーダーが書かれています。

まず、MTLDeviceについて解説を行います。
MTLDeviceは単一のGPUのインターフェイスです。
MTLDeviceなどのMetal関連の機能の多くはクラスではなくプロトコルなのですが、Metalが動作するデバイス毎にオブジェクトの型が異なるので、実装よりもインターフェイスを重視したためと思われます。
（参考）[objc.io](https://www.objc.io/issues/18-games/metal/)

サンプルコードではプロトコルを実装したオブジェクトの生成をAAPLViewController.mで行なっています。
[MTKView](https://developer.apple.com/reference/metalkit/mtkview)がMTLDeviceを実装したオブジェクトをプロパティとして持つ必要があるからです。

```Objective-C:AAPLViewController.m
@property (nonatomic, weak) MTKView *metalView;
...
self.metalView = (MTKView *)self.view;
...
self.metalView.device = MTLCreateSystemDefaultDevice();

```

AAPLRender側ではこれをViewごと受け取り、weakなプロパティに入れておきます。

```Objective-C:AAPLRender.m
@property (nonatomic, weak) id<MTLDevice> device;
...
_device = _view.device;

```

この_deviceを用いて、以下のプロトコルを実装したオブジェクトが生成されます。

* MTLLibrary
* MTLCommandQueue
* MTLBuffer
* MTLRenderPipelineState
* MTLTexture
* MTLComputePipelineState
* MTLSamplerState

このように、MTLDeviceは様々なMetal関連のオブジェクトの生成に用いるとても重要なプロトコルなのです。

ちなみに、GPUの名前はMTLDeviseのnameプロパティで取得することができます。

```
NSLog(@"Devise name: %@", self.metalView.device.name); 
```

例えばiPhone6 Plusの場合、上記はApple A8 GPUと出力されます。

今回はライフゲームのサンプルコード内におけるMTLDeviceの解説を行いました。
次回以降、サンプルコードの他の箇所についての解説を行なっていきます。
MacでDocker環境をインスコした

## 対象者

- @luccafort 
- Dockerを自分のMacにインストールしたい人
- DockerとやらがあるがVagrantと何が違うのかわからない人
- Docker ToolboxとDocker for Macがなにかわからない人

## 概要

ただmacOS Sierraでもきちんと動いたよ！というただの報告です。
公式サイト通りにやれば問題なく立ち上がるかと思うのでぼくのような雑な内容よりはそちらを参照したほうが有益です。

## 環境

- MacBook Pro（Retina, 15-inch, Late 2013）
- macOS Sierra(version 10.12.1)
- VirtualBox(version 5.0.30 r112061)
- メモリ 16GB

## 要求スペックとか

以下、[公式サイト](https://docs.docker.com/engine/installation/mac/)から抜粋。
スペックなどは問題になる人が少なそうですが、VirtualBoxのバージョンが4.3.30以下だとエラーになるみたいなので念のためチェックしておいたほうがいいかもしれません。

> ###### Requirements
> 
> - Mac must be a 2010 or newer model, with Intel’s hardware support for memory management unit (MMU) virtualization; i.e., Extended Page Tables (EPT)
> - macOS 10.10.3 Yosemite or newer
> - At least 4GB of RAM
> - VirtualBox prior to version 4.3.30 must NOT be installed (it is incompatible with Docker for Mac). Docker for Mac will error out on install in this case. Uninstall the older version of VirtualBox and re-try the install.



## 必要なもの
- Docker for Macが必要なので[公式からDL](https://docs.docker.com/docker-for-mac/)してくる
    - Docker ToolboxはどうやらDocker for Mac以前に使用されていたアプリケーションみたいですね。詳しくないのでいや全然ちげえよ！とかあったら編集リクエストください。

## インストール

基本的に公式サイトの各ステップ毎に実行したところ問題なく起動しました。
ここで公式と同じことを書いても仕方がないかなと思いますのでその辺は割愛します。

## 感想

インストール後にちょっと感動というかすげー！となった点が2つほどあったので補足しておきます。

### 気軽さ

```docker run -d -p 80:80 --name webserver nginx```

たったこれだけでnginxが起動しました、このお手軽感はすごいなと改めて実感しました。
みんながDockerは手軽に作って、捨てる…みたいなこと言ってたけど「へーそうなのかー」くらいに聞き流してた部分があったのですが実感すると確かに手軽ですね！
（これが沼の始まりかもしれないなーとはちょっとだけ思いましたが）

止めるときは```docker stop webserver```してあげれば止まります。
再開したいときは```docker start webserver```で再開出来ます、楽ちん。
いらなくなったら止めたあとで```docker rm -f webserver```してあげればコンテナの削除はされる模様。
この辺の話しも全て公式サイトに書いてあるので英語だからと思考停止させずに目を通してもらえればと思います。

### 起動中のコンテナ確認

```docker ps```

これで現在起動しているコンテナが確認できるんですが、楽ちん&```ps```という慣れ親しんだコマンドで確認出来るのがいいですね。

今まで想像していた以上に手軽にインストールできたり、コンテナ立ち上げたり出来たのでこれで個人開発が捗りそうな気がしてます。
一人放課後プロジェクトをちまちまと行っていたのですが環境つくんのめんどくせえなーと思った矢先のことだったのでちょっと感動して初投稿してしまいました。

![gutspose_man.png](https://qiita-image-store.s3.amazonaws.com/0/18493/4d15b458-33f9-951a-efa4-5cf0acfe5fe9.png)