OmniAICreator/Qiita-1.07M huggingface dataset:
[Ansible入門] 2. インストール後の動作確認(接続確認)

今回は、Ansibleインストールしたマシンが正常に動くかを動作確認します

## 実行環境

Mac上にVagrantで下記環境を作成して実行しています

```
# Ansibleを実行するマシン　# 入門1にてAnsibleをインストールしたマシン
呼称：Controller
OS:CentOS6
IP: 192.168.33.11
user: vagrant
pass: vagrant
# Ansibleを実行されるマシン
呼称： Target
OS: CentOS6
IP: 192.168.33.12
user: vagrant
pass: vagrant
```

## SSH Keyの準備
AnsibleはSSHで接続してプロビジョニングを行うみたいなので、 `Controller` から `Target` にSSH Keyで接続できるようにしておく

```
# SSH Keyの生成
[vagrant@controller ~]$ cd .ssh/
[vagrant@controller .ssh]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa): # 何も入力せずEnter
# Targetに認証させる
[vagrant@controller .ssh]$ ssh-copy-id vagrant@192.168.33.12
vagrant@192.168.33.12's password:
Now try logging into the machine, with "ssh 'vagrant@192.168.33.12'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.
```
これでログインできるはず

```
[vagrant@controller .ssh]$ ssh 192.168.33.12
Last login: Mon Sep 26 03:58:54 2016 from 192.168.33.1
Welcome to your Vagrant-built virtual machine.
[vagrant@target ~]$ # ログインできた！（hostnameが変わっている）
```

## Ansible用ディレクトリなどの準備
[ここ](http://qiita.com/t_nakayama0714/items/fe55ee56d6446f67113c#ansible%E3%81%AE%E5%AE%9F%E8%A1%8C%E3%83%86%E3%82%B9%E3%83%88)を参考にテスト接続してみます

```
[vagrant@controller ~]$ mkdir ansible
[vagrant@controller ~]$ cd ansible
[vagrant@controller ansible]$ mkdir inventory
[vagrant@controller ansible]$ vi inventory/hosts
```
viで作るファイルの中身はこんな感じ

```
[targets]
192.168.33.12
```

## 動作確認の実行

```
[vagrant@controller ansible]$ ansible all -i inventory/hosts -m ping
192.168.33.12 | FAILED! => {
    "failed": true,
    "msg": "failed to resolve remote temporary directory from ansible-tmp-1474855390.1-240110546260352: `( umask 77 && mkdir -p \"` echo $HOME/.ansible/tmp/ansible-tmp-1474855390.1-240110546260352 `\" && echo ansible-tmp-1474855390.1-240110546260352=\"` echo $HOME/.ansible/tmp/ansible-tmp-1474855390.1-240110546260352 `\" )` returned empty string"
}
```

ダメだった...

[公式ドキュメント](http://docs.ansible.com/ansible/intro_getting_started.html)でこんな記述があった

```
Ansible will attempt to remote connect to the machines using your current user name, just like SSH would. To override the remote user name, just use the ‘-u’ parameter.
```

デフォルトで現在のユーザ名になるって書いてあるから無駄かもしれんけども、 `-u` つけたら動くんじゃ、と思って実行してみる

```
[vagrant@controller ansible]$ ansible all -i inventory/hosts -m ping -u vagrant
192.168.33.12 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
```

動いた！

**いつから公式ドキュメントが正しいと錯覚していた** ってやつでした

とりあえず動いたので今回はこれで終わり
macOS Sierra のSSH接続で、秘密鍵へのパスを覚えてくれない問題

macOS Sierra にアップデートされる方はsshに注意です。
どうやらsshする際に指定した秘密鍵へのパスフレーズを覚えてくれない?ようで、しかも仕様みたいです。

"So it looks like Apple changed the behaviour of the ssh-agent in macOS Sierra. Now it does not autoload all the keys in the keychain that were added with ssh-add -K, so you must explicitly call ssh-add -A."
引用元:https://www.reddit.com/r/osx/comments/52zn5r/difficulties_with_sshagent_in_macos_sierra/

とりあえず解決策としては
・configファイルを作って秘密鍵へのパスを指定
・ログイン時に"ssh-add -A"のコマンドを実行するplisetを作成して配置
　参考URL:https://github.com/jirsbek/SSH-keys-in-macOS-Sierra-keychain
のいずれかだそうです。
ちなみに、後者で接続できることを確認しています。

前者はターミナルで接続を試みる分には色々と便利なのですが、SourceTreeとかでSSHする場合には不便なので後者が良いのでは？と思います。
※コメントで"ppengotsu"さんより指摘があり、どうやらSourceTreeでもちゃんとsshのconfigを見ているようです。前者を試されることをお勧めします。

先週この問題にぶち当たった際には全然情報がなかったのですが、今週に入ってにわかに情報が出てきました。今の所日本語で解説しているところがないので調べる際は英語サイトを見てみたら色々と分かるかと思います。

追記
一応念のため、今回 macOS Sierra はクリーンインストールしているので、El Capitan からアップデートされた場合にどうなるのかは把握していません。あしからず。
AndroidのSQLiteのバージョンによる差分


だいぶ今更な内容ではありますが、Androidのバージョンによって搭載されているSQLiteのバージョンが異なります。
それによって一部仕様の違いがあり、場合によってはプログラムのかき分けが必要となります。

# Androidに搭載されているSQLiteのバージョン

| API level | SQLiteバージョン |
| --- | --- |
| 14、15 | 3.7.4 |
| 16~20 | 3.7.11 |

他は以下を参照
[AndroidでのSQLiteバージョン](http://stackoverflow.com/questions/2421189/version-of-sqlite-used-in-android)

# 3.7.4と3.7.11での差分

## Bulk Insertの対応

| SQLiteバージョン | 対応 |
| :---: | :---: |
| 3.7.4 | × |
| 3.7.11 | ◯ |

3.7.4ではBulk Insertに対応していないため、API level 15以下では以下の様なインサート文が書けない

```sql
INSERT INTO table (a, b, c) VALUES (1, 2, 3), (4, 5, 6), ....
```

そのため、API level 15と16以降を共存させる場合はクエリの書きわけが必要となる。
一行ずつのインサートはパフォーマンスがよくないためできるだけBulk Insertを用いるのがよいが
バージョンの差分により実行できないため、せめてトランザクションを貼ってのループ処理が良い。
トランザクションをはらずに一行ずつの実行は非常にコストが高い(一行の実行ずつにトランザクションが貼られてしまうため)。

```java
public void insertAll(List<String> dataList) {

    SQLiteDatabase db = ...;
    ...
    db.beginTransaction();
    for (String data : dataList) {
        // インサート処理。Prepared StatementあるいはContentValuesなどを使用。
    }
    db.endTransaction();
}
```

[参考](http://qiita.com/alzybaad/items/b350b49740a3d25297c1)
高性能 Mysql

###SQL 的四种隔离级别
* **READ UNCOMMITED（未提交读）**
    
    即使事务没有提交，对其他事务依然是可读的，也称之为脏读。
    
* **READ COMMITED（提交读）**
	
	大多数数据库系统的默认隔离级别（Mysql 不是）。在事务提交前，所做的任何修改对其他事务均不可见，也称之为不可重复读（norepeatable read），因为两次查询可能得到不同的结果。
	
* **REPEATABLE READ（可重复读）** —— Mysql 默认

   可解决脏读问题，但是无法解决幻读（Phantom Read）问题（a 事务在读取某范围的记录时，b 事务又在该范围插入了新的记录，导致 a 再次读取的时候产生幻行，InnoDB 和 XtraDB 通过多版本并发控制来解决幻读问题）。

* **SERIALIZABLE（可串型化）**

	SQL 的最高隔离级别。强制事务串行执行，以此来避免幻读问题。SERIALIZABLE 会在读取的每条记录上都加锁，所以可能导致锁争用和超时问题。


|隔离级别         |脏读可能性 |不可重复读可能性|幻读可能性| 加锁读 |
|----------------|---------|------------|---------|--------|
|READ UNCOMMITED |YES      |YES         |NO       |NO      |
|READ COMMITED   |NO       |YES         |YES      |NO      |
|REPEATABLE READ |NO       |NO          |YES      |NO      |
|SERIALIZABLE    |NO       |NO          |NO       |YES     |


###死锁
**解决死锁的两种方式**

* 检测循环依赖，并立即返回错误（比如 InnoDB）
* 设定锁等待时间

**死锁产生的原因**

* 数据冲突
* 存储引擎的实现方式导致

### 事务
事务日志可以提高事务的效率。存储引擎在修改表的数据时，只需修改其在内存中的拷贝，再把修改行为记录持久在硬盘中。事务日志采用追加的方式，因此操作的是一小块 I/O 区域，可以提高速度，并且内存中修改的记录可以缓慢的持久到硬盘中。
存储引擎会自动恢复因为系统奔溃而出现的已经修改，但是尚未写回磁盘的数据。

Mysql 的事务默认采用自动提交的方式：

```Mysql
show variables like 'autocommit'
```

使用 `Mysql` 命令行可以启用／禁用自动提交
当 `AUTOCOMMIT=0` 时，所有的操作都在同一个事务里执行，直到显示执行 `commit` 或者 `rollback`，该事务结束，同时又开启了另一个新事务。
而对于非事务类型的表，比如 `MyISAM` 或者 内存表，修改 `autocommit` 不会有任何影响，相当于一直开启自动提交事务的状态。
Windows環境でangular/cliを使えるようにする

# Windows環境でangular/cliを使えるようになるまで
Windows10に1からangular/cliを入れようとしたところ、いろいろと躓いたので
その備忘録を書いてみる。

2017/06/09
yarnに対応
node 8.1.0
yarn 0.24.6
angular/cli 1.1.1

## 0. 事前準備
なし。

一応まっさらに近いVMware上で確認をしながら書いています。
（Windows10 x64 バージョン1703 ビルド番号 15063.332 VMWareToolsのみインストール）

## 1. node.js
パッケージ管理とバージョン管理が出来るようにする。
まずchocolateyというwindows版のyumやapt-getに相当するものをインストールする。
PowerShellを管理者権限で開き以下のコマンドでポリシーの確認をする。

```
$ Get-ExecutionPolicy
Restricted
```
結果が「Restricted」となった場合は以下のコマンドで外部ツールをインストール出来るようにします。

```
$ Set-ExecutionPolicy Bypass
実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (http://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
```

これでchocolateyのインストールが出来るようになったので以下のコマンドでインストールを行います。

```$ iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))```

次にnode.jsのバージョン管理ツールのnodistをインストールする。
```$ cinst nodist -y```
インストールが終わったらPowerShellを閉じて開きなおす。
開きなおして以下のコマンドを入れてnodistの初期設定をする。(2017/06/09現在)

```
$ nodist -v
0.8.8
$ nodist 8.1.0
8.1.0
$ nodist npm 5.0.3
5.0.3
```
以下確認

```
$ nodist
  (x64)
  7.2.1
> 8.1.0 (global: 8.1.0)
$ nodist npm
  4.0.5
> 5.0.3  (global: 5.0.3)
```
これでnode.jsの設定は終わりです。

## 1-1. npmの代わりにYARNを使う場合
angular/cliのデフォルトパッケージ管理ツールがnpmからYARNに変わったのでYARNの導入方法を書く。
chocolateyで以下のコマンドでYARNのインストールができる。
```$ cinst yarn -y```
インストールが終わったらPowerShellを開きなおしインストール確認を行う。

```
$ yarn -v
yarn install v0.24.6
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.93s.
```


## 2. python2.x.x, MSBuild
angular-cliではnode-gypを使うため2.x.x系のPythonとMSBuildが必要となる。
どちらとも自動でインストールしてくれるパッケージがあるのでそれを使う。
下記のコマンドで自動で設定まで完了します。

* YARN ```$ yarn global add windows-build-tools```

* npm ```$ npm install --global windows-build-tools```

以上でpythonとMSBuildの設定は終わりです。

### ※nodejsが64bit版の場合は以下の方法でpythonを64bit版にする。
下記から64bit版のpythonをダウンロードしインストーラに従い
インストールしてください。
https://www.python.org/ftp/python/2.7.13/python-2.7.13.amd64.msi
インストールが終わったら下記コマンドによりnpmのパスを変更してください。
```$ npm config set python C:\Python27\ --global```


## 3. angular/cli
angular/cliは必ずキャッシュをクリアしてからインストールする。

* YARN

```
$ yarn cache clean
$ yarn global add @angular/cli
```

* npm

```
$ npm --global cache clean
$ npm install --global @angular/cli
```

以下確認

```
$ ng -v
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/
@angular/cli: 1.1.0
node: 8.1.0
os: win32 x64
@angular/animations: 4.1.3
@angular/common: 4.1.3
@angular/compiler: 4.1.3
@angular/core: 4.1.3
@angular/flex-layout: 2.0.0-rc.1
@angular/forms: 4.1.3
@angular/http: 4.1.3
@angular/material: 2.0.0-beta.6-52b6692
@angular/platform-browser: 4.1.3
@angular/platform-browser-dynamic: 4.1.3
@angular/router: 4.1.3
@angular/cli: 1.1.0
@angular/compiler-cli: 4.1.3
@angular/language-service: 4.1.3
```

これでangular/cliのインストールは完了です。
Swift3でDispatchQueue.main.syncを安全に呼び出す

## Swift2まで
メインスレッド上から`dispatch_sync`でメインキューに突っ込もうとするとデッドロックしてしまうことがあり、Swift2まではだいたい以下のような書き方で対応していたと思います。

```swift:swift2まで
public func dispatch_sync_main_safe(block: dispatch_block_t) {
    if NSThread.isMainThread() {
        block()
    } else {
        dispatch_sync(dispatch_get_main_queue(), block)
    }
}
```

## Swift3から
Swift3では`dispatch_xxx`という関数での使用の仕方から、`DispatchQueue`クラスを使った書き方に変わったのもあり、以下のように書き換えたらいいんじゃないかなと思います。

```swift:swift3から
extension DispatchQueue {
    class func mainSyncSafe(execute work: () -> Void) {
        if Thread.isMainThread {
            work()
        } else {
            DispatchQueue.main.sync(execute: work)
        }
    }

    class func mainSyncSafe<T>(execute work: () throws -> T) rethrows -> T {
        if Thread.isMainThread {
            return try work()
        } else {
            return try DispatchQueue.main.sync(execute: work)
        }
    }    
}
```

使用方法はこんな感じ。

```swift
DispatchQueue.mainSyncSafe {
    // ...
}
```

`mainSyncSafe`ってのがう〜んって場合はお好みで`main_sync_safe`なり変えてあげると良いんじゃないかと思います。

### 変更点
#### DispatchQueueの *sync* 関数が大きく分けて2通りある
よく見てみると、性質の異なる *sync* 関数が2つあります。(正確には2つではないけど他は一旦割愛)

```swift
public func sync(execute block: () -> Swift.Void)
public func sync<T>(execute work: () throws -> T) rethrows -> T
```

片方はいつもどおりの *sync* 関数ですが、もう片方は **例外を投げられるようになっている** ことと、 workのclosureの結果から **返り値を受け取ることができる** ところが差分となります。
なのでどちらにも対応できるように準備してあげます。

#### NSThread -> Thread
ここも地味な変化です。

### `class func`にした理由
普通の`func syncSafe(...)`として定義してしまうと、以下のようにグローバルキューに対しても呼べてしまう問題が発生するので、若干関数名がダサいとは思いつつも、`class func`にすることにしました。(今回はあくまでも、メインスレッド上から`dispatch_sync`でメインキューに突っ込もうとするとデッドロックが起きてしまうのを防ぐ呼び方として定義したかったのが強いからです。)

```swift
// ok!
DispatchQueue.main.syncSafe {
    // ....
}

// ????
DispatchQueue.global().syncSafe {
    // ....
}
```

<br /><br /><br />
こっちの方がcoolに書けるぜ！とかあったら教えてください...！
Rails のルーティングで GET パラメータの中身を使ってリダイレクト先を変更

redirect に渡すブロックの中で、 req.params にリクエストされたパラメータが入っているのでそれを使う

```rb
get :foo, to: redirect { |params, req| req.params[:bar].present? ? "/foo/#{req.params[:bar]}" : "/baz" }
```

こうすることで

```
/foo           # /baz へリダイレクト
/foo?bar=qux   # /foo/qux へリダイレクト
```
とすることができる

この辺で設定されている
https://github.com/rails/rails/blob/cf5f55cd30aef0f90300c7c8f333060fe258cd8a/actionpack/lib/action_dispatch/http/parameters.rb#L30-L44

params でも取れそうな気がするが、よくわからないがダメだった
Swift3版「Calendarアプリを作る」を要望

iPadで動作する表計算型のアプリを作ろうと思い、"[Swift]calendarアプリを作る"にたどり着きました。読み解き開始の直前にXcode8に更新してしまったのでエラーの山になってしまいました。Swift3版の"[Swift]calendarアプリを作る"を公開される予定はないのでしょうか？
他にUIcollectionViewを使った気の利いたサンプルが見当たらないので是非お願い致します。
備忘録_css継承プロパティ

たまに気になって調べるので自分用にメモ

##テキスト/フォント系

- font-family
- font-style
- font-variant
- font-whight
- font-size
- line-height
- font (各プロパティに準じる)
- font-stretch
- font-feature-settings
- text-transform
- text-align
- text-justify
- text-align-last
- text-indent
- letter-spacing
- word-spacing
- tab-size
- white-space
- word-break
- line-break
- overflow-wrap / word-wrap
- hyphnes
- direction
- writing-mode
- text-emphasis-style
- text-emphasis-color
- text-emphasis
- text-empasis-position
- text-shadow
- list-style-image
- list-style-type
- list-style-position
- list-style (各プロパティに準ずる)
- color

##テーブル/ボックス系

- visibility
- border-collapse
- border-spacing
- empty-cells
- caption-side

##その他

- cursor
- image-orientation
沈思黙考：デザインパターン(Factory Method パターン)


# Factory Method パターンとは

既存のアプリケーションを流用し、その一部を変更することで新たなアプリケーションを作成する、ということはよくあることだ。アプリケーションおよびコンポーネントをサブクラス化し、変更したいコンポーネントの生成をアプリケーションのサブクラスで行うことで、利用するコンポーネントを切り替える、という手法が**Factory Method パターン**である。

# **Factory Method パターン**の実装

流用前の構成は、アプリケーション(以下アプリとする)とアプリが使うコンポーネントがいくつか存在し、アプリがコンポーネントの生成を行い、その機能を呼び出しているとする。

```java:Fig1.流用前のアプリ構成
class MyApp {
 public void execute() {
  CompA a = new CompA();/* 直接生成する */
  CompB b = new CompB();
  a.somethingA();
  b.somethingB();
 }
}
class CompA {
 public void somthingA() {
 /* 従来の機能 */
 }
}
class CompB {
 public void somthingB() {
 /* 何らかの機能 */
 }
}
``` 

流用の設計方針としては、アプリおよびコンポーネントのサブクラス化を行ない、それぞれ抽象クラスー具象クラスの構成にし、アプリの具象クラスとコンポーネントの具象クラスが1つのアプリケーションセットになるようにする。

アプリの元のソースコードをアプリの抽象クラスにおく。コンポーネントの元のソースコードをコンポーネントの具象クラスにおき、コンポーネントの抽象クラスには、インターフェースの宣言をおく。このようにすると、アプリは、コンポーネントの抽象クラスで定義されたインターフェースだけでプログラムされることになる。

このようにした上で、アプリの具象クラスにコンポーネントを生成するメソッドを追加して、アプリの具象クラスに対応するコンポーネントの具象クラスのインスタンスを返すようにする。このメソッドをアプリの抽象クラスにあるインスタンスの生成処理と置き換える。

```java:Fig1.流用後のアプリ構成
abstract class MyApp {
 abstract  public CompA createCompA();
 public void execute() {
  CompA a = createCompA();/* 具象クラスで生成する */
  CompB b = new CompB(); /*今回は手を入れないのでそのまま */
  a.somethingA();
  b.somethingB();
 }
}
class MyApp1 {
 public  CompA createCompA() {
  return new CompA1(); /* 対となる具象クラスのインスタンスを返す */ 
 }
}
class MyApp2 {
 public  CompA createCompA() {
  return new CompA2(); /* 対となる具象クラスのインスタンスを返す */
 }
}
abstract　class CompA {
 abstract public void somthingA();/* インターフェースを定義する */
}
class CompA1 extends CompA {
 public void somethingA() {
  /* 従来の機能 */
 }
}
class CompA2 extends CompA {
 public void somethingA() {
  /* ここに従来の機能から変更するコードを記述する */
 }
}
class CompB {
 public void somthingB() {
 /* 何らかの機能 */
 }
}
``` 

このようにしたときのcreateCompA()を**factory method**という。

# Factory Method パターンのメリット

すでに存在するアプリケーションを流用して、別のアプリケーションに仕立てる場合に便利なパターンである。既存のコードをほとんど修正しなくて済むというのは最大のメリットだ。

なお、既存のコードをほぼ修正しなくて済むというのは、実は**Factory Method パターン**の機能ではない。それは「継承」の機能だ。**factory method**はコンポーネントの子クラスのオブジェクトを返しているに過ぎない。継承の機能をうまく使えるように、オブジェクトを切り替える、というのが**Factory Method パターン**の特徴といえるだろう。

# Factory Method パターンの適用例

たとえば、DBを読み出してファイルに書く処理のようなものが考えられる。この処理を流用して、ファイルに書くところをメールの発送に代える、というような要求の場合にこのパターンを使うと良いだろう。

一般的には、入出力先を変更する、出力フォーマットを変更する、料金計算方法を変更する、などへの応用になるのではないだろうか。

一方、暗号方法やソート順のような、アルゴリズムの変更に関しては、この方法ではなく、Strategyパターンを検討すべきと考える。というのは、**Factory Method パターン**を使った場合、アルゴリズムの数だけアプリのサブクラスを作成する必要がある。あまり得策とは思えない。

# Abstract Factoryパターンとの比較

**Abstract Factoryパターン**と**Factory Method パターン**は、使っているクラスのインスタンスを切り替える、という点では同じ目的である。しかし、切り替えているものは何かという考察をすると、両パターンの違いが明確になるだろう。**Abstract Factoryパターン**は、(DAOのような)複数の似たような機能のクラス群のなかから1つのクラス群を選択するものだ。一方、**Factory Method パターン**は複数のアプリケーションから１つを選んだ結果、必要なクラス群を切り替える、というものになる。
このことを頭にいれておくと、どちらのパターンを使うか、悩むことは無いだろう。

- 参考文献 オブジェクト指向における再利用のためのデザインパターン 改訂版 1999/11/1 初版
requirejs 和 AMD 的关系


#模块的目的

为什么需要 javascript 的模块? 目的何在?

- 定义:怎么样能够将一块 javascript 的代码封装到一个单元里,怎么将它作为一个模块发挥它的价值?
- 依赖关系:怎么引用其他的代码块?



#当今的 web

```
(function () {
    var $ = this.jQuery;

    this.myExample = function () {};
}());
```

当今的大部分 javascript 代码就是类似上面的写法?

- 通过一个立即执行的模式来包裹一块代码
- 然后把所有的依赖统统赛扫全局的变量域中.
- 而依赖关系是非常脆弱的,开发人员需要清除他们的依赖优先级,如` Backbone` 的代码是不能够在` jQuery` 之前加载的.
- 部署的时候需要额外的工具来压缩很多的` script`tag.

小项目没事,而大项目呢? 特别是应用了很多的零碎的 js 脚本库的情况下呢?手写他们显然不靠谱, 而且这样不能够很好地任意扩展.

#CommonJS

CommonJS 从一开始工作的对象是 javascript 这个语言本身,而并不是浏览器里 js 的运行环境. 如果对于浏览器的环境, 通常是计划采用一个工具将这些代码转换为浏览器可以处理的状态.

- 在服务器端处理这些 CJS 模块
- 通过 XHR 下载这些代码然后在浏览器端编译他们.

同时 CJS 只允许一个文件只能包含一个模块定义, 所以在编译处理的时候通常都是需要多个文件多次处理.

- 网络加载
- 异步性


对于web 来发来说这样的方法显然比较费力. 而且对于这样事前编译的方式 debug 通常都很难做.

#AMD

```
define(['jquery'] , function ($) {
    return function () {};
});

```


AMD 的设计就是看上去基于当前的 web 开发 javascript 的写法那样,可以手动显式的管理当前代码段的依赖以及依赖的优先级. 而且这些代码都可以直接在浏览器里执行. debug 起来很简单并不需要服务器的一些工作作为辅助. 它借助的` Dojo` 的一些经验通过 **  XHR+eval**来避免了一些弱点. 它提高了当前 web 开发中的 **全局模式**, 因为:

- 通过借鉴 CommonJS 就是的 id 来标示依赖,清理了依赖关系并且避免了冲突发生.
- 这些文件通常可以保存在多个目录. 更加方便 mock 测试.

相比 CommonJS 它又如下优点:

- 浏览器友好
- 一个文件可以定义多个模块
- 可以返回一个函数,( node 里可以` module.exports=funciton(){}`但是 CommonJS 的定义里是不允许的,它要求始终返回一个对象.)
Rails 5へのアップグレードでやったこと。

（社内LT用の資料としてざっとまとめました。）
質問とかあればコメントでお願いします。

---

## 概要
Rails4.2 => Rails5.0 へのアップグレード頑張った。

---

## やったこと
- アップグレード用のブランチを用意
- Rubyを2.2以上にする。
- bundle update rails が完了できるまで頑張る。
- Rails5標準の実装に変更する。（Rails5 アップグレードガイドとリリースノートを見つつ）
- テストが実行できるまで、gem を update したり、パッチ当てたり頑張る。
- 落ちてるテストをひたすら修正する。
- deprecation warning を出している gem をアップデート
- rails s で モンキーテストする。

---

## アップグレード用のブランチを用意
間違ってもmasterにアップデートコミットを積まないように。

---

## Ruby2.2 以上にアップデートする。
rbenv で 2.3.1 に切り替える。
Gemfileでrubyディレクティブを使ってバージョンを指定するのがおすすめ。

```Gemfile
ruby '2.3.1'
```

---

## bundle update rails が完了できるまで頑張る。

Gemfile で ``` gem 'rails', '5.0.0' ``` に書き換えて、``` bundle update rails ```を実行。
バージョンの競合とかで色々、エラーになって進まないので、ひたすら、バージョンの整合性を整えつつ、update する gem を追加していく。

---

【例】

```
Bundler could not find compatible versions for gem "activerecord":
  In Gemfile:
    activerecord-session_store was resolved to 1.0.0, which depends on
      activerecord (< 5.1, >= 4.0)

    rails (= 5.0.0) was resolved to 5.0.0, which depends on
      activerecord (= 5.0.0)

    seed-fu was resolved to 2.3.5, which depends on
      activerecord (< 4.3, >= 3.1)
```
上記の例だと、seed_fu が activerecord の5.0.0以上のものを利用しているバージョンまで update する必要がある。

最終的に以下のupdateを行った。

```
bundle update rails act-fluent-logger-rails i18n_generators inherited_resources sass-rails seed-fu default_value_for jquery-rails sinatra
```

---

## Rails5標準の実装に変更する。 （Rails5 アップグレードガイドとリリースノートを見つつ）

```
rake rails:update
```

でアップデートする。
競合するconfig内ファイルはdiffを見て、上書きするかどうか決める。
別ディレクトリに rails new で作成したファイルと比較するのも良い。

後は [Rails5 アップグレードガイド](http://railsguides.jp/upgrading_ruby_on_rails.html) や [リリースノート](http://railsguides.jp/5_0_release_notes.html) を見つつ、必要に応じて、ファイルを修正していく。

---

## テストが実行できるまで、gem を update したり、パッチ当てたり頑張る。
テストが無事に実行できるまで、エラーになる gem を修正する。
gem の updateにあたっては以下の手順で対応のバージョン、またはリビジョンを探す。

1. githubの対応ブランチを探す。
2. issueやpull reqの状況を確認する
3. forkする or 捨てる

詳しくは [参考URL](http://qiita.com/joker1007/items/82db0b5d1a7f2572710b) を参照すること。

---

## 落ちてるテストをひたすら修正する。
頑張れ、超頑張れ！！

---

## deprecation warning を出している gem をアップデート
deprecation warning がなくなるまで、該当箇所を修正したり、gemをアップデートする。
gemのアップデート手順は bundle update のやり方と同じ。

---

## rails s で モンキーテストする。
テストコードが整備されていないようなところは手動でテスト

---

## 参考まで
- http://qiita.com/joker1007/items/82db0b5d1a7f2572710b
- http://railsguides.jp/upgrading_ruby_on_rails.html
macOS sierra で reattach-to-user-namespace 

OS を sierra にしたら、tmux.conf の 以下の設定で warrning が出た。

```
set-option -g default-command "reattach-to-user-namespace -l bash"
```

ので、`brew upgrade` で対応。

```
$ brew upgrade reattach-to-user-namespace
==> Upgrading 1 outdated package, with result:
reattach-to-user-namespace 2.5
==> Upgrading reattach-to-user-namespace
==> Downloading https://homebrew.bintray.com/bottles/reattach-to-user-namespace-2.5.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring reattach-to-user-namespace-2.5.sierra.bottle.tar.gz
🍺  /usr/local/Cellar/reattach-to-user-namespace/2.5: 6 files, 34.1K
$
```
~~~/sp/index.html のスマホ版サイトにpcでアクセスした時にpcサイトに飛ばす


```js:hoge.js
// sp版アクセスして、PCだったら飛ばす

if ((navigator.userAgent.indexOf('iPhone') > 0 &&
 navigator.userAgent.indexOf('iPad') == -1) || 
 navigator.userAgent.indexOf('iPod') > 0 || 
 navigator.userAgent.indexOf('Android') > 0) {
}else{
  location.href = '/';   //ここに飛ばしたい階層
}

```

スマホでpc版アクセス→spに遷移はやったけど、
逆もやってよと言われた時
New Relicのnoteの使い方メモ

newrelicは無料版だと過去の記録は24時間分しか残らないので、残したかったらスクリーンショットを撮るか、noteを活用するという手段があります。

<img width="715" alt="newrelic note" src="https://qiita-image-store.s3.amazonaws.com/0/57635/6ed327e4-d8d9-a33c-564a-4112e33a227a.png">

グラフの下に"Add to note"とある箇所をクリックします。

<img width="680" alt="newrelic note" src="https://qiita-image-store.s3.amazonaws.com/0/57635/06785763-2ba9-7a59-a911-370e18fd50d8.png">

コメントは後に見出しになるため、後から見て分かるようなコメントを書いておくと良いでしょう。
「create a new note」は新しいnoteとして新しく一覧に追加されます。
「Append to an existing note」は既にある最新のnoteの下に追記される形で保存されます。

後からnote一覧にアクセスしたい場合は、画面右上の"Tools" > "Notes" にアクセスします。 
<img width="389" alt="20.png" src="https://qiita-image-store.s3.amazonaws.com/0/57635/91ba7d46-23c3-384a-4d73-0011e0b5afae.png">
macOS Sierra で右コマンドキーを日本語ON/OFFに割り当てる方法。


これまでのバージョンでは、karabinerで一発だったんですがkarabinerが使えなくなったので、ほんの少し手間がかかります。

## karabiner-Elementsをインストールして起動させる。

https://github.com/tekezo/Karabiner-Elements/blob/master/usage/README.md

## karabiner.jsonを作成

ディレクトリ ~/.karabiner.d/configuration を作成して、以下のファイルをkarabiner.jsonという名前で保存します。

```json
{
    "profiles": [
        {
            "name": "Default profile",
            "selected": true,
            "simple_modifications": {
                "right_command": "f10"
            }
        }
    ]
}
```

## 環境設定を変更

環境設定-キーボード-ショートカット-入力ソースでキーボードショートカットを変更します。

入力ソースの次のソースを選択 → F10

この例では、F10キーを日本語ON/OFFに割り当てましたが、当然他のキーでも使えます。

以上。
serverspec-runner使ってみた

ubuntu16.04.1で動作確認しましたが、
(gemで入れたものとaptで入れたものは名前が変わっているのかそもまま動かなくてつらみ。
 `SpecInfra` が `Specinfra` になっていたり、DetectOSがDetectOsだったり)

## 参考

* [serverspec-runnerにて独自リソースを使う - Qiita](http://qiita.com/hiracy/items/49e177624adef5fbee74)
* [serverspec-runnerを使って複数のホストのテストレポートを作る - Qiita](http://qiita.com/hiracy/items/1ebc7b82f1a6ffa69ed0)

## インストール

```ruby
gem install serverspec-runner
```

* `/usr/local/bin/serverspec-runner`が入る。

```ruby
mkdir test; cd test
serverspec-runner -r .
# yを入力
```

## 設定

* `vim ./scenario.yml`

```diff:scenario.yml
  example:
    - anyhost-01
  ---
  anyhost-01:
-   host:        127.0.0.1
+   host:        192.168.0.9
```

```bash:実行
serverspec-runner -t mkd
```

* 実行される spec ファイルは `spec/example/default.rb`

```ruby:結果
|description                                                      | result |
|:----------------------------------------------------------------|:------:|
|example@anyhost-01(192.168.0.9)                                  |        |
|  User "root"                                                    |        |
|    should exist                                                 |   OK   |
|    should have uid 0                                            |   OK   |
|    should have home directory "/root"                           |   OK   |
|  Group "root"                                                   |        |
|    should have gid 0                                            |   OK   |
|  Filesystem                                                     |        |
|    File "/"                                                     |        |
|      should be mounted                                          |   OK   |
|  Host "www.google.com"                                          |        |
|    should be resolvable                                         |   OK   |
|    should be reachable                                          |   OK   |
|  Command "dmesg | grep "FAIL\|Fail\|fail\|ERROR\|Error\|error"" |        |
|    exit_status                                                  |        |
|      should not eq 0                                            |   NG   |
```

```bash:コンソール向けに出力
serverspec-runner -t aa
```

![スクリーンショット_2016-09-26_09-19-55.png](https://qiita-image-store.s3.amazonaws.com/0/25728/614e09f7-0629-33ea-dbe3-82815fed2694.png)
プログラミング Elixir 第三章

# 概要

[プログラミング Elixir](https://www.amazon.co.jp/dp/4274219151)

Elixir の大きな特徴の一つである「不変性」について解説している章。

Elixir では（束縛し直さない限り）常に変数は同じ値を参照する。そのため、オブジェクト指向言語のように、このメソッドは変数自体を書き換えるのか？コピーを返すのか？と悩む必要がなく、可読性が高いコードを実装することができる。

# 不変性

## 不変性とは

例えば

```
ids = [1, 2, 3]
do_something_with(ids)
print(ids)
```

こんな感じで、「最初に id のリストを渡して、`do_something_with` で何らかの処理を行う。最後にデバック用に、どんな id を渡したか出力する」という実装が存在した場合、最後の `print` では `1, 2, 3` が出力されることを期待してまう。

しかし、例えば `do_something_with` が以下のような実装なら (Ruby)

```rb
def do_something_with(a)
  a.delete(2)
end

ids = [1, 2, 3]
do_something_with(ids)
print(ids) 

#=> [1, 3]
```

途中 2 が消されて ids の値が変わってしまっている。
こういう具合に、多くのオブジェクト指向言語では簡単に期待を覆す実装ができてしまう。

それに対して、Elixir は常に「不変」で、メソッドは引数のコピーを作成して返すので、これが「破壊的」かどうかについて頭を悩ませる必要がない。これは、可読性を上げて、並行性の怖さを軽減してくれる。

## 不変性の性能

Elixir はデータを更新するごとに毎回新しいデータのコピーを作るので、そこら中にゴミが残ってしまい、とても非効率に見えるが、実際は逆である。
不変であるからこそ、新しいデータを作成する際に、前のデータを再利用することができる。

```iex
> list1 = [3, 2, 1]
[3, 2, 1]
> list2 = [4 | list1]
[4, 3, 2, 1]
```

多くの言語では list2 を作成する際は、`4, 3, 2, 1` が入った新しいリストを作成する。これは `list1` が「可変」だからである。
しかし、Elixir は `list1` が「不変」であることを知っているので、単に「先頭に 4、末尾に list 1」を持つリストを作ればよい。

また、多くの言語と同じようにメモリを解放するために Elixir もガーベージコレクタを備えている。

このガーベージコレクタは性能に悪影響を及ぼす場合があるが、Elixir は各プロセスが個別のヒープを持っているため、全てのデータを一つのヒープで扱う言語に比べ、各ヒープがとても小さい。
そのため、ガーベージコレクションは高速で、その上ヒープが一杯になる前にプロセスが終了すれば、ガーベージコレクションを使うことなくメモリが解放される。

上記の様に不変性による性能への影響は心配する必要がない。
Serverspec使ってみた

今からやるなら[serverspec-runner使ってみた - Qiita](http://qiita.com/tukiyo3/items/10154c8f41f33a7f29f2)がおすすめ。

* 出力結果が見やすい(csv,markdownのtable形式などに対応)
* 複数ホスト
* sshオプション指定

## 参考

* [serverspecのリソースタイプ・マッチャー - Qiita](http://qiita.com/ando-masaki/items/e02960789c7a4e0c4d20)
* [Serverspecでよく使うテストの書き方まとめ - Qiita](http://qiita.com/minamijoyo/items/467ddd13c0cab15330bf)

## インストール

```ruby
sudo gem install serverspec
mkdir test; cd test
serverspec-init
```

```ruby:入力
  1) UN*X
  1) SSH
Vagrant instance y/n: n
Input target host name: server01
```

* spec/server01/ 以下に `sample_spec.rb` が生成される。

```bash:実行
rake spec:server01
```

## カスタマイズ

* `/etc/resolv.conf`に`nameserver 8.8.8.8`が登録されていることを確認する例

```ruby
cd spec/server01
touch etc_spec.rb
```

```ruby:etc_spec.rb
require 'spec_helper'

describe file('/etc/resolv.conf') do
  its(:content) { should match /^nameserver 8.8.8.8/ }
end
```

```ruby:実行
rake spec:server01
```
htmlのバリデーション

htmlファイルのバリデートに関してです．
htmlを書くときにW3Cで定められたいろいろなルールがあると思います．
例えば，インライン要素の中に，ブロック要素を入れてはいけないなどです．

ですが，以下の二つを実際に表示してみると，クリック可能な範囲が異なるものの，どちらも表示されます．
（h1要素はブロック要素，a要素はインライン要素です．したがって，h1要素内にa要素を入れるのがW3C的には正しい）

```
<h1>
    <a href="#">リンク</a>
</h1>
```

```
<a href="#">
    <h1>リンク</h1>
</a>
```

このようなものでも，

https://validator.w3.org/

にバリデートをかけたいhtmlファイルをアップデートすると，書式が間違っている箇所を教えてくれます．
やってみると，「あ，この書き方だめだったんだ．知らなった！」のようなこともあるので，ぜひ試してみてください．



ちなみに，上の例(a要素内にh1要素)だと，


>Error Line 22, Column 16: document type does not allow element "a" here; missing one of "p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "pre", "address", "fieldset", "ins", "del" start-tag
    ```<a href="#">```

>The mentioned element is not allowed to appear in the context in which you've placed it; the other mentioned elements are the only ones that are both allowed there and can contain the element mentioned. This might mean that you need a containing element, or possibly that you've forgotten to close a previous element.

>One possible cause for this message is that you have attempted to put a block-level element (such as "```<p>```" or "```<table>```") inside an inline element (such as "```<a>```", "```<span>```", or "```<font>```").

と、

>Error Line 23, Column 12: document type does not allow element "h1" here; missing one of "object", "ins", "del", "map", "button" start-tag
        ```<h1>link</h1>```

>The mentioned element is not allowed to appear in the context in which you've placed it; the other mentioned elements are the only ones that are both allowed there and can contain the element mentioned. This might mean that you need a containing element, or possibly that you've forgotten to close a previous element.

>One possible cause for this message is that you have attempted to put a block-level element (such as "```<p>```" or "```<table>```") inside an inline element (such as "```<a>```", "```<span>```", or "```<font>```").


のように，インライン要素の中に、ブロック要素をいれるな！！とちゃんと注意してくれます．
Ubuntu 16.04 LTS でフルHD（1920*1080）に画面出力できないときにやったこと

# 現象

Ubuntuインストール中に画面が真っ暗になってインストールができなくなった。
他の小さいディスプレイに接続したところ表示できたので解像度が対応していない様子。

# 解決策

NVIDIAのグラフィックドライバをインストールしたら表示できました。
（当方GTX1070で現時点で最新のnvidia-370をインストール）

```bash
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt-cache search 'nvidia-[0-9]+$'

# nvidia-370 みたいなのがずらずらと表示される

sudo apt-get install nvidia-370
```

# 参考リンク
* [Ubuntu 14.04 で 最新の NVIDIA ドライバーにアップデートする](http://zondeel.hateblo.jp/entry/2015/04/30/212015)
* [How to install latest nvidia drivers (xorg edgers doesn't work) [duplicate]](http://askubuntu.com/questions/681198/how-to-install-latest-nvidia-drivers-xorg-edgers-doesnt-work)
知っていると少し幸せになれる、Chrome検証機能の小技まとめ

みなさんブラウザは何を使っていますか。
僕はchromeです。

今回はchromeの検証の便利な機能を紹介したいと思います。
各種ショートカットキーはMacのものです。

何か便利小技が増えたら、ここに追記していこうかと思います。

## 1. 拡大縮小
拡大：**「command」 + 「shift」 + 「+」**
縮小：**「command」 + 「-」**
元の大きさに戻す：**「command」 + 「0」**

通常のブラウザの拡大・縮小と同じ

## 2. 上下キーで値の変更

**Shift+↑ 10の増減**
**Alt+↑ 0.1の増減**

![demo_qiita.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/24401f07-e07f-2094-aee6-9654e44184c0.gif)


## 3. 色をカラーピッカーから選択
カラーピッカーから色を選択できます。
さらに以前はchromeの拡張機能からしかできなかったような、サイト上から色を選択してとってくることもできます。

![chrome2.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/bf402e30-1e66-0286-0489-a4cd30e61ba3.gif)

透明度も変更できる
![chrome3.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/373f782c-80b3-d351-f1e7-e1344c0a8f9d.gif)


## 4. minify化しているファイルを整形
minify化されているようなファイルを整形して見やすくします。

最初にcommand+p で検索パネルを表示してます。
ファイルを開いた後左下にある「{}」をクリックすると整形されます。

![chrome4.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/ae60cd57-8c05-e2ca-8b99-f03619c216e3.gif)


## 5. hover状態を確認する
なかなか確認が難しかったマウスオーバも:hoverの状態を維持させることで確認できるようになります。

Elementsパネルでaタグの場所でメニューを表示させ、:hoverを選択すると:hover状態を維持できます。

他の:activeとか:visitedとかも同じ。

![chrome5.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/42639e90-bd1e-d5bf-8d39-3b8a5601cdb5.gif)


## 6. Computedパネルで最終的にその要素に適用されたCSSの状況をまとめて確認できる
Stylesパネルで確認するとCSSファイル内で指定した箇所がバラバラに表示されてしまう。Stylesパネルの隣のComputedパネルを見るとページ内でのCSSの設定をまとめて確認できます。

さらに設定内容をクリックすると、Stylesパネルの該当箇所へ移動

![chrome6.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/697f859b-1179-40ba-e12a-fb2c8120bec5.gif)


## 7. 変更履歴の管理
CSSの値をchrome上で変更をすると、
Sources → 右クリック → LocalModifications
で見たときに変更履歴をを確認することができます。

また過去の変更状態にまで戻れます。

![chrome8.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/2d195191-fd78-ee56-6ab5-389e74973a05.gif)

↑ちょっとわかりずらいですが、背景色と文字色を変更して変更点をrevertするまでです。

## 8. 定規を表示
ピクセルピッチの定規を表示します。

### 1. 右上の点が3つ縦にならんでいるところ > Settings、で設定画面を表示
<img width="387" alt="スクリーンショット 2016-09-24 20.47.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/eb0aa257-3d0d-81e0-c8d6-451fdb203d83.png">

  
    
### 2. Elements内のShow rulesにチェック

<img width="354" alt="スクリーンショット 2016-09-24 20.47.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/005ab661-8b80-30bf-81ee-7102e18ecd04.png">


これでchrome上に定規が表示されます。
<img width="448" alt="スクリーンショット 2016-09-24 20.48.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/132028b6-7d96-d7cb-38e6-30635b59a966.png">



## 9. デバイスごとの表示変更

Elementsパネルの隣のスマホのアイコンをクリック
「Responsive▼」をクリックするとデバイスが選択できるようになります

![chrome9.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/c3c4c456-b579-afaf-4f93-05ca47f29527.gif)


## 10. ソースファイル全部から検索
**command opt + f**で検索できます。
そのページ内のhtml、css、js全てから検索してくれる。

![chrome10.gif](https://qiita-image-store.s3.amazonaws.com/0/6808/aa2413ed-ab68-ad63-43dc-9bf40c4110db.gif)
Circle CIのmvn integration-testをmvn testに変更する

Circle CIでは、mavenを利用している場合のtestはデフォルトでmvn integration-testになる。
※[公式のこの辺りに書いてある](https://circleci.com/docs/language-java/#dependencies--tests)

別にこのままでも良かったんだけど、ちょっとテストの実行時間をもう少し短縮できないものかと思って、mvn testに変えてみることにした。circle.ymlに以下を追加するだけ。
※[公式のこの辺りに書いてある](https://circleci.com/docs/configuration/#test)

```circle.yml
test:
  override:
    - mvn test
```

ちなみに、mvn integration-testとmvn testでテストを4回ずつ回した時の平均実行時間は以下のようになった。

|テストコマンド|平均実行時間|
|:--|:--|
|mvn integration-test|38.75秒|
|mvn test|33.25|

約5秒短縮された。MAXで8秒の短縮が見られた。

※mvn integration-test
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/23101/a98b7718-3ec4-94bd-5316-24ad74897909.png)

※mvn-test
![無.png](https://qiita-image-store.s3.amazonaws.com/0/23101/2ca3a366-7b11-8740-608a-52a4a11e7fb3.png)
技術英語 > In a survey of the literature, ... / According to the statistics, / I literally copied the code word for word

@ Code Complete (No. 13209 / 36077)

> In a survey of the literature, ...

意訳「文献調査によると」

<hr>
関連して見つかったのは

> According to the literature,

僕が覚えていたのは

> According to the statistics, 

<hr>
関連して見つけたのは

https://www.codecademy.com/en/forum_questions/5464f7a252f863d05600477f

> I literally copied the code word for word and it doesn't work.
Redux 登場人物の説明箇条書き


redux-react のチュートリアル的なものをチラチラ見ながら、分からなかった事を調べたメモ。
誤り等が有るかも知れない。今後も更新していくかも知れない。間違いを放置したくないので指摘は歓迎です。

## Store

- state tree を保持する
- Store はクラスではなく単なるオブジェクト
- createStore で作成される
- Provider の store 属性に渡される

### state

- アプリケーションの状態を保持するプレーンな値もしくはオブジェクト
- state を変更する唯一の手段は action を引数に渡して dispatch すること
- つまり dispatch 関数を実行する事でしか変更出来ない

### dispatch(action)

- dispatch(action)
- state を変更する唯一の方法
- 引数に action を渡す
- 実行すると reducer 関数が全て呼び出される

### getState()

- 現在の state tree を返す
- 最後に reducer から渡された state と一致する

## Reducer

- ``reducer(state, action) => newState``
- プレーンな関数
- 副作用があってはいけない
- 同じ引数なら毎回同じ返り値でなくてはいけない ( Date.now() とかダメ )
- 引数に state と action を受け取る
- 返り値は state ただし既存の state を変更せずに新しく作る
- dispatch すると全ての reducer は実行される
- reducer は渡される action の action.type から処理すべきかどうか判断して state を返す
- createStore する(Providerの初回配置時?)と実行されて、初回の state が決定される

### combineReducers(reducers)

- combineReducers で複数の reducer 関数をまとめる事ができる
- combineReducers の引数となる形式は ```{ stateName: reducerFunc, stateName2: reducerFunc2 }```
- reducerFunc に渡される state は sate.stateName になる
- まとめられた reducer は createStore の引数にできる


## Action

- プレーンなオブジェクト
- type プロパティが必須
- type プロパティでどんなアクションが発生したかを判別する(reducerで)
- それ以外のプロパティは任意
- dispatch 関数の引数として渡される


## (用語) Presentation Components, Container Components

[Presentational and Container Components](http://redux.js.org/docs/basics/UsageWithReact.html#presentational-and-container-components)

- Presentation Components
  - 普通の React.Component
  - 見ためを規定する ( タグ構造とか )
  - データがどこから来るのかは知らない
  - どうやってデータを変更するかも知らない
  - Redux へ依存してない
  - React.Component を継承したクラスを定義して作成する
- Container Componentns
  - 見た目は関知しない
  - データを提供する ( mapStateToProps で props に渡すデータを作成する )
  - データを変更する手段を提供する ( mapDispatchToProps で dispatch の実行を受け持つ property を作る )
  - Presentation Componentns のクラスに mapStateToProps と mapDispatchToProps を connect する事で作成する


### connect(mapStateToProps, mapDispatchToProps)(component)

- Presentation Components を作成する関数
- Redux の世界と React の世界を繋げる、と言われる
- component の props に mapStateToProps と mapDispatchToProps をバインドする
  - mapStateToProps で Presentation Components に props 経由でデータを提供する
  - mapDispatchToProps で Presentation Components に props 経由で dispatch する手段を提供する
- ``mapStateToProps``
  - 引数に state が渡される関数
  - 戻り値はオブジェクトで component の props にバインドされる
  - ```{ propName: propValue, propName2: propValue2 }``` の形式
  - ```component.prop.propName``` が propValue となる
- ``mapDispatchToProps``
  - 引数に dispatch 関数が渡される関数
  - 戻り値はオブジェクトで component の props にバインドされる
  - ``{ propName: dispatchFunc, propNam2: dispatchFunc2 }``
  - dispatchFunc の中で mapDispatchToProps 関数の引数に渡された dispatch を使って dispatch の処理する
  - component の中で特定のイベントが発生した際に dispatch させたい場合、任意の場所で ``dispatchFunc()`` を実行させてその中で ``dispatch`` する
- Store#subscribe() でも同じ事が出来るらしいが connect なら簡単に出来るらしい

## 処理の流れ

1. createStore する
2. reducer が初回実行される
3. reducer 初回実行により初期状態の state が決定される
4. Provider の store 属性に store を渡す
5. 何かイベントが発生する
6. 対応する action を生成する
7. connect で受け取った dispatch する為のメソッド経由で action を dispatch する
8. reducers が全て実行される
9. 各 reducer は action.type を見て処理すべきなら state を返す
10. state が Component に反映される
iOS App StoreにアップロードしたのにiTunes connectに出てこない


iOS10になったせい？レビューの手順が変わった？XcodeのOrganizerからファイルをアップロードしてもiTunes connect上に現れないという現象に遭遇しました。

で、半日くらいしてから届いたのが以下のメール。

> iTunes Connect: Your app "XXX" (Apple ID: xxx) has one or more issues

GPSへのアクセスの時だけ必須だったInfo.plistへのキー追加がカメラとフォトライブラリにも必須になったようです。

> The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

これらのキーの値は、許可を求めるダイアログの説明文として使用されます。また以前はコピペしないと設定できなかった（はず）のキーも、「Privacy」というグループにまとめられて簡単に探せるようになっています。
【Android】WebViewでキャッシュやクッキー削除をする


# キャッシュの削除方法

```java:
webView.clearCache(true);
```

ちなみにキャッシュを使わないで常に表示を行いたい時は

```java:
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
```


# クッキーの削除

Lollipop以降と前で推奨されるメソッドが変わるので処理を分けます

```java:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   CookieManager.getInstance().removeAllCookies(null);
   CookieManager.getInstance().flush();
} else {
   CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(getApplicationContext());
   cookieSyncMngr.startSync();
   CookieManager cookieManager=CookieManager.getInstance();
   cookieManager.removeAllCookie();
   cookieManager.removeSessionCookie();
   cookieSyncMngr.stopSync();
   cookieSyncMngr.sync();
}
```
[メモ]laravel5.2でmigrateをしたのにフリーズしてエラー文言も出ずにハマった時の対処

症状
・laravel初期設定後、php artisan migrateを実行してもずっとフリーズしたままエラー文言も出ずに困りはてた

環境
・mysql-ctl cliでちゃんと接続できる状態
・.envのDB設定はこれまでcloud9で使ってきた設定
・gitのmasterブランチ

最初の対処
・.envのDB設定をいじったり、ルートディレクトリを変えたり
・「laravel artisan migrate 止まる」等の文言で検索したり
・gitの設定の問題？と疑っていろいろ調べてみたり
 ->うまくいかず

原因の切り分け
①gitが原因かどうか確定するためにgit以外全く同じ環境を最初から作ってみた
　->同様の症状が出た
②以前作ったlaravelプロジェクト(git利用無し)で試す
　->うまくmigrate出来た
③うまくmigrate出来たlaravelプロジェクトの.envでDB設定を確認
　->port番号が異なることが発覚
④うまくmigrate出来たlaravelプロジェクトでport番号をうまくいかなかったプロジェクトのport番号に変えてmigrateしてみた
　->最初の症状と同じ症状が出た
⑤原因がport番号であることがほぼ確定
⑥元のプロジェクトでport番号を変えてmigrate実行
　->エラー解消！！！

まとめ
・勘でいろいろ試すんじゃなくて、ちゃんと原因の切り分けを一つずつ順番にやっていくことの大切さを知りました。なんとなくこれじゃね？と手当たり次第やっていくうちに時間がどんどんすぎてしまうので、次回からは最初からしっかり原因の仮説を立て->切り分けて->原因に対する打ち手を考える、という流れでやっていこうと思います
awkに関するメモ

awk

■ 実行
awk -f foo.awk
gawk -f foo.awk
nawk -f foo.awk
mawk -f foo.awk

nawk -f foo1.awk -f foo2.awk -f foo3.awk
nawk 'BEGIN { print "Hello World" }'

■ 基本構文
BEGIN {} : タイトル、項目名、フィールドセパレータの設定
pattern {action} : main loop :ファイル読み込み
END {action} : 合計や平均値の算出・表示
BEGIN {
	a = 1
}

{
	if(){
	}
}

NR == 1{
	if(){
	}
}

END {
	if(){
	}
}

■ 演算子
~ 正規表現マッチする
!~ 正規表現マッチしない
他はC言語と同じ

■ 変数
● レコードとフィールド
入力データの単位。
・レコード : 行(改行区切り)
・フィールド : 列(空白区切り)

● システム変数とフィールド変数

○ システム変数
・FS : 入力フィールドの区切り
・RS : 入力レコードの区切り
・OFS : 出力フィールドの区切り
・ORS : 出力レコードの区切り
・NF : 現在の入力フィールドの個数
・NR : 現在の入力レコードの番号　(ファイルリスト通し番号)
・FNR : 現在の入力レコードの番号 (入力ファイルごと)
・FILENAME : 現在の入力ファイル名

○ フィールド変数
フィールドを参照するためのシステム変数。
・$0 : 行全体
・$n : nフィールド(n >= 1)

# 全ての行を表示
{ print $0 }

# 段落 (空行) 単位をレコードとして $0 を表示
BEGIN { RS = "" } { print $0 }

# 最初と最後の要素を表示
{ print $1, $NF }

# フィールド分割を "," (カンマ) 区切り (CSV) にして $1 を表示
BEGIN { FS = "," } { print $1 }

# 最初の 10 行を表示
NR <= 10 { print $0 }

■ str
・連結
str2 = str1 "def"; 
・置換には一度だけ置換する sub 関数と全てを置換する gsub 関数の2種類
BEGIN { str = "abc"; gsub(/[a-z]/, "A", str); print str }

■ 配列
リストがないので、1個づつ代入
str = "1 2 3 4 5";
# num_arr には配列の個数 (5) が代入される
num_arr = split(str, arr);

・繰り返し
for (index in arr) {
    num++;                              # 配列の個数が加算される
}

■ 入出力

● ファイル入出力
if (err_num > 0) {
    # 標準エラー出力に "Error" と表示
    print "Error" > "/dev/stderr";
} else {
    # 標準出力に "Not Error" と表示
    print "Not Error" > "/dev/stdout";
}

● getline : 1行読み込み(デフォルトでは改行なし)
# date コマンドの結果を変数 var に格納し表示
BEGIN { "date" | getline var; print var }

ファイルを読み込む
アクションブロック以外で読み込む際に良く使われる。
# foo.txt の中身を表示
BEGIN {
    while (getline < "foo.txt" > 0) {
        print $0;
    }
    close("foo.txt");
}

■ 終了
exit;
ブロック単位で記載する必要がある。

● コマンドライン引数
コマンドライン引数は配列 ARGV に格納される。
# コマンドライン引数を全て表示
BEGIN {
    for (i in ARGV) {
        print i, ARGV[i];
    }
}
■ 関数
function tan(num,    val) {
    val = sin(num) / cos(num);

    return val;
}
Unity5.5でデプスバッファのnearとfarが入れ替わった話

EffekseerがUnity5.5β環境で描画がおかしくなるという報告がありました。

![unity.png](https://qiita-image-store.s3.amazonaws.com/0/11172/ab97e810-e122-e5c1-fc02-c076299424a0.png)

報告によるとデプスバッファの仕様変更が影響しているんじゃないかとのこと。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Coming in Unity 5.5 : reversed depth buffer, finally! Far greater precision for  shadows and post-process. <a href="https://t.co/IUp8yfe54v">pic.twitter.com/IUp8yfe54v</a></p>&mdash; Tim Soret (@timsoret) <a href="https://twitter.com/timsoret/status/768082633821650944">2016年8月23日</a></blockquote>

どうやら5.5からの仕様変更のようです。
逆floatアルゴリズムによって影の品質が改善するとか。

# 影響があるプラットフォーム
- Windows DirectX11
- Windows DirectX12
- macOS/iOS Metal
- PS4

# 影響があるケース
- ポストエフェクト等でデプスバッファを使っている
- ネイティブプラグインで描画している

## ポストエフェクト等でデプスバッファを使っている

SAMPLE_DEPTH_TEXTURE で生のデプス値を使っている場合は対策が必要です。
UNITY_REVERSED_Z というシェーダ定義が追加されたそうなので、以下のようにプリプロセッサ分岐してやるのがよさそうです。

```
#if defined(UNITY_REVERSED_Z)
    o.pos.z -= _MotionVectorDepthBias * o.pos.w;
#else
    o.pos.z += _MotionVectorDepthBias * o.pos.w;
#endif
```

## ネイティブプラグインで描画している

普通に描画していても、デプステストは大体していると思うので対策必須です。
Unityバージョンとグラフィックスデバイスタイプを見て、デプステストのDepthFuncを切り替えましょう。

```
if (unityReversedZ) {
    depthFunc = D3D11_COMPARISON_GREATER;
} else {
    depthFunc = D3D11_COMPARISON_LESS;
}
```
Android アプリのコードを綺麗に保つためのコードレビューのチェックリスト4項目

Android アプリの開発で起きがちな問題を予防するためのコードレビューのチェックリストです。

# チェックリストの方針
極力数少ない項目で多くの問題を防げること。
要は「最低限これを守ってくれるとまずまず OK だと思います」くらいのものです。

項目が少ないので重要な事柄に集中できますしレビュワの経験が少ない人もとっかかりやすいと思います。

全体的に、開発経験がそこまで豊富ではない方向けのチェックリストになっていると思います。

# チェックリスト
全4項目です。

## 1. なるべく Activity にフィールドでフラグを持たせないこと
### そうすべき理由
予想外のバグが発生するのを減らすためです。
下記の状況に陥ると問題が発生するのでこれらを回避します。

* 色々な箇所で色々なフラグを変更していてどこで何をしているかを把握できず、実装時にフラグの操作漏れが発生する
* 複数のフラグの組み合わせで挙動が変化するようになっていて、複雑なので、間違ったように理解してしまう

具体的には、1つの画面に複数の「モード」があるときに該当しやすいと思います。例えば写真撮影アプリに「連写モード」「タイマーモード」「通常モード」などがあり、それぞれの「モード」をフラグで表現している場合です。
「モード」は得てしてアプリのバージョンアップで追加されていくことが多いので、開発初期は問題がなくても、気がつくとフラグだらけでコードが理解できなくなってしまうことがあります
「通常モード」でしか「レトロ風フィルターモード」を使えなかったりというように、「モード」同士の関係性に制約があると、「モード」をフラグで管理するのはますます困難になります。
どのフラグをどのタイミングでどのような値にすべきかを把握しないとコードの変更が出来ないので、フラグが増えるほど問題が大きくなります。

### とるべき改善策
* フラグではなくストラテジパターン等の別の手段で挙動を変える
* 1つの Activity に実装することを諦めて Activity を分割する

また、どうしてもフラグをなくせない場合は、次善策として下記のようにすると可読性を保ちやすいと思います。

* 各フラグに値を設定する箇所を Activity の中の1箇所に集める
* フラグ同士の排他関係などを Enum などを使って上手く整理する

## 2. Activity や AsyncTask からビューを細かく操作しすぎないこと
### そのようにすべき理由
違反すると、コードを理解するのに長い時間がかかるようになってしまうからです。
具体的には下記の状況に陥って問題が発生しやすくなります。

* Activity や AsyncTask の中にコントローラ的なロジックやサーバとの通信やビューの操作などが入り乱れて、どこで何をしているのかが分からない。ビューの挙動を確認したいだけなのにあちこちのコードをさまようハメになる
* XML ではなく Java のどこかでビューが生成されている場合には、ビューの構造を理解したいだけなのに Java のコードをあちこちさまようハメになる

ユーザーの操作などに応じて画面の見た目が動的に激しく変化する場合にこの問題が生じがちです。

### とるべき改善策
* 複数のまとまったビューを同じタイミングで操作しているなら、カスタムビューやフラグメントにまとめる
* カスタムビューの中のビューを直接 Activity からいじるのではなく、詳細な処理はカスタムビュー自身に任せる
    * （つまり Activity からカスタムビューのメソッドを1つ叩けば、カスタムビュー自身がその中の各ビューを操作するようにする）

## 3. 性能的に問題がないこと
### そのようにすべき理由
下記のようなアプリになると、ユーザがイライラしてしまいます。

* 処理が遅い
* メモリ不足で落ちる
* バッテリの消費が激しい

例えば下記のような場合にこの問題がおきます。

* ユーザがボタンを一つ押すと SQL が大量に投げられる。取得した大量のレコードをリスト表示する際に大量の画像を読み込む
* OpenGL で無闇やたらに描画を更新しようとしている（どうせ60FPSが限界なのに1msごとに更新をかけている、など）

### とるべき改善策
* スペックが低い機種でテストして、問題の有無や対処の優先度を確認する
* 大量に SQL を投げているなら1つにまとめる
* [Bitmap はサブサンプルしたものを読み込むようにして](https://developer.android.com/training/displaying-bitmaps/load-bitmap.html)メモリの消費を抑える
* そもそも無駄な処理をなくす

## 4. 画面が小さな端末、ピクセル密度が大きな端末や小さな端末でも、意図通りに表示される画面になっていること
### そうすべき理由
表示が崩れるとかっこ悪いからです。
ありがちなのは下記のような問題です

* 画面が小さな端末でレイアウトが崩れている。ボタンが画面からはみ出していて操作が不可能になっている
* ピクセル密度が高い端末で、ボタンがものすごく小さく表示されている
* ボタンが小さくて押しづらい

### とるべき改善策
* ビューのサイズやマージンなどは理由がない限りピクセルを使わない
* ボタンの当たり判定は見た目よりも大きくする（たとえば InsetDrawable を使う）

# チェックリストの効果
レビュワとしても実装担当者としても、実感したのは、チェックリストの項目数はまずは少なくしておくほうが使いやすいということです。
少ないほうが最低限抑えるべき重要な事柄に集中しやすいからです。
チームやプロダクトの課題に合わせてチェックリストの内容は更新していくといいと思いました。
IDCFクラウド仮想マシンを無停止スケールアップしてみた

[仮想マシンを停止せずにリサイズできますか？ \| IDCFクラウド](https://www.faq.idcf.jp/app/answers/detail/a_id/55/c/13) によると

>以下の場合を除き、仮想マシンを停止することなくCPU、メモリのスペック変更が可能です。
>(以下略)

どうやら、CentOS6以上でLight.S1/S2以外ならば、仮想マシンをシャットダウンせずにスケールアップ可能のようです。
また、Light.S1であっても「S1→S2」への変更ならば可能のようです。

「(一部のケースを除けば) **停止せずスペック変更できる** 」と、さも当たり前かのように書いてあるのですが、これは結構魅力的な機能なのではないでしょうか。
少なくとも、Microsoft Azure VMs や AWS EC2 を多く触ってきた自分にとってはあまり馴染みのない概念です。

本当に無停止でできるのかどうか、実験してみました。

## 事前準備

CentOS7で仮想マシンを構築しておき、sshログインできるようにしておきます。

```
$ ssh (ホスト名)
$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
```

### 今回の操作手順

1. IDCFクラウド仮想マシンにsshログイン
2. topコマンド実行
3. IDCFクラウド管理コンソールから「コンピューティング」→「仮想マシン」→「リサイズ」でスケールアップ

## 実験: Light.S1 → Light.S2

まずは、ワンコインで構築できることがウリのLight.S1仮想マシンを、メモリとCPUクロック数が倍増するS2に上げてみました。

name|CPU|RAM
:--|:--:|:--:
Light.S1|1CPU|1GB
Light.S2|1CPU|2GB

![out1.gif](https://qiita-image-store.s3.amazonaws.com/0/50391/5fa89229-6401-b55e-89de-954a194158ec.gif)
(Windowsでttyrecした録画データをMacでttygif化したせいか多少崩れていますが気にしないでください)

IDCFクラウド管理画面から操作して10秒程度で、topで観測していたメモリが突如 1,010,340→2,058,916 KiB に倍増しました。
再起動はおろか、sshセッションもtopプロセスも途切れることなく、何事もなくいきなりスペックだけが上がりました。

しかしCPUの動作クロック数が上がったのかどうかは、ちょっとこれだけではよく分かりません。

## 実験: Standard.L16 → Standard.XL32

せっかくならCPU数もちゃんと増加させてみたいと思い、先ほどと同じ仮想マシンを一旦シャットダウンしてStandard.L16に変更し、再度実験してみました。

name|CPU|RAM
:--|:--:|:--:
Standard.L16|4CPU|16GB
Standard.XL32|8CPU|32GB

![out3.gif](https://qiita-image-store.s3.amazonaws.com/0/50391/abac6be5-39a0-8a1a-1c45-7b7f801ff648.gif)

※メモリが倍増したのを確認した後、手動で「1」キーを2回押してCPU毎の状態を再表示させています。

Cpu0～3までだったのが、0～7までの8CPUに増加しています。
CPUもメモリも、サーバを停止させることなく増加することが分かりました。

## まとめ

一部の条件を除けば、IDCFクラウドで仮想マシンを無停止でスケールアップできることが分かりました。

実際サーバは無停止でスケールアップできても「稼働中のサービスが影響を受けずに継続できるか？」「スペックアップで空いたリソースの恩恵をサービスが無停止で受けられるのか？」など、本番環境での実戦投入にはいくつか検証が必要だと思います。ですがsshセッションもtopプロセスも切れずに反映されたことを鑑みると、大体ある程度は大丈夫なのではないでしょうか。

もちろん、無停止でのスケーリングが必要ならスケールアウトの手立てを予め用意しておくのが理想だと思います。
しかしWebサイトが知らぬ内にワールドビジネスサテライトに取り上げられていた等、インフラ構築時に予期しきれないレベルの緊急事態に対する切り札として予め検証しておくと、夜も安心して眠れるのではないかと思いました。
[Ansible入門] 1. Ansibleのインストール(pipを利用)

今さらですが、CentOSに Ansibleをインストールしたので手順をメモっておきます
pipでインストールします
色々な方法でインストールできるみたいなので、他の方法を知りたい方は[公式ページ](http://docs.ansible.com/ansible/intro_installation.html)を参照ください

## 環境メモ
```
# OS
[vagrant@localhost ~]$ cat /etc/redhat-release
CentOS release 6.6 (Final) # vagrantで入れやすかったので
# Python
[vagrant@localhost ~]$ python --version
Python 2.6.6
```

## pipのインストール
下記コマンドで一発
```
curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python
```

## Ansibleのインストール
```
sudo yum install gcc libffi-devel python-devel openssl-devel # 必要なパッケージを先にインストール
sudo pip install ansible
```

## インストールしたバージョン
```
[vagrant@localhost ~]$ ansible --version
ansible 2.1.1.0
  config file =
  configured module search path = Default w/o overrides
```


## 遭遇したエラーなど

何もインストールせずに `sudo pip install ansible` やると下記のようなエラーでた

```
    build/temp.linux-x86_64-2.6/_openssl.c:70068: error: ‘_cffi_f_sk_X509_NAME_num’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70069: error: ‘_cffi_f_sk_X509_NAME_push’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70070: error: ‘_cffi_f_sk_X509_NAME_value’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70071: error: ‘_cffi_f_sk_X509_REVOKED_num’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70072: error: ‘_cffi_f_sk_X509_REVOKED_value’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70073: error: ‘_cffi_f_sk_X509_free’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70074: error: ‘_cffi_f_sk_X509_new_null’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70075: error: ‘_cffi_f_sk_X509_num’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70076: error: ‘_cffi_f_sk_X509_push’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70077: error: ‘_cffi_f_sk_X509_value’ undeclared here (not in a function)
    build/temp.linux-x86_64-2.6/_openssl.c:70787: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘init_openssl’
    error: command 'gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-lOBHHV/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-phrkUY-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-lOBHHV/cryptography/
```

↓下記コマンドで解決
```
sudo yum install gcc libffi-devel python-devel openssl-devel
```
参考↓
http://stackoverflow.com/questions/22073516/failed-to-install-python-cryptography-package-with-pip-and-setup-py