OmniAICreator/Qiita-1.07M huggingface dataset:
Backlogによるチーム開発提案


※画像は全てbacklogのヘルプページから借用しました
（まもなくuiが変わるとの噂ですが・・）

# Backlogを使う上での最低限のルール
見た目が直感的なので採用されたタスク管理ツール、backlogなのですが、どうしてもチーム開発をする上で守って欲しいことが出てきましたので下にまとめます

このルールを守ることで、以下の効果を期待しています
1. より早いタスクの完了（不要な待ちの発生しないスピード感を持った開発）
2. より納得感がある、共通認識としてのタスク優先度

## 絶対に守って欲しい3つのルール + 1

1. 「担当者」を明示する
    ![image](https://qiita-image-store.s3.amazonaws.com/0/42407/22730e05-5f3e-9c03-7a50-b42051d52be4.png)
2. 「お知らせしたいユーザー」を忘れない
    ![image](https://qiita-image-store.s3.amazonaws.com/0/42407/3e6fe7a0-8c98-8ad6-b4ac-ec0fc30e5510.png)
3. 自分の作業が終わったら「担当者」を変更する
4. backlog以外での確認も行う


### タスクに担当者を登録する

例えば、「サイトxxxをリニューアルする」とかいう案件があった場合に、一つタスクに必要事項を全て埋めていく方式と、担当者毎に子課題を作成するのと、2つのパターンが考えられます。

プロジェクト管理の原則としては、タスクを細かく分割して、期限の見積を行い開始日と完了日の制御を細かく行う事で、進捗率や予算消化傾向などが把握できるのですが、現状はそこまでは求めません。

では、最低限をどこにおくか。
* マネージャーなどが、現在会社が抱えているプロジェクトを俯瞰できること
* それぞれの仕事は誰がボールを握っているのか（誰が担当者なのか）
とします。

そのため、
* まずは、今抱えている仕事、誰かに依頼したい作業は「全てbacklogに上げる」
ことを徹底しましょう。

そして、

* 各仕事について現在関わっている人を「担当者」としましょう

平行して複数の担当者が作業を行っている場合どうすればいいか？

* 原則に立ち返って、担当者毎にタスクをわけましょう

### お知らせユーザー

このやり方だと、毎日大量のタスク、およびその変更が発生します。その中で確実に相手に読んでほしいものについては
* 「コメントをお知らせしたいユーザー」にセットした上で
* skype, hangout, line、そして一番いいのは「口頭」で相手に確認する
* 皆さんは最低限「自分宛のお知らせ」を確認することは忘れずに。
→ ブラウザでbacklogを立ち上げて「数字」が上がっていたらそれを読みましょう！
![image](https://qiita-image-store.s3.amazonaws.com/0/42407/b60b8754-60ea-6377-fb8a-77a89ea26cc9.png)

## できれば守って欲しい 5つのこと + 1

1. 自分の作業でタスクの要求が満たされたら、状態を「処理済み」にし、担当者をタスク作成者に戻す (タスクの整理を効率的に行うために）
2. タスクを作った人が、タスクの状態を見届けた後、タスクの状態を「完了」にする (タスクの整理を効率的に行うために）
3. タスク作成時、もしくは担当者を変える際に「期限日」を設ける。できれば、主要なマイルストーンについてはタスクの「詳細」に記載する
4. タスクの「詳細」には。「何が終わればタスクが完了するのか」明記をすること
5. 仕様や主要なファイルのやりとりは全てタスク上にコメント・ファイルの添付などで残すこと。特に、機能開発時の仕様は「詳細」を編集する
6. 「スター」は、「ご苦労様！」「ナイスジョブ！」と賞賛したい場合以外にも、コメントつけるまでも無いけど、「読んだよー」と自己主張したい場合に使えます

## その他ローカルルール

1. タスク完了後も、参照される可能性が高いことはWikiに残す（wikiの方にはタスクのURLを貼り付けるだけでも良い）
2. タスクに伴うコードコミットは、コメントに貼り付ける（本当はbacklogのリポジトリ管理が使えればいいのだけど、bitbucketの利便性にはかなわない・・）
Qiita > summary表記を試して気づいた事項


http://blog.qiita.com/post/151329031329/detailssummarysupport

`<summary>これはサマリです</summary><details>昔々あるところにおじいさんとおばあさんがいました。</details>
`

- <summary>これはサマリです<details>昔々あるところにおじいさんとおばあさんがいました。</details></summary>

confluenceであったexapandと同等機能がhtml5として使えていて、それがQiitaでも使えるようになった。

スライドモードではサマリしか表示されないのは当然と言えば当然か。

この機能の有効利用は今後考えてみる。

## v0.2

上記の書き方は間違いで以下のようにするようだ。
個人的にはsummaryタグがあり、そのあとにdetailsタグがあるというのが違和感が少ないがhtml5での認識が難しいのだろう。

`<details><summary>これはサマリです</summary>昔々あるところにおじいさんとおばあさんがいました。</details>`

- <details><summary>これはサマリです</summary>昔々あるところにおじいさんとおばあさんがいました。</details>

http://www.htmq.com/html5/details.shtml

## 使い道

confluenceの2年前の自作記事を思い出した。
http://qiita.com/7of9/items/a58bc6261ad233175a33

やたら長いコードがある時、そのコードが長いために全体の見通しが悪くなる。
そういう場合にsummary表記は使える。

1. ビルド作業
2. QEMUで起動確認できる
3. zImageから圧縮されたuImageを作る
4. ~~ここにあるarm_ramdisk_image.gzを取得して、以下の手順でuramdisk.image.gzを作成する~~ (この作業は不要)

<details>
<summary>5. XSDKにてBOOT.binを作成する。</summary>
linuxで作成した以下のファイルをVivadoとXSDKをインストールしたWindowsに持っていく
- system.dtb : 手順1にてimages/linux以下にビルドされたファイル
- u-boot.elf : 手順1にてimages/linux以下にビルドされたファイル
- uImage : 手順3で作成したファイル
- (不要) uramdisk.image.gz : 手順4で作成したファイル
- zynq_fsbl.elf : 手順1にてimages/linux以下にビルドされたファイル  
Windows上にてXSDKを起動する
Xilinx Tools > Create Zynq Boot Imageを選択する
Create new BIF fileを選択して、ファイルをoutput.bif(任意のファイル名)とする。ファイルパスはBOOT.binを作成するところにしておけばいい。
右下のAddを選択して、上記のファイルを以下の順で追加していく。ここで「Partition type」は「datafile」としておけばよさそう。
1. zynq_fsbl.elf
2. u-boot.elf
3. uImage
4. (選択不要) uramdisk.image.gz
5. system.dtb
Create Imageを選択してBoot.binを作成する
</details>

`6. ファイルをmicroSDにコピーする
`7. microSDをMicroZedに入れて、MicroZedを起動するとPetaLinuxが立ち上がる

<font color=blue>ただし、途中に空白行があると分断される仕様のようだ。</font>
このため、リスト表示を開始する直前の空白行を用意できず、リスト表示をdetailsに含めることができない。

あと、展開した時にインデントがついてないので見栄えは良くない。
展開時に意図しない空白行があるのはなぜだろうか (「linuxで作成した」の前と「Windows上にてXSDKを起動する」の前)。

`<details>`の前に空白行が必要のようだ。空白行がないとdetailsの項目表示が途中までになる。そのため、上記のようにリスト4の直後に空白行が必要となり、リストが分断される。結果として、リスト6,7の表記に工夫が必要となる。

Confluenceの以下の機能は使いやすかったです。
http://qiita.com/7of9/items/454ba9d9c3876883faaf
結託したスパムレビュアを発見するアルゴリズム

# はじめに
[![Logo](https://rgmining.github.io/fraud-eagle/_static/image.png)](https://rgmining.github.io/)
オンラインショッピングやレストランレビューサイトにおいて，
結託してレビュー結果が不当に高くまたは低くなるようにダミーレビューを投稿する
スパムレビュアーを発見したい．

今回は，2013年に [AAAI Conference on Weblogs and Social Media](http://www.icwsm.org/2013/) という国際会議で発表された，[Fraud Eagle](https://www.aaai.org/ocs/index.php/ICWSM/ICWSM13/paper/viewFile/5981/6338) アルゴリズムを[実装](https://rgmining.github.io/fraud-eagle/)した．

# レビューデータ
Fraud Eagle では下の図のようなレビューグラフを考える．

![graph2.png](https://qiita-image-store.s3.amazonaws.com/0/62253/4cd408eb-2286-dd62-c3bc-52946de1a477.png)


つまり，レビューを投稿した人（レビュア）とレビューの投稿先（商品）をそれぞれ頂点とし，
レビュー関係を枝で表す．レビュー自体は文章でも星何個でも良いが，
そのレビューがポジティブなのかネガティブなのか判断できる必要がある．
今回は，レビューは 0 から 1 までの間の数値を取ることにし，0.5 以上ならばポジティブ，
そうでなければネガティブと判断することにした．

# 使い方
今回作成した [`rgmining-fraud-eagle`](https://rgmining.github.io/fraud-eagle/) は PyPI からインストールできる．

```shell-session
pip install --upgrade rgmining-fraud-eagle
```

fraud_eagle というパッケージがインストールされるので，
その中から`ReviewGraph` クラスのインスタンスを作成する．
なお，Fraud Eagle は 0 より大きく 0.5 未満ののパラメータを一つとる．
パラメータはデータセットによって最適値が変わるが，今回は中央 0.25 を設定してみる．

```py
import fraud_eagle as feagle

graph = feagle.ReviewGraph(0.25)
```

次に，グラフにレビュア，商品，そしてレビューを追加する．
上記図の通りのグラフを作成する場合，

```py
reviewers = [graph.new_reviewer("reviewer-{0}".format(i)) for i in range(2)]
products = [graph.new_product("product-{0}".format(i)) for i in range(3)]
graph.add_review(reviewers[0], products[0], 0.2)
graph.add_review(reviewers[0], products[1], 0.9)
graph.add_review(reviewers[0], products[2], 0.6)
graph.add_review(reviewers[1], products[0], 0.1)
graph.add_review(reviewers[1], products[1], 0.7)
```

となる．レビュアと商品は `ReviewGraph` の `new_reviewer`, `new_product` メソッドを使って作成する．
レビューは `add_review` メソッドで追加する．

グラフを作成し終わったら，`ReviewGraph` の `update` メソッドを，更新が収束するまで実行する．
Fraud Eagle は Loopy belief propagation というアルゴリズムを使っており，
update の呼び出し一回で 1ループに対応させている．
update メソッドは，最大修正量を返すので，十分小さくなったところで終了する．

```py
print("Start iterations.")
max_iteration = 10000
for i in range(max_iteration):

   # Run one iteration.
   diff = graph.update()
   print("Iteration %d ends. (diff=%s)", i + 1, diff)

   # 最大修正量が 10^-5 ならば収束したと思う
   if diff < 10**-5:
       break
```

最後に，解析結果を取得する．
`new_reviewer` メソッドが返したレビュアには `anomalous_score` という属性がある．
この属性は 0 から 1 の値を取り，そのレビュアがどの程度特異（スパマー）かを表している．

```py
for r in graph.reviewers:
    print(r.name, r.anomalous_score)
```

また，`new_product` メソッドが返した商品オブジェクトには `summary` という属性がある．
この値は，その商品に付けられたレビュースコアのレビュアの `anomalous_score` による重み付き平均を返す．（`anomalous_score` が大きいレビュアのレビューはあまり考慮しない平均値）

```py
for p in graph.products:
    print(p.name, p.summary)
```

# まとめ
結託したスパムレビュアーを発見する Fraud Eagle アルゴリズムを実装した．
また，この種類のスパムレビュアー発見アルゴリズムの評価用[人工データ](https://rgmining.github.io/synthetic/) も公開している．
人工データの使い方は[スパムレビュア発見アルゴリズムの評価用データセット](http://qiita.com/jkawamoto/items/9a7647c47998fab4a1ad)にまとめてある．
スパムレビュー対策に取り組んでいる人の参考になればと思う．
[短文ネタ] try節、except節とfinally節の両方でreturnした場合

ふと気になったので、やってみた。Python2.7とPython3.4で確認。

```py:try節とfinally節でreturn
def f():
    try:
        return "try"
    finally:
        return "finally"

print(f())
```

⇒`finally`

```py:except節とfinally節でreturn
def f():
    try:
        raise ValueError
    except ValueError:
        return "except"
    finally:
        return "finally"

print(f())
```

⇒`finally`

たぶん使うことはないけど。知らなかった。
MacOSXにPowerShellをインストールしてみる

作業メモ。

# 環境

+ MacOSX10.11.6
+ PowerShell 6.0.0-alpha

# やってみる

基本的に以下のREADMEに従えば良い。

[PowerShell/PowerShell](https://github.com/PowerShell/PowerShell)

```bash
# pkgファイルをダウンロード
$wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.10/powershell-6.0.0-alpha.10.pkg

# pkgをインストール
$sudo installer -pkg powershell-6.0.0-alpha.10.pkg -target /
installer: Package name is powershell-6.0.0-alpha.10
installer: Installing at base path /
installer: The install was successful.

# powershellを起動
$powershell
PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

# PowerShellのバージョンを確認
PS /Users/xxxx> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.0.0-alpha
PSEdition                      Core
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   3.0.0.0
GitCommitId                    v6.0.0-alpha.10
CLRVersion
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

```

簡単でした。
戻るボタンを押した時にホーム画面に戻る方法


戻るボタンを押した時にホーム画面に戻るという実装に
少し時間がかかったので、メモ。

#参考にした資料
・[戻るボタンのイベントを取得する方法](http://rikisha-android.hatenablog.com/entry/2014/05/23/151601)
・[アプリ側でホーム画面に戻る方法](http://android-note.open-memo.net/sub/system__back_to_home_screen.html)

#本題
###戻るボタンを押した時のイベントを取得方法
戻るボタンのイベントを取得するためには、Activity.onKeyDown(int, keyEvent)メソッドをオーバーライドすればいい。
第１引数のkeyCodeには、何のボタンが押されているかが入っているので、これを条件分岐して、戻るボタンを押した時の処理を書く。

```Java
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK) {
        // 戻るボタンの処理
        return super.onKeyDown(keyCode, event);
    } else {
        return super.onKeyDown(keyCode, event);
    }
}
```

###ホーム画面に移動させる方法
Intentを発行して、ホームアプリに移動するようにする。
Intent発行の例↓

```Java
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);          
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(homeIntent);
```

下記の２つの部分がホーム画面に行くために必要なインテントらしい。

```Java
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
```

この２文でなぜホーム画面に行くのか、詳しくは、よくわからなかったので、どなたか教えてください。
もし、わかったら追記します。

###2つの処理を組み合わせる

上記に書いたものを組み合わせると戻るボタンを押した時にホーム画面に戻るようになる。

```Java
@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Intent homeIntent = new Intent(Intent.ACTION_MAIN);
            homeIntent.addCategory(Intent.CATEGORY_HOME);
            homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            Timer.this.startActivity(homeIntent);
            return super.onKeyDown(keyCode, event);
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }
```

これを実装したいActivityに記せば、戻るボタンを押してた時に、ホーム画面に戻るようになります。

#まとめ
詳しい仕組みはさておき、意外と簡単に実装できることがわかった。

これを実装すれば、戻るボタンを押してもonDestroy()メソッドも呼ばれることはなく、Activityが破棄されることはない。
ただ、どこかでFinish()を呼び出すようにしたほうがいいと思う。

以上。
Dockerイメージを軽くするために、オフィシャルのイメージがやってることを調べてみた

自分でカスタマイズしたDockerイメージを作成しようと思って、オフィシャルのDockerファイルを読み込んでみると変わった処理が行われていることに気づいた。

以下はredis3.0のオフィシャルイメージの一部([Redisイメージ](https://github.com/docker-library/redis/blob/6cb8a8015f126e2a7251c5d011b86b657e9febd6/3.0/Dockerfile))

```
RUN apt-get update && apt-get install -y --no-install-recommends \
		ca-certificates \
		wget \
	&& rm -rf /var/lib/apt/lists/*
```

基本的には余計なものは入れない、要件が終わると削除するという精神で作成を行っています。
--no-install-recommands
を使うと「推奨」パッケージをインストールせずに必要最低限の依存パッケージをインストールしてくれます。（推奨パッケージなんてあったんですね汗：余談ですが、よくapt-getとaptitudeの比較が挙げられていますが、aptitudeは推奨パッケージも自動で入れてくれるそうです。）

rm -rf /var/lib/apt/lists/*
キャッシュのようなファイルが置かれているそう
apt-get updateを実行すれば、新しく作成されるので削除しても問題ないということです。
http://unix.stackexchange.com/questions/217369/clear-apt-get-list

最後にまとめて削除すればいいんじゃない？と思うかもしれないのですが、

**それではダメなんです**

容量の大きなファイルを作成して、一行のRUNに収める場合と2行のRUNに収める場合で検証してみます。
Aパターン

```
FROM ruby:2.1.7

RUN dd if=/dev/zero of=/10megafile bs=1M count=10
RUN rm /10megafile
```

Bパターン

```
FROM ruby:2.1.7

RUN dd if=/dev/zero of=/10megafile bs=1M count=10 && rm /10megafile
```

Aからdocker build split .でイメージを作成
Bからdocker build same .でイメージを作成して、docker imagesで容量を確認します。

```
% docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
same                             latest              bc928bf2446f        7 seconds ago       718.2 MB
split                            latest              53e3478f8d2d        2 minutes ago       728.7 MB
```

ちょうど10MBの差が確認できました。

このことからもわかるのですが、Dockerfileのコマンドはそれぞれレイヤーを作成します。
イメージの容量はすべてのレイヤーの合計になることがわかりました。

Dockerイメージがどのようなレイヤーで構成されているかは
docker history REPOSITORY
コマンドで見ることができます。

AパターンとBパターンでは

```
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
53e3478f8d2d        8 minutes ago       /bin/sh -c rm /10megafile                       0 B
933d9d0cda06        8 minutes ago       /bin/sh -c dd if=/dev/zero of=/10megafile bs=   10.49 MB

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
bc928bf2446f        3 minutes ago       /bin/sh -c dd if=/dev/zero of=/10megafile bs=   0 B
```

このような違いが出ます。
イメージのレイヤーをわかりやすく表示してくれるサービスもあるようです。
例えばredis3.0
https://imagelayers.io/?images=redis:3.0.0

あと、ひとつのRUNに詰め込みすぎじゃない？って思う方もいらっしゃると思いますが、これにも理由があって、レイヤーが127階層までしか作れないからだそうです。

まとめ
Dockerのイメージを軽くするためには、

* よけいなものをインストールしない
* 使ったら同じレイヤーの中で消す

ということでした。
werckerでのビルド時間短縮のためにやった2つのこと

# はじめに

僕が所属するプロジェクトでは、CIツールとしてwerckerを使ってます。
テストの実行からコードの反映までを、githubへのプッシュをトリガーにして行ってくれるのでとても便利だなーと思うのですが、少し時間がかかるようになってきました(だいたい50分くらい)

ビルド->デプロイ
という流れで処理が実行されます。
ビルドのパイプラインでは、基本的にテストコードの実行(bundle exec rspec)を行っていて、デプロイではcapコマンドを叩いてコードの反映を行っています。

今回着目したのはビルドのパイプラインです。

時間は50分のうちの20分を占めるのですが

* werckerでは同時に実行できるパイプラインが2つまでという制約
* ビルドはプルリクエスト状態のすべてのブランチで実行されること

から、ビルド待ちの渋滞ができてしまって、「デプロイしたいけどできないお・ω・」
という状態になってしまっていました。
実行待ちのビルドを停止していって、やっとデプロイしたいリボジトリのビルドが動き始めるという...

# 時間がかかる要因
ビルドという作業の内訳をもう少し細かく確認していくと

1. werckerのboxのセットアップ
2. bundle install
3. 足りてないツールのインストール、バージョンのアップデート
4. npm install
5. gulpの実行でjsファイルをコンパイル
6. rspecの実行
7. 出力の保存

というタスクが実行されていました。
それぞれで使っている時間はマチマチだったのですが、毎回ボトルネックになっていたのが3, 4, 6の処理でした。
そのあたりの改善を中心に行いました。

# 足りてないツールのインストールとバージョンのアップデート(Dockerイメージの作成)
オリジナルのboxを作成することで解決を試みました。
werckerではDockerHubに保存したイメージを利用できることからDockerイメージを作成します。

ベースはruby:2.1.7のイメージを使って必要なツールをインストールしていきます。

```
$docker run -i -t ruby:2.1.7 /bin/bash
```

シェルが立ち上がるので、ツールをインストールしていきます。
apt-getを使ってひたすらコマンドを叩いていきます。

必要なツールのインストールが終わったらimageを作成します。exitでコンテナから抜け出します。

```
$docker pa -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                     PORTS               NAMES
1c3f9a438bae        ruby:2.1.7              "/bin/bash"              13 minutes ago      Exited (0) 2 minutes ago                       pedantic_hamilton
```

先程作成したコンテナがいるので変更をコミットします。

```
$docker commit 1c3f9a438bae my-ruby-env
```

これで修正を加えたコンテナのイメージが作成されました。
docker imagesコマンドで確認できると思います。

続いてDockerhubへアップロードします。

```
$docker tag my-ruby-env g_ryotaro/my-ruby-env
$docker login
ログイン情報の入力を求められるので、入力
$docker push g_ryotaro/my-ruby-env
```

これでDockerhubに自分のオリジナルイメージがアップロードされました。
werckerでも、このオリジナルのイメージを利用することで、もともと5分かかっていたタスクを4分ほど短縮することができました。

# rspecの実行時間を短縮する
テストを並列実行するように設定を行いました。
[parallel_tests](https://github.com/grosser/parallel_tests)
導入すると簡単に並列処理することができます。

行った作業は、bundle exec rspecを実行していたコマンドをbundle exec rake parallel:specに変更するだけです。
CPUの数を自動的に判定し、スペックをそれぞれに割り振ってくれます。

これだけで実行時間が10分から5分に減りました。

2つをあわせて、合計9分の短縮が行えました。
およそ半分です。

# ハマったこと
オリジナルのイメージを使いはじめて、一部の環境にデプロイする際に失敗するケースがみられるようになりました。
capコマンドを実行している際にsshのコネクションが切れてしまって、次の処理が行われないことが原因でした。

オリジナルのDockerイメージに下記の設定を追加し、問題なくデプロイできるようになりました。

/etc/ssh/ssh_config
```
ServerAliveInterval 15
```

# まとめ
werckerのビルド時間を短縮するために行った対策をざっと書いてみました。
結果、ビルドにかかる時間は半分になり、ビルド待ちの渋滞は少なくなったのですが、やはりピークの時間帯になると渋滞してしまいます。
今後は、Jenkinsを用いたCIになる予定なので、2つしか実行できないという制限がなくなると思われます。
Dockerhubを使えたり、なかなかいい勉強になったと思いました。
Generator は Countable を実装しないので count 関数にそのまま渡すことを避ける


概要
---

Generator は `Countable` を実装しないので、`count` 関数に渡すと常に1の値が返されます。1 が返されることは[マニュアル](http://php.net/manual/ja/function.count.php)に明記されています。要素の数がゼロであるかの判定をする際に Generator を配列と同じように考えると正しく処理できない可能性があります。PHP Internals に提出された [RFC](https://wiki.php.net/rfc/counting_non_countables) は典型的な間違えとして次のコードを示しています。

```php
function handle_records(iterable $iterable)
{
    if (count($iterable) === 0) {
        return handle_empty();
    }
 
    foreach ($iterable as $value) {
        handle_value($val);
    }
}
```

`iterable` は `array` および `Traversable` を実装するオブジェクトの両方を引数として受け入れます。PHP 7.1 で導入されました ([RFC](https://wiki.php.net/rfc/iterable))。同時に `is_iterable` 関数も導入されました。

このコードでは `$iterable` が Generator の場合、`count($iterable) === 0` の行が常に `false` になるので、`handle_empty()` は常に実行されません。

この RFC は `Countable` を実装しないオブジェクトに対して PHP は警告を発するべきではないかと提案しています。

コードの例
--------

かんたんな Generator を定義して、`count` の戻り値が 1 になるか確認してみましょう。

```php
function xrange($start, $limit, $step = 1) {
    for ($i = $start; $i <= $limit; $i += $step) {
        yield $i;
    }
}

var_dump(
    1 === count(xrange(1, 5))
);
```

対策
---


`count` 関数を適用する前に配列もしくは `Countable` を実装するオブジェクトであることをチェックします。複数の箇所で `count` を使うのであれば、次のような関数を定義するとよいでしょう。

```php
function is_countable($array_or_object) {
    return is_array($array_or_object) || $array_or_object instanceof Countable;
}

var_dump(
    true === is_countable(range(1, 5)),
    false === is_countable(xrange(1, 5))
);
```

一番最初に示したコードは次のように修正されます。

```php
if (is_countable($iterable) && count($iterable) === 0) {
    return handle_empty();
}
```

`count` の引数の改善も考えましょう。最初に Generator を `iterator_to_array` で配列に変換してから `count` に渡す方法を挙げます。

```php
var_dump(
    5 === count(iterator_to_array(xrange(1, 5), false))
);
```

次に `IteratorAggregate` と `Countable` を実装するクラスを用意する方法を挙げます。クラスを再利用しないのであれば、PHP 7.0 で導入された匿名クラスを利用します。

```php
$gen = new class implements IteratorAggregate, Countable {
    public function getIterator() {
        return xrange(1, 5);
    }
    public function count() {
        $count = 0;
        foreach ($this as $value) { $count++; }
        return $count;
    }
};

var_dump(
    5 === count($gen)
);
```
技術英語 > Over my dead body. / Standing on the shoulders of giants

ふと思い出した英語

> Over my dead body.

意訳「俺の屍を超えていけ」

http://american-phrases.blogspot.jp/2010/08/over-my-dead-body.html
> 「意味」俺の目の黒いうちはさせないぞ。

>※直訳すると「（やるのなら）俺の死体を乗り越えて（やれ）」で、あることに強く反対する場合に使うフレーズです。けんか腰の場合もありますが、冗談ぽく使う場合もあります。

「俺の目の黒いうちはさせないぞ。」の意味とは知らなかった。。。
「もう無理。今から屍（しかばね）るから、あとよろしく」ではないのか。


<hr>
関連して思い出したのは

> Standing on the shoulders of giants
http://ejje.weblio.jp/content/Standing+on+the+shoulders+of+giants

shoulders もgiantsも複数形なのか。

ちっぽけな我々でも巨人の肩の上にいると遠くまで見渡せるということ。

様々な技術のベースが巨人として、その上でコードを書くのは、いわば「Standing on the shoulders of giants」なのかもしれない。

自分が何かできた時、それは多くの方々が時間をかけて蓄積した技術というベースがあるからできるのだろう。
Ubuntu 16.04上のmysqlへアクセスできない


## 概要

ubuntu 14.04からubuntu 16.04へOSをアップグレードし、同じ手順でシステムをインストールしようとしたところ、mysqlでデータベースを作成する時にaccess deniedのエラーが発生

解決方法は、mysqlコマンドにsudoをつけて、管理者権限で実行すること

## インストール時

ubuntuのパッケージ管理コマンドを利用してインストール

```
$ sudo apt-get install mysql-server -y
## 途中でrootのパスワードパスワード設定を求められるが何も入力せずEnterを押してインストール
```

## mysqlアクセス時

ubuntu 14.04時には問題なくアクセスできていた方法でアクセスするとアクセスが拒否される

```
$ mysql -u root
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

```

## 解決方法

sudoを利用して管理者権限でアクセスすればアクセスできる

```
$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.13-0ubuntu0.16.04.2 (Ubuntu)

Copyright (c) 2000, 2016, 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.

mysql>
```
Docker for Mac 環境で Docker connection plugin for Ansible を利用する。

# Docker connection plugin for Ansible とは？
[Docker connection plugin for Ansible](https://github.com/lorin/ansible-docker-connection)は、Ansible 2.0 より利用が可能になった機能です。
Ansibe が Docker API へ接続することで、従来の様にコンテナ上でSSHデーモンを起動させることなく、コンテナファイルを直接操作できるようになりました。

# 設定
早速、手順に沿って設定します。
手順では、環境変数の DOCKER_HOST に Docker API のホストアドレスを記載するように書かれています。

Docker for Mac での Docker API は、TCPではなく UnixSocket となります。
GitHub上には書かれていませんが、[こちら](https://docs.ansible.com/ansible/docker_container_module.html)にはUnixSocketかTCPと書かれているので、

```sh
export DOCKER_HOST="unix://var/run/docker.sock"
```

と実行し、環境変数を設定します。

## 参考
Docker for Mac の挙動は、[こちら](https://docs.docker.com/docker-for-mac/docker-toolbox/)に詳しく書かれています。

# 実行
動作検証のために簡単なPlayBookとInventoryを用意しました。Dockeｒ上の2つのコンテナにPINGを送信します。

- hosts

```
[containers]
high_bardeen
gigantic_almeida
```


- sample.yml

```yml
- hosts: containers
  connection: docker 

  tasks:
  - name: ping
    ping:
```

```sh
$ ansible-playbook -i hosts.yml sample.yml

PLAY [containers] **************************************************************

TASK [setup] *******************************************************************
ok: [high_bardeen]
ok: [gigantic_almeida]

TASK [ping] ********************************************************************
ok: [gigantic_almeida]
ok: [high_bardeen]

PLAY RECAP *********************************************************************
gigantic_almeida           : ok=2    changed=0    unreachable=0    failed=0
high_bardeen               : ok=2    changed=0    unreachable=0    failed=0
```

はい、成功です。

ですが、ここで落とし穴がありました。
環境変数を設定後Dockerコマンドを実行すると、下記のようになります。

```sh
$ docker info
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
```

[DOCKER_HOST] を設定することで、Docker for Mac に含まれるDockerコマンドが正常に稼働しなくなるようです。

なお、

```sh
$ unset DOCKER_HOST
```

とすることで、設定した[$DOCKER_HOST]は削除でき、Dockerコマンドは正常に動きました。


# 解決
なんとかして[DOCKER_HOST]を設定する必要があります。
そこで、PlayBook中に[DOCKER_HOST]変数を定義します。

- sample2.yml

```yml
- hosts: containers
  connection: docker 

  vars:
  - DOCKER_HOST: "unix://var/run/docker.sock"

  tasks:
  - name: ping
    ping:
```

```sh
$ ansible-playbook -i hosts.yml sample2.yml

PLAY [containers] **************************************************************

TASK [setup] *******************************************************************
ok: [high_bardeen]
ok: [gigantic_almeida]

TASK [ping] ********************************************************************
ok: [gigantic_almeida]
ok: [high_bardeen]

PLAY RECAP *********************************************************************
gigantic_almeida           : ok=2    changed=0    unreachable=0    failed=0
high_bardeen               : ok=2    changed=0    unreachable=0    failed=0
```

はい、上手くいきました。
これで、Docker for Mac 上のコンテナへもコンテナ上でSSHデーモンを起動せずにAnsibleの実行が可能となります。

ニッチなケースかもしれませんが、ご活用ください。
GKEでnginxコンテナを起動する

Google Container Engine（GKE）上でngnixのコンテナを立ち上げるまでの手順です。（2016/10現在）

# コンテナ クラスタの起動
GCPにログインして、nginxのコンテナを実行させるコンテナ クラスタを起動します。

1. 「コンテナ クラスタを作成」を選択
<img width="1280" alt="GKE-Console-Top.png" src="https://qiita-image-store.s3.amazonaws.com/0/141783/ad0d3656-fd0f-7cc8-8a7d-d881132f94fb.png">

2. クラスタの各種パラメータを設定。今回は何も変更せずデフォルト値を利用しています。
<img width="1278" alt="GKE-Make-Cluster-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/141783/320fc6b0-f132-47de-8f76-8eb95147b629.png">

3. 起動完了。下の図のようになれば、クラスタが起動は完了です。
<img width="1280" alt="GKE-AfterMakeCluster.png" src="https://qiita-image-store.s3.amazonaws.com/0/141783/53f674c0-af8c-6c21-4d91-f0145174d299.png">

# Google Cloud Shellの起動
Google Cloud ShellにはGoogle Cloud SDK、Docker、kubectl等、コンテナを操作する上で必要なツールがデフォルトでインストールされているので、これを利用します。

1. コンソールの右上のGoogle Cloud Shellのアイコンを選択
<img width="1280" alt="GKE-Start-GoogleCloudShell.png" src="https://qiita-image-store.s3.amazonaws.com/0/141783/29b75602-2082-c4ff-3792-5f188ad21de9.png">

起動が完了すると画面下部にコンソールが表示されるので、ここで作業を行っていきます。

# 環境設定
早速作業に入って行きたいところですが、作業に入る前にGoogle Cloud Shellからkubectlのコマンドを操作できるように、下記コマンドを実行して設定を行います。
下記コマンドを実行すると認証情報が取得でき、kubectlを利用してコンテナ クラスタ上にコンテナを用意できるようになります。

```
gcloud container clusters get-credentials cluster-1 --zone us-central1-b
```

# Replication Controllerの起動
今までの作業で準備が終わったので、まずはnginxのPodを立ち上げます。
Podだけでもいいのですが、今回はReplication Controllerも起動してPodを監視させるようにしています。

・YAMLファイル作成

```shell:nginx-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
        - containerPort: 80
```

・Replication Controller作成
Google Cloud Shell上で上記YAMLファイルを元に、Replication Controllerを作成します。
Replication Controllerを作成すると、監視対象であるnginxのコンテナを含んだPodが自動で起動されるので、別途Podを起動する必要はありません。

```
kubectl create -f nginx-rc.yaml
```

# Serviceの作成
Replication Conrollerを起動したことにより、Podおよびnginxのコンテナも起動しましたが、そのままではまだ外部からアクセスすることはできません。
その為、外部からの接続を各Podにルーティングする役割をもったServiceを立ち上げます。

・YAMLファイル作成

```shell:nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer
```

・Service作成
YAMLファイルを元にServiceを作成します。

```
kubectl create -f nginx-service.yaml
```

・外部接続用IPの確認
Serviceが起動するとnginxにアクセスできるようになります。
接続する為のIPは、下記コマンドを実行した時に表示される「EXTERNAL-IP」欄に記載されているIPです。

```
>> kubectl get service

NAME         CLUSTER-IP    EXTERNAL-IP     PORT(S)   AGE
frontend     10.3.244.85   130.211.148.1   80/TCP    2m
```

試しにブラウザから「130.211.148.1」で接続すると、nginxの画面が表示されるかと思います。

# 最後に
GKEを利用することによって、比較的簡単にkubernetes上にコンテナを配置することができました。
一番上の画像にある「クイックスタートを使用」を利用すると、チュートリアルに沿って操作するだけでサンプルアプリケーションをGKEに構築することができるので、初めての方はそちらもオススメです。
ベクトルの加減乗除早見

## ベクトルとは
> 大きさだけでなく、向きももった量。例、速度・力。

## 表記
**極座標** （$\vec{A}$は量、@$\theta$は角度）

```math
ベクトルA = \vec{A}@\theta
```

**デカルト座標系** （$\hat{i}$はx軸方向、$\hat{j}$はy軸方向の大きさ１の単位ベクトル）

```math
ベクトルA = a_1\hat{i} + a_2\hat{j}=\begin{bmatrix}
a_1 \\
a_2
\end{bmatrix}
```

## 変換
**極座標（$\vec{A}@\theta$） → デカルト座標系**

```math
a_1 = \vec{A}\cos\theta\\
a_2 = \vec{A}\sin\theta\\
```

**デカルト座標系（$a_1\hat{i} + a_2\hat{j}$）→ 極座標**

```math
\begin{align}
\vec{A} &= \sqrt{a_1^2 + a_2^2}\\
@\theta &= \tan^{-1}(\frac{b_2}{b_1})
\end{align}
```

## ベクトルとベクトルの加算・減算
基本

```math
ベクトルA + ベクトルB = ベクトルB + ベクトルA\\
```

ベクトルA = $\vec{A}@\theta$の場合

```math
\vec{A+B} ≠ \vec{A} + \vec{B}
```

ベクトルA = $a_1\hat{i}+a_2\hat{j}$、ベクトルB = $b_1\hat{i}+b_2\hat{j}$の場合

```math
\begin{align}
A + B &= (a_1+b_1)\hat{i}+(a_2+b_2)\hat{j}\\
A - B &= (a_1-b_1)\hat{i}+(a_2-b_2)\hat{j}
\end{align}
```

## ベクトルとスカラーの乗算・除算
ベクトルA = $\vec{A}@\theta$、スカラーcの場合

```math
A\times c = \vec{A}\times c @\theta 
```

ベクトルA = $a_1\hat{i}+a_2\hat{j}$、スカラーcの場合

```math
\begin{align}
A \times c &= (a_1\times c)\hat{i}+(a_2\times c)\hat{j}\\
A \div c &= [(a_1\div c)\hat{i}+(a_2\div c)\hat{j}
\end{align}
```

## ベクトルとベクトルの乗算：内積
ベクトルとベクトルを掛け合わせスカラー値として求める。角度が求まる。

ベクトルA = $a_1\hat{i}+a_2\hat{j}$、ベクトルB = $b_1\hat{i}+b_2\hat{j}$の場合

```math
\begin{align}
A \cdot B &= a_1 b_1 + a_2 b_2\\
A \cdot B &= \vec{A}\vec{B}\cos\theta\\
\end{align}
```

この時


```math
\begin{align}
A \cdot B &= 0 →A⊥B\\
A \cdot B &< 0 →\theta > 90^\circ\\
A \cdot B &> 0 →\theta < 90^\circ
\end{align}
```

## ベクトルとベクトルの乗算：外積
ベクトルとベクトルを掛け合わたベクトルを求める。
ベクトルとベクトルが成す面に対する垂直なベクトルが求まる。

ベクトルA = $a_1\hat{i}+a_2\hat{j}+a_3\hat{k}$、ベクトルB = $b_1\hat{i}+b_2\hat{j}+b_3\hat{k}$の場合

```math
A \times B = (a_2 b_3 - a_3 b_2) + (a_3 b_1 - a_1 b_3) + (a_1 b_2 - a_2 b_1)\\
\begin{align}
A \times B &≠ B \times A\\
A \times B &= -(B \times A)
\end{align}
```

**面法線**

```math
A \hat{\times} B = \frac{A \times B}{\vec{A \times B}}\\
```

この時、２つの３次元ベクトルのなす角は


```math
\vec{A \times B} = \vec{A}\vec{B}\sin\theta
```
PHP 7の配列と連想配列の速度差（読み込み編）

PHP 7で、要素数600万の配列および連想配列の全要素にアクセスしてみて、その実行時間を測定してみました。

```php:php7-array-access-test.php
<?php
$array_size = 6000000;

$a = range(1, $array_size);
$b = range(1, $array_size);
$b['x'] = -1; // 文字列キーの要素を追加することで内部構造を連想配列化する

foreach ($a as $k=>$v) {
    $c['x'.$k] = $v;
}

// (1)定数アクセス
$start = microtime(true);
for ($i = 0; $i < $array_size; $i++) {
    $v = 0;
    'x'.$i; // $cに対する公平性のため
}
var_dump(microtime(true)-$start);

// (2)配列アクセス（数値キー）
$start = microtime(true);
for ($i = 0; $i < $array_size; $i++) {
    $v = $a[$i];
    'x'.$i; // $cに対する公平性のため
}
var_dump(microtime(true)-$start);

// (3)連想配列アクセス（数値キー）
$start = microtime(true);
for ($i = 0; $i < $array_size; $i++) {
    $v = $b[$i];
    'x'.$i; // $cに対する公平性のため
}
var_dump(microtime(true)-$start);

// (4)連想配列アクセス（文字列キー）
$start = microtime(true);
for ($i = 0; $i < $array_size; $i++) {
    $v = $c['x'.$i];
}
var_dump(microtime(true)-$start);
```

下記は私の手元のマシン（MacBook 12inch + PHP 7.0.9）で10回測定したときの平均値です。`memory_limit=2G`で実験しました。

|                        | 実行時間(sec)|
|:-----------------------|------------:|
|**(1)定数アクセス**              |0.577|
|**(2)配列アクセス（数値キー）**      |0.654|
|**(3)連想配列アクセス（数値キー）**  |0.662|
|**(4)連想配列アクセス（文字列キー）**|0.819|

上記結果から配列アクセスの時間だけを取り出すため、それぞれから(1)の時間を引き算してみましょう。

|                        | アクセス時間(sec)|
|:-----------------------|------------:|
|**(2)配列アクセス（数値キー）**      |0.077|
|**(3)連想配列アクセス（数値キー）**  |0.085|
|**(4)連想配列アクセス（文字列キー）**|0.242|

数値キーのときのハッシュ値計算はmod計算だけなので連想配列アクセスでも配列アクセスに対してあまり大きなペナルティは無いと言えそうです。一方、文字列キーのハッシュ値計算に使っているDJBX33Aは比較的軽い処理だと言われますが、配列アクセスと比べれば倍以上のペナルティがありますね、ということが確認できました。

（注：配列アクセスの時間だけを取り出すのに引き算をしているのが議論として若干雑になっている可能性があります。厳密に測定したい場合はPHP拡張モジュールをCで実装して実験すべきでしょう）

## 補足：マイクロベンチの結果をどう読み取るかについて

これは内部実装の差が観測できるかどうかの実験であり、普段のコーディングに役立つものではありません。この結果だけを見て、連想配列アクセスになっているコードをわざわざ配列アクセスに直したりする意味は無いはずです。もしこの速度差が問題になるような処理があったとすれば、PHP以外の言語で書き直した方が良いかもしれません。
El Capitanで therubyracer 0.11.4 をどうにかインストールしたかったけどできなかった

# El Capitanで therubyracer 0.11.4 をどうにかインストールしたかったけどできなかった

JaVaScriptエンジンである v8 をrubyで使えるようにするための therubyracer ですが、インストールにはいつも何かしら問題が起きます。

「therubyracer」で検索すると、インストールできなかった場合の対処法が1ページ目を占めるくらい利用者の頭を悩ますところですが、つい最近自分も悩んで結局解決できなかったので、それを書きとめます。


## Rails4.0.0案件を動かしたかった

昔の案件で、
- Rails4.0.0
- ruby2.0.0

のプロジェクトを検証するために、ElCapitanで動かそうとしました。

この条件下では、therubyracerのバージョンを特に指定しなければ、`0.11.4`をインストールしようとします。最初、てっきりRails4.0.0では0.11.4しか動かない、と思い込んでいたのがそもそもの間違いでした。


## ビルド時のオプションを指定しないとエラー
ソースコードを配置して
`bundle install`
をすると、therubyracerの箇所で以下のようなエラーになります。
```
(省略)
checking for v8.h... no
*** extconf.rb failed ***
(省略)
```

v8が見つからないと言われます。ただ、v8は入ってはいます。

## ビルド時のオプションを指定してもエラー

http://qiita.com/tags/therubyracer

を参考にすれば、世の中のtherubyracer問題のほとんどが解決できる気がします。
すなわち、ビルド時のパスを指定します。

```
bundle config --local build.libv8 --with-system-v8
bundle config --local build.therubyracer --with-v8-dir=/usr/local/opt/v8
or 
bundle config --local build.therubyracer --with-v8-dir=/usr/local/opt/v8-315
```

そして、`bundle install`すると

```
(省略)
checking for v8.h... yes
(省略)
2 warnings and 1 error generated.
make: *** [context.o] Error 1
```
v8は認識するようになりましたがエラーが起きました。

```
bundle update libv8
```

や

```
bundle config --local build.libv8 --with-cxx=/usr/local/bin/g++-4.2
```
をやってみても結果は同じでした。

## 諦めてtherubyracerを最新にする
`0.11.4`は古いため、最新の`0.12.2`を指定します。


```
$ vim Gemfile

gem 'therubyracer', :platforms => :ruby
↓
gem 'therubyracer', '>= 0.12.2', :platforms => :ruby

$ bundle install
...
Installing libv8 3.16.14.15 (was 3.11.8.17)
Installing therubyracer 0.12.2 (was 0.11.4) with native extensions
...
Bundle complete! 37 Gemfile dependencies, 118 gems now installed.
```

ついでにlibv8もアップグレードされ最新版が入り、問題なく完了しました。

そして、アプリを起動しても問題なく動きました。

## 結論
- ElCapitanではtherubyracer0.11.4は入らない
- Rails4.0.0でもtherubyracer0.12.2は動くので、バージョンアップすればいい
Gitでhttps接続するときのパスワードを保存したい

## Gitでリモートに接続する際に毎回アカウントを要求されてた

GithubでもGitlabでもBitbucketでも何でもいいですが、
proxy環境下でhttps接続が必須で、cloneでもpushでもpullでもとにかく毎回要求されててツライ...

sshで公開鍵認証できればそちら使いますけど、社内proxyでsshが使えない、gitプロトコルも使えないという大きな壁があって我慢していましたが、いい加減殺る気出していくつかの方法を検討してみました。

## .netrc

ホームディレクトリの.netrcにユーザー名とパスワード、プロトコルを記入することで、remoteへ接続する際に参照してくれます。ただしホームディレクトリ内に平文でファイル置くのでセキュリティ的にヤバそう。

```
vi ~/.netrc
```

例

```
machine github.com
login username
password password
protocol https
```

## credential.helper

利用可能な管理方法がいくつかありますが、検討したのは下記。

### store
.netrcみたいにファイルに保存します。ただし、パスワードが平文...

```
git config --global credential.helper store
```

これで
`~/.git-credentials`に保存されています。**平文で。**

### cache
常駐プロセスに記憶させます。

```
git config --global credential.helper cache
```

デフォルトでは900秒。変更するにはtimeoutオプション。（例：1時間）

```
git config --global credential.helper store --timeout=3600
```

これだと1時間後にはまた要求されるので微妙。

### osxkeychain
OSXの場合、保存先がキーチェーンに保存されます。やったーこれは便利！

```
git config --global credential.helper osxkeychain
```

初回パスワード入力時に保存されるので、キーチェーンを消さない限り以後入力不要。
今回こちらを採用しました。

これで毎度pull/pushするごとにアカウント要求されるつらみが解消されるのではないでしょうか。

**社内proxyと戦っているソルジャー達に幸あらんことを。**
[Swift]ヒートマップの色を返す関数の作り方

マップを使ったアプリを作っている時にヒートマップで色を重畳表示したい場面があったので作成しました。青が一番値が小さく、みどり→黄色→オレンジ→赤と表示されます。



```swift:Heatmap.swift
import Foundation
import UIKit

func CreateHeatMap(a: CGFloat) -> UIColor{
    
    var Color:UIColor = UIColor()
    var redcolor = CGFloat()
    var greencolor = CGFloat()
    var bluecolor = CGFloat()
    
    if a < 128 {
        redcolor = 0
    }else if a > 127 && a < 191 {
        redcolor = (a - 127)*4
    }else if a > 190 {
        redcolor = 255
    }
    
    if a >= 64 && a <= 191 {
        greencolor = 255
    }else if a < 64 {
        greencolor = a * 4
    }else {
        greencolor = 256 - (a - 191)*4
    }
    
    if a <= 64{
        bluecolor = 255
    }else if a > 64 && a < 127 {
        bluecolor = 255 - (a - 64)*4
    }else if a >= 127 {
        bluecolor = 0
    }
    
    Color = UIColor(red:redcolor / 255.0, green: greencolor / 255.0, blue:bluecolor / 255.0, alpha:1.0)
    
    return Color
}
```
Fabricの各種ツールを同時に使うときの罠

### 環境
Windows 10
AndroidStudio 2.2
TwitterKit 2.0.1
Crashlytics 2.6.4
Answers 1.3.10

## 何が罠か？
通常FabricのKitを使う際は
`Fabric.with(this, new Crashlytics());`
などとコード上で書いてあげるだけで使用可能になるんですが複数のものを扱う際はこのコードではおかしなことになるというとんでもないものだったという。

## 具体的にどんな不具合が起きるか
コード上に

``` java
Fabric.with(this, new Crashlytics());
Fabric.with(this, new Answers());
Fabric.with(this, new Twitter(config));
```

などと書くとCrashlyticsとAnswersは動作するのにTwitterは動作しなくなり

``` java
Fabric.with(context, new Twitter(config));
Fabric.with(context, new Crashlytics());
Fabric.with(context, new Answers());
```

と書くとTwitter以外動作しなくなるというもの。
つまり順番を入れ替えるだけで動作可否が決まる上に、このコード実行時にはエラーを吐かないという鬼畜仕様（各種Kitを使うときに初めてエラーになるものがある）

ならどうすればいいのか？

## Fabric.Builderを使う
FabricにはBuilderが実装されているので使いたいKitが複数の時は下記のようにするとうまくいく。

``` java
Fabric.Builder builder = new Fabric.Builder(context)
                .kits(new Twitter(config), 
                        new Crashlytics(), 
                        new Answers());
Fabric.with(builder.build());
```

以上
jquery templateの外部ファイル

テンプレートライブラリにて作成した部品を外部ファイル出しして、getで取得。

あぁ～js分からないことだらけなんじゃ～。
ほんと通勤とな週末とか勉強しよ。

あとなんかSafariの開発者モードが上手く修正ファイル読み込まないみたい……。

intellijがぶっ壊れてんのかな？
とりあえず、MacOS慣れないとな。

まぁなんとかなるでしょう！がんばろ！
Swift3でUIBarButtonItemを追加したいのですが、なにか？

Swiftでアプリ書いていますが、なかなか進まずです。
いかんですねえ、だめですねえ、こんなんじゃ。

ナビゲーションバーにボタンをつけようと思って、こう書きましたが、**Expected expression in assignment** とでて進まず。

何がいけないのか。

```
func pushButton(sender:UIButton) {

}

let barButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.add, target: self, action: "pushButton:")
```

Selectorの呼び出しが変わったようなので、こうしてみました。それでもエラーメッセージは変わらず。

```
let barButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.add, target: self, action: #selector(ViewController.pushButton(_:)))
```

さらに修正し、これでビルドできました。

```
let barButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.add, target: self, action: #selector(ViewController.pushButton(sender:)))
```
【検証用メモ】インストールするもの


# 説明
検証用のメモとして使用。
chef-soloもしくはknife-zeroでの各MWインストール手順を検証。
手動でインストールしてから、chef用のコード作成
順番はあとから揃える。

# 環境

```bash
[ec2-user@ip-192-168-0-8~]$ uname -a
Linux ip-192-168-0-8 4.4.11-23.53.amzn1.x86_64 #1 SMP Wed Jun 1 22:22:50 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
```

## clamav

### 手動

#### インストール

```bash
[ec2-user@ip-192-168-0-8 ~]$ sudo yum install clamd
```

#### シンボリックリンク作成

```bash
[ec2-user@ip-192-168-0-8 ~]$ sudo ln -s /etc/clamd.d/scan.conf /etc/clamd.conf
```

しないと怒られる

```bash
[ec2-user@ip-192-168-0-8 ~]$ clamd --version
ERROR: Can't open/parse the config file /etc/clamd.conf
```


準備①
参考:https://centossrv.com/clamav.shtml

```vim
[ec2-user@ip-192-168-0-8 ~]$ sudo vim /etc/clamd.d/scan.conf  
7 # Comment or remove the line below. 
8 # Example　　←コメントアウト(ウィルス定義ファイル更新機能の有効化）
```

準備②
```vim
[ec2-user@ip-192-168-0-8 ~]$ sudo vim /etc/clamd.d/scan.conf 
101 TCPSocket 3310　　←コメントアウト外す
・
・
・
109 TCPAddr 127.0.0.1　　←コメントアウト外す
```

#### バージョン確認
[ec2-user@ip-192-168-0-8 ~]$ clamd --version
ClamAV 0.99.2/21723/Mon Jun 13 13:53:00 2016

#### サービス開始

エラー
```bash
[ec2-user@ip-192-168-0-8 ~]$ sudo /etc/rc.d/init.d/clamd.scan start
Starting clamd.scan: LibClamAV Warning: **************************************************
LibClamAV Warning: ***  The virus database is older than 7 days!  ***
LibClamAV Warning: ***   Please update it as soon as possible.    ***
LibClamAV Warning: **************************************************
```


#### ウイルス定義更新

freshclamコマンドが見つからない

```bash
[ec2-user@ip-192-168-0-8 ~]$ freshclam
-bash: freshclam: command not found
```

clamav-updateパッケージが入っていないとだめらしい
参考:
http://www.server-memo.net/server-setting/clamav/epel-clamav-install.html

```bash
[ec2-user@ip-192-168-0-8 ~]$ rpm -qa | grep clamav-update
[ec2-user@ip-192-168-0-8 ~]$
```

無いのでインストール

```bash
[ec2-user@ip-192-168-0-8 ~]$ sudo yum install clamav-update
```

コマンドはできた
```bash
[ec2-user@ip-192-168-0-8 ~]$ freshclam
ERROR: Please edit the example config file /etc/freshclam.conf
ERROR: Can't open/parse the config file /etc/freshclam.conf
```


↓編集
```bash
[ec2-user@ip-192-168-0-8 ~]$ sudo vim /etc/freshclam.conf
8 # Example　　←コメントアウト
139 #NotifyClamd /path/to/clamd.conf
140  NotifyClamd /etc/clamd.d/scan.conf　←追記
```

sudo で出来た
```bash
[ec2-user@ip-192-168-0-8 ~]$ freshclam
ERROR: Can't create temporary directory /var/lib/clamav/clamav-4ff21dfd9e840f07506ef088bce528fc.tmp
Hint: The database directory must be writable for UID 500 or GID 500
[ec2-user@ip-192-168-0-8 ~]$ sudo vim /etc/freshclam.conf
(略)
bytecode.cld updated (version: 283, sigs: 53, f-level: 63, builder: neo)
Database updated (4879174 signatures) from database.clamav.net (IP: 203.178.137.175) ERROR: NotifyClamd: Can't connect to clamd on 127.0.0.1:3310: Connection refused

```

設定が足りないらしい


今日はココまで





## aide(改ざん検知)





## apache

## mysql
平成○年○月○日をrubyでparse

gem入れたらparseできるけど、gemは入れたくない時用。

いつも何年足せばいいか忘れるので。`match`しないと`nil`を返す。

```.rb
'平成28年9月29日'.match('平成(\d+)年(\d+)月(\d+)日'){ Date.new($1.to_i + 1988, $2.to_i, $3.to_i) }
```
perl使いのpythonメモ - join


- pythonのjoinであれ？とおもったのでメモしときます。

## 数字をjoinしたらエラー

- 年月日を文字列にするイメージです。"2016/4"がほしい値です。

```python
>>> ym = [2016,4]
>>> "/".join(ym)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found

```

- エラーになりました。文字列で連結しろよってことですね。

## 文字列に変換

- mapで文字列に変換します。

```python
>>> ym = [2016,4]
>>> "/".join(map(lambda x:str(x),ym))
'2016/4'
```

- 欲しい形になりました。

## 桁揃え

- monthの部分を0埋めしたいとおもいます。"2016/04"がほしい値です。

```python
>>> ym = [2016,4]
>>> "/".join(map(lambda x:(u"%02d"%x),ym))
'2016/04'
```

## perlなら...

- こんな感じですかね。0埋めしないのならperlのほうが簡単ですね。

```shell
% perl -le 'my @ym = (2016,4);print join("/",@ym)'
2016/4

% perl -le 'my @ym = (2016,4);print join("/",map {sprintf("%02d",$_)}@ym)'
2016/04
```
【iOS】アプリケーションバンドルのデータを取得する

#この記事の概要
iOSアプリに必要なリソースファイル（プロパティリストやJSONファイル）を、プログラムから扱う時の準備及び手続きをいつも忘れてしまうので、基本的な事項ではあるけど記事にまとめておきました。
要は、XcodeプロジェクトにあるファイルをViewControllerクラスのプロパティに格納するまでの作業です。
Swift3になって、データ型の名前やプロパティ名も変更があったようなのでちょうどいい機会かとも思います。

#環境
Xcode8 ~
Swift3 ~
iOS10 ~

#準備
1. iOS系テンプレートで適当なプロジェクトを作成。
2. 「メニュー > File > New > File... > Resource > GeoJSON File」を選択。
3. ここでは、「data」というファイル名にしてます。

#手順
自分でも不思議なくらい毎回のごとく手順があやふやなので、一旦整理。
以下の処理を`getData()->Any?メソッド`なんかを定義しておいて、'viewWillAppear(_:)メソッド'なんかで実行したりする。
1. パスを取得
2. URLを生成
3. Dataインスタンスを生成

##パスを取得する

```swift:パス取得
func getData() -> Data? {

    guard let path = Bundle.main.path(forResource: "data", ofType: "geojson") else { return nil }
}
```
バンドルは、アプリケーションをビルドした後もパッケージ化されているリソースの保存領域のこと。
パスを記述しなくても、ファイル名を指定すればバンドル内を検索してパスを生成してくれる。
生成されたパスは`String?`型になっている。
Guard-Let構文にしておけば、パスを生成できなかったときに対策できる。


##URLに変換する

```swift:パス取得>URL生成
func getData() -> Data? {

    guard let path = Bundle.main.path(forResource: "data", ofType: "geojson") else { return nil }

    let url = URL(fileURLWithPath: path)
}
```
`path`には、ファイルパスがString型の文字列として格納されている。
構造体`URL`型のイニシャライザを使って、URLを生成して`url`に代入。
`URL`型の`url`オブジェクトを得ている。


##データのインスタンスを得る

```swift:パス取得>URL生成>>データ
func getData() -> Data? {

    guard let path = Bundle.main.path(forResource: "data", ofType: "geojson") else { return nil }

    let url = URL(fileURLWithPath: path)

    guard let data = try? Data(contentsOf: url) else { return nil }

    return data
}
```
構造体`Data`型のイニシャライザを使って、`data`オブジェクトを生成している。
パスが間違っていたりして、生成できなかった時のためにGuard-Let構文を使っている。
`data`オブジェクトは`Any`型になっている。
この`data`オブジェクトを`JSONSerialization`クラスなどを使って、解析することになる。

##呼び出し

```swift:viewController.swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let data = getData()
    print(data)
}
```
どこでも必要なタイミングで呼び出せばいいかと思います。
今回の内容ではJSONなどに解析はしていないので、解析後のDictionaryなどはメンバワイズプロパティに持っておくと、いろんなところからアクセスできて便利なんだろうと思います。


#自分へ
忘れるな。
そして、覚えろ。
PHP条件分岐と文字列検索を使ってHTMLを出し分けする

# やりたいこと
PHPでサイトを作っていて、ヘッダーやフッターなどの共通パーツは外部化してインクルードしている。
ページによって、その共通パーツの中身をちょこっと変えたいときがある。

例えば、
ヘッダーに設置したお問合せボタンのリンク先をAのページではあっち、Bのページではそっちにリンク張りたい。でもA用とB用のヘッダーファイルを作るのは面倒だから1ファイルで済ましたい。みたいな感じ。

ガッツリ変えるならファイル分けたほうがいいかもしれないけど、ちょこっとだけのとき用。

※コメントいただき、タイトルと本文を編集しました。

# ①リンクの出し分け
http://自分のサイト.com/a/ 以下にアクセスした際は、Yahooにリンクをはる。
http://自分のサイト.com/abc/ 以下にアクセスした際は、Googleにリンクをはる。

```html+php:ヘッダー.php
<?php 
$path = $_SERVER['SCRIPT_NAME'];
 //ファイルのパスを取得 (例) /a/index.php

if (strpos($path, '/a/') !== false) {
 //strpos($path, '★ここに検索する文字列を書く★')
 $url = 'http://www.yahoo.co.jp/';
 //処理を書く
}
elseif (strpos($path, '/abc/') !== false) {
 $url = 'https://www.google.co.jp/';
}

<header>
 <a href="<?php echo $url; ?>">おすすめのサイト</a>
</header>
```

上記では実現できないような検索をしたいときは、正規表現を使う。

```html+php:ヘッダー(正規表現).php
<?php 
$path = $_SERVER['SCRIPT_NAME'];

if (preg_match('|★正規表現1★|', $path)) {
 $url = 'http://www.yahoo.co.jp/';
 //処理を書く
}
elseif (preg_match('|★正規表現2★|', $path)) {
 $url = 'https://www.google.co.jp/';
}

<header>
 <a href="<?php echo $url; ?>">おすすめのサイト</a>
</header>
?>
```


# ②複数行HTMLの出し分け
ヒアドキュメントを使うと便利。

```html+php:ヘッダー.php
<header>
<div class="bunsyou">
<?php
$path = $_SERVER['SCRIPT_NAME'];

if (strpos($path, '/a/') !== false): ?>
「http://自分のサイト.com/a/ 」<br>
以下にアクセスした際は、<br>
この文章が<br>
表示される。<br>

<?php elseif (strpos($path, '/abc/') !== false): ?>
「http://自分のサイト.com/abc/」<br>
以下にアクセスした際は、<br>
略

<?php endif; ?>
</div>
</header>
```

```html+php:ヘッダー(正規表現).php
<header>
<div class="bunsyou">
<?php
$path = $_SERVER['SCRIPT_NAME'];

if (preg_match('|/a/|', $path)): ?>
「http://自分のサイト.com/a/ 」<br>
以下にアクセスした際は、<br>
この文章が<br>
表示される。<br>

<?php elseif (preg_match('|/abc/|' $path)): ?>
「http://自分のサイト.com/abc/」<br>
以下にアクセスした際は、<br>
略
<?php endif; ?>
</div>
</header>
```
# おまけ
昔こういうのも書いた。
[ユーザーエージェントを取得して、端末によってHTMLを変更する](http://bass-inu.hateblo.jp/entry/2014/04/11/194745)


```html+php:コピペ用
<?php 
$path = $_SERVER['SCRIPT_NAME'];
if(strpos($path, '') !== false){
$url = '';
}elseif(strpos($path, '') !== false){
$url = '';
}elseif(strpos($path, '') !== false){
$url = '';
}elseif(strpos($path, '') !== false){
$url = '';
}
?>

<?php 
$path = $_SERVER['SCRIPT_NAME'];
if(preg_match('||', $path)){
$url = '';
}elseif(preg_match('||', $path)){
$url = '';
}elseif(preg_match('||', $path)){
$url = '';
}elseif(preg_match('||', $path)){
$url = '';
}
?>

<?php echo $url; ?>
```
Docker HubはどこのCDNを使っているのか

Docker imageは数MBから数百MBほどの大きさになることが多いかと思います。アップロードしたイメージをDocker Hubからダウンロードする場合、どのような経路になるのでしょうか。

**「どっかのCDNを使ってるんでしょ？Dockerだけに。」「」**

気になったのでちょっと調べてみました。

## docker pull中の通信を見る

`docker pull`中にWiresharkを起動して怪しい通信を探したところ、`54.192.233.29:443`との通信がイメージのダウンロードに対応しているようです。

```
$ dig +short -x 54.192.233.29
server-54-192-233-29.nrt12.r.cloudfront.net.
```

逆引きしてみるとCloudFrontでした。docker.ioもEC2で提供されているようで、今のところAWSベッタリみたいですね。
白黒陣取りゲーム


- 問題：http://mtsmfm.github.io/2016/10/01/doukaku-e08.html
- 累積和を取る問題例 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0098
  - こんな風に既出ですので、別に[しえるさんメソッド](http://ideone.com/SOs5g7)というわけではないです…
- いもす法 http://imoz.jp/algorithms/imos_method.html
- いもす法の15言語による実践例 http://qiita.com/cielavenir/items/f5c3fcc0553ce0751b29

---

- 計算量を減らす工夫をいろいろしてます。<del>O(HW+min(nC3,HW<sup>2</sup>))となりましょうか。</del>
  - ならしでだいたいO(nHW)になりました(間違ってるかもしれませんが…)
- とりあえず、ideoneで0.1秒になったようです。http://ideone.com/cFZZXQ

```rb:tyama_henae08.rb
#!/usr/bin/env ruby
#http://mtsmfm.github.io/2016/10/01/doukaku-e08.html
#http://qiita.com/mtsmfm/items/94ebd353fa3b7e608f68

H=W=19
while gets
	# 要素が0..18の数値2つ(x座標,y座標)からなる配列
	a=$_.chomp.split(',').map{|e|e.scan(/[a-z]\d+/).map{|f|[f[0].ord-97,f[1..-1].to_i-1]}.sort}
	h=a.map{|e|Hash[*e.flat_map{|(x,y)|[x+y*W,1]}]}
	puts 2.times.map{|i|
		#相手のフィールド：駒を配置して累積和を取る
		#cf: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0098
		opponent=(H+1).times.map{[0]*(W+1)}
		a[i^1].each{|x,y|opponent[y+1][x+1]=1}
		(H+1).times.map{|y|W.times.map{|x|opponent[y][x+1]+=opponent[y][x]}}
		H.times.map{|y|(W+1).times.map{|x|opponent[y+1][x]+=opponent[y][x]}}

if false
		#自分の駒を列挙するには方法が2つある
		#1:3点を列挙して、矩形をなすもう1点の存在を判定する
		#2:x座標の2つ組とy座標の2つ組をそれぞれ列挙して、4点の存在を判定する
		#今回は、列挙する個数が少ない方を自動で選択するようにした
		#(テストケースに依存するが、今回は0.6sから0.5sに高速化)
		xl,yl=a[i].transpose.map{|e|e.uniq.sort}
		f = if a[i].size*(a[i].size+1)*(a[i].size+2)/6 < xl.size*(xl.size+1)*yl.size*(yl.size+1)/4
			Enumerator.new{|y|
				a[i].combination(3){|b|
					if b[0][0]==b[1][0] && b[0][1]==b[2][1] && h[i][b[2][0]+b[1][1]*W]
						y<<[b[1][0],b[2][0]+1,b[2][1],b[1][1]+1]
					end
				}
			}
		else
			Enumerator.new{|y|
				xl.combination(2).to_a.product(yl.combination(2).to_a).each{|(w1,w2),(h1,h2)|
					if h[i][w1+h1*W] && h[i][w1+h2*W] && h[i][w2+h1*W] && h[i][w2+h2*W]
						y<<[w1,w2+1,h1,h2+1]
					end
				}
			}
		end
else
		#cia_ranaさんのアルゴリズムを再現してみました
		#https://bitbucket.org/snippets/cia_rana/aoqqq/e08
		f = Enumerator.new{|z|
			st=0
			a[i].chunk{|x,y|x}.each{|k,v|
				st+=v.size
				(v.size-1).times{|j|
					same_y=a[i][st..-1].select{|x0,y0|y0==v[j][1]}
					(j+1...v.size).each{|k|
						if q=same_y.find{|x0,y0|h[i][x0+v[k][1]*W]}
							z<<[v[j][0],q[0]+1,v[j][1],v[k][1]+1]
						end
					}
				}
			}
		}
end

		#4点が存在することを確認したら、最後に、内部に相手の駒がないことを確認し、陣地に加える
		#陣地の管理はいもす法( http://imoz.jp/algorithms/imos_method.html )を用いる
		#cf: http://qiita.com/cielavenir/items/f5c3fcc0553ce0751b29 (paiza poh5 4b)
		imos=(H+1).times.map{[0]*(W+1)}
		f.each{|w1,w2,h1,h2|
			if opponent[h1][w1]-opponent[h1][w2]-opponent[h2][w1]+opponent[h2][w2]==0
				imos[h1+1][w1+1]+=1
				imos[h1+1][w2]-=1
				imos[h2][w1+1]-=1
				imos[h2][w2]+=1
			end
		}
		(H+1).times.map{|y|W.times.map{|x|imos[y][x+1]+=imos[y][x]}}
		H.times.map{|y|(W+1).times.map{|x|imos[y+1][x]+=imos[y][x]}}
		r=0
		(H+1).times.map{|y|(W+1).times.map{|x|r+=1 if imos[y][x]>0}}
		r
	}*','
	STDOUT.flush
end
```
はたして iPhone は iOS 10 なら動画を自動再生できるのか


結論から言えば可能になりました。
ただし、無音に限る。

## Video要素で自動再生する
[iOS10 Mobile Safariにおけるビデオの自動再生](http://qiita.com/hayakix/items/4c841ea76eab70a66e91)
↑すでに記事があったのでこちらでファイナルアンサーです。

一応自分も検証用にデモを用意したのでリンクだけ貼っておきます。
http://s.codepen.io/haribote/debug/qaVoav
※【大容量注意報】 携帯電話回線での閲覧は通信容量を消費するのでご注意ください！！

### 実装コード例
 [CodePen - video auto play](http://codepen.io/haribote/pen/qaVoav) より一部抜粋

```html
<video src="path/to/video.mp4" width="1280" height="720" autoplay muted playsinline></video>

```
自動再生させるには `autoplay`, `muted`, `playsinline` の3つの属性を設定することが必要です。

## YouTubeも自動再生できませんか…？
YouTubeのIFrame API を利用することで可能です！

こちらも検証用にデモを用意したのでリンク貼ります。
http://s.codepen.io/haribote/debug/NRwYXv
※【大容量注意報】 携帯電話回線での閲覧は通信容量を消費するのでご注意ください！！

### 実装コード例
 [CodePen - youtube auto play](http://codepen.io/haribote/pen/NRwYXv) より一部抜粋

```javascript
const scriptEl = document.createElement('script');
const headEl   = document.querySelector('head');

scriptEl.src = "https://www.youtube.com/iframe_api";
headEl.appendChild(scriptEl);

function onYouTubeIframeAPIReady() {
  const player = new YT.Player('video', {
    videoId: 'YE7VzlLtp-4',
    width: '1280',
    height: '720',
    playerVars: {
      playsinline: 1,
    },
    events: {
      'onReady': onPlayerReady
    }
  });
}

function onPlayerReady(event) {
  const player = event.target;

  player.mute();
  player.playVideo();
}

```
`YT.Player`インスタンスを作るときに `{ playerVars: { playsinline: 1 } }` を設定し、`onReady`ハンドラで `mute()` してから `playVideo()` すれば自動再生します！

## できるからといってやって良いとは限らない
PCサイトでよく見る、トップページの背景に動画を再生させておくようなものをスマホ向けに作ろうと思うと、これまでは大量の画像を用意してパラパラ漫画の要領で`canvas`に描き出す方式が一般的でした。
動作環境として iOS 9 が切れるようになったら（およそ1年後？）、そのような実装は必要なくなるかもしれません。
しかし動画にしてもパラパラ漫画にしても大容量のデータを必要とすることには変わりなく、通信容量制限のある携帯電話回線での閲覧を考えると安易な採用は控えるべきでしょう。
回線種別などを取得することのできる[Network Information API](http://wicg.github.io/netinfo/)が多くのブラウザに実装されれば、「携帯電話回線では自動再生しない」などの振り分けも簡単なのですが…。
ということでスマホ向けに動画の自動再生（っぽいもの含め）を実装するなら用法・用量を守って正しく使ってね（←これが言いたかった）！