OmniAICreator/Qiita-1.07M huggingface dataset:
いい加減 Ruby チュートリアルをやろうと思ったら環境構築で心を折られた話

たぶん 2 万番煎じくらいの記事
きっと Rails あるあるだと思う

# 背景

いい加減社内の人達と共通の言語で会話したくなった（自分が Ruby on Rails 弱すぎてときどき何話してんのか分かんないので）

# 始めてみた環境

- OS X El Capitan (10.11.5)
- iTerm2
- エディタは適当に vim とか
- rbenv だけインストール済み


# 構築で心折れてから成功するまで

とりあえずチュートリアルだし色々壊しても大丈夫なように [こちら](http://qiita.com/egopro/items/aba12261c053eecd6d19) を参考にローカルインストールを試してみた。

```bash
MacBook-Air:rails-tutorial niship$ rbenv versions
  system
* 2.2.3 (set by /Users/niship/.rbenv/version)
MacBook-Air:rails-tutorial niship$ cat Gemfile
# frozen_string_literal: true
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem "rails", "4.2.7"
```

（肝心なこの辺でキャプチャ撮る前に閉じてしまったので適当に書く）

そしたら華麗に `nokogiri-1.6.8` のインストールでエラー。
こいつはいつもぼくの心をへし折ってくる。

なんか `nokogiri-1.6.8/gem_make.out` 見てねって出てるから見た。
したら `libxml2` が見つからないとか言われてた。
んで、実行してるコマンドが先頭に書いてあったから見たらすーごく長いパスで Xcode の下にある `libxml2` 探しに行った挙句無いとか言われてた。

ので、一旦 `$ sudo brew install libxml2` してからの [この辺](https://teratail.com/questions/39554) 参考に参照パスを変更。
（`libxml2` がどこにあるのかは分かんなかったから適当に `$ sudo find / -name "libxml2"` した）
こんな感じ↓

```
rbenv exec bundle config build.nokogiri --use-system-libraries --with-xml2-include=/usr/local/Cellar/libxml2/2.9.4/include/libxml2
```

んでもっかい `bundle install` したら無事成功。
`nokogiri` と `libxml2` はいつも構築で心折ってくる割に構築しようとしてる環境によって原因が微妙に異なってくるのでもしかしたらこの広くはない日本にいるかも知れない同じ環境を構築しようとした人向けにメモ書き。
~~どうせ自分でもっかいくらい忘れて見返すだろうし~~
Git/GitHubをCUIで操作してRuby GemをGitHubにPushするまで

[株式会社オズビジョン](http://www.oz-vision.co.jp/)の@terra_yuccoです。
2016年度、[enPiTプログラム履修生](http://enpit.aiit.ac.jp/)として、
7月～ 品川シーサイドの産業技術大学院大学にて学んでいます。

```
本記事は、2016/07のenPiT事前講義(フレームワーク開発特論)の時に初稿をあげましたが、
本番講義(コラボレイティブ開発特論)の受講契機でリライトしています。
```

職場ではGit/GitHubはTortoiseGitで操作していますが、
講義内ではCUI操作なので、自分のための覚書も兼ねてまとめています。


# 作業の流れ
- GitHubへssh連携
- `bundle gem my_gem_name`でgemの雛形を作成
- 作成された雛形をGitHubへ反映
- branch作成とcommit
- commit後、push

# よく使ったコマンド

コマンド名|簡易説明
:--|:--
git create|GitHubにPublic Repository作成<br />`bundle gem`で作成されたディレクトリ配下で実行してた 
git status|困ったら使ってた
git branch|local branch一覧取得
git branch -r|remote branch一覧取得
git branch -a|local + remote branch一覧取得(上2つは今は未使用)
git branch `test_branch`|`test_branch`でlocal branch作成
git checkout `test_branch`|local branchを`test_branch`に切り替え
git add .|変更のあったファイルすべてをcommit対象に追加
git commit -m '`<commit message>`'|`<commit message>`をコミットメッセージにして commit
git push origin `test_branch`|local branch `test_branch`からremote branch `test_branch`へpush。remoteになければbranch作成も。
git pull|作業が終わった後に最新化するのに使っていた。fetchとの違い理解してない
git fetch|作業が終わった後に最新化するのに使っていた。pullとの違い理解してない
git branch -d `test_branch`|local branch `test_branch`削除

# Gem作成からPull Requestを経てMergeするまで
1. `bundle gem `my_gem_name`
2. git create
    - ID / Password聞かれる
3. git checkout -b `test_branch`
4. vi xxx
    - 編集作業
5. git add .
6. git commit -m `'<commit message>'`
7. git push origin `test_branch`
8. (後はGitHubでCreate Pull Request - Review - Merge - Delete (remote) branch)
9. git checkout `master`
10. git pull
11. git branch -d `test_branch`
12. git fetch -p


# Gitコマンドとは無関係の作業たち
## GitHubへssh連携
- この辺りを参考に
    - [Generating an SSH key](https://help.github.com/articles/generating-an-ssh-key/)

## GitHub操作
- hubコマンド使えばコマンドラインで完結可能

# まとめ
enPiTプログラム事前授業内でよく利用したコマンドをまとめました。
コマンドライン初心者のGit奮闘の現在地の記録。(2016-07-23)

おしまい。
gitのcommit時にどのリポジトリでもAWSのアクセスキーが含まれているかをチェックする設定

gitにはhook機能があり、例えばcommit時にcommitの直前にスクリプトを動かすことが可能です。
これによって、AWSのアクセスキーを誤ってcommitしてしまうことを防ぐことができます。

[AWSアクセスキーをgitに誤って登録しないようにする ｜ Developers.IO](http://dev.classmethod.jp/etc/git_aws_access_key/)

ただ、これだとGitのリポジトリを作るたびにこのhook機能を指定しなければなリません。
いろんなサービスを担当していると、いろんなGitリポジトリを扱うこともありますし、検証の時にふと作ったものに混入する恐れもあります。
Gitリポジトリを作る際に、必ず最初にHookの設定をしなければならないため、いささか面倒でした。

理想は、何も意識せずとも、どんなリポジトリでも必ずAWSのアクセスキーが含まれているかをチェックしたい。

と思ったら、Gitの2.9からはHookのパスをリポジトリに限らず設定できるようになっていました。

* [git 2.9 の core.hooksPath でフックスクリプトの一元管理をやってみた - Qiita](http://qiita.com/kawaz/items/cf8d2a6675e5e3e66e50)
* [git 2.9がリリース，merge/rebase/commitなどに新機能を追加](https://www.infoq.com/jp/news/2016/07/git-29-released)

ということで、めでたくGit2.9からは意識せずに、どんなGitリポジトリでもAWSアクセスキーのチェックができるようになりました。

# Gitのhook機能をグローバルに設定する

まず、`pre-commit`のhookの設定です。ここでは`~/.config/hooks`配下に設定します。

```~/.config/hooks/pre-commit
#!/bin/bash
GREP_RESULT=$(git diff --cached | grep KEY | grep AKIA)

if [ -n "${GREP_RESULT}" ] ; then
  echo 'AWS_ACCESS_KEY might be in this index. Please check with git diff --cached'
  echo "${GREP_RESULT}"
  exit 1
fi
```

ほとんどDevelopers.IOさんの通りです。
実行権を付与しておきます。

```
chmod u+x ~/.config/hooks/pre-commit
```

最後に、このhookをグローバルに設定しておきます。

```
git config --global core.hooksPath ~/.config/hooks
```

ここまでで、端末上のどのリポジトリでも、commit時に勝手にAWSのアクセスキーの確認を行ってくれます。
これまで、必ずリポジトリの単位で設定しなければならなかったのが、最初に1回だけ設定しておけば良くなったので、相当楽になりました。

アクセスキーを設定していると、以下のように怒られます。

```
$ git commit -m "test"
AWS_ACCESS_KEY might be in this index. Please check with git diff --cached
+export AWS_ACCESS_KEY_ID=AKIAXXXXXXXXX
```

皆さんの端末に、とりあえず設定しておけば安心ではないでしょうか。
iOSのUITableViewが難しい話 (初心者向け)

# iOSのUITableViewが難しい話

[Mobile Act NAGOYA #1](http://mobileactnagoya.connpass.com/event/34626/)でのLTの内容をQiita用に投稿します。

---

# 自己紹介

* 龍一郎 (@K_Ryuichirou)
* エンジニア(主にiOS, ARも少々)
* アプリ開発勉強会を開催中 (2016/3〜)
  - Nagoya.Swift+
* 最近Doorkeeperを使い始めました

---

# 今日の内容

* iOSの学習でつまづきがちな箇所について共有
* 実際に勉強会で課題になった箇所について共有します
* 学習者から見て、何が難しいのかについてお話します
* 解決策については対象外とします

---

# 勉強会のご紹介

* Nagoya.Swift+ 
	- 2016年3月から毎月一回開催中
	- 向上心と好奇心を満たすため、分野を超えて挑戦するフリをして遊びます
* メンバー：11名
	- 主に主催の個人的な知り合い
* 内容: Swift, Unity, 機械学習など各自が気になったもの
* 後援: idea+ (http://www.idea-plus.biz/)

---

# 勉強会の参加者

* 参加者のうち、ほとんどがIT系エンジニア

* 普段は開発をやっていない方々がメイン
  - 開発経験者も「書くこともある」程度

* 入門書を書き写したりして勉強する方が多め
  - 自分でテーマを設定して学習する人も

---

# 勉強会の風景

![image.jpeg](https://qiita-image-store.s3.amazonaws.com/0/41266/c77985d3-a38b-7434-7f9d-0070497a2331.jpeg)

---

# iOS学習時によくある問題

- 入門書のサンプルアプリ1〜2個はできた！
- Hello, world.的なアプリはOK
- if文、while文とかもOK
- クラスの定義も書いた

---

# UITableViewを使ったアプリをやる！

---

# なぜか動かない

---

# どうすればいいのかわからない

---

# FIN.

---

# ありがちな症状

1. 何を言っているのかわからない
2. 何をやっているのかわからない
3. なぜ動かないのかわからない

---

# 1. 何を言っているのかわからない

---

# 原因1. 用語の急な増大

* 入門書でも3ページでこれだけ増える
  - UITableView
  - UITableViewController
  - UITableViewCell
  - UITableViewDelegate
  - UITableViewDataSource
  - delegate
  - dataSource
  - プロトコル

---

# 原因2. デリゲートの多義性

* 油断すると全部「デリゲート」と言ってしまう
  - UITableViewのプロパティ(delegate)
  - UITableViewDelegateプロトコル
  - デリゲートパターン

* 「UITableViewのデリゲートを設定する」はどれ？

---

# 2. 何をやっているのかわからない

---

# 原因3. InterfaceBuilder

* StoryboardでUITableViewのプロパティを設定する操作が、それと気がつきにくい
* 更に知っている人は「UITableViewのデリゲートを設定すればいいよ」とか言ってしまう
* Storyboardを使うなと言っているわけではない

---

# 原因4. デザインパターンの壁

* デリゲートでデザインパターンが初めて出てくる
* 初心者向け書籍では解説されない
	- 良くて「デリゲートは処理を他のクラスに移譲することです」程度
	- 全くない場合もままある

---

# 原因5. フレームワークの壁

* MVC的な考え方をここではっきり意識することになる
	- ViewとViewControllerの違いがわからなくなりがち
* 当然、初心者向け書籍では解説されない

---

# 3. なぜ動かないのかわからない

---

# 原因6. UIに関する部分のデバッグが難しい

* Storyboardの設定ミスではアプリが黙って落ちる
* コードを逐次実行していくとAppDelegateで落ちる
* 書いていないところで落ちて何が何だかわからない

---

# 原因7. 入門書が間違っている

* なぜかUITableViewになると解説書の間違いが多くなる
* 今までと同じ方法で動かなくなるのは大変なストレス

---

# 原因8. コードが悪いのか自分が悪いのかわからない

* 「こんな簡単なことを聞いていいのか」となりがち
* Webサイトのコードが動かなかった場合に発症
	- 大概、サイトが悪いけれどそれがわからない
* 特に書籍のコードが動かなかった場合に被害が深刻

---

# 解決策

---

![image.jpeg](https://qiita-image-store.s3.amazonaws.com/0/41266/c77985d3-a38b-7434-7f9d-0070497a2331.jpeg)

---

# 解決の方針

1. 何が難しいのか共有する
2. 何故それが難しいのか解説する
3. その難しさにどう対処しているのか解説する

---

# まとめ

* これから書く人向け: UITableViewはむずかしい
	* 1人で理解しようとしてえらいことになりました
* 書ける人向け: UITableViewはむずかしい
	* その難しさを分析できるだけの能力があるはず
	* 初心者の視点から解説するの大事

---

# 向上心と好奇心を満たすため、分野を超えて挑戦するフリをして遊びましょう
【注意：動作しません】【Realm】【Kotlin】RealmでEnumフィールドを定義するとKotlinならここまで楽になる

#以下の方法では動きません
以下で記載されている方法では動作しません。
すみません。

#どんな記事？
RealmのフィールドにはEnumなどの型サポートがないので、
特定の値しか入らないようなフィールドを自作した。

そんで、Kotlinを使うとここまで楽になったよという話。

今回は分かりやすくするために普通のRDBと同じ用語を使います。

#Enumでsafetyにしたい
例えば PERSONというテーブルにPEREFCTUREという都道府県が入るカラムがあるとします。
当然ここには、存在する都道府県以外の名称は入ってほしくないですよね。

特定の値しか許容しない仕組みといえば、列挙型（Enum）ですが、
RealmではEnum型のフィールドはサポートしていないようです。

じゃあ、自作してしまおう。

#早速コード
```PrefectureEnum.kt
enum class PrefectureEnum(val value: String) {
    TOKYO("東京都"),
    KANAGAWA("神奈川県"),
    // .....以下47都道府県
}
```
```Person.kt
class Person(
    /** 名前 */
    @Required @PrimaryKey open var name: String = "",
    /** 都道府県 */
    prefecture: String = ""

    companion object {
        // 値が含まれているかをチェックする
        @JvmStatic fun contains(value: String): Boolean {
            return values().map { it.value }.contains(value)
        }
    }


) : RealmObject() {
    open var prefecture: String = ""
        //カスタムゲッターでEnum以外の値は取得できないようにする
        get() = if (PrefectureEnum.contains(field) field else "あなたどこ出身？"
        //カスタムセッターでEnum以外の値はセットできないようにする
        set(value) {
            if (PrefectureEnum.contains(value)) field = value
            else field = "あなたどこ出身？"
        }

    init {
        this.prefecture = prefecture
    }
}
```
## Enumクラスに独自のcontainsメソッドを定義

Enum.valuesだとEnum型の配列として取得されるので、mapで値の配列に変換してから
containsで値が含まれているかのチェックを行うようにしました。

Streamが手軽に使えるのはKotlinの大きな強みっすね。

## Personクラスにカスタムセッターゲッターを定義
特定のフィールドにEnumを適応したい場合には
カスタムセッターとゲッターを指定するのがポイント。

Enumクラスで定義した値が含まれていなかったときには、それ専用の値を入れてます。
注意点はcontainsの引数や戻り値には直接のプロパティを渡してはいけないところ。

プロパティ自体を渡すと自分のgetter/setterが再び呼ばれるのでスタックオーバーフローで死にます。
必ず、値だけを渡すようにfieldを指定してください。

## Kotlinサイコーかよ
Kotlinのカスタムゲッター、セッターが存分に活かされたとこです。
StreamもAndroidでJava8が対応したとはいえ、まだ一部機能は制限されてますからね。

というわけでKotlinはやっぱ良い。
CentOS7 を設定するときに役に立ったコマンドたち


## 特定ポートに対する通信チェック（疎通チェック）

```
$ curl -v telnet://localhost:22
$ nc localhost 22
```

## 現在listenしているサービスを確認

```
$ ss -lt
```

## コンテキスト関連
### コンテキストを管理するコマンド
 chcon、semanage fcontext、restorecon
### コンテキストの確認

```
$ ls -lZ
```

### 一時的な変更

```
$ chcon -t type file-name
```

ここでのタイプは httpd_config_t などを指定

### cp でコンテキストを維持する

```
$ cp --preserve=context /etc/passowrd .
```

### パッケージのコンテキストの設定を確認

```
$ sudo semanage fcontext -l | grep nginx
```

### 独自に作成したディレクトリに、nginx と同じタイプ httpd_sys_content_t のコンテキストを設定する

```
$ sudo semanage fcontext -a -t httpd_sys_content_t "/xxx/html(/.*)?"
$ sudo restorecon -R -v /xxx/html/
```

### 設定したコンテキストの設定を削除する

```
$ sudo semanage fcontext -d "/xxx/html(/.*)?"
$ sudo restorecon -R -v /xxx/html/
```

参考：http://www.kakiro-web.com/linux/selinux.html

## 「SELinuxが原因かな？」と思ったら
/var/log/messages または /var/log/audit/audit.logに、"avc: denied"というメッセージが記録されていないか確認

## アカウントのパスワードの長さの設定
/etc/login.defs
PASS_MIN_LEN

## インストールされているサービス一覧や自動起動の確認

```
% systemctl in-active (or status or list-util-files)
```

## コマンドが必要としているライブラリを調べる

```
% ldd /bin/bash
```

## ネットワークの設定
### 設定ファイルの場所
/etc/sysconfig/network-scripts/ifcfg-NIC名
 
### ネットワークの再起動

```
% sudo systemctl restart network
```

## 利用可能なターゲットを確認

```
% systemctl list-units --type=target --all --no-pager
```

## ログ機構「Systemd Journal」
### ブートログを出力する

```
% journalctl -b
```

### 日時でフィルタリングする

```
% journalctl --since="2014-09-05 01:23:45" --until="2014-09-07 04:56:00"
```

### ログをリアルタイムで閲覧（tail -f みたいな使い方）

```
% journalctl -f
```

### 特定のプライオリティのログのみを出力

```
% journalctl -p warning
```

```
% journalctl -p 0       ← emerg
% journalctl -p 1       ← alert
% journalctl -p 2       ← crit
% journalctl -p 3       ← err
% journalctl -p 4       ← warning
% journalctl -p 5       ← notice
% journalctl -p 6       ← debug
```

### カーネルログのみを表示（従来のsyslog管理のdmesgに相当）

```
% journalctl -k
```

### 特定のプロセスIDのみログを出力

```
% journalctl _PID=10765
```

### crond に関するログの表示

```
% journalctl /usr/sbin/crond
```
Vagrant コマンドラインインターフェース STATUS

#STATUS

##Command: vagrant status [name|id]

Vagrantが管理しているマシンのステータスを表示する。

Vagrantに慣れるとマシンのステータスが運転中（RUNNING）か、中断中（SUSPENDED）か、または未作成（NOT CREATED）かを忘れてしまうことがある。
そのような時にこのコマンドを使い、ゲストマシンのステータスを確認できる。
Vagrant コマンドラインインターフェース VERSION

#VERSION

##Command: vagrant version

インストールされているVagrantのバージョンと入手可能な最新バージョンの情報を表示する。

Vagrantの最新バージョン取得にはネットワーク接続を要する。
インストールされているバージョンのみを確認するには、

<b>vagrant --version</b>

を使用する。
Vagrant コマンドラインインターフェース 目次

# Vagrant コマンドラインインターフェース

### 目次

| No | コマンド |
|-----------:|:------------|
|1|[box](http://qiita.com/CsFactoryitter/items/d4d16f6fcd328c97ebc8)|
|2|[connect](http://qiita.com/CsFactoryitter/items/37ef8ae00ea905a237b0)|
|3|[destroy](http://qiita.com/CsFactoryitter/items/a3d6da6052d5a0025849)|
|4|[global-status](http://qiita.com/CsFactoryitter/items/fd92a945f05c61937a0f)|
|5|[halt](http://qiita.com/CsFactoryitter/items/ba9e93da68692bf852be)|
|6|[init](http://qiita.com/CsFactoryitter/items/c3a5a23a38cf44ffdc40)|
|7|[login](http://qiita.com/CsFactoryitter/items/a4a87c1629af053114b2)|
|8|package|
|9|[plugin](http://qiita.com/CsFactoryitter/items/37009635dfc85717e59a)|
|10|[port](http://qiita.com/CsFactoryitter/items/07986b4c2c2f19487b57)|
|11|[powershell](http://qiita.com/CsFactoryitter/items/3f060cd92a43c6ccd827)|
|12|provision|
|13|rdp|
|14|[reload](http://qiita.com/CsFactoryitter/items/3c8b9a8c1849ceb21a7f)|
|15|resume|
|16|share|
|17|snapshot|
|18|ssh|
|19|ssh-config|
|20|[status](http://qiita.com/CsFactoryitter/items/18e8885d6fb5b6f986cc)|
|21|suspend|
|22|[up](http://qiita.com/CsFactoryitter/items/364bfeb65700cf3db8a4)|
|23|[version](http://qiita.com/CsFactoryitter/items/6fdb5fb81be092ffbd45)|
npm から gulp インストールまでの手順

こういうのすぐ忘れるのでメモしつつ、新しい発見があったら追記。
自分で書かないと覚えないんだよなぁ。

## node.js

╭( ･ㅂ･)و node.js をインストールしておきます。
https://nodejs.org/en/

## npm（Node Package Manager）の設定・確認

╭( ･ㅂ･)و node.jsをインストールをするとnpmコマンドが使えるようになります。

### npmのバージョンを確認しておく

```
npm -v
```

### npmのバージョンを最新にしておく

╭( ･ㅂ･)و 既にインストール済みであれば、最新バージョンを導入しておきます。
2016/07/23 時点 version 3.10.5 が最新みたい。

```
sudo npm install -g npm
```

### npmの設定ファイルを作成

```
npm init
```

╭( ･ㅂ･)و コマンドを叩いたディレクトリに `package.json ` というファイルができます。

## gulpの設定・確認

╭( ･ㅂ･)و gulpはグローバルとローカルにインストールする必要があります。

### グローバルインストール

╭( ･ㅂ･)و ローカルにインストールした `gulp` を実行させるためにグローバルの `gulp` は必要らしい。

```
sudo npm install -g gulp
```

### ローカルインストール

 - --save

```
sudo npm install gulp --save
```

`--save` パラメータは、 `package.json` の `dependencies` という項目に追加されます。

```
  "dependencies": {
    "gulp": "^3.9.1"
  },
```

 - --save-dev

`--save-dev` パラメータは、 `package.json` の `devDependencies` という項目に追加されます。

```
  "devDependencies": {
    "gulp": "^3.9.1"
  },
```

#### Q. dependencies と devDependencies の違いは？

╭( ･ㅂ･)و [ dependencies（意味：依存関係） ]
その名の通り、そのパッケージに依存するファイルを管理しています。例えば `jQuery` などWebサイトに使用するファイルは、 `dependencies` で管理しますかね。

```
npm install jquery --save
```

バージョン指定をする場合には、インストールするパッケージ名の後ろに @ でバージョンを指定します。（指定なしは最新バージョンがインストールされます）

```
npm install jquery@1.11.3 --save
```

╭( ･ㅂ･)و [ devDependencies（意味：開発者に必要な依存関係） ]
実際のパッケージには必要ないファイルで、開発時に使用するものはこちらですかね。 `gulp` はこっちでいいかな。

```
npm install gulp --save-dev
```

### package.json の役割

`npm install` で `--save` をつけると、 package.json にインストールしたパッケージ名とそのバージョンが自動的に保存されます。これで `npm` コマンドが使えるPCであれば同じ環境を作ることが出来ます。インストールしたファイルごと管理しなくて済むステキツール。
`node_modules` というディレクトリに `npm` でインストールしたものは保存されるので、 `.gitignore` で監視下から外しておくことでインストールしたファイルまでバージョン管理しなくてよくなります。 `package.json` だけメンテナンスしておけばいいんだもんね。

`gulp` ファイルの設定は別の記事に書こう。混乱する。自分が。| ω・)
Chainerを使う時の注意点


## Chainerを使う時は目的変数は0から始める

いろいろやってみた感じ、sklearnでは目的変数は[-1,0,1]等でできるのだが、どうもChainerでは[0,1,2]のようにした方がいい。
たぶん、損失関数の計算でおかしなことが起きていると思われる。

## predictの注意

以下のようにサンプル等では書かれることが多い。

```python
class ChainerClassifier(BaseChainerEstimator, base.ClassifierMixin):
    def predict(self, x_data):
        return BaseChainerEstimator.predict(self, x_data).argmax(1) #argmaxは行列の行の中で最大になるインデックスを返す。つまりクラスは0から1,2としていかないといけない
```

コメントにも記載したようにargmax関数はインデックスを返すので、目的変数を-1から始めていたりするとおかしなことになるので注意。

## max_pooling_2dとaverage_pooling_2dのpollingサイズ指定の違い

maxプーリングではpoolingははみ出してもいい。
つまり、奇数のカラム数もしくは行数に対して偶数のpoolingサイズでも問題無い。
逆も然り。

だが、averageプーリングでは厳密にカラム数と行数はpoolingサイズの倍数でないといけない。

たぶん、maxは少なくても計算できるが、平均は計算できないため。

なお、maxプーリングの方が速度が遅い。
標準出力のバッファリングを用いてHTML出力をきれいに

# 概要
PHPで変数や関数が入り混じったビューを記述しているときにそれを関数に収めてまとめて結果を返したい時ってあると思います。
例えばこんな感じにある関数からHTMLを返し、それをいろいろ編集したり、処理を加えてから出力する場面です。

```php
<?php

function getFamilyName()
{
    return "<p>仲良し家族</p>";
}

function getHtml()
{
    $str = '';

    $str .= '<div id="parent">';
    $str .= getFamilyName();
    $str .= '<div id="child-1">たいち</div>';
    $str .= '<div id="child-2">たけし</div>';
    $str .= '<div id="child-3">たけよし</div>';
    $str .= '<div id="child-4">たけお</div>';
    $str .= '</div>';

    return $str;
}

$html = getHtml();

//何か処理した後
//何か処理した後
//何か処理した後

echo $html;
```
この中ではもちろんechoとかPHPタグで区切ってしまった時点で関数の実行時に出力されてしまうので、その方法はとれません。
ヒアドキュメントを使用した場合、下記のようになりますが、エディタによって整形が行えなかったりします。
また、中で関数が使用できないので、最初に変数に格納するといった処理が必要となってしまいますね。

```php
<?php

function getFamilyName()
{
    return "<p>仲良し家族</p>";
}

function getHtml()
{
    $familyName = getFamilyName();
    $str = <<<EOF
<div id="parent">
{$familyName}
<div id="child-1">たいち</div>
<div id="child-2">たけし</div>
<div id="child-3">たけよし</div>
<div id="child-4">たけお</div>
</div>
EOF;

    return $str;
}

$html = getHtml();

echo $html;
```



こんなときは標準出力のバッファリングを扱うことによって綺麗にかつスマートにできます。

# 実際の手法
**ob_start**、**ob_get_contents**という関数を使っていきます。
出力をバッファリングしてくれる関数です。
PHPのecho、print、PHPタグで囲われていない箇所は、標準出力といい、ブラウザであれば画面(ソース)に、ターミナルであればターミナル上に出力されます。
その出力内容を出力せず、一時的に蓄えるようにするのがob_startです。
実際に上のコードを書き直してみましょう。

```php
<?php

function getFamilyName()
{
    return "<p>仲良し家族</p>";
}

function getHtml()
{
    ob_start(); // バッファリング開始
    ?>
    <div id="parent">
        <?php echo getFamilyName(); ?>
        <div id="child-1">たいち</div>
        <div id="child-2">たけし</div>
        <div id="child-3">たけよし</div>
        <div id="child-4">たけお</div>
    </div>
    <?php
    $str = ob_get_contents(); // バッファリング取得
    ob_end_clean(); // バッファリング終了

    return $str;
}

$html = getHtml();

//何か処理した後
//何か処理した後
//何か処理した後

echo $html;
```
ob_startでまずバッファリングを開始します。ここから出力は一時的に蓄えられます。
ob_get_contentsで実行した時点の蓄えた出力内容を取得することができるので変数に格納することができます。
ob_end_cleanでバッファリングを終了、蓄えた出力内容を破棄します。

これによって、整形ツールなどでビュー部分をきれいに保てたり、値を返す関数をechoで出力しているものを、別に出力専用の関数がある場合そちらに書き直すこともできます。


# 実活用例
例えば、WordPressのショートコードで使用するための関数では、出力をその関数内で行うのではなく、出力したい結果を返す形が正しい形です。
他にも、テンプレートエンジンのようなものでも活用できるのではないでしょうか。

下記はWordPressのショートコードの例です。

```php:shortcode.php
add_shortcode('test', 'testFunc');
function testFunc()
{
    ob_start();
    ?>
    <div class="detail">
        <div class="name"><?php the_title(); ?></div>
        <div class="date"><?php the_date(); ?></div>
    </div>
    <?php
    $str = ob_get_contents();
    ob_end_clean();

    return $str;
}

```

これでWordPressの記事本文で[test]という記述があれば、その記述の箇所に正しく出力してくれます。

# 参考
http://blog.s-giken.net/249.html
Xamarinをアンインストール後、関連ファイルを手動で削除した（Mac OS X）

# 背景
- Xamarinをインストールしたら、ストレージの残り容量が12〜13GB減った
- [AppCleaner](http://beadored.com/mac-application-uninstall-delete-related-files/)でXamarinを削除したけど、残り容量が3〜4GBしか増えなかった
- 他にもまだまだ消せるファイルがあるのでは

# 結論
- AppCleanerでは消してくれないファイルがたくさんある
- 不要ファイルはfindコマンドで探して、手動で消すと良いのでは

# AppCleanerでは消してくれないファイルを探す
参考記事：
[Mac で Xamarin 環境をクリーンに再インストールするには](http://ytabuchi.hatenablog.com/entry/2014/02/27/204508)
※「Xamarinといえばエクセルソフト田淵さん」の記事が見つかった。

これも参考にしつつ、いっそfindコマンドでストレージ全体を検索。

```bash
$ sudo find / -name Xamarin*
```


# 結果的に手動で消したやつ
findコマンドで探して、以下のものをfinderから手動で削除。

- ~/Library/Xamarin
- ~/Library/XamarinStudio-5.0
- ~/Library/Preferences/Xamarin
- /Developer/MonoTouch
- /Developer/MonoAndroid ※シンボリックリンク
- /Library/Frameworks/Xamarin.Android.framework
- /Library/Frameworks/Mono.framework

- ~/.local/share/MonoForAndroid
- ~/.local/share/Xamarin
- ~/.local/share/XamarinInsights
- ~/Downloads/app-crm-master
- ~/Library/Caches/XamarinInstaller　　※ちなみにこのディレクトリだけで6.95GBあった。。。

- ~/Library/Logs/XamarinInstaller
- ~/Library/Logs/XamarinStudio-5.0
- ~/Library/Logs/XamarinStudio-6.0


以下は、AndroidのAVD Managerで削除
- ~/.android/avd/Xamarin Android API 15.avd
- ~/.android/avd/Xamarin Android API 23.avd
- ~/.android/avd/Xamarin_Android_API_15.ini
- ~/.android/avd/Xamarin_Android_API_23.ini


これで8GB〜10GB程度の空き容量が増えた。
~/Library/Caches にはXamarin以外にもまだまだいろんなゴミが残ってそうだなと。



![スクリーンショット 2016-07-23 15.05.36.png](https://qiita-image-store.s3.amazonaws.com/0/59209/ddf0b3a1-d4cf-bd3c-59ee-d6fce3add323.png)
Xamarinをアンインストール前は、36GB空きくらいだったのが、54GB空きまで改善。
（ただしXamarin以外も数GB程度消している）

やっぱり128GBじゃなくて、256GBを買っておけば良かったかなぁ。。。
MacのOSをEl CapitanにアップグレードしたらPHPが使えなくなったので対処しました。

## 背景

アップグレード恐怖症なわたくしですが、だいぶ眺めの様子見期間に終止符を打つべく
MacBook Proにて以下の環境からOSをEl Capitanにアップグレード。

- MacBook Pro (Retina, 13-inch, Mid 2014)
- OS: Yosemite（バージョン情報メモってなかったのでわかりません）
- PHP 5.5.31
- Apache/2.4.18 (Unix)

その後、何か動かなくなったり使えなくなったりしているアプリケーションとか無いかなぁと確認中に
以下事象が判明。

## 事象

PHP動いてるかなぁと、MacのデフォルトDocumentRoot(/Library/WebServer/Documents)に置いていた動作確認用のファイル「phpinfo.php」

```php:phpinfo.php
<?php

phpinfo();

?>

```

にブラウザからアクセス( http://localhost/phpinfo.php )したら...

![スクリーンショット 2016-07-23 14.01.48.png](https://qiita-image-store.s3.amazonaws.com/0/74725/1f770c9b-224d-1693-8a99-57bc5e4fe0bd.png)

ありゃ、動いとらんねと判明。

## 原因

コードは表示されているのでApacheは起動している。
ってことはApacheの設定が書き換わったか？

と推察し確認してみたら、OSのアップグレードによって
Apacheの設定ファイルが上書きされ、PHPモジュール読み込みの記述がコメントアウトされていた...オイ！（笑）

`$ ls -al /etc/apache2/`

<img width="796" alt="スクリーンショット 2016-07-23 14.06.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/74725/9a42d4f3-53a9-b35d-1f78-49a51975fc4a.png">

`$ sudo vim /etc/apache2/httpd.conf`

```apache:httpd.conf
168 #LoadModule ...
169 #LoadModule php5_module libexec/apache2/libphp5.so
170 #LoadModule ...
```

## 解決策

### 1. /etc/apache2/httpd.conf のPHPモジュール読み込み部分のコメントアウトを外す

`$ sudo vim /etc/apache2/httpd.conf`

```apache:httpd.conf
168 #LoadModule ...
169 LoadModule php5_module libexec/apache2/libphp5.so
170 #LoadModule ...
```

### 2. Apacheを再起動

`$ sudo apachectl restart`

## 再度ブラウザにて確認

![スクリーンショット 2016-07-23 14.33.32.png](https://qiita-image-store.s3.amazonaws.com/0/74725/50d46b6e-7cb2-1ae0-9778-424e9eda2fd5.png)

はい完了。


## 最後に

「Time　Machineでバックアップは取ってるから何か問題があったら戻しゃあいいかー」
という前提でOSをアップグレードしたのですが、やはり何かありましたね。
まぁ大した問題ではなかったですが。
Macをホストとして他サーバへAnsibleする手順


### 前提・例
対象サーバにおいて
* IPアドレス: `192.168.1.5`
* CentOS
* `taro01`というsudo権限のあるユーザがいる

これらの例を前提とします

## MacにAnsibleをインストール
[公式](http://docs.ansible.com/ansible/intro_installation.html#latest-releases-on-mac-osx)によると、Pythonで使われるpipを利用するのが一番良いらしい。

参考

* [Ansible公式](http://docs.ansible.com/ansible/intro_installation.html#latest-releases-via-pip)
* [Pythonインストール（Mac編）](http://qiita.com/ms-rock/items/6e4498a5963f3d9c4a67)
* [MacでPython使う時の最低限のメモ（Homebrew編）](http://qiita.com/zaburo/items/fbdaf6c04151671407db)

これらを参考にpipを手に入れる

virtualenvでpipを使い分けるなど良しなに

#### Ansibleをpipでインストール

```
$ pip install ansible
```

#### 最新バージョンをインストールする場合

```
$ pip install git+git://github.com/ansible/ansible.git@devel
```


## MacのSSH公開鍵を対象サーバの`~/.ssh/authorized_keys`へ追記


Macの`~/.ssh/id_rsa.pub`の中身を
対象サーバ内の`/home/taro01/.ssh/authorized_keys`ファイルへ
FTPやらコピペやら等を利用して追記する

例
### Mac側で

#### Mac側で公開鍵を作っていなかったら作る

```
$ ssh-keygen
```

#### SCPで公開鍵ファイル転送

```
$ cd ~/.ssh
$ scp id_rsa.pub taro01@192.168.1.5:~/.ssh/mac_rsa.pub
```



### 対象サーバ側で

#### `authorized_keys`ファイルに追記

```
$ cd ~/.ssh
$ cat mac_rsa.pub >> authorized_keys
```

#### 公開鍵を削除しておく

```
$ rm ~/.ssh/mac_rsa.pub
```

## Ansibleのインベントリファイルを作成
#### Mac側でインベントリファイルを作成
例

```hosts
[all]
192.168.1.5
```

## Pingで接続確認
Mac側で

```
$ ansible 192.168.1.5 -m ping -i hosts -u taro01
```

正常に接続できることを確認する


## Ansilbe Playbook利用

ここまで整えばAnsibleで環境構築が可能

#### PlayBookを作成

プレイブックYAMLファイル 例

```site.yml
---
- name: sample playbook
  hosts: all
  remote_user: 
  become: True

  tasks:
	- name: install the latest version of Apache
	  yum: name=httpd state=latest
```

#### `ansible-playbook`コマンドを実行

```
$ ansible-playbook site.yml -i hosts -u taro01
```

Ansibleが実行される
ZYBO / VHDL > カウント値をトリガタイミングでホールドする

```txt:動作確認
Vivado 2015.4 on Windows 8.1 pro (64bit)
```

パルスカウンタなどで使うと思われるカウント値のホールド機能を考えてみた。
言葉しか知らないラッチ回路やフリップフロップ回路と関係あるのか今は未消化。

仕組みとしては、以下で実装したカウンタ機能において、trigの立ち上がりエッジ時にカウンタ値を別のstd_logic_vector型にコピーするということにした。
http://qiita.com/7of9/items/b669e37d52721273c923

### code

```countStore.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity countStore is
port(   clk : in std_logic;
        reset : in std_logic;
        cnt_d : inout std_logic_vector (3 downto 0); -- counter
        trig : in std_logic; -- trigger to store the cnt_d value
        str_d : out std_logic_vector (3 downto 0) -- store of the counter value 
        );
end countStore;

architecture Behavior of countStore is
signal DFF_4 : std_logic_vector (3 downto 0) := "0000";

begin

process(trig)
begin
    if ( trig'event and trig = '1') then
        str_d <= cnt_d;
    end if;
end process;

process(Clk, Reset)
begin
    cnt_d <= DFF_4;
    if (Reset = '1') then
        DFF_4 <= (others => '0');
    elsif ( clk'event and clk = '1') then    
        if (DFF_4 = "1111") then
            DFF_4 <= (others => '0');
        end if;
        DFF_4 <= DFF_4 + 1;
    end if;
end process;
end Behavior;
```

```countStore.tb
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity testbench is
end testbench;

architecture behavior of testbench is
signal clk : std_logic;
signal reset : std_logic;
signal cnt_d : std_logic_vector (3 downto 0);
signal trig : std_logic;
signal str_d : std_logic_vector (3 downto 0);
constant clk_period : time := 10 ns;

begin
uut: entity work.countStore PORT MAP (
    clk => clk,
    reset => reset,
    cnt_d => cnt_d,
    trig => trig,
    str_d => str_d);

trigger : process
begin
    wait for 5 * clk_period / 2; -- for delay (5: arbitrary)

    wait for 20 * clk_period / 2; -- (20: arbitrary)
    trig <= '1';
    wait for 20 * clk_period / 2;    
    trig <= '0';
end process;

stimulus : process
begin
    wait for 32 * clk_period / 2;
    reset <= '1';
    wait for 32 * clk_period / 2;
    reset <= '0';
--    wait for 300 ns;
end process;

clk_process : process
begin
    clk <= '0';
    wait for clk_period / 2;
    clk <= '1';
    wait for clk_period / 2;
end process;

end behavior;
```

### 結果

trigの立ち上がりエッジ時のcnt_dの値がstr_dにコピーされている。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7c28f7f0-9bdc-1fcf-6418-860118b2954e.png)


図でオレンジ色になっている部分は初期化処理が失敗している。このあたりはこれからの課題。
よく使うGitコマンド

これだけ覚えときゃ仕事でなんとかなる。オレの場合は。

#ブランチの確認

* ローカルのブランチ確認

```
git branch
```

* リモートのブランチ確認

```
git branch -r
```

* 追跡中のブランチ確認

```
git branch -vv
```

#ブランチの作成
* カレントブランチからブランチを作成

```
git checkout -b branch_name
```

* リモートからクローンしてブランチを作成

```
git checkout -b branch_name origin/branch_name
```

#ブランチの切り替え

```
git checkout branch_name
```

#指定したファイルのチェックアウト

```
git checkout コミットID path
```
pathにファイルのパスを指定すると、そのファイルだけチェックアウトできる。  
pathにディレクトリを指定するとそのディレクトリ配下のファイルを全てチェックアウトできる。

#git logをツリー表示
* コミットID省略版

```
git log --graph --pretty=format:"%h %cd %s"
```

* コミットID全表示版

```
git log --graph --pretty=format:"%H %cd %s"
```

* 変更したファイルを表示

```
git log --name-status
```
#ファイルのステージング

```
git add .
```


#コミット

* 普通のコミット

```
git commit
```

* ブランチを作った直後に初期コミット

```
git commit --allow-empty
```

#プッシュ
* 追跡中ブランチへのプッシュ

```
git push
```

* カレントブランチ名と追跡中ブランチ名が異なる場合のプッシュ

```
git push origin current_branch_name
```

* リモートのカレントブランチを追跡するようにさせつつプッシュ

```
git push -u origin current_branch_name
```

#ブランチの削除
* 安全な削除

```
git branch -d branch_name
```

* 強制削除

```
git branch -D branch_name
```

#マージ

branch_nameのブランチをカレントブランチにマージする

```
git merge branch_name
```

#リモートの変更の取り込み

```
git pull
```
Windows上のknife zero でCentOSのプロビジョニング

knife zero でCentOSのプロビジョニング

## 対象

* クライアントOS Windows7
* プロビジョニング対象ホストOS CentOS 6.7

## 対象ホストにインストールするもの

* rbenv
* ruby_build::system

## クライアントの設定

### .ssh/config 設定

まずIPアドレスとかでなく名前でアクセスしたいので ~/.ssh/config を編集する。

~/.ssh の場所は C:\Users\hogeuser\.ssh
```
Host centos
  HostName 192.168.0.200
  Port 22
  User hogeuser
```

ホストの名前、IPアドレス、ユーザーなどは環境に合わせて適宜設定する。

### knife.rb 準備

あらかじめknife.rb を以下の内容で準備する。
どこかで「cookbook_pathを複数設定できない」とか見た気がするが、今のバージョンでは大丈夫っぽい。

```
ocal_mode true
chef_repo_path   File.expand_path('../' , __FILE__)
cookbook_path    [ 
  File.expand_path('../cookbooks' , __FILE__), 
  File.expand_path('../site-cookbooks' , __FILE__)
]

knife[:ssh_attribute] = "centos"
knife[:use_sudo] = true

knife[:automatic_attribute_whitelist] = %w[
  fqdn
  os
  os_version
  hostname
  ipaddress
  roles
  recipes
  ipaddress
  platform
  platform_version
  cloud
  cloud_v2
  chef_packages
]
```


## 対象ホストの準備

knife zero bootstrap コマンドを使ってプロビジョニング対象ホストにchef-clientをインストールさせる。

```
PS C:...\> knife zero bootstrap centos --ssh-user hogeuser --sudo
```

## レシピ作成

Berksfile に以下を記述

```
source "https://supermarket.chef.io"

cookbook 'ruby_rbenv', :git => 'https://github.com/chef-rbenv/chef-rbenv.git'
```

Berksレシピ取込

```
PS C:...\> berks vendor cookbooks
```

他、自前のレシピが必要ならsite-cookbooksに作成しておく。

## runlist、attribute設定

node.jsonを修正してrunlistなどを設定する。

runlist

```
  "run_list": [
    "recipe[ruby_build]",
    "recipe[ruby_rbenv::system]"
  ]
```

## プロビジョニング 実行

いよいよ実行

```
PS C:...\> knife zero converge 'name:centos.example.com' --attribute ipaddress --ssh-user hogeuser --sudo
```

## その他

本当は system globalに ruby 2.3.1をインストールした状態にしたかったのだけど、node.jsonの書き方を間違ったのかできなかった。
vim上でのphp−cs−fixer実行時にdiffの結果を表示させる方法

#やりたいこと
vim上でphp-cs-fixerを実行した時、一度dry−runをかけて変更箇所（どこがどう変更されるのか）を確認してから実際にfixさせたい！

#前提
vim上でphp-cs-fixerを実行できる状態まで持っていきます。手順は以下を参考にしてください。

- php-cs-fixerのインストール
https://github.com/FriendsOfPHP/PHP-CS-Fixer


- php-cs-fixerをvim上で実行させるプラグインのインストール
https://github.com/stephpy/vim-php-cs-fixer

#デフォルトのOption Available
stephpy/vim-php-cs-fixerで指定できるオプションを確認してみると、diffの項目がありません。

```vim
" If php-cs-fixer is in $PATH, you don't need to define line below
" let g:php_cs_fixer_path = "~/php-cs-fixer.phar" " define the path to the php-cs-fixer.phar
let g:php_cs_fixer_level = "symfony"              " which level ?
let g:php_cs_fixer_config = "default"             " configuration
"let g:php_cs_fixer_config_file = '.php_cs'       " configuration file
let g:php_cs_fixer_php_path = "php"               " Path to PHP
" If you want to define specific fixers:
"let g:php_cs_fixer_fixers_list = "linefeed,short_tag,indentation"
let g:php_cs_fixer_enable_default_mapping = 1     " Enable the mapping by default (<leader>pcd)
let g:php_cs_fixer_dry_run = 0                    " Call command with dry-run option
let g:php_cs_fixer_verbose = 0                    " Return the output of command if 1, else an inline information.
```

なので今回はプラグイン本体に修正を加え、diffの結果を表示できるようにします。


#プラグインの変更
デフォルトでは次のようになっています。

```vim:~/.vim/bundle/vim-php-cs-fixer/plugin/php-cs-fixer.vim
 44     if a:dry_run == 1
 45         echohl Title | echo "[DRY RUN MODE]" | echohl None
 46         let command = command.' --dry-run'
 47     endif
```


これを以下のように修正します。今回は一度dry−runを実行し、変更箇所を確認してから、実際にfixをかけるようにしたかったので、dry−run実行時にdiffを一緒に指定しました。

```vim:~/.vim/bundle/vim-php-cs-fixer/plugin/php-cs-fixer.vim
 44     if a:dry_run == 1
 45         echohl Title | echo "[DRY RUN MODE]" | echohl None
 46         let command = command.' --dry-run --diff'
 47     endif
```

このように変更を加えた後、オプションのdry_runとverboseの項目を１にしてやればOK。これでvim上からphp−cs−fixerを実行した時に、一度dry−runを走らせ変更箇所を確認したのちに、実際にfixをかけられるようになります。


```vim
" If php-cs-fixer is in $PATH, you don't need to define line below
" let g:php_cs_fixer_path = "~/php-cs-fixer.phar" " define the path to the php-cs-fixer.phar
let g:php_cs_fixer_level = "symfony"              " which level ?
let g:php_cs_fixer_config = "default"             " configuration
"let g:php_cs_fixer_config_file = '.php_cs'       " configuration file
let g:php_cs_fixer_php_path = "php"               " Path to PHP
" If you want to define specific fixers:
"let g:php_cs_fixer_fixers_list = "linefeed,short_tag,indentation"
let g:php_cs_fixer_enable_default_mapping = 1     " Enable the mapping by default (<leader>pcd)
let g:php_cs_fixer_dry_run = 1                    " Call command with dry-run option
let g:php_cs_fixer_verbose = 1                    " Return the output of command if 1, else an inline information.
```

なおこの方法では、diffの結果の表示色は全てオレンジとなってしまいます。ターミナル上でdiffの結果を表示させた時は変更前が赤、変更後は緑、みたいな感じで表示されているので、それに合わせに行きたいところですが、目的は達成されたので一旦ここまでとします。
Rails4でgem 'meta_search'を消してくれと言われた時の対処法

#問題
gem 'meta_search'を消してくれと言われたけど、そんなgem入れた覚えない。

```zsh
Your bundle requires gems that depend on each other, creating an infinite loop. Please remove gem 'meta_search' and try again.
```

#原因と解決策
原因はactiveadminだった。

```gemfile.
gem 'activeadmin'
```

gem 'activeadmin'を入れる際に、Railsのバージョンによっては、bundle install しようとするだけでエラーが出るようだ。下記のように書き換えるとbundle installできた。

```gemfile.
gem 'activeadmin', github: 'activeadmin'
```

#環境
ruby 2.2.3
Rails 4.2.6
こんなプロジェクトは破綻する②

続編です。

# メンバーが、スケジュールを把握していない。

これ結構あります。
場当たり的に作業しているので少しづつ遅れます。

パターンは、大きく2つあります。

### 寄せ集めチームの場合

この場合は、チーム内でコミュニケーションをとらない人が多くなりがちです。
商流の深い人は特にそうなりやすいです。

「単純に言われた作業だけしている」的な状態なので、生産性も低いです。

### 仲良しチームの場合

この場合、スケジュールがちょこちょこ変わって来ると危険です。
それでも
「細かいことを言わないで、ドンドン進めよう」
的な雰囲気になるので、結果遅れます。

### 対策
当たり前かもしれませんが

- 締め切りを明示する。
- 日々の進捗を管理する
が必要です。


# 日報の報告欄で常に 「問題なし」

そんなはずはないです。
開発していると、小さな問題はあるはずです。
ただ面倒で報告していないだけです。

一人一人話をして、問題を見つけに行かないと、
隠れた問題が積み重なり、対処しきれなくなります。

また、初めての取引先に外注している時は特に注意が必要です。

しっかり実状を把握しておかないと、取り返しがつかなくなります。

# PMが一番たくさん開発作業をしている。

このパターンは、他にやるべきことができていない場合が多いです。

たとえば、
- 次の工程の準備
- メンバーの育成(生産性をあげる作業)や作業指示
- 成果物のチェック(品質管理)
- 進捗のチェック

などです。

開発作業はなるべくメンバーにおねがいして、
自分はチームのリードと管理業務をしっかりやる方がうまくいきます。。


つづく
文系エンジニアが機械学習に入門するために小学校の算数から高校数学までを一気に復習してみました。

※この記事の1年後に[文系エンジニアがCourseraの機械学習コースを1ヶ月で修了したので振り返ってみました。](http://qiita.com/poly_soft/items/0f7c09470af4ad5dbd39)という記事もアップしました。

文系エンジニアが機械学習に入門しようと思うと、どうしても「数学の壁」にぶつかります。

一般的に、機械学習を理解するためには、大学レベルの「微分積分」「線形代数」「確率統計」の知識が必須とされていますが、私のような典型的文系エンジニアの場合、それを学習するための基本的知識自体が圧倒的に不足しているため、まずは高校までの数学を一からやり直してみました。

# 学習前の私の数学スペック

* 学生時代の数学の学習歴は高校2年生の2学期位まで。
* 大学で経済数学の授業があった気がするがほとんど出席していない。
* 仕事で使った数学知識は三角関数程度。(画像処理ソフトを開発した際に使用)

# 学習に要した時間

* 小学校の算数 5時間
* 中学数学 6時間
* 数I/数A 12時間
* 数II/数B 50時間
* 数III/数C 50時間

合計 約120時間

# 学習教材

[小学校6年間の算数が6時間でわかる本](https://www.amazon.co.jp/dp/456970848X)
[中学3年間の数学を8時間でやり直す本](https://www.amazon.co.jp/dp/4569795676)
[高校1年の数学[数I・数A]が10時間でわかる本](https://www.amazon.co.jp/dp/4756915361/)
[スバラシク面白いと評判の初めから始める数学II・B (Part1)](https://www.amazon.co.jp/dp/4944178360/)
[スバラシク面白いと評判の初めから始める数学II・B (Part2)](https://www.amazon.co.jp/dp/4944178379/)
[スバラシク面白いと評判の初めから始める数学III・C (Part1)](https://www.amazon.co.jp/dp/4944178387/)
[スバラシク面白いと評判の初めから始める数学III・C (Part2)](https://www.amazon.co.jp/dp/4944178395/)

* 数I・数Aに関しては「高校1年の数学[数I・数A]が10時間でわかる本」を使いましたが、内容がかなり薄いというか省略されているため、結局後で不足部分の学習を別に行う必要が発生してしまったので、数学II・Bおよび数学III・Cと同シリーズの「スバラシク面白いと評判の初めから始める数学I・A」の[Part1](https://www.amazon.co.jp/dp/4944178344/)と[Part2](https://www.amazon.co.jp/dp/4944178352/)を最初からやっといた方が良かったなという印象です。
<br />

* 「スバラシク面白いと評判の…」シリーズに関しては、改訂版ではなく、2005年前後に出版された旧カリキュラム用の版を購入しました。理由としては単に「中古本がかなり安かったから」ですが、後述するように2012年のカリキュラム変更(数Cの廃止)により、改訂版だと「行列」が科目から除外されてしまっているので、今振り返ってみると旧版を購入しておいて良かったなと。

### 補助教材

[マンガでわかる微分積分](https://www.amazon.co.jp/dp/4797342501/)

* 上記はかなりの良書でした。数学IIの微分積分をやる前に読んでおくと、勉強効率がかなり上がると思います。

[マンガでわかる統計学](https://www.amazon.co.jp/dp/4274065707/)

* 後半はかなり読者置いてけぼり感がありますが、とりあえず読みやすいので入門としては良い本なのではないでしょうか。

[対数eの不思議](https://www.amazon.co.jp/dp/406132862X/)

* eを使うと何が便利なのかよく分からなかったので購入してみました。とりあえず読み物として結構面白いです。

### 注意点

2012年の高校数学のカリキュラム変更により、数Cが廃止されました。
そのため、2012年以降の新教科書に対応した参考書の場合、「行列」が科目として存在しないため、この場合は行列だけ別の参考書で学習する必要がありますのでご注意ください。

参考：[数学C](https://ja.wikipedia.org/wiki/%E6%95%B0%E5%AD%A6C)

> #### 2012年4月施行での取扱い
> 平面上の曲線が数学IIIに移行。
> 確率分布（条件付き確率を除く）と統計処理は数学Bに移行。条件付き確率は数学Aに移行。
> 行列は新科目「数学活用」で引用されるだけになり、普通科での履修科目から事実上消滅する。

# まとめ

個人差は当然あると思いますが、私のように高校の途中までしか数学を学習していない＆数学知識をほぼ全て忘却している文系エンジニアが、小学校の算数〜高校数学までを学習する場合、おおよそ100〜150時間程度は必要になると見積もっておいた方が良いと思われます。

また、高校数学の教材に関しては「同じシリーズで揃える」ようにしておいた方が無難だと思います。(高校数学の参考書としては、「スバラシク面白いと評判の〜」シリーズか、「[やさしい高校数学](https://www.amazon.co.jp/dp/4053035333/)シリーズ」辺りが、説明が丁寧なので良いのではないかと)

また、2012年以降の新カリキュラムに対応している参考書を購入する場合は、カリキュラムから削除された「行列」用の参考書を別に購入する必要がありますのでご注意ください。

# おまけ

Youtubeの方で、Web系エンジニアやWeb系エンジニアに興味のある方たち向けの[雑食系エンジニアTV](https://www.youtube.com/channel/UC_HLK-ksslL-Z_2wiIZDlMg)というチャンネルをやっています。もしご興味ございましたらチャンネル登録してみて頂けると大変嬉しいです。

また、2019年から「[雑食系エンジニアサロン](https://kentakatsumata.net/archives/10)」というオンラインサロンも始めました。

Twitterの方でも「Web系エンジニアのキャリア戦略」を中心に色々と情報を発信しておりますので、もし宜しければフォローしてみてください。[@poly_soft](https://twitter.com/poly_soft)
HHVM (HipHop Virtual Machine for PHP)/Hack のdocker imageを作成する

既存のPHPで作成されたプロダクトをAmazon ECSを利用し、Hack/HHVMへ移行しようと試みています。
上記に先行して、HHVMのdocker imageを作成し、簡単な稼動確認をしてみました。
最終的には、apacheを経由し、FactCGIで動かそう(docker-compose)としていますが、今回は、Hack/HHVMの単独検証です。

##HHVMのdockerfileを作成する
[公式HP](https://docs.hhvm.com/hhvm/installation/introduction "HACK")を参照すると、ubuntu、debianとあるので、ベースイメージはubuntuの最新Ver(2016/7/23時点)の15.10を用いる。
インストール手順は、公式を参照の元記載。

```dockerfile:dockerfile
FROM ubuntu:15.10

MAINTAINER takeshi.hirosue@bigtreetc.com

RUN apt-get update \
        && apt-get install -y software-properties-common \
        && apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449 \
        && add-apt-repository "deb http://dl.hhvm.com/ubuntu $(lsb_release -sc) main" 
RUN apt-get update \ 
        && apt-get install -y hhvm 

ADD scripts/ /scripts/
ADD .hhconfig /app/
RUN chmod 755 /scripts/*.sh \
        && chmod 755 /app/

EXPOSE 9000

CMD ["/scripts/start.sh"]
```

```bash:start.sh
#!/bin/bash
exec hhvm --mode server -d hhvm.server.port=9000 -d hhvm.server.source_root=/app/
```

[参考ソース](https://hub.docker.com/r/mirrored1976/hhvm/~/dockerfile/ "DockerHub")

##docker image作成/起動
docker imageを作成し、9000ポートで起動する

```bash
#build
docker build -t hhvm .
#run
docker run -p 9000:9000 -d --name hhvm hhvm
```

##動作確認(PHP)
phpinfoを作成し、コンテナにコピーし、ブラウザで以下URLへ
http://localhost:9000/phpinfo.php

```bash
echo '<?php phpinfo(); ?>' >> phpinfo.php
docker cp phpinfo.php hhvm:/app/
```

##動作確認(Hack)
コンテナへ入って、Hackや型検証を試す

```bash
docker exec -ti hhvm /bin/bash
```

以下コンテナ内

```bash
#cd app root
$ cd /app/
$ echo '<?hh echo "hello hhvm\n";' >> hello.hh
$ hhvm hello.hh
hello hhvm
```

以下の検証ファイルを用いて、型検証を試す
[参考ソース](https://github.com/Thirosue/docker-hhvm "GitHub")

+ エラー検証

```bash
#run NG
$ hhvm /app/error.hh

Catchable fatal error: Hack type error: Invalid return type at /app/error.hh line 4

#hh_client check NG
$ cd /app/ ; hh_client ; echo $?
error.hh:4:10,29: Invalid return type (Typing[4110])
  error.hh:3:15,17: This is an int
  error.hh:4:10,29: It is incompatible with a string
2
```

+ 正常検証

```bash
#run OK
$ rm /app/error.hh ; hhvm /app/ok.hh
ok! I am string

#hh_client check OK
$ cd /app/ ; hh_client ; echo $?
No errors!
0
```

※以下利用したサンプル

```hack:ok.hh
<?hh
function h(): string {
  return 'ok! I am string';
}
echo h() . "\n";
```

```hack:error.hh
<?hh
function h(): int {
  return 'error! I am string';
}
echo h() . "\n";
```

##終わりに
Typecheckerは使えそうですね。
次は、docker-composeを利用して、FastCGIで動かしてみたいと思います。
ZYBO / VHDL > LEDのMSB点灯失敗の原因調査 > ResetピンがLレベルの間にすべてを処理させる

```txt:動作確認
Vivado 2015.4 on Windows 8.1 pro (64bit)
DIGILENT ZYBO
```

http://qiita.com/7of9/items/fd8c6a7c329f130ab7c9#%E6%9C%AA%E6%B6%88%E5%8C%96
においてClockCounterのResetの周期をClk周期の16倍とした時に4ビット表示用LEDのMSB相当が点灯しなかった。

## code v0.1 > MSBが点灯しないバージョン

VHDLとテストベンチを作って同じ状況を確認した。

```clockCounter2.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter is
port(   Clk : in std_logic;
        Reset : in std_logic;
        OUT_D : out std_logic_vector (3 downto 0)
        );
end counter;

architecture Behavior of counter is
signal DFF_8 : std_logic_vector (3 downto 0);

begin

process(Clk, Reset)
begin
    OUT_D <= DFF_8;
    if (Reset = '1') then
        DFF_8 <= (others => '0');
    elsif ( clk'event and clk = '1') then    
        if (DFF_8 = "1111") then
            DFF_8 <= (others => '0');
        end if;
        DFF_8 <= DFF_8 + 1;
    end if;
end process;
end Behavior;
```

```clockCounter2.tb
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity testbench is
end testbench;

architecture behavior of testbench is
signal clk : std_logic;
signal reset : std_logic;
signal out_d : std_logic_vector (3 downto 0);
constant clk_period : time := 10 ns;

begin
uut: entity work.counter PORT MAP (
    clk => clk,
    reset => reset,
    out_d => out_d);

stimulus : process
begin
    wait for 16 * clk_period / 2;
    reset <= '1';
    wait for 16 * clk_period / 2;
    reset <= '0';
--    wait for 300 ns;
end process;

clk_process : process
begin
    clk <= '0';
    wait for clk_period / 2;
    clk <= '1';
    wait for clk_period / 2;
end process;

end behavior;
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/c2fc85ba-08df-1050-b62d-8c240dcdfb92.png)

ResetのタイミングによってMSB (out_d[3])が短時間しかHレベルにならず、リセットがかかてしまっていることが確認できた。

ResetピンがLレベルの間に4ビットすべてが処理されないといけないということか。
そうなると16分周でなく32分周が必要になるということに整合性が取れるようだ。

## code v0.2 > MSBも点灯するバージョン

テストベンチだけを16分周から32分周に変更した。

```clockCounter2.tb
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity testbench is
end testbench;

architecture behavior of testbench is
signal clk : std_logic;
signal reset : std_logic;
signal out_d : std_logic_vector (3 downto 0);
constant clk_period : time := 10 ns;

begin
uut: entity work.counter PORT MAP (
    clk => clk,
    reset => reset,
    out_d => out_d);

stimulus : process
begin
--    wait for 16 * clk_period / 2;
    wait for 32 * clk_period / 2;
    reset <= '1';
--    wait for 16 * clk_period / 2;
    wait for 32 * clk_period / 2;
    reset <= '0';
--    wait for 300 ns;
end process;

clk_process : process
begin
    clk <= '0';
    wait for clk_period / 2;
    clk <= '1';
    wait for clk_period / 2;
end process;

end behavior;
```

ResetピンがLレベルの間に4ビットのカウントがすべて処理されるようになった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b5b341d0-1958-070e-d3c0-3ed020b77f3f.png)


ResetピンがHレベルの時間が長いかもという問題は将来の課題としておく。
WatchOS1からWatchOS2への移行トラブル記録

http://qiita.com/sassymanyuichi/items/ed32c5a10bdc1b799c6a と http://qiita.com/YoheiMiyamoto/items/57c7df1633bc62263835 を参考にプロジェクトを再設定してみたところ以下のエラーメールが来るようになった。

```
Dear developer,

We have discovered one or more issues with your recent delivery for "標高ワカール - 山登り・防災のための海抜測定". To process your delivery, the following issues must be corrected:

Invalid Swift Support - The Watch OS application has Swift libraries at both /Payload/Elevation.app/Elevation WatchKit.app/Elevation WatchKit Extension.appex/Frameworks/ and /Payload/Elevation.app/Elevation WatchKit.app/Frameworks/. Remove all of the Swift libraries from one of the locations and resubmit your app.

Though you are not required to fix the following issues, we wanted to make you aware of them:

WatchKit 1.0 - Your previous version used an extension for Apple Watch but your current version doesn’t. Users who haven’t updated their Apple Watch to watchOS 2 or later may lose access to their Apple Watch extension.

Once the required corrections have been made, you can then redeliver the corrected binary.

Regards,

The App Store team
```

https://forums.developer.apple.com/thread/17931 を参考にEmbedded Content Contains Swift CodeをElevation WatchKitはNOでElevation WatchKit ExtensionはYESにしてみたところ次のようになった。

```
Dear developer,

We have discovered one or more issues with your recent delivery for "標高ワカール - 山登り・防災のための海抜測定". To process your delivery, the following issues must be corrected:

Invalid Swift Support - The SwiftSupport folder is missing. Rebuild your app using the current public (GM) version of Xcode and resubmit it.

Though you are not required to fix the following issues, we wanted to make you aware of them:

WatchKit 1.0 - Your previous version used an extension for Apple Watch but your current version doesn’t. Users who haven’t updated their Apple Watch to watchOS 2 or later may lose access to their Apple Watch extension.

Once the required corrections have been made, you can then redeliver the corrected binary.

Regards,

The App Store team
```

これはおそらく、fasllaneでUSE_LEGACY_BUILD_APIを使っているため。そのため http://qiita.com/yoneapp/items/bc8e1fc6cafe79418f59 のように変更したところ次のようになった。

```
Dear developer,

We have discovered one or more issues with your recent delivery for "標高ワカール - 山登り・防災のための海抜測定". Your delivery was successful, but you may wish to correct the following issues in your next delivery:

WatchKit 1.0 - Your previous version used an extension for Apple Watch but your current version doesn’t. Users who haven’t updated their Apple Watch to watchOS 2 or later may lose access to their Apple Watch extension.

After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to iTunes Connect.

Regards,

The App Store team
```

これはWatchKit 1.0を切ったためにでる警告なので、無視しても良さそうと判断した。
WIP@FastlaneのUSE_LEGACY_BUILD_APIをfasleにした場合のProvisioning指定の調査

USE_LEGACY_BUILD_APIをfalseにした場合SIGH_PROFILE_PATHの指定が無効になるという警告が表示されます。

```
You're using Xcode 7, the `provisioning_profile_path` value will be ignored
Please follow the Code Signing Guide: https://codesigning.guide (for match) or https://github.com/fastlane/fastlane/blob/master/fastlane/docs/CodeSigning.md
```

provisioning_profile_pathが設定できないということは、例えば私は以下のようにadhocとbetaでProvisioningを分けているのですが、これが効かないことになりそうです。

```rb
fastlane_version "1.98.0"

default_platform :ios

platform :ios do
  before_all do
    ENV['GYM_WORKSPACE']             = "Elevation.xcworkspace"
    ENV['GYM_SCHEME']                = "Elevation"
    ENV['GYM_USE_LEGACY_BUILD_API']  = "false"
    ENV['GYM_INCLUDE_SYMBOLS']       = "true"
    ENV['GYM_INCLUDE_BITCODE']       = "true"
  end

  lane :adhoc do
    ENV['SIGH_PROFILE_PATH'] = "AdHoc_com.yoneapp.Elevation.mobileprovision"
    ENV['GYM_CONFIGURATION'] = "Debug"
    gym
    deploygate
  end

  lane :beta do
    ENV['SIGH_PROFILE_PATH'] = "AppStore_com.yoneapp.Elevation.mobileprovision"
    ENV['GYM_CONFIGURATION'] = "Release"
    gym
    pilot(skip_waiting_for_build_processing: true)

    p Gym.config[:provisioning_profile_path]
  end

  lane :app_store do
    ENV['SIGH_PROFILE_PATH'] = "AppStore_com.yoneapp.Elevation.mobileprovision"
    ENV['GYM_CONFIGURATION'] = "Release"
    gym
    deliver(skip_screenshots: true, skip_metadata: true)
  end
end
```

対策としてXcode7では少し面倒ですが https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Codesigning/XcodeProject.md#readme に書いてあるようにすればよいでしょう。

と思ってSIGH_PROFILE_PATHを消してみたのですが、次のように聴かれるようになってしまい`You're using Xcode 7, the `provisioning_profile_path...`の警告はそのままでした。

```
Found more than one provisioning profile in the project directory:
1. AdHoc_com.yoneapp.Elevation.mobileprovision
2. AppStore_com.yoneapp.Elevation.mobileprovision
```

https://github.com/fastlane/fastlane/blob/d01b7c2240df289ea2e2dfc58bffeb028f97e805/gym/lib/gym/options.rb#L161 と https://github.com/fastlane/fastlane/blob/c24d064811ec0718e3c6c98489b0180b0100eab8/gym/lib/gym/generators/package_command_generator_xcode7.rb#L164 が関連コードだと思うけどFastfileでは指定してないんだけども。

適当にしのいで、Xcode8を待ったほうがいいかな...
PHPで確認するクッキーとセッションメモ - 訪問回数のカウント

# 概要

PHPでクッキーとセッションの動作を確認する。たまによく分からなくなるので、基本の動きのメモ。
# 確認手順

## １．ソースコードの準備
Webサーバに配置すること
◯参考
　セッション変数の書き込みと読み込み - セッション管理 - PHP入門 　
　http://www.phpbook.jp/tutorial/session/index2.html

```php:index.php
<?php
    session_start();
?>

<html>
<head><title>PHP TEST</title></head>
<body>

<?php

    if (!isset($_SESSION["visited"])){
        print('初回の訪問です。セッションを開始します。');
        $_SESSION["visited"] = 1;
    }else{
        $visited = $_SESSION["visited"];
        $visited++;

        print('訪問回数は'.$visited.'です。<br>');

        $_SESSION["visited"] = $visited;
    }

?>

</body>
</html>
```

## 動作確認
### 初回アクセス
![2.png](https://qiita-image-store.s3.amazonaws.com/0/50690/27a61330-af32-2eb1-7795-3d228c003396.png)

### 2回目アクセス

![ScreenClip.png](https://qiita-image-store.s3.amazonaws.com/0/50690/7e49f584-00cc-8acd-a7a3-142e47f83739.png)

## 何が起きたのか
- 初回のアクセスはブラウザにクッキーが保存されていないためクッキーの送信は無い
- サーバからは初回アクセス用のHTMLのメッセージと、「Set-Cookie」にセッションIDの文字列がクッキとしてレスポンスされる
- サーバにはセッション情報が保存される（下部「セッション情報確認コマンド」参照）
- 次回のアクセスはブラウザにクッキーが保存されているため、クッキーの情報を添えて、リクエストされる


![シーケンス.png](https://qiita-image-store.s3.amazonaws.com/0/50690/c067dd16-6582-1ca2-219a-665464aebd93.png)

## パケットキャプチャで確認する
### 初回アクセス
#### リクエスト
![1req.png](https://qiita-image-store.s3.amazonaws.com/0/50690/a2c96767-e45d-00bc-f044-f36a83b24c2d.png)
#### レスポンス
![1res.png](https://qiita-image-store.s3.amazonaws.com/0/50690/4b3c707c-5b5f-9f7b-bd81-0b1f1799ffad.png)


### 2回目アクセス
#### リクエスト
![2req.png](https://qiita-image-store.s3.amazonaws.com/0/50690/ed029828-44dd-5168-cdf7-130ffc30a6c7.png)

#### レスポンス
![2res.png](https://qiita-image-store.s3.amazonaws.com/0/50690/8ff022c2-79ab-538e-355d-fd0fe5476a1b.png)

## 保存されたセッション情報の確認

```bash:セッション情報確認コマンド
# cat /etc/php.ini | grep session.save_path
session.save_path = "/var/lib/php/session"

# cat /var/lib/php/session/sess_
sess_06lplefgvgqa4psh1dgeqoaf02  sess_fggcljpfulitqkf32ghkqq2271  sess_rhdcn2thun0ia6lh1f829qjov4
sess_1j7cf2s2j6ki0ggchd5ju6ekk3  sess_hhajts2ogc6ckab2hmrhfuhp30  sess_sagu5svbl9c45mbgk4f2m8tts0
sess_5gpns2ua4880su39smk34r7nc2  sess_jv1iosc08o3sd0s3f269cgo127  sess_sjbi3u7mstusbo2pp7q05phu00
sess_bghto98dmkpak768f9dpjq1tv1  sess_kfhl7os3qmqr0grmh9cm9slet4  sess_ve05koevrn7h66bk53c9428lh7
sess_dacumrc334sadijnrksou7ftu3  sess_kvdf9sdvr80tetn6q9idr560a0  sess_vg3n5f05e3hlf8t8bobqrsvkv3
sess_drug7beoli4bnj3fmtq5np89v6  sess_o5rrhkcquilub02hi92fbaa303

# cat /var/lib/php/session/sess_hhajts2ogc6ckab2hmrhfuhp30
visited|i:2;
```