OmniAICreator/Qiita-1.07M huggingface dataset:
Phalconでmemcachedを使う時にハマったこと

# memchachedをphalconで使おうと思ったらハマった。 

スピードを重視するためにphalconを選んだので、今までcacheをfileでごまかしていた部分を解消するために、memcachedを使おうと思った時にハマった。 

memcacheではなく、memcachedを利用したかった。 

```php
$FrontCache = new Phalcon\Cache\Frontend\Data(array(
    "lifetime" => 1728000
));

$cache = new \Phalcon\Cache\Backend\Memcache($FrontCache, array(
    'host' => 'localhost',
    'port' => 11211,
    'persistent' => false
));

$cache = $cache->get('my-cache');

if( NULL === $cache ){
    $data = array('a','b','c');
    $cache->save('my-cache',$data);
}
```
これでやると、以下のエラーが表示される
`Failed storing data in memcached, error code: 47`  

ググったところ、こんな記事が。。。
[Phalconで一生Memcacheクラスが使えない](http://arimo.hatenablog.com/entry/cant_phalcon_memcache)  
 
しかし、そんな訳は無いはずと再度phalconのマニュアルを見ると

[Phalcon docs](https://docs.phalconphp.com/ja/latest/reference/cache.html)
に、バックエンドでmemcachedを使う方法がちっちゃく載ってる。
要は、MemcacheではなくLibmemcachedを使えということみたい。   

```php
$cache = new \Phalcon\Cache\Backend\Libmemcached($FrontCache, array(
    'host' => 'localhost',
    'port' => 11211,
    'persistent' => false
));
```
にすることで問題解決。
phalcon-devetoolesを使ってクラス補完をしていたので、Memcachedが無い事に愕然としていたがどうってことなかった。しかし、命名規則に統一性が無いとこんな簡単なことにハマってしまう。
基幹部分のプログラムには十分に注意しないとなと、人様のコードをみて改めて感じた。
CSSでHTMLの記述順とは異なる並び順にする

<h2>「float」、「position」使う方法</h2>
<h3>サイドバーを左、メインを右の表示にする(2カラム)</h3>
##html
```qiita.html
<div class="main">
    メイン
</div>
<div class="sidebar">
    サイドバー
</div>
```

##css
```qiita.css
.main {
    float: right;
    width: 70%;
    height: 300px;
    background: #E3F0FB;
}

.sidebar {
    float: left;
    width: 30%;
    height: 300px;
    background: #CCC;
}
```
[サンプル](http://www.pc-weblog.com/sample/colum/colum01.html)

<h3>サイドバーを左右、メインを中央の表示にする(3カラム)</h3>
##html
```qiita.html
<div class="box-left">
    <div class="box-mid">
        <div class="main">
            メイン
        </div>
        <div class="sidebar01">
            サイドバー01
        </div>
        <div class="sidebar02">
            サイドバー02
        </div>
    </div>
</div>
```

##css
```qiita.css
.box-left {
    position: relative;
    right: 25%;
}

.box-mid {
    position: relative;
    right: 50%;
}

.main {
    position: relative;
    left: 98%;
    float: left;
    width: 54%;
    height: 300px;
    background: #E3F0FB;
}

.sidebar01 {
    position: relative;
    left: 21%;
    float: left;
    width: 23%;
    height: 300px;
    background: #CCC;
}

.sidebar02 {
    position: relative;
    left: 75%;
    float: left;
    width: 23%;
    height: 300px;
    background: #CCC;
}
```
[サンプル](http://www.pc-weblog.com/sample/colum/colum02.html)

<h2>CSS3の「Flexbox」を使う方法</h2>
<h3>サイドバーを左、メインを右の表示にする(2カラム)</h3>
##html
```qiita.html
<div class="container">
    <div class="main">
        メイン
    </div>
    <div class="sidebar">
        サイドバー
    </div>
</div>
```

##css
```qiita.css
.container {
    display: flex;
}

.main {
    order: 2;
    width: 70%;
    height: 300px;
    background: #E3F0FB;
}

.sidebar {
    order: 1;
    width: 30%;
    height: 300px;
    background: #CCC;
}
```
[サンプル](http://www.pc-weblog.com/sample/colum/colum03.html)

<h3>サイドバーを左右、メインを中央の表示にする(3カラム)</h3>
##html
```qiita.html
<div class="container">
    <div class="main">
        メイン
    </div>
    <div class="sidebar01">
        サイドバー01
    </div>
    <div class="sidebar02">
        サイドバー02
    </div>
</div>
```

##css
```qiita.css
.container {
    display: flex;
}

.main {
    order: 2;
    width: 54%;
    height: 300px;
    background: #E3F0FB;
}

.sidebar01 {
    order: 1;
    width: 23%;
    height: 300px;
    background: #CCC;
}

.sidebar02 {
    order: 3;
    width: 23%;
    height: 300px;
    background: #CCC;
}
```
[サンプル](http://www.pc-weblog.com/sample/colum/colum04.html)
PowerShell を使ってテキストファイル読み込み/書きこみ

# PowerShell
[PowerShellとは](https://ja.wikipedia.org/wiki/Windows_PowerShell)
色々細かい処理を作る場合、rubyを使うことが多かったけれど、
標準でWindowsについている機能を使用した方がよい場合があったので乗り換え(乗り換え中）。

# コーディング
## 準備
Windows7 以上であれば標準で **PowerShell 2.0** が使用可能。
`すべてのプログラム > アクセサリ > Windows PowerShell > Windows PowerShell ISE`
というIDEが標準でインストールされている。

## テキストファイル読み込み
スクリプトと同じディレクトリにある"test.txt"を読み込んで表示。

```ps1
# 実行中のパス取得/移動
$path = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location $path

# ファイル読み込み
# StreamReaderのコンストラクタに直接 「$path + "\test.txt"」を入力するとエラーになるので分ける
$fileName = $path + "\test.txt"
$file = New-Object System.IO.StreamReader($fileName, [System.Text.Encoding]::GetEncoding("sjis"))
while (($line = $file.ReadLine()) -ne $null)
{
	Write-Host($line)
}
Write-Host("")
$file.Close()

# 終了
Write-Host("終了")
```

## テキストファイル書き込み
スクリプトと同じディレクトリに"test2.txt"を作成して上書き。

```ps1
# 実行中のパス取得/移動
$path = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location $path

# ファイル書きこみ
# StreamReaderのコンストラクタに直接 「$path + "\test.txt"」を入力するとエラーになるので分ける
$fileName = $path + "\test2.txt"
$file = New-Object System.IO.StreamWriter($fileName, $false, [System.Text.Encoding]::GetEncoding("sjis"))
$file.WriteLine("あいうえお")
$file.WriteLine("かきくけこ")
$file.WriteLine("さしすせそ")
Write-Host("")
$file.Close()

# 終了
Write-Host("終了")
```

# 参考
https://codezine.jp/article/detail/3592
[【改訂新版】 Windows PowerShell ポケットリファレンス](https://www.amazon.co.jp/dp/477415542X)
LaravelとValidation


Laravel のValidationの使い方を

RestAPIの受け取りなど型のチェックが面倒な際にまとめて行いたい時など便利。

````
use Illuminate\Validation\Factory;

/** @var Factory $validator */
$validator = app("validator");
$val = $validator->make([
    "data" => $contents
],[
    "data" => "is_array",
    "data.status" => "is_array",
]);

````

### ルールの一覧

https://laravel.com/docs/5.2/validation#available-validation-rules

## 実行

内部的に検証の実施は `passes`メソドが行っている。

````
if($val->passes()){
	// 成功時の処理
}
````

`fails`メソドは内部的に`passes`を呼び出し`!`で逆評価している。

````
if($val->fails){
	// エラー時の処理
}
````

`messages`はエラーメッセージを取得するメソドで自動的に`passes`を呼び出す。

````
$errors = $val->messages();
```` 

`valid` `invalid`は検証に成功した/失敗したデータを返すメソドで、自動的に`passes`を呼び出す。

````
$data = $val->valid();
```` 

### passes 実行後にコールするもの

`messages`は`passes`実行後にコールしても、再度検証が実行されるということはない。

`failed`は検証に失敗したルールの取得で呼び出す。 `failed`だからすでに検証実行した前提。

````
// 失敗したルールの取得
$val->failed();
````

失敗時の処理を例外に投げたい場合には `ValidationException`を使用するのが便利。

コンストラクタの第一引数に`$val`を渡してあげる感じ。

Laravel と Validation 


## エラーの判定

Validator::make() で作成したエラーオブジェクトから

エラーの有無をチェックする -> fails() :bool
エラーを取得する -> errors() :Illuminate\Support\MessageBag

が使える。

## MessageBag


### MessageBag::all() :array

メッセージを全件取得する。フィールド名とかのインデックスはつかない。


### MessageBag::get($key) :array

フィールド名`$key`でメッセージを取得。　メッセージは配列

エラーがないときは空の配列を


### MessageBag::first($key) :string

フィールド名`$key`でメッセージを取得。　最初の一件のみで文字列取得出来る。

エラーが無いときは空の文字列を

## 例外について

ValidationException は２つある。

````
Illuminate\Validation\ValidationException;
Illuminate\Contracts\Validation\ValidationException
````

### Illuminate\Validation\ValidationException;

https://github.com/illuminate/validation/blob/master/ValidationException.php

`\Exception`を直接の親に持つ

コンストラクタ引数は `$validatior` と `$response = null`

ErrorHandlerで$response付きだとrenderされるタイプの例外で dontReport対象

### Illuminate\Contracts\Validation\ValidationException

`\RuntimeException`を直接の親に持つ

コンストラクタの引数は `\Illuminate\Contracts\Support\MessageProvider  $provider`

`\Illuminate\Validation\ValidatesWhenResolvedTrait `のthrow系メソドではこちらの例外が投げられるみたい。
【Zabbix3.0】CentOS7.xへのインストール

# **環境**
- CentOS7.2 64bit
- zabbix_server (Zabbix) 3.0.3

# **手順概要**
1. Zabbixサーバのインストール
2. Webインターフェースのインストール


# **手順詳細**
## **Zabbixサーバのインストール**
```text:yumリポジトリの登録
# rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm
```

```text:RPMを利用してインストール
# yum install zabbix-server-mysql mariadb-server
```

```text:MariaDBの起動
# systemctl start mariadb
```

```sql:データベースの作成
# mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.47-MariaDB MariaDB Server

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

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

MariaDB [(none)]> create database zabbix character set utf8 collate utf8_bin;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> grant all privileges on zabbix.* to zabbix@localhost identified by 'Password';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> exit;
Bye
```

```text:初期データベースのインポート
# cd /usr/share/doc/zabbix-server-mysql-x.x.x
# zcat create.sql.gz | mysql -u zabbix -p zabbix
```

```text:Zabbixサーバ設定ファイル修正
# vi /etc/zabbix/zabbix_server.conf
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword={PASSWORD}
```

```text:Zabbixサーバの起動
# systemctl start zabbix-server
```

## **Webインターフェースのインストール**
```text:RPMを利用したバイナリのインストール
# yum install zabbix-web-mysql zabbix-web-japanese
```

```text:PHP設定の確認とタイムゾーン設定
# vi /etc/httpd/conf.d/zabbix.conf
<IfModule mod_php5.c>
    php_value max_execution_time 300
    php_value memory_limit 128M
    php_value post_max_size 16M
    php_value upload_max_filesize 2M
    php_value max_input_time 300
    php_value always_populate_raw_post_data -1
    php_value date.timezone Asia/Tokyo
</IfModule>
```

```text:Apacheの起動
# systemctl start httpd
```

### ブラウザからWebインターフェースにアクセス
- http://{Zabbix-Server-IP}/zabbix

![WS000613.png](https://qiita-image-store.s3.amazonaws.com/0/79134/2f196a72-d416-9df3-e691-3ff5b592376f.png)


### 必要なライブラリやPHPパラメータの確認
- 全てOKとなっていることを確認

![WS000614.png](https://qiita-image-store.s3.amazonaws.com/0/79134/5b7798ce-8af5-fcce-62cd-78884bdcd86d.png)

### Counfigure DB connection
- DB接続設定を入力

![WS000615.png](https://qiita-image-store.s3.amazonaws.com/0/79134/ccbc21ef-eff1-bf72-10cc-6a041e2982bd.png)

### Zabbix server details
| パラメータ | 設定値 |
|:--|:--|
| Host | Zabbixサーバが起動しているIPアドレス |
| Port | ZabbixサーバのTrapperポートを設定<br>（デフォルト10051） |
| Name | Webインターフェースの右上に設定した文字列が表示される<br>（複数のZabbixを利用する場合に有用）  |

![WS000616.png](https://qiita-image-store.s3.amazonaws.com/0/79134/442dd2fa-a301-310c-de64-d419450d5d3b.png)

![WS000617.png](https://qiita-image-store.s3.amazonaws.com/0/79134/d084b7ba-4584-027e-87e9-47c277c6057d.png)

# ログイン
- ID:Admin/PW:zabbix でログイン実施

![WS000619.png](https://qiita-image-store.s3.amazonaws.com/0/79134/02afcd97-9504-c7f0-de83-80ecf750aebd.png)


**以上！**
UIKeyboardDidShowNotificationでtextFieldをキーボードの高さの分だけ移動させる方法

LINEのようなチャットアプリでありがちな、画面下部にテキストの入力欄を設けて、そこをタップするとキーボードがせり上がってきてもそれに合わせてテキストの入力欄の位置も移動させる機能を実装したい。

いろいろ試行錯誤してみたのですが、次の3ステップがシンプルかもしれません。

# StoryBoardでUIViewControllerの上に、UITableViewとUITextFieldなどを配置する

UITableViewをUIViewControllerの上部に、UITextFieldとその背景のUIView、送信ボタンのUIButtonを合わせてUIViewControllerの下部に配置。

AutoLayoutを当てて、UIViewはサイズを375*40で固定。UITableViewを可変にします。
![UIViewController.png](https://qiita-image-store.s3.amazonaws.com/0/9674/76bf1af6-2c1e-a8de-8fb8-3891bcf1dee7.png)


# viewDidLoadにNSNotificationCenterを記述

UITableView、UITextField、UIView、UIButtonをソースコードにOutlet接続した上で、`viewDidLoad`に下記を記述します。

```swift:ViewController.swift
    override func viewDidLoad() {
      //省略
      
      // NSNotificationでキーボードを開けたイベントを取得
      let notificationCenter = NSNotificationCenter.defaultCenter()
      notificationCenter.addObserver(self, selector: #selector(self.openKeyboard(_:)), name: UIKeyboardDidShowNotification, object: nil)
    }
```

`UIKeyboardDidShowNotification`で、キーボードを表示し終えたことの通知が可能です。

# キーボードを開いたときに行う処理を記述

通知センターから受け取った`userInfo`を元に、そのユーザーが開いているキーボードのサイズを取得し、そのキーボードの高さの分だけ`self.textField.frame`などを上に移動させます。

```swift:ViewController.swift
    //キーボードを開いたときに入力フィールドを移動させる
    func openKeyboard(notification: NSNotification) {
        if let userInfo = notification.userInfo {
            if let keyboard = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue{
                let keyBoardRect = keyboard.CGRectValue()
                
                self.textField.frame = CGRectMake(5, (self.view.frame.height - 28 - keyBoardRect.size.height), self.view.frame.width - 70, 28)
                self.sendView.frame = CGRectMake(0, (self.view.frame.height - 40 - keyBoardRect.size.height), self.view.frame.width, 40)
                self.sendButton.frame = CGRectMake(self.view.frame.width - 55, (self.view.frame.height - 28 - keyBoardRect.size.height), 50, 28)
                
            }
        }
    }
```

これにより、iPhoneを縦向きにしていても横向きにしていても、キーボードの高さの分だけ、テキスト入力欄の高さを上げることができます。

<img width="375" alt="keyboard-height.png" src="https://qiita-image-store.s3.amazonaws.com/0/9674/239064ed-f91f-71c2-cb18-c84ee40bb3af.png">
Pythonで書いた移動平均の計算時間を比較してみた

前回の記事
[MetaTraderのLWMAをscipyのFIRフィルタ関数で実装してみる](http://qiita.com/toyolab/items/e0588284dbe5e68c40d4)
で、LWMA(線形加重移動平均)を`lfilter()`関数で書き換えてみたのですが、すっきりしただけではありがたみがないので、計算時間を比較してみました。

予想としてはそれほど差はないかなと思ったので、移動平均を取る時系列データをちょっと多めにしてみました。以下（自分のブログ記事ですが）を参考にして EUR/USDの１年分の１分足データを読み込んでみました。

[PythonでFXヒストリカルデータを読み込む](http://forex.toyolab.com/?p=627)

````py
import numpy as np
import pandas as pd

dataM1 = pd.read_csv('DAT_ASCII_EURUSD_M1_2015.csv', sep=';',
                     names=('Time','Open','High','Low','Close', ''),
                     index_col='Time', parse_dates=True)
````

始値、高値、安値、終値それぞれ37万個くらいあります。

#LWMAの比較

時間を計測するためにJupyter Notebookで、`%time`コマンド使ってみました。まずは、LWMAの古い方のバージョン。出力を１個ずつ計算します。

````py
def LWMA(s, ma_period):
    y = pd.Series(0.0, index=s.index)
    for i in range(len(y)):
        if i<ma_period-1: y[i] = 'NaN'
        else:
            y[i] = 0
            for j in range(ma_period):
                y[i] += s[i-j]*(ma_period-j)
            y[i] /= ma_period*(ma_period+1)/2
    return y

%time MA = LWMA(dataM1['Close'], 10)
````
この結果

    Wall time: 3min 35s

なんと３分半も。データが多いと言っても37万個でこんなにかかるとは、Python使えないのか。。。

気を取り直してLWMAの新しいバージョンのテスト。scipyのフィルタ関数を使ったもの。

````py
from scipy.signal import lfilter
def LWMAnew(s, ma_period):
    h = np.arange(ma_period, 0, -1)*2/ma_period/(ma_period+1)
    y = lfilter(h, 1, s)
    y[:ma_period-1] = 'NaN'
    return pd.Series(y, index=s.index)

%time MA = LWMAnew(dataM1['Close'], 10)
````

この結果

    Wall time: 6 ms

なんと！６ミリ秒。35000倍速くなったのか？元が遅すぎるのか。scipy使える。

ちなみに `%time`の代わりに`%timeit`で実行すると、

    100 loops, best of 3: 3.4 ms per loop

100回実行しても１秒以内に完了。速いときは３ミリ秒くらいで実行できるらしい。

#SMAの比較

scipy速いということで、こんどは、pandasの関数と比較してみました。SMAはpandasのメソッド関数で次のように書けます。

````py
def SMA(s, ma_period):
    return s.rolling(ma_period).mean()

%timeit MA = SMA(dataM1['Close'], 10)
````

この結果

    100 loops, best of 3: 16 ms per loop

100回実行して速くて16ミリ秒。まあまあの速さです。では、これをscipyのフィルタ関数を使って書いてみます。

````py
def SMAnew(s, ma_period):
    h = np.ones(ma_period)/ma_period
    y = lfilter(h, 1, s)
    y[:ma_period-1] = 'NaN'
    return pd.Series(y, index=s.index)

%timeit MA = SMAnew(dataM1['Close'], 10)
````

この結果

    100 loops, best of 3: 3.44 ms per loop

速い。pandasの５倍くらい。やはりscipy速いということで、ほかの移動平均も`lfilter()`使って書き換えた方がいいかも。
CentOS 7でのRuby on Rails動作環境を構築する

既に色々な方が書かれており、目新しい事はなにもないですが、備忘録も兼ねてアップロードします。

# 前提
- CentOS7 インストール済み
- Ruby 2.3.1
- Rails 4.2.6
- SSHにて実行

# 手順
##1. 必要なパッケージのインストール
```
yum install gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel
```
##2. rbenvインストール
```
git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv
echo 'export RBENV_ROOT="/usr/local/rbenv"' >> /etc/profile
echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile
echo 'eval "$(rbenv init -)"' >> /etc/profile
```
SSHを切断し、再接続して

```
rbenv --version
```
を実行して、バージョンの確認をする
##3. ruby-buildインストール
```
git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build
```
##4. rubyインストール
rbenvでインストールできるRubyのバージョン一覧確認

```
rbenv install -l
```
Rubyのバージョンを指定してインストール

```
rbenv install -v 2.3.1
rbenv rehash
```
使用するRubyのバージョンを指定

```
rbenv global 2.3.1
```
バージョンを確認する

```
ruby -v
```
##5. Railsインストール
```
gem update --system
gem install --no-ri --no-rdoc rails
gem install bundler
rbenv rehash
```
バージョンを確認する

```
rails -v
```

#MySQLを使用する場合
こちらを参考にMySQLのインストールからRubyでの使用方法までを記載しています。
[MySQLのインストール手順](http://www.techbox.jp/entry/rubyonrails-mysql)
トランザクション分離レベルをrepeatable_read（MySQLのデフォルト）にしてロストアップデートを体験してみる

# ロストアップデート発生！！
トランザクション分離レベルをrepeatable_read（MySQLのデフォルト）にしてロストアップデートを発生させてみる。

## ワーカー
```rb
class HogeWorker
  @queue = :hoge

  def self.perform
    ActiveRecord::Base.transaction(isolation: :repeatable_read) do
      h = Hoge.find_by(id: 1)
      sleep(3.0)
      h.count = h.count + 1
      h.save!
    end
  rescue => e
    # ここを通ることはなかった
    Resque.logger.info('ERRORRRRRRRRR s')
    Resque.logger.info(e.class)
    Resque.logger.info(e)
    Resque.logger.info('ERRORRRRRRRRR e')
  end
end
```

## ワーカー呼び出し
```rb
100.times do
  Resque.enqueue(HogeWorker)
end
```

## ワーカー起動
ワーカーが1つだと綺麗に1つずつ処理されるので、ロストアップデートが起こらなかった。
なので、ワーカーは5つ立ち上げた。

```
VVERBOSE=1 bundle exec env rake resque:workers QUEUE='*' COUNT='5'
```

結果
`countカラム`が`0`から始まった場合、本当は`100`になっているところ、ロストアップデートが発生したので、`21`になっていた。

具体的なSQLとしては、下記のように`+1`した結果が`19`になっている`UPDATE文`が何回も発行されていた（同様にして`18（などの他の数字も）`のものも複数発行されている）。

```sql
UPDATE `hoges` SET `count` = 19, `updated_at` = '2016-06-28 07:09:22' WHERE `hoges`.`id` = 1
```

## ロストアップデートが発生しないように、SELECT FOR UPDATEでロックしてみる
`find_by`のところで、ロックさせてみる。

```
c = Hoge.find_by(id: 1).lock!
```

このようにしたとき、`count`を`0`から始めたとき結果は`100`になっていた。
おそらく、SELECT FOR UPDATEがうまく機能した例といえると思う。


## ちなみに、トランザクション分離レベルで最も最強の（まったく制約を緩めていない）`serializable`を指定してみると...
```rb
class HogeWorker
  @queue = :hoge

  def self.perform
    ActiveRecord::Base.transaction(isolation: :serializable) do
      h = Hoge.find_by(id: 1)
      sleep(3.0)
      h.count = h.count + 1
      h.save!
    end
  rescue => e
    # ここを通ることはなかった
    Resque.logger.info('ERRORRRRRRRRR s')
    Resque.logger.info(e.class)
    Resque.logger.info(e)
    Resque.logger.info('ERRORRRRRRRRR e')
  end
end
```

このように制約をまったく緩めない最強レベルの`serializable`を指定した場合は、
`ActiveRecord::StatementInvalid`という`例外`が発生する。

> Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction: UPDATE 以下略

といったメッセージもログに添えられていた。

### ちなみに、serializableの場合は lockしてもlockしてないときと同じく例外発生した
`serializable`で`Hoge.find_by(id: 1).lock!`としてみたが、
`ActiveRecord::StatementInvalid`となり`Mysql2::Error: Deadlock`が複数発生した。
【デザインパターン】複数にデリゲートする方法 Multicast Delegate Pattern

# Multicast Delegate Pattern

delegateは処理の一部を委譲するときに使うものです。
この通知先を複数にする方法を紹介します。

#使用例

```objc
MultiDelegateProxy *delegateProxy = [[MultiDelegateProxy alloc] initWithTarget:self, nil];
[delegateProxy addTarget:xxx];
[delegateProxy addTarget:zzz];
self.scrollView.delegate = (id)delegateProxy;
```

#実装例

```objc:MultiDelegateProxy.h
#import <Foundation/Foundation.h>

@interface MultiDelegateProxy : NSProxy
- (instancetype)initWithTarget:(NSObject *)targets, ... NS_REQUIRES_NIL_TERMINATION;
- (void)addTarget:(NSObject *)target;
- (void)removeTarget:(NSObject *)target;
@end

```

```objc:MultiDelegateProxy.m
#import "MultiDelegateProxy.h"

@interface MultiDelegateProxy ()
@property (strong, nonatomic) NSMutableArray* targets;
@end

@implementation MultiDelegateProxy

- (instancetype)initWithTarget:(NSObject *)targets, ... {
    _targets = @[].mutableCopy;
    va_list arguments;
    va_start(arguments, targets);
    NSObject *value = targets;
    while (value) {
        [_targets addObject:value];
        value = va_arg(arguments, typeof(NSObject*));
    }
    va_end(arguments);
    return _targets.count ? self : nil;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    for(NSObject *target in _targets.copy) {
        if ([target respondsToSelector:invocation.selector]) {
            [invocation invokeWithTarget:target];
        }
    }
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    for(NSObject *target in _targets.copy) {
        if ([target respondsToSelector:sel]) {
            return [target methodSignatureForSelector:sel];
        }
    }
    return nil;
}

- (BOOL)respondsToSelector:(SEL)aSelector {

    if ([super respondsToSelector:aSelector]) {
        return YES;
    }

    for(NSObject *target in _targets.copy) {
        if ([target respondsToSelector:aSelector]) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)conformsToProtocol:(Protocol *)aProtocol {
    for(NSObject *target in _targets.copy) {
        if ([target conformsToProtocol:aProtocol]) {
            return YES;
        }
    }
    return NO;
}

- (void)addTarget:(NSObject *)target {
    if (target && ![_targets containsObject:target]) {
        [_targets addObject:target];
    }
}

- (void)removeTarget:(NSObject *)target {
    if (target && [_targets containsObject:target]) {
        [_targets removeObject:target];
    }
}

@end
``` 

#参考リンク

##Article
http://blog.fenrir-inc.com/jp/2013/11/nsproxy.html
http://blog.scottlogic.com/2012/11/19/a-multicast-delegate-pattern-for-ios-controls.html
http://www.gregread.com/2016/02/23/multicast-delegates-in-swift/

##OSS
https://github.com/tumtumtum/SwiftMulticastDelegate
https://github.com/jonasman/MulticastDelegate

[Original](https://tamazawa.net/2016/06/28/【デザインパターン】複数にデリゲートする方法-m/)
MacでMAMP + Python + SQLAlchemy(Mysql-Python)の導入

MAMP環境でのPython開発が必要となり、mac(OS X El Capitan バージョン 10.11.5）でMAMP環境でSQLAlchemyを利用しようとした際に軽くハマりそうだったので、手順をまとめます。
（2016/06/28 現在）

尚、
・python 2.7.9
・Mysql 未インストール
・ 以下の利用が可能
　・homebrew
　・pip
　・pyenv-virtualenv

が前提での記載となります。

## MAMPのセットアップ

まずMAMP環境を構築します。

### ダウンロード

https://www.mamp.info/en/downloads/ からダウンロード
![スクリーンショット 2016-06-28 15.42.51.png](https://qiita-image-store.s3.amazonaws.com/0/82503/2fc1c2b3-d455-a27d-47d1-32c66850550c.png)

### インストール
ダウンロードしたpkgを実行してインストール。
尚、同時にMAMP PROがインストールされますが、個人的には不要だったので、/Application/MAMP PROにあるuninstaller.appを実行してアンインストール。

MAMP PROを利用してからアンインストールすると、中身のデータは問答無用で消去されるほか、アンインストールされない場合もみたいなので、不要な場合は即時消去されることをお勧めします。

### セットアップ

本件では特に影響無いので、各々セットアップしてください。

## python 作業環境準備

こちらは必須ではないですが、一応。

```
$ pyenv virtualenv 2.7.9 hogehoge
$ cd <アプリケーションルート>
$ pyenv local hogehoge
```

## Mysql-Pythonのインストール

SQLAlchemyで利用するMySQLドライバをインストールします。

#### mysql-conncector-cのインストール

特に何もせずにMysql-Pythonをインストールしようとすると　（以下、一部抜粋）

```
    building '_mysql' extension
    creating build/temp.macosx-10.11-x86_64-2.7
    clang -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Dversion_info=(1,2,5,'final',1) -D__version__=1.2.5 -I/Applications/MAMP/Library/include -I/Users/fujito/.pyenv/versions/2.7.9/include/python2.7 -c _mysql.c -o build/temp.macosx-10.11-x86_64-2.7/_mysql.o -fno-omit-frame-pointer -g -DNDEBUG
    _mysql.c:44:10: fatal error: 'my_config.h' file not found
    #include "my_config.h" 
             ^
    1 error generated.
    error: command 'clang' failed with exit status 1
```
みたいな感じでインストールができません。

利用するMysqlはMAMPのインストールでインストールされたものとなりますが、こちらにmy_config.hが含まれない為に発生するようです。
そこで、必要な差分のファイルをインストールします。

```
$ brew install mysql-connector-c
```

### Mysql-Pythonインストール

満を辞してMysql-Pythonをインストール
```
$ pip install Mysql-Python
```

## SQLAlchemyのインストール

最後に（最後じゃなくてもいいけど）SQLAlchemyをインストール
```
$ pip install SQLAlchemy
```
【TechShop Tokyo】真空成形のノウハウ

# 症状
材料のあまりによるブリッジの発生
![IMG_0733.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/aeb18ee5-18bc-55ce-5c81-489f5be517ff.jpeg)
![IMG_0734.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/43a340e0-24f2-c9ce-37e3-46eb34a64cfe.jpeg)
使用した型
![IMG_0732.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/8eeb4f2d-cece-cb5d-c78a-9e6e0d2c86e2.jpeg)
# 対策
あまりを伸ばす型を考案
## 案1
四辺に球を出して伸ばしてみる
![IMG_0736.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/5615ff2c-0a9b-aa98-a519-d2ca98cef903.jpeg)
球との間にブリッジ。全然ダメ。
![IMG_0737.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/9a1fa16c-aeec-d944-b724-2299c1781a5a.jpeg)
## 案2
下部に土台の円柱をつける
![IMG_0735.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/0dc64c25-7b51-9403-b913-9a3d3223149a.jpeg)
土台つけても全然ダメ。
![IMG_0738.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/501e6f59-4273-4877-3217-be7822debc32.jpeg)
## 方針転換
土台をなくす。
![IMG_0745.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/bd100e29-852c-77a8-e29e-cf8e35565777.jpeg)
ブリッジ激減。
![IMG_0747.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/9715000b-ab7d-7b00-343e-be7d671cd02d.jpeg)
伸びたPETを引っ張るために、正方形をおく
![IMG_0748.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/551d2dce-19fd-1c95-0bcd-f744efc0cea3.jpeg)
いいところまで行ったけど、ブリッジがまだ残ってる
![IMG_0739.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/2e4168fa-3c42-555d-cfa6-d1c783558fe4.jpeg)
![IMG_0750.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/6896a343-8503-e623-4469-a3f6b096c854.jpeg)
![IMG_0744.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/efd0c0e1-bee2-9155-0ace-a6315f2833e1.jpeg)
![IMG_0751.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/2b1bb1d7-f665-0e09-d3d6-1a9d620e8608.jpeg)
![IMG_0740.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/e87e53cd-c97d-cabe-ca3c-dc58f1253834.jpeg)
あと一歩
# 正解
正解はこのパターン
![IMG_0752.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/0ae13405-50c9-62e3-60bc-34bb38f8b6b2.jpeg)
# 完成
![IMG_0754.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/b661542a-e0b9-9dc1-4d88-ac9f00bb00a0.jpeg)

![IMG_0755.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/5a571160-68c9-e28d-369c-e8e007255ecd.jpeg)

![IMG_0753.jpg](https://qiita-image-store.s3.amazonaws.com/0/63450/072ed614-7d16-ef93-8987-21d1b78874c8.jpeg)
Swift 型の型

Catクラスを定義する。
クラスメソッドhogeを定義する。

```swift
class Cat {
    class func hoge() -> String {
        return "Cat::hoge"
    }
}
```

---

Catクラスを受け取って、クラスメソッドhogeを呼ぶ関数を作る。
受け取る部分で出てくる **型の型** は `型名.Type` で書ける。

```swift
func callCatClassHoge(catClass: Cat.Type) -> String {
    return catClass.hoge()
}
```

---

型の値を `型名.self` で取れる。

先ほどの関数にCatクラスを渡す。

```swift
callCatClassHoge(Cat.self) // => Cat::Hoge
```

クラスメソッドが呼びだせた。

---

Catのサブクラス、RoboCatクラスを定義する。
クラスメソッドはオーバライドできる。

```swift
class RoboCat : Cat {
    override class func hoge() -> String {
        return "RoboCat::hoge"
    }
}
```

---

サブクラスはクラスに互換性がある。
つまり、`RoboCat.self is Cat.Type == true` である。

よって、先ほどの関数にRoboCatクラスを渡せる。

```swift
callCatClassHoge(RoboCat.self) // => RoboCat::hoge
```

オーバライドした実装が呼び出された。

---

式の型の値を`.dynamicType`で取得できる。

```swift
let a: Cat = Cat()
callCatClassHoge(a.dynamicType) // => Cat::hoge
```

aはCatのインスタンスだから、aの型はCatだ。

---

RoboCatで同じ事をすれば、
RoboCatのクラスメソッドが呼ばれる。

```swift
let b: RoboCat = RoboCat()
callCatClassHoge(b.dynamicType) // => RoboCat::hoge
```

---

dynamicTypeは動的に評価されているので、
静的にはCat型の式でも、式の型の値はRoboCatだ。

```swift
let c: Cat = b as Cat
callCatClassHoge(c.dynamicType) // => RoboCat::hoge
```

---

おわり🐱
WWDC2016: What's New in watchOS 3のもくじ

#はじめに#
WWDC2016のWhat's New in watchOS 3- Session 208の目次を共有します。関心のある部分にジャンプしやすいように、(再生時刻)を書いてあります。

2016/06/24の時点では、CCとして英語字幕が表示されないビデオのようです。

#3つの要素(1:33)#
・Glanceable, Actionable, Responsive
・GlanceがDockに統合された

#Background App Refresh(8:39)#
・Dockにお気に入りのアプリを入れることができ、それはメモリをキャプチャする
・Update complication, Update app
・Update Snapshot(Dockの各アプリのサムネイルのこと。)
・Snapshotの更新はwatchOSが自動的に行ってくれる。
・Complicationのアップデート
・Complication Push Updates。ユーザの行動やデータにもとづいて適当なタイミングで更新する。
・Scheduled Updates

・デジタルクラウンを回転させると、ページが遷移する。
・Buyボタン
・通知が新しいフレームワークになった。

#Enhanced API Availability(29:30)#
・バックグラウンドリフレッシュ
・フィットネスアプリ

#Background runtime(32:00)#
・CPUの使用

#ハードウェアへのアクセス(35:00)#
・Crown events
・株価を見るアプリのデモ
・スワイプでアイコンが切り替わるデモ

#Visualize(36:00)#
・SceneKitでジャンプする人のデモ
・GameKit
・Fishing Gameのデモ

#CloudKit(39:30)#

#Apple Pay(40:00)#
サイドボタンをダブルタップすると、使える。

Discoverability and Configuration

#Gallery#
OpenGL/GLFWはじめての人がD言語でウィンドウを表示するまで

DでOpenGLとかそういうのが使いたくなったので練習をした。  
Dubを使って環境構築した記事がなかなか見つからなかったのでまとめ記事を書く。  
Ubuntu 16.04 LTS。

# OpenGLとGLFWの導入

```console
OpenGL
$sudo apt install mesa-utils

GLFW
$sudo apt install xorg-dev
$git clone https://github.com/glfw/glfw.git
$cd glfw
```

[ここで共有ライブラリを作るようにCMakeLists.txtを書き換える。](http://qiita.com/maueki/items/9d1e241cdd345220fc1b)  
でないと実行時にこうなる。

```console:エラー
libglfw3.so - libglfw3.so: cannot open shared object file: No such file or directory
libglfw.so.3 - libglfw.so.3: cannot open shared object file: No such file or directory
```

```diff:CMakeLists.txt
-option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
```

```console
$cmake .
$make
$sudo make install
-- Installing: /usr/local/lib/libglfw.so.3
-- Installing: /usr/local/lib/libglfw.so
```

# プロジェクトを作る

```console
$dub init PROJECTNAME derelict-gl3 derelict-glfw3
```

以前は[一つのリポジトリにすべてが入っていた](https://github.com/mdparker/Derelict3)ようだが、[今はバラになっていた。](https://github.com/DerelictOrg)

# テスト
[参考元](https://trap.tokyotech.org/blog/2015/12/d%E8%A8%80%E8%AA%9E%E3%81%A7opengl%E2%80%A0%E5%85%A5%E9%96%80%E2%80%A0/)

```d:source/app.d
import derelict.opengl3.gl;
import derelict.glfw3.glfw3;

void main()
{
    //Derelictの初期化。この下からOpenGLやGLFWのいろいろが使えるようになる。
    DerelictGL.load();
    DerelictGLFW3.load();

    glfwInit();

    GLFWwindow *window = glfwCreateWindow(100, 100, "test", null, null);
    
    glfwMakeContextCurrent(window);

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        glEnd();
        glfwSwapBuffers(window);

        glfwPollEvents();
    }

    glfwTerminate();
}

```

```console
$dub run
```

![gltest.png](https://qiita-image-store.s3.amazonaws.com/0/57768/47c378ea-ccb1-ec6f-2d69-8e01b1cde3fa.png)

うまくいけばこんな感じの小さなウィンドウが出てくる。
UserAgentからIEの互換モードを判別する

レガシーブラウザをブロックしているようなWebページにて
IE7はブロックしたいけどIEの互換モードであれば利用させたい時にどうしたらいいか調べてみました。
結果的にUserAgentで判別出来る事が分かったのでまとめておきます。

#まずはMSIEを確認
IEの場合にはUAに含まれるMSIEという識別子からバージョンが判別できます。
これは広く知られている手法ですね。

#続いてTridentを確認
IE8以降はMSIEだけでなくTridentという識別子が含まれるようになっており、こちらでもバージョンが判別できます。

ちょっと実際のUAを見てみましょう。

IE9だとこんな感じです
> Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Trident => 5はIE9に該当します。

MSIEとTridentの関係は以下のようになります。

|IE  |MSIE|Trident|
|:---|:---|:------|
|8   |8   |4      |
|9   |9   |5      |
|10  |10  |6      |
|11  |11  |7      |

#互換モード使用時のUA
互換モードを使用するとこの関係に変化が現れます。

ではIE11で互換モードを使用した場合のUAを見てみましょう。
> Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; InfoPath.3; GWX:DOWNLOADED; GWX:RESERVED; GWX:QUALIFIED)

Tridentは互換モード使用前後で変わりませんが、MSIEは互換後のバージョンになっているのが分かります。

互換モードを使用した時のMSIEとTridentの関係は以下のようになります。


|IE            |MSIE |Trident|
|:-------------|:----|:------|
|8  (互換モード) |7    |4      |
|9  (互換モード) |7    |5      |
|10 (互換モード) |7    |6      |
|11 (互換モード) |7    |7      |

#互換モードの判定方法
**「Trident == 7」かつ「MSIE != 11」**=> 互換モード
**「Trident == 6」かつ「MSIE != 10」**=> 互換モード
**「Trident == 5」かつ「MSIE != 9」**=> 互換モード   という具合。

ちなみに僕が検証した端末では互換モードを使用するとどれもIE7として振る舞うようだったので
**「Tridentが含まれる」かつ「MSIE == 7」**=> 互換モード　と判別しても良いかも。
rails new 、bundle installの実行時にエラーが発生。 環境(Nitrous)。　※自分用メモ

**環境(Nitrous)**
rails new 、bundle installの実行時にエラーが発生。


create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
         run  bundle install
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies....
Installing rake 11.2.2
Installing i18n 0.7.0
Using json 1.8.3
Installing minitest 5.9.0
Installing thread_safe 0.3.5
Your disk is out of space. Free some space to be able to install your bundle.
         run  bundle exec spring binstub --all
bundler: command not found: spring
Install missing gem executables with `bundle install`
➜  code  bundle exec spring binstub --all
Could not locate Gemfile
➜  code  cd ../sample_app
cd: no such file or directory: ../sample_app
➜  code  cd ..
➜  ~  cd code/sample_app
➜  sample_app  bundle exec spring binstub --all
bundler: command not found: spring
Install missing gem executables with `bundle install`
➜  sample_app  bundle install
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies.....
Using rake 11.2.2
Using i18n 0.7.0
Using json 1.8.3
Using minitest 5.9.0
Installing thread_safe 0.3.5
Your disk is out of space. Free some space to be able to install your bundle.

➜  sample_app  gem install nokogiri -v '1.6.8'
Fetching: mini_portile2-2.1.0.gem (100%)
Successfully installed mini_portile2-2.1.0
Fetching: pkg-config-1.1.7.gem (100%)
Successfully installed pkg-config-1.1.7
Fetching: nokogiri-1.6.8.gem (100%)
ERROR:  While executing gem ... (Errno::ENOSPC)
    No space left on device @ io_write - /usr/local/opt/rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/cache/nokogiri-1.6.8.gem

※rails new sample_app -d postgresql 実行時にエラー
※bundle install 実行時にエラー
※nokogiri のエラー

**原因**
Space、No space、原因はNitrousのスペース(容量)(Gemをインストールするスペース？)が足らなかったから。
なので、使用していないアプリ(eeviewなど)を削除した。
その後、rails new、bundle installを実行したら、正常にアプリを作成できて、bundle installも実行できた。
個人用まとめ_ChefとかAnsibleの導入に必要なもの

※個人用まとめ※

# はじめに

## 構成管理ツールとは
サーバ構築を自動化するためのツールです。
繰り返し行うような構築作業の手間と時間を減らすことや人為的ミスの防止、構築の可視化などが導入する目的となります。
また、構築手順を記述したもの（Recipeやplaybook）をGit等で管理することでサーバ設定の変更履歴を管理したり、属人化を防ぐといったメリットもあります。

Chef, Ansible, puppetなどが有名です。

## 用語の定義
以下の通り用語を定義します。

  - **ローカルPC** ： 構成管理用のファイル/ディレクトリの作成等を行う端末   
  - **管理サーバ** ： 構成管理用のファイル/ディレクトリ等を管理するサーバ
  - **クライアントサーバ** ： 構成管理対象のサーバ（構成管理をされる側）

## この記事の内容について
  - 諸事情により「Chef」と「Ansible」に絞って記載します。他のツールについては記載しません。   
  - 「構成管理ツールを導入するためには何が必要か？」ということを調査の目的としていたため、ChefとAnsibleを動作させる環境ができるまでの手順をまとめることをゴールとしています。そのため、Recipeやplaybookの具体的な書き方等には触れません。

# Chef、Ansibleの導入に必要なもの
## ■Chef
### 公式サイトhttps://docs.chef.io/index.html


### 基本構成
無理やり図にすると下記のような形。

```Workstation（ローカルPC）-------------------------|--- ChefServer（管理サーバ）【Chef-server等】
　　|--- Node（クライアントサーバ）【Chef-client】---|
　　|--- Node（クライアントサーバ）【Chef-client】---|```  　

参考サイト: https://codezine.jp/article/detail/7484 ←こちらの図の方が分かりやすいです。


### 必要なもの、作業
   1. sshのインストール（ローカルPC、クライアントサーバ）※クラウド環境では不要と思われる
   1. sudo可能なユーザを作成（クライアントサーバ）
   1. sudoユーザが管理サーバへsshで接続できるように設定（クライアントサーバ -> 管理サーバ）
   1. Rubyの動作環境を構築（クライアントサーバ、管理サーバ）
   1. Chef-Zeroをインストール（ローカルPC）、もしくはChef-Serverをインストール（管理サーバ）、もしくはChefのHosted型を契約（管理サーバ）   
   ※「Chefの種類」参照。Chef-Zeroの場合はローカルPCと管理サーバは同じものになります。
   1. Chef-Clientをインストール（クライアントサーバ）
   1. Knifeのインストール（クライアントサーバ、ローカルPC） ※ KnifeはChefをコマンドラインから操作するためのプラグインです。
   1. kitchen（chefのリポジトリ）を作成（ローカルPC）   
   ```$ chef generate repo <cookbookを置くディレクトリ>```  
   kitchen (キッチン)　＞ cookbooks(クックブック) ＞ Recipeレシピ という階層になります。   
   1. Recipeの作成   
   1. クライアントサーバにRecipeを実行する   
   ```knife zero -c conf.rb chef_client 'name:[ホスト名]' -x [ユーザ名] -i [公開鍵]```


### Chefの種類
  - Chef Hosted: 管理画面あり。無料で5ノードまで利用可。Chef社によるSaaSモデルの提供。※公式の推奨。サポート付らしい。
  - Chef Server: 管理画面あり。無料で25ノードまで利用可。オープンソース。クライアントーサーバ型。※こちらも別料金でアドオンやサポートが付く。
  - Chef Zero: ローカルで動作するインメモリのChefServer。※公式でテスト運用を推奨とされている。
  - Chef-provisioning：クラスタをプロビジョニングするためのツール。機能的に構成管理もやろうと思えばできる。ただし、サポートされているプラットフォームが少ない（クラウドはAWSとGCPが対応予定という程度）。
  - Chef Solo：今までは単一で動作する環境として提供されていたが、まもなく非推奨となる。

## Ansible

### 公式サイト
http://docs.ansible.com/ansible/

### 基本構成
管理サーバ（=ローカルPC）
　　|---＞ クライアントサーバ
　　|---＞ クライアントサーバ

### 必要なもの、作業
   1. sshをインストール（管理サーバ、クライアントサーバ）※クラウド環境では不要と思われる   
   1. Pythonの動作環境を構築（クライアントサーバ、管理サーバ）※Linux系はデフォルトで動作する場合が多いので不要かもしれない。   
   ※2016/7/4追記：CentOSにデフォルトで入っているpythonのバージョンは2.6だったので、python 2.7以上が必要なansibleはデフォルトでは動作しないようです。   
   1. sudo可能なユーザを作成（クライアントサーバ）
   1. 管理サーバからsudoユーザへsshで接続できるように設定（管理サーバ -> クライアントサーバ）
   1. ansibleをインストール（管理サーバ）   
   1. playbookの作成   
   1. インベントリファイル（サーバ情報やSSHの接続情報等を定義するファイル）の作成   
   1. 管理サーバでplaybookを実行する   
   ```ansible-playbook -i [インベントリファイル名] [playbookの実行ファイル名]```

### その他
   - Ansibleは元々GitHubで開発されていたオープンソースのアプリケーションです。   
     Ansible本体のライセンスはGPL v3です。公開されているパッケージを利用するだけであれば特に制約はありません。   
    ※ただし、本体のソースコードに手を加え、Ansibleを含んだツールやプロダクト販売する場合には制約があるようです。   
    参考ページ： https://github.com/ansible/ansible/blob/devel/COPYING   
   - 2015年にRedHatに買収されました。それにより、サポートやコンサルティングに関連した有料プランが提供されています。
Firebase(FCMのtopic)をcurlで実行してもiPhoneアプリにプッシュ通知がでない時の対処方法

FCM Server経由でiPhoneアプリとAndroidアプリにtopicを利用したpush通知を送りたくて、curlで確認したところかなりハマってしまったのでメモとして残しておきます。

前提として、両アプリともFirebase Cloud Messaging(FCM)を組み込んでいて、Firebase ConsoleからNotificationsが送れるものとします。

「[Firebaseによるプッシュ通知のハマりどころ](http://qiita.com/mituoh/items/2dc87618edf234afd8f0)」を参考にして作ってますが、自分のところではiPhoneアプリで手こずりました。Androidアプリはさすがにすんなり動作しました。

以下が動作したパターンです。

```
 curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"to\": \"/topics/info\",\"priority\":\"high\",\"content_available\":true,\"notification\": {\"body\": \"お知らせ\",\"badge\": \"1\"}}"
```


私の間違ったポイントは以下です。
* api_keyはFirebase Settings -> CLOUD MESSAGING -> Server key を利用する。でないと認証で失敗する。
* priorityをhighにする (iPhoneで必要)
* content_availableをtrueする (最終的に必要かどうか分からない)
* notificationにbodyを指定する(これがないとiPhoneに表示されない。最後までハマった)

何かのお役に立てれば幸いです
three.jsでパーティクル


ごにょごにょと、three.js学ぶ日々

![スクリーンショット 2016-06-28 15.24.41.png](https://qiita-image-store.s3.amazonaws.com/0/76843/30d572a4-3660-bdb2-2685-e7812d76ee9c.png)




```html:hogehoge.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>three.js</title>
</head>
<body>
 <div id="stage"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.js"></script>
  <script>
  (function() {
    'use strict';

    var scene;
    var camera;
    var renderer;
    var width = 1000;
    var height = 1000;
    var controls;

    var particles;
    var loader;

    // scene ステージ
    scene = new THREE.Scene();

    // camera
    camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
    camera.position.set(100, 100, 100);
    camera.lookAt(scene.position);

    // renderer
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(width, height);
    renderer.setClearColor(0x000000);
    renderer.setPixelRatio(window.devicePixelRatio);
    document.getElementById('stage').appendChild(renderer.domElement);

    // particles
    // mesh: Points
    // geometry: 図形の頂点
    // material: PointsMaterial
    loader = new THREE.TextureLoader();
    loader.load('particle.png', function(texture) {
      createParticles(texture);
      render();
    });

    function createParticles(texture) {
      var pGeometry;
      var pMaterial;
      var count = 2000;
      var i;

      // pGeometry
      pGeometry = new THREE.Geometry();
      for (i = 0; i < count; i++) {
        pGeometry.vertices.push(
          new THREE.Vector3(

            Math.random() * 200 - 100, // -100~100の乱数
            Math.random() * 200 - 100,
            Math.random() * 200 - 100
          )
        );
      }

      // pMaterial
      pMaterial = new THREE.PointsMaterial({
        map: texture,
        size: 3, // サイズ
        blending: THREE.AdditiveBlending, // ブレンドモード(加算)
        transparent: true, // 透過true
        depthTest: false // 物体が重なった時に後ろにあるものを描画するかしないか
      });

      particles = new THREE.Points(pGeometry, pMaterial);
      scene.add(particles);
    }

    function render() {
      requestAnimationFrame(render);
      particles.rotation.y += 0.002;
      renderer.render(scene, camera);
    }

  })();
  </script>
</html>
```
svgで線を描いてみる。

## 四角い点線

[サンプルコード](https://jsfiddle.net/akiho/8f9qsoxt/)
html,cssのみで記述しています。
hoverしたら、点線がぐるぐるまわります。

![スクリーンショット 2015-05-28 20.07.56.png](https://qiita-image-store.s3.amazonaws.com/0/62259/25d6d0ee-baaf-2e7e-7fde-b8d425e66a01.png)

```html:html
<svg viewBox="0 0 200 200">
    <polygon points="20,20 20,100 120,100, 120,20"/>
</svg>
```

```css:css
svg {
    stroke: #09d;
    stroke-width: 2;
    stroke-dashoffset: 0;
    stroke-dasharray: 5;
    fill: none;
    -webkit-transition: all 2s ease-in-out;
}

svg:hover {
    stroke-dashoffset: 100;
    stroke-width: 1;
    stroke-dasharray: 3;    
}
```
消費MPを意識したミーティング

#話すこと
## MTGやめろ
## 消費MPを考える
## 無駄なMTGをなくすには
## まとめ

---
# MTGやめろ

---
## 正確には、無駄なMTG開くのやめてほしい

 + 内職してる人
 + 発言しない人
 + 共有のため参加してもらう人


いらない

---
# 時間=資源の無駄

---
## 資源には限界がある
会社全体で使える時間も有限なので、無駄なMTGは会社全体の損失になる。

---
有限な資源を大切に利用しなければならない。

---
# 消費MPを考える

---
## 消費MP（ミーティングポイント）

 + 会社やメンバーが浪費するリソースの評価値
 + 消費MPの高いMTGは負担
 + 消費MPに比例して、MTGの効果も高まらなければならない

---
## MP算出方法
[(個人消費MPの合計) * (全体消費MP)] / 楽しさ補正

---
注：厳密な数字を出すわけではありません。意識することが重要


---
### 個人消費MP
（戦闘力） / （自由時間係数）

#### 戦闘力
知名度、役職、実力などから求まる。めんどくさかったらおちんぎんでよい。

---
#### 自由時間係数
（MTG可能時間） / （勤務時間）

---
#### 詳細（長いので飛ばしても良い）
その人の勤務時間に対してMTGが可能な時間の割合。
例えば、８時間勤務だとして、その人がめちゃ忙しく、２時間しか空きがない場合、その人に30分のMTGを入れると、2時間のうち30分を消費するので、８時間計算した際には１２０分その人の時間を奪うことになる。つまり消費MPに計算される戦闘力は４倍で計算される。

---
####要は、空き時間が少ない人に来てもらうMTGは消費MPが高まる

---
### 全体消費MP
（場所代 * 開催時間）　+ （移動コスト）

#### 場所代
フリースペースや廊下などはコストが低い。みんなが使う会議室はコストが高い。社外の場合はさらに。

#### 移動コスト
時間や距離で高まる。

---
### 楽しさ補正

 + 楽しいMTGなら全体消費MPが下がり、そうでなければ上がる
 + 仲がいい人とのMTGなら消費MPが下がる

---
## MTG例

+ デスクで行うチームミーティング5分
+ １０人くらいで毎日行われる３０分定例
+ マネージャーと10分面談
+ 部長集めて障害報告30分

---
## 消費MPが求まると
MTGに重み付けができる

---
## MTG例

+ デスクで行うチームミーティング５分：低い
    + 場所代も時間も安い
+ １０人くらいで毎日行われる３０分定例：すごく高い
    + １０人集めて３０分毎日話す内容なんて無い
+ マネージャーと10分面談：高い
    + マネージャーの戦闘力は一般的に高い。時間を短く
+ 部長集めて障害報告30分：すごく高い
    + 戦闘力が高く、楽しさ補正がマイナス

---
# 無駄なMTGを減らすには
## MTG開くのをやめる
## 消費MPを下げる
## 費用対効果を高める

---
## MTG開くのやめる
+ メール、電話もある（使いたく無いけど）
+ SlackやIRCなど、チャットツールもある
+ その人の席に直接行ってもいい

---
### 相談は沢山してほしい 

---
### でもMTGは出たくない

---
### MTGは最終手段

MTGは

 + リアルタイムで全員のレスポンスが必要であり
 + 顔を合わせる必要があり
 + その場で一定の合議が必要である

場合にのみ開催されてほしい

---
### 以下のようなMTGは明日から廃止
 + 結果報告
     + 資料を送付して読ませれば良い
     + 読まないやつはMTGも聞かない
         + マジで気になる案件なら勝手に読む
 + 日時連絡
     + 同上
 + 目的のない、とりあえず相談系

---
### 例外
 + チームメンバーとの日例
     + メンバーとのコミュニケーションは大切
 + 会社、法律上のフローとして外せない会議
     + 筋を通すことは重要
 + 顔合わせ、キックオフミーティング
     + アイサツは実際大事
 + 楽しいこと
     + ソウルジェムの浄化は必要

---
## 消費MPを下げる

---
+ 会議の参加者や開催時間を削る
    + 個人の消費MPは大きなウェイトを占める
    + 開催時間は参加者全体にかかる
+ 偉い人にはメールで議事録などを渡す
+ 途中退出、途中入場を利用する
    + 前半10分だけ居てもらうとかする

---
# 費用対効果を高める

---
## 消費MPが高い = 悪では無い

---
## 効果の高いMTGを
+ その場で何かしらの合意を得る
+ その合意の結果が記録として残される

### 持ち帰って相談したい場合
+ 誰がボールを持つのか合意を得る
+ どんな結論が、いつまでに出るのか合意を得る

---
# まとめ

---
## 消費MPの高いMTGは高い効果が必要

---
## MTG以外の相談方法を活用したほうがお得

---
## めっちゃいっぱい相談してほしい

---
## でもMTGはなるべく開か無いでほしい

---
# おわり

---
意識低いスライドを作れるのでQiitaのスライドモードは神かもしれない
Mou というマークダウン専用エディタ


MouというMac用のエディタ。
マークダウン専用と割りきっても良いぐらいショートカットを覚えると便利。

## 表示/非表示系

|項目|キー|
|:--|:--|
|ウィンドウを半透明/不透明表示|⌘ + ⇧ + t|
|ウィンドウの最前面固定をON/OFF|⌘ + ⇧ + f|
|プレビューをON/OFF|⌘ + ⇧ + i|
|単語数カウンタをON/OFF|⌘ + ⇧ + w|
|エディタ:プレビューを1:1に|⌘ + 0|

## 挿入系

|項目|キー|
|:--|:--|
|Markdown改行(スペース2個+改行)を挿入する|^ + Enter|
|カーソルの次の行に改行を挿入<br>行の途中にカーソルあっても途中で改行されない|⌘ + Enter|
|リンクを挿入([link](http://))|^ + ⇧ + l|
|画像を挿入(![image](http://))|^ + ⇧ + i|
|HTMLコメントを挿入(<!---->)|⌘ + /|

## 選択、選択したものを~~系

|項目|キー|
|:--|:--|
|単語選択|⌥ + ^ + w|
|行選択|⌘ + ⇧ + l|
|選択した行を引用にする|^ + q|
|選択した行をリストにする|^ + l|
|選択した文字を強調する|⌘ + b|
|選択した文字をインラインコードにする|⌘ + k|
|選択した文字を~~取り消し線~~にする|⌘ + u|

選択系コマンドはvimバインド使わせてくれぃ。。。。

以下から使ってるものだけ選抜しました。
参考：[Mouのショートカットを覚えて爆速コーディング](http://leko.jp/archives/695)
Jenkins の Pipeline Plugin を試す。異なるノードへ値を渡すとか

# 概要

Jenkins の Pipeline Plugin を試した。

# わかったこと

## 異なるノードへ値を渡す
同じノードなら、ファイルにほぞんしてあげればよいとおもうのだが、
ことなるノードへ値を渡すとしたら stash/unstash を使うと良さそう。

もうちょっときれいにかけるかもしれないけど。

```
def OTHERNODEVALUE=""
node('node1'){
    stage "Run node1"
    sh "echo -n 'hello history' > value1.txt"
    stash("value1.txt")
}
node('node2'){
    stage "Wait hisat2 single end"
    unstash("value1.txt")
    OTHERNODEVALUE=readFile("value1.txt")
    sh "echo OTHERNODEVALUE=[{$OTHERNODEVALUE}]"
}
```

## うまくいってないこと１(2016-06-28)

Docker の Jenkins を -u を指定して実行すると

```
Pipeline script from SCM
```

すると

```
stderr: No user exists for uid 12345
```

のようなエラーがでる。

ふつうのジョブの場合にはでないので、なにかの問題なのか、こちらの環境の問題か、、、

コンテナの中にはいって、
/etc/passwd
に追記してあげると、一応このエラーはでなくなる。

## うまくいってないこと２(2016-06-28)

workspace をきれいにするボタンがない気がする。
git のレポジトリを変更することができなかったり、
あとからSparseを指定しようとしてもうまくいってないようにみえた。

ただ、これは、そもそもうまく取り出せないことが原因かもしれない。

# 近々やってみたいこと

Jenkins を 2 系にして再度テストしてみたい
[AWS] RDS のパラメータグループに設定されてる値を CSV として保存

管理資料にのせたいときとかに RDS のパラメータグループに設定されている値を CSV 化したい時ってあるよね。
そんな時は jq を使えば簡単。

```text
$ aws rds \
 describe-db-parameters \
 --db-parameter-group-name {PARAMETER-GROUP-NAME-HERE} \
 | jq -r '.Parameters[] | "\(.ParameterName), \(.ParameterValue)"' \
 > rds_parameters.csv
```
Array を (左右上下) 反転する 4 つの方法 in Julia

Julia では、Python (NumPy) にあるような `[::-1]` のようなスライス表記をつかうことができません。データの可視化などをする際の多次元配列の整形操作に便利な関数などをまとめてみます。(多分、ただの僕の備忘録になりそうです笑)

`flipdim` 関数
==============
`flipdim` という関数で、左右上下を反転することができます。反転しているのがわかりやすいように次のような行列を作っておきます。

```julia
A = begin
  A = eye(3)
  for i in 1:3
    A[i, :] *= i
  end
  A
end
@show A
# 3x3 Array{Float64,2}:
# 1.0  0.0  0.0
# 0.0  2.0  0.0
# 0.0  0.0  3.0
```

まず、`flipdim` は `flipdim(A, dim)` というように引数を取ります。`dim` は `axis` のような感じですね。たとえば、`dim = 1` とすると、次のように上下反転します。

```julia
flipdim(A, 1)
# 3x3 Array{Float64,2}:
# 0.0  0.0  3.0
# 0.0  2.0  0.0
# 1.0  0.0  0.0
```

また、`dim = 2` なら左右反転です。

```julia
flipdim(A, 2)
# 3x3 Array{Float64,2}:
# 0.0  0.0  1.0
# 0.0  2.0  0.0
# 3.0  0.0  0.0
```

`circshift` 関数
================
`circshift` というのもあります。これは `circshift(A, shifts)` のように使います。`shifts` にしたがって軸をとり、回転させるような変形をします。(迷名: トイレットペーパーシフト)

`shifts` にはシーケンスを代入しますが、Int の場合には、行方向に軸をとって回転します。値の大きさによってどれくらい回すか(シフトさせるか)のステップ数を指定できます。

```julia
circshift(A, 1)
# 3x3 Array{Float64,2}:
#  0.0  0.0  3.0
#  1.0  0.0  0.0
#  0.0  2.0  0.0
```

負値にすると、逆方向に回ります。

```julia
circshift(A, -1)
# 3x3 Array{Float64,2}:
#  0.0  2.0  0.0
#  0.0  0.0  3.0
#  1.0  0.0  0.0
```

`shifts = [0, 1]` にすれば、軸ごとにどれくらい回すか指定できます。

```julia
circshift(A, [0, 1])
# 3x3 Array{Float64,2}:
#  0.0  1.0  0.0
#  0.0  0.0  2.0
#  3.0  0.0  0.0
```

転置
====
Julia では、`A'` のように `'` をつけることで、 転置させることができます。対角行列では転置がわからないので、`randn` で適当に乱数行列を作ります。

```julia
srand(100) # set seed
X = randn(2, 2)
# 2x2 Array{Float64,2}:
#  -0.658136  -0.601421
#  0.383753  -0.211517
```

では、転置させてみます。

```jl
X'
# 2x2 Array{Float64,2}:
#  -0.658136   0.383753
#  -0.601421  -0.211517
```

ちゃんと転置できていますね。

範囲 (Range) でどうにかする
=======================
範囲を使うことで、どうにかすることも可能です。

```jl
srand(100)
Y = randn(3, 3)
# 3x3 Array{Float64,2}:
#  -0.658136  -0.211517   0.396071
#   0.383753   1.57874   -0.870703
#  -0.601421   2.03256   -0.705681
```

これについて、`flipdim` を使わずに範囲だけで上下反転させます。

```jl
Y[end:-1:1, :]
# 3x3 Array{Float64,2}:
#  -0.601421   2.03256   -0.705681
#   0.383753   1.57874   -0.870703
#  -0.658136  -0.211517   0.396071
```

できました。`end` とステップをつかうことで、反転させることは割と簡単にできます。`@time` マクロでみるとわかるように、範囲で反転させるほうが `flipdim` より早く、アロケーションも少ないようです。

また、以下で点対称に反転できます。

```jl
@time Y[end:-1:1, end:-1:1]
# 0.000009 seconds (12 allocations: 528 bytes)
# 3x3 Array{Float64,2}:
#  -0.705681   2.03256   -0.601421
#  -0.870703   1.57874    0.383753
#   0.396071  -0.211517  -0.658136

# is equivalent to 

@time flipdim(flipdim(Y, 1), 2)
# 0.000031 seconds (51 allocations: 1.750 KB)
# 3x3 Array{Float64,2}:
#  -0.705681   2.03256   -0.601421
#  -0.870703   1.57874    0.383753
#   0.396071  -0.211517  -0.658136
```

以上で、Julia における配列の整形操作まとめを終わります。Julia 初心者のため、他にもありましたらご教授ください。

Reference
=========
- [Julia Reverse N-dimensional arrays | stackoverflow](http://stackoverflow.com/questions/27411401/julia-reverse-n-dimensional-arrays)
- [Arrays | Julia Docs](http://docs.julialang.org/en/release-0.4/stdlib/arrays/#arrays)