OmniAICreator/Qiita-1.07M huggingface dataset:
Odoo8プラグイン全部入りイメージ作った(896.4 MB)

# 概要

[covetel/odoo8](https://registry.hub.docker.com/u/covetel/odoo8/)をカスタマイズした。

```bash:起動方法
sudo docker run -it -p 8069:8069 tukiyo3/odoo8 /odoostart.sh
```

* default setting => http://docker-ip:8069/, Email:admin, Password:admin

## 作ろうと思ったきっかけ

* 初回のodooの起動はできるが、2回目移行の起動が失敗！？
* プラグイン全部のインストールが30分くらいかかる。-> つらい
* イメージ多すぎなので自分用が欲しかった。

# 元となった記事

https://github.com/odoo/odoo

dockerイメージ多すぎたのでとりあえず[covetel/odoo8](https://registry.hub.docker.com/u/covetel/odoo8/)を使ってみた。

```bash:
sudo docker run -it -p 8069:8069 covetel/odoo8 /bin/bash
```

```bash:
/etc/init.d/postgresql start
mkdir /home/odoo
chown odoo:odoo /home/odoo
su - odoo -s /bin/bash
openerp-server -c /etc/odoo/openerp-server.conf
```

http://url:8069/ にブラウザでアクセス。

![installer.png](https://qiita-image-store.s3.amazonaws.com/0/25728/2e05f1ee-8e0c-6590-7a4b-eb36888ff969.png)

マスターパスワードはデフォルトで`admin`なのであとで変えとく。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/61f8fec5-c48e-a1a9-a57e-931c139a0b75.png)

インストール１つ5分くらいかかる

![3.png](https://qiita-image-store.s3.amazonaws.com/0/25728/5fe0b4a7-284e-0574-9080-5dbc37462f21.png)

コンテナ再起動後odooが`Internal Server Error`になる！？

# メモ

> GPG error: http://nightly.odoo.com ./ Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY DEF2A2198183CBB5

```bash:
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DEF2A2198183CBB5
```

## wkhtmltopdf 0.12を入れる

参考: [ODOO wkhtmltopdf](http://webkul.com/blog/odoo-wkhtmltopdf-upgrade-version/)

```bash:
apt install wkhtmltopdf wget fonts-takao
apt-get remove wkhtmltopdf
wget http://sourceforge.net/projects/wkhtmltopdf/files/0.12.2.1/wkhtmltox-0.12.2.1_linux-trusty-amd64.deb
dpkg -i wkhtmltox-0.12.2.1_linux-trusty-amd64.deb
apt-get -f install
dpkg -i wkhtmltox-0.12.2.1_linux-trusty-amd64.deb
```
リストを連結して文字列にする

# はじめに

Rubyのjoinみたいな関数がないので勉強のため書いてみました。
セパレータを挟んで連結する関数はRubyを使うときに、よく使用するのであれば便利だと思いました。

# joinとは

Rubyの他にも様々な言語で実装されていると思いますが、今回はRubyを例にします。
処理内容は配列を受け取り、区切り文字で連結した文字列を返すというものです。
例として下にソースコードを示します。

```rb:join.rb
[1, 2, 3, 4].join(",")          # => "1,2,3,4"
['a', 'b', 'c', 'd'].join("=")        # => "a=b=c=d"
```

例のように配列を指定した区切り文字で連結して文字列を返しているのが分かります。
Rubyの実装では配列が入れ子になったものも平滑化して、関数を適用してくれます。Lispではリストの平滑化を行うflattenという関数を定義し、その関数を適用したリストを今回作成した関数に渡すと可能です。

# ソースコード

```cl:join.lisp
(defun join (list sep)
 (with-output-to-string (s)
   (labels ((fn (list)
              (cond ((null (cdr list)) (princ (car list) s))
                    (t (princ (car list) s)
                       (princ sep s)
                       (fn (cdr list))))))
     (fn list))))
;=> JOIN

(join '(1 2 3 4) ",")
;=> "1,2,3,4"

(join '(a b c d) "=")
;=> "A=B=C=D"

(join '(a b c d) "===")
;=> "A===B===C===D"
```

# おわりに

loopとformatで出来ると思ったのですが、最後に余計な区切り文字が入り、それを取り除く方法が分からなかったので諦めてしまいました。
Lispを勉強する前はループでまず解決しようと考えていたのですが、Lispを勉強し始めて再帰をまず使うような思考に切り替わったような気がします。

# 追記

doによるループでも実装してみました。

```cl:join_do.lisp
(defun join (list sep)
 (with-output-to-string (s)
   (do ((elem list (cdr elem)))
       ((null (cdr elem)) (princ (car elem) s))
     (princ (car elem) s)
     (princ sep s))))
;=> JOIN

(join '(1 2 3 4) ",")
;=> "1,2,3,4"

(join '(a b c d) "=")
;=> "A=B=C=D"

(join '(a b c d) "===")
;=> "A===B===C===D"
```
猫年齢を人間年齢に換算する（DoubleとStringを相互変換）

![アプリ画像](http://i.gyazo.com/236ec8e85eaf8a61b6ffc9c810670b4d.png)

###やったこと
* 猫年齢<->人間年齢換算アプリを作る
* 数値キーボードにクリアボタンを表示する
* 画面タップでキーボードを非表示にする

Double<->Stringの変換が多少役に立つかと。

「詳細Objective-C iPhoneアプリ開発入門ノート」Chapter4-3の学習記録です。

###コード
```swift:ViewController.swift
class ViewController: UIViewController {

    // 年齢テキストボックス
    @IBOutlet weak var inputAge: UITextField!
    // 換算後年齢ラベル
    @IBOutlet weak var resultAge: UILabel!
    // 自作クラス
    var mp = MyProc()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
    }

    // 換算ボタンを押す
    @IBAction func convertAge(sender: AnyObject) {
        
        var input = self.inputAge.text
        var res:NSString = mp.convertAgeFromCatToHuman(input)
        self.resultAge.text = res
    }
    
    // 背景をタップ
    @IBAction func bkgTapped(sender: UITapGestureRecognizer) {
        
        //キーボードを閉じる
        self.view.endEditing(true)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
```

```swift:MyProc.swift

class MyProc:NSObject {
    
    // 初期化
    override init() {
        
    }
    
    // 猫の年齢を人間の年齢に変換する
    func convertAgeFromCatToHuman(catAge: NSString) -> String{
        
        // Doubleに変換
        var catAgeDbl = catAge.doubleValue
        var hmnAge:Double = 0
        if (catAgeDbl <= 1) {
            hmnAge = catAgeDbl + 20
        } else if (catAgeDbl <= 5) {
            hmnAge = catAgeDbl * 6 + 15
        } else if (catAgeDbl <= 10) {
            hmnAge = catAgeDbl * 5 + 20
        } else if (catAgeDbl <= 15) {
            hmnAge = catAgeDbl * 4 + 30
        } else {
            hmnAge = catAgeDbl * 3 + 45
        }
        
        var hmnAgeStr = NSString(format: "%.1f", hmnAge)
        return hmnAgeStr
    }
}
```
###ソースアップ
https://github.com/hanoopy/ios_study1024_2.git

###わからない
* コンソールにエラーが出る
*2014-10-24 22:49:04.462 CatAge[2506:72454] Can't find keyplane that supports type 8 for keyboard iPhone-Portrait-DecimalPad; using 1425143906_Portrait_iPhone-Simple-Pad_Default*


* 本にはテキストボックスの入力制御をdelegateでやってたんだけど、delegateメソッドの書き方がわからない。ので今回はやめた。
Railsのcolumn名に special? とか付けたい時にどうするか。

カラム名に`?`が使えないので真偽値を返すメソッドの末尾に`?`をつけて使いたいときにどうするかというお話。

### 解決策

例えば単に`special`ってカラム名で列を追加して型をbooleanにしたら`foo.special?`で呼び出せるようになる。すごい。

ちなみにこういう時に使える英単語に `automagically` というのがあります。プログラム関係でしか出てこないので英会話教室とかではまず出てこないので覚えておくと良いかもしれません。
Githubのユーザ名で 簡単にアイコンを取得できるよ

表題の通り、`https://github.com/<username>.png` で簡単にGithubのユーザアイコンURLへリダイレクトさせてくれるので便利でした

```shell-session
[~]$ curl -I https://github.com/mizoR.png
HTTP/1.1 302 Found
Server: GitHub.com
Date: Fri, 24 Oct 2014 23:41:14 GMT
Content-Type: image/png; charset=utf-8
Status: 302 Found
...
Location: https://avatars0.githubusercontent.com/u/1257116?v=2
...
```
外部ファイル読み込み時の「require」と「require_dependency」の違い


##はじめに
`rails`を使ってモジュールを読み込むときはrequireを使っていましたが、require_dependencyなるものを聞いたので紹介します。

##現象（事の発端）
`rails`で自作モジュールを作成して`require`で読み込んでいたのですが、モジュールを編集して再度実行するとNoMethodとなって読み込んでくれないことがありました。
スペルミスったかな？と思って確認しても間違いは見当たらず。
この原因として`require`の処理内容を理解していなかったということがわかりました。

##「require」と「require_dependency」
外部ファイル読み込み時にはおなじみの「`require`」と、「`require_dependency`」というものもあります。
この２つの特徴はざっとするとこんな感じ。

- **「require」** 
	1. `ruby`の組み込み関数
	1. 引数で指定した`ruby`ファイル（.rb）を読み込む
	1. 既に読み込み済みのファイルなら読み込まない
	1. キャッシュ済みの場合はそちらを読み込む
- **「require_dependency」**
	1. `rails`が定義した独自メソッド
	1. 引数で指定した`ruby`ファイル（.rb）を読み込む
	1. 既に読み込み済みのファイルなら読み込まない
	1. キャッシュ済みであっても再読み込み（`load`)

この２つの違いは、`load`を使って読み込むかどうかです。
`require_dependency`は、developmentモードで実行しているときは`load`を使って読み込まれます。
productionモードで実行しているときは`require`を使って読み込まれるようです。
ということで、この２つ何が違うかというと、
developmentモード時は **ロード対象の`ruby`ファイルが変更されている時に再読み込みをするかどうか** が異なっています。
`require_dependency`は無条件に`load`するので変更点があった場合はその変更が反映されます。

開発中はよく変更がありますよね。そんなとき`require_dependency`を使っていればキャッシュしてようが再読み込みして変更点を反映してくれます。
そのままproductionモードで実行しても処理は`require`を使って読み込まれるので問題なしです。
開発中は`require_dependency`を使うと便利ですね！

**※`require_dependency`は`rails`の独自メソッドなのでお気をつけ下さい**

##おわりに
もっと`rails`のコード読んで早く知っておけばよかったです。
もっと注意深く読んで見ます。
今回はこちらの記事を参考にさせてもらいました。ありがとうございます。

>requireとrequire_dependencyとRuby 1.8.7とRuby 1.9.2
>http://masamitsu-murase.blogspot.jp/2011/11/requirerequiredependencyruby-187ruby.html

>require_dependencyとrequireの違い
>http://d.hatena.ne.jp/sai-ou89/20081218/1208940536
ビューの階層構造をログ出力する

UIViewにはビュー階層を表示するためのプライベートメソッド`recursiveDescription` があるので、これを使います。
このメソッドを呼び出すと、以下のようにビュー階層をログ出力してくれます。

```ログ出力例
<UIView: 0x7ff192717cc0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7ff19264f0d0>; layer = <CALayer: 0x7ff192717d90>>
   | <UIView: 0x7ff1927198e0; frame = (0 60; 320 183); autoresize = RM+BM; layer = <CALayer: 0x7ff1927199b0>>
   |    | <UITextField: 0x7ff192656c40; frame = (8 57; 304 30); text = '1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7ff1926596a0>; layer = <CALayer: 0x7ff1926570e0>>
   |    |    | <UIButton: 0x7ff19266cd10; frame = (280 6; 19 19); opaque = NO; layer = <CALayer: 0x7ff19266c950>>
   |    |    |    | <UIImageView: 0x7ff192677260; frame = (2.5 2.5; 14 14); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7ff192677360>>
.
.
.
```

デバッガから`recursiveDescription`を実行する方法とコード内で呼び出す方法がありますが、ブレークさせたくない場合はコードに記述することになるでしょう。



##デバッガからコマンド実行する方法
ブレークで止めた後、デバッグコンソールから以下を実行(po以降を入力)します。階層表示するビューは適宜変更してください。

```
(lldb) po [self.view recursiveDescription]
```


##コードから実行する方法

```objectivec
NSLog(@"%@", [self.view recursiveDescription]); // error
NSLog(@"%@", [self.view performSelector:@selector(recursiveDescription)]); // warning

```

これだけだとメソッドが見つからないので怒られてしまいます(プライベートメソッドなので)。
カテゴリでメソッドを追加(宣言のみ)したうえで上記呼び出しを行えうことで怒りを鎮めることができます。

```objectivec
@interface UIView (debug) //無名カテゴリでもよいです
- (NSString *)recursiveDescription;
@end
```

※ プライベートメソッドなので、リリースビルド時には使わないようにしましょう。


##参考

[Technical Note TN2239: iOS Debugging Magic](https://developer.apple.com/library/ios/technotes/tn2239/_index.html#//apple_ref/doc/uid/DTS40010638-CH1-SUBSECTION34)

> UIView implements a useful description method. In addition, it implements a recursiveDescription method that you can call to get a summary of an entire view hierarchy.
メモ: windows10における古いActiveXコントロールのブロックされる！？

[10/21版のWindows 10 Technical Preview](http://www.itmedia.co.jp/pcuser/articles/1410/22/news066.html)にて試した。


本番サーバのActiveXをテストサーバ(ドメインが異なる)に設置、URLをそこに指定。
しかし発行元が`Unknown`となりインストールが出来ない。


> Program name: Unknown program
> Publisher: Unknown
> File origin: Downloaded from the Internet
> Program location: http://url〜/〜.cab

:ok_woman: 記述が間違っていました

```html:正しい書き方例
<object id="act1" width="0" height="0" classid="clsid:FCB1312F-3DF6-B4D6-A821-AD1489EB796D" codebase="act1.cab#version=1,0,1,0"></object>
```


# 以下ゴミ情報

## 挑戦1

> コンピューターの構成（またはユーザーの構成）\管理用テンプレート\Windows コンポーネント\Internet Explorer\セキュリティの設定\アドオン管理\Internet Explorer で古い ActiveX コントロールのブロックを無効にする

この項目はなかった。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/c1a004b3-6132-238a-0c24-457a44bf2870.png)

## 挑戦2

> コンピューターの構成（またはユーザーの構成）\管理用テンプレート\Windows コンポーネント\Internet Explorer\インターネット コントロール パネル\セキュリティ ページ\サイトとゾーンの割り当て一覧

これはあった。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/e542a645-6361-785e-d85f-c98e241b2c88.png)

どう設定したらよいのかちょっとわからなかったのと、デメリットがありそうなのでやめた。

## 挑戦3

> REG ADD "HKCU\Software\Microsoft\Internet Explorer\VersionManager" /v DownloadVersionList /t REG_DWORD /d 0 /f
> DEL "%LOCALAPPDATA%\Microsoft\Internet Explorer\VersionManager\versionlist2.xml"

やはりダメだった。(なおversionlist2.xmlは存在しなかった。)

## 挑戦4

本番のActiveXをインストールしてから、テスト環境にアクセス
 -> ActiveXがインストール済みとみなされて動作する。

うーむ、本番にアクセスさせずにインストールさせたい。。
imgタグにはwidthとheightを明示する

widthとheightが省略されたimg要素は、画像の読み込みが完了するまで自身のサイズを確定できません。
サイズを明示することでレンダリングコストを抑制できます。もしくは、HTML属性値の代わりにCSSで指定しても構いません。

```html:Example
<img src="test.jpg" width="300" height="100" alt="test"></img>
```
[baserCMS]ユーザー（UserModel）保存時にパスワードの暗号化処理が不要な動作となっている件


ユーザーモデルをオーバーライドして機能作成中に気付いたんでシェア。

## 環境

- baserCMS 3.0.6.1
- PHP 5.4.19


## 発生するタイミングと状況
- baserCMSのUserModelを利用して会員機能とか作ってるとき
- 会員のパスワードを保存するフィールド名が「password」のとき
- 以下のように、コントローラーでパスワードに対して暗号化処理を入れずに保存

```php
if (!empty($this->request->data)) {
	$this->Member->create($this->request->data);
	if ($this->Member->save()) {
		$this->setMessage('追加しました。', false, true);
		$this->redirect(array('action' => 'edit', $id));
	} else {
		$this->setMessage('入力エラーです。内容を修正してください。', true);
	}
}
```

- DBの中身を見るとしっかり暗号化されている

あれ？どうして？
ちなみに通常であればこんな感じになるかな、と。

```php
if (!empty($this->request->data)) {
	$this->request->data['Member']['password'] = $this->BcAuth->password($this->data['Member']['password']);
	$this->Member->create($this->request->data);
	if ($this->Member->save()) {
		$this->setMessage('追加しました。', false, true);
		$this->redirect(array('action' => 'edit', $id));
	} else {
		$this->setMessage('入力エラーです。内容を修正してください。', true);
	}
}
```


## 正体
UserModelのbeforeSave()で、passwordというフィールド名が存在する場合は、暗号化処理を施すようにしてありました。

```/lib/Baser/Model/User.php
/**
 * beforeSave
 * 
 * @param type $options
 * @return boolean
 */
	public function beforeSave($options = array()) {
		if (isset($this->data[$this->alias]['password'])) {
			App::uses('AuthComponent', 'Controller/Component');
			$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
		}
		return true;
	}
```

baserCMSは、制作者さんにやさしいCMSですね。
vimdiffの色設定を変更して見やすくする（黒背景用）

Linuxにおける差分表示ツールとしてはdiffコマンドがありますけれども、複雑な変更になってくるとvimdiffが使いやすい場面も多々あるわけでございます。特に横に並べて比較できるのは大きなメリットですよね。

ところが、デフォルトの設定ですと結構色が見辛いわけで、何とかしたいわけです。ちょっと検索して調べてみましたが、自分が思うような色設定がどっかに載ってたりとかしなかったので、自分で設定してみることにしましたよ。いつも黒背景で使っておりますので、そこに最適化してあることにご注意ください。

というわけで、下記の記述を .vimrc に加えればOKです。

```vim:~/.vimrc
" vimdiffの色設定
highlight DiffAdd    cterm=bold ctermfg=10 ctermbg=22
highlight DiffDelete cterm=bold ctermfg=10 ctermbg=52
highlight DiffChange cterm=bold ctermfg=10 ctermbg=17
highlight DiffText   cterm=bold ctermfg=10 ctermbg=21
```

これでvimdiffコマンドを実行するとこのようになります。

![スクリーンショット 2014-03-28 5.47.40.png](https://qiita-image-store.s3.amazonaws.com/0/48289/6e788173-bea8-625c-d874-cf7bacedc52d.png)

背景の色を差分の種類によって分けており、追加行は緑、削除行は赤、変更行は青で変更部分が明るい青になってます。

これでだいぶ見やすくなるんじゃないかと思います。

※[自分のブログ](http://takaaki-kasai-tech.blogspot.jp/2014/03/color-settings-for-better-readability-of-vimdiff.html)より転載。
SquidのログをLTSVで出す

###設定ファイル

```shell-session:/etc/squid/squid.conf
logformat ltsv src_ip:%>a       src_port:%>p    time:%{%Y/%m/%d %H:%M:%S}tl     req_method:%rm  req_url:%ru     protocol:HTTP/%rv    status_code:%>Hs        referer:"%{Referer}>h"  user-agent:"%{User-Agent}>h"    squid_req_status:%Ss
```

###出力結果

```shell-session:access_ltsv.log
src_ip:192.168.0.185    src_port:49290  time:2014/10/24 18:18:23        req_method:CONNECT      req_url:login.finalfantasyxiv.com:443   protocol:1.1    status_code:200 referer:"-"     user-agent:"LIBRA/1.0"  squid_req_status:TCP_MISS
src_ip:192.168.0.185    src_port:49291  time:2014/10/24 18:18:24        req_method:CONNECT      req_url:login.finalfantasyxiv.com:443   protocol:1.1    status_code:200 referer:"-"     user-agent:"LIBRA/1.0"  squid_req_status:TCP_MISS
```

簡単ですね。`\t`が使えないのが面倒ですけども(´・ω・｀)
Android用のライブラリを作る


そういえばやったことなかったので。

## Library Projectを作る

まずいつもと同じように
eclipse->File->New->Project...にてAndroid Application Project
でプロジェクト作成開始。

アイコンもアクティビティもいらないので`Create custom launcher icon`と`Create activity`のチェックを外す。

`Mark this project as a library`にチェックを入れる。

![Screen_Shot_2014-10-25_at_01_08_25.png](https://qiita-image-store.s3.amazonaws.com/0/8868/5d3c8c48-b931-2f0c-4d03-07746ec9a5a5.png "Screen_Shot_2014-10-25_at_01_08_25.png")

Finish

できたProjectのProperties->Androidを見てみると`is Library`にチェックがついている。

![Screen_Shot_2014-10-25_at_01_15_57.png](https://qiita-image-store.s3.amazonaws.com/0/8868/ae6bdeab-e765-f810-1dfe-9c53f5f60b64.png "Screen_Shot_2014-10-25_at_01_15_57.png")

## Libraryの中身開発

適当にクラスを追加する

```Sample.java
package com.jollyjoester.samplelibrary.sample;

import android.util.Log;

public class Sample {
	
	public static void sampleMethod(){
	
		Log.d("LibrarySample", "Log from Library");

	}
}

```

## 他のプロジェクトから使う

他のAndroid Application ProjectのProperties->AndroidのLibraryにて
上で作ったライブラリを`Add`する。

![Screen_Shot_2014-10-25_at_01_24_21.png](https://qiita-image-store.s3.amazonaws.com/0/8868/d09f275a-71c0-60a0-a9e6-33198f27d36c.png "Screen_Shot_2014-10-25_at_01_24_21.png")

下記みたいな感じで使える

```java
import com.jollyjoester.samplelibrary.sample

	// ・・・

	Sample.sampleMethod();

	// ・・・
```

以上
jQuery で input の value を変更する際に attr は使用しない方がいい

jQuery で、input の value 値を変更する際に、.val('値') と .attr('value', '値') があるのですが。今回これで少しハマったのでメモします。
※ chrome 38.0.2125.104 で確認しています

# .attr('value', '値') の問題点
初期値を設定する場合は問題なく動作するのですが、一度ユーザーが編集もしくは、.val('値') によって編集されてしまうと、動作しなくなります。

実際に jsfiddle でサンプルを作成しました。
http://jsfiddle.net/kazunari_yamashiro/zzjaftva/1/

変更(attr) ボタンを連打すると、value として cnt がインクリメントしているのが確認できます。
しかし、input の中身を直接編集するかもしくは、変更(val) のボタンを押すと、変更(attr) ボタンを押しても中身の変更が行われなくなります。
しかし、直接編集後も、変更(val) は有効です。


# 結論
~~なぜそうなるのか、についてはわかりませんが~~**※下記追記しました。**input の value を変更する際は .val('値') を使用する方が無難なようです。


# 追記
value プロパティと value 属性のアクセスの違いのようです。
http://www.softel.co.jp/blogs/tech/archives/1595

.attr() は setAttribute を利用していて
.val() は value のプロパティアクセスをしているように思われます。
Phoenix v0.4.1 のアプリを v0.5.0 にアップグレードした

Phoenix v0.4.1 で作ったアプリを v0.5.0 に upgrade したときにやったことをメモする。

## Phoenix v0.5.0 を用意

```console
$ cd phoenix
$ git pull
$ git checkout v0.5.0
$ mix do deps.get, compile
...省略
** (Mix) You're trying to run :phoenix on Elixir v1.0.0 but it has declared in its mix.exs file it supports only Elixir ~> 1.0.1 or ~> 1.1
```

失敗。。エラーメッセージから Elixir 1.0.1 以上が必要とのこと。
exenv 使っているので以下の通り Elixir 1.0.1 を install した。

```console
$ exenv install 1.0.1
$ exenv global 1.0.1
```

気を取り直して `phoenix.app` 作り直した。

```console
$ mix do deps.get, compile
...省略
Generated phoenix.app
```

## アプリを v0.5.0 に上げる

Rails でいうところの `rake rails:update` はないので、アプリ作成コマンドを代用する。
`mix phoenix.new` で v0.4.1 で作られているアプリを上書きする。とりあえず全て Y 押した。

```console
$ cd phoenix
$ mix phoenix.new my_v0.4.1_app ../my_v0.4.1_app/
* creating ../my_v0.4.1_app/.gitignore
/my_v0.4.1_app/.gitignore already exists, overwrite? [Yn] Y
...以下上書きするファイルを同様に聞かれる
```

上書きされたファイルの内容をチェックして、直すところは直す。

```console
$ mix do deps.get, compile
```

## v0.5.0 用に実際に直したところ

CHANGELOG を確認するのが手っ取り早い。いくつか breaking change も入っている。

https://github.com/phoenixframework/phoenix/blob/master/CHANGELOG.md 

以下実際に直したところ、というか直さないと動かなかったところ。

- controller に `plug :action` が必要になった
  - なのでつける
- default で `JSON` の alias がなくなった
  - Phoenix が依存している `Poison` という json library を使う
  - 具体的には `alias Poison, as: JSON` をつける
- heroku に上げていたので、`elixir_buildpack.config` の Elixir version を変更
  - 1.0.0 -> 1.0.1 にした
  - 1.0.0 のままだと plug 周りで以下のコンパイルエラーがでた

```console
== Compilation error on file lib/plug/conn/adapter.ex ==
** (RuntimeError) cannot compile Plug because the :cowboy application is not available. Please ensure it is listed as a dependency before the plug one.
    lib/plug/conn/adapter.ex:4: (file)
    (elixir) src/elixir_lexical.erl:17: :elixir_lexical.run/3
    (elixir) lib/kernel/parallel_compiler.ex:97: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/8

could not compile dependency plug, mix compile failed. You can recompile this dependency with `mix deps.compile plug` or update it with `mix deps.update plug`
```

## ちなみに。。。

v0.5.0 は heroku で動かない。パスの問題があるためなのだけど、この[コミット](https://github.com/phoenixframework/phoenix/commit/86dee56b42da5f465c81cae6b0556942069a2165)で直っている。v0.5.0 を諦めて master を使ったら動いた。ということで今すぐやるなら master(v0.6.0dev) がおすすめ。

## SEE ALSO

- [Migrating Applications From Phoenix 0.4.1 to Phoenix 0.5.0](http://learnelixir.com/blog/2014/10/29/migrating-applications-from-phoenix-0-dot-4-1-to-phoenix-0-dot-5-0/)
  - 手作業でやる方法について詳しく載っています
- https://github.com/phoenixframework/phoenix/blob/master/CHANGELOG.md
- https://github.com/phoenixframework/phoenix/commit/86dee56b42da5f465c81cae6b0556942069a2165
Perl の each の挙動


Ruby での Hash の each_pair みたいなのを Perl でやりたくてロクに仕様を知らずに each を使ったらハマった。
Perl のバージョンは 5.21.1。

ちなみに Ruby だと以下のように書ける処理。

```ruby
h.each_pair {|k, v|
  p "#{k} : #{v}"
}
```

これだけなら Perl でも普通に書ける。

```perl
while (my ($k, $v) = each(%$h)) {
    print "key = $k, value = $v\n";
}
```

ただ、特定の条件の場合にループを抜ける、みたいなコードを書いてみると、二度目の実行から想定通りに動作しない。

```perl
use strict;
use warnings;

my $h = +{
    foo  => 1,
    bar  => 2,
    baz  => 3,
    qux  => 4,
    quux => 5,
};

# 一度目の実行
while (my ($k, $v) = each(%$h)) {
    print "key = $k, value = $v\n";
    last if $k eq "baz";  # 値が一致したらループを抜ける
}

print "--------------------\n";

# もう一度最初からループを実行(したい)
while (my ($k, $v) = each(%$h)) {
    print "key = $k, value = $v\n";
}
```

実行すると以下のような感じ。

```
key = qux, value = 4
key = baz, value = 3
--------------------
key = foo, value = 1
key = bar, value = 2
key = quux, value = 5
```

二度目の実行では途中で抜けるような処理は行っていないにも関わらず、全部の値が出力されていない。

順不同なので結果は実行する度に変わるが、どうも each が二度目の実行時に一度目に繰り返しを進めた位置を覚えているような挙動をしている事が分かる。

この挙動の原因がわからず、散々悩んだ末に検索していたら詳しく解説されている以下の記事を発見。

eachの途中で止めると再開が途中からになる話 - Perl日記
http://r9.hateblo.jp/entry/20130128/p1

明らかに直感的じゃない気がするが、どうも each の仕様という事らしい。

で、結局問題の処理は foreach と keys を使って以下のような感じで書く事にした。

```perl
use strict;
use warnings;

my $h = +{
    foo  => 1,
    bar  => 2,
    baz  => 3,
    qux  => 4,
    quux => 5,
};

foreach my $k (keys(%$h)) {
    print "key = $k, value = $h->{$k}\n";
    last if $k eq "baz";
}

print "--------------------\n";

foreach my $k (keys(%$h)) {
    print "key = $k, value = $h->{$k}\n";
}
```

### 参考

each - perldoc.perl.org
http://perldoc.perl.org/functions/each.html

keys - perldoc.perl.org
http://perldoc.perl.org/functions/keys.html
git rm で fatal: pathspec did not match any filesが出るときの解決方法

`git rm`でディレクトリの中味を空にしようとしました。するとfatalエラーがでました。

```bash:rmできないとエラー
git rm -r ./*
fatal: pathspec './hoge' did not match any files
```
これはGitに登録していないファイルがあると出るらしいです。

どうやら `--ignore-unmatch` をつけると、Gitに登録していないファイルを無視して削除してくれるみたいです。

```bash:Gitに登録していないファイルを無視してrm
git rm -r --ignore-unmatch  ./*
```
今度はちゃんと削除できました(☝ ՞ਊ ՞)
`vendor/cache`なしで`carton install --cached`を実行すると何が起きるのか

依存しているモジュールがすべてCPANにあれば`vendor/cache`がなくてもインストールが成功するらしい。ただし将来的には成功しなくなる可能性があるので、この挙動に依存するべきではない。

cartonの内部では次のような処理が行われている。

1. [Carton::CLI#cmd_install](https://github.com/perl-carton/carton/blob/dcc4dfb7edbc95bc35d6256e4f77d7695cac3394/lib/Carton/CLI.pm#L220): `--cached`が付いていたら`$builder->mirror`を設定する。
1. [Carton::Builder#install](https://github.com/perl-carton/carton/blob/dcc4dfb7edbc95bc35d6256e4f77d7695cac3394/lib/Carton/Builder.pm#L53): cpanmを呼び出す。`$builder->effective_mirrors`をミラーとして渡す。
1. [Carton::Builder#effective_mirrors](https://github.com/perl-carton/carton/blob/dcc4dfb7edbc95bc35d6256e4f77d7695cac3394/lib/Carton/Builder.pm#L13): 常に http://cpan.metacpan.org/ と http://backpan.perl.org/ が追加される。
  - 関数内には<pre>
        # push default CPAN mirror always, as a fallback
        # TODO don't pass fallback if --cached is set?
    </pre>
    というコメントが付いている。今後、`--cached`が付いているときにはミラーを追加しないように変更されるかもしれない。

<a rel="license" href="http://creativecommons.org/publicdomain/zero/1.0/"><img src="http://i.creativecommons.org/p/zero/1.0/80x15.png" style="border-style: none;" alt="CC0" /></a>
手を動かしながら学ぶ ビジネスに活かすデータマイニング 正誤表

書籍『[手を動かしながら学ぶ ビジネスに活かすデータマイニング](http://www.amazon.co.jp/gp/product/477416674X)』を読んで見つけた誤植をまとめます。

[本家サポートサイト](http://gihyo.jp/book/2014/978-4-7741-6674-2/support)の誤植一覧にはまだ載っていないものです。

- p011
右下あたり。「データ現場」→「データ分析の現場」とか？

- p015
補足*11 の「奇数個」は「偶数個」の間違い

- p043
最初の文章の「つなげます」→「使います」

- p043
「cbind はマトリクスでもデータフレームでも使えますが、rbind はマトリクスでしか使えない」→ 使えます

- p106
ロジスティック回帰の式、βに i がいらない

- p128など
True, False は R では TRUE, FALSE では？

【参考】この本に対する私の書評はこちら：
[ビジネス側の人がデータ分析できるようになるために最初に読むべき一冊](http://d.hatena.ne.jp/hoxo_m/20141010/p1)
Solrjの日時パースメソッドは危険

Solrに付随しているライブラリ、Solrjに`DateUtil.parseDate()`というSimpleDateFormatクラスを使わずに文字列をDate型にパースしてくれる便利そうなメソッドがありますが、かなり危険なようです。

今のところ確認した事象

solrj 4.10.1で確認

---

１. DateクラスをtoString()で出力した文字列(EEE MMM d HH:mm:ss z yyyy形式)が12時の時にこのメソッドを使うと時の部分が0時になってしまう。


```:java
import org.apache.solr.common.util.DateUtil;

public class DateTest {
  public static void main(String[] args) throws ParseException {
    String dateStr = "Fri Oct 24 12:11:57 JST 2014";
    System.out.println(DateUtil.parseDate(dateStr));
  }
}
```

出力結果は
```
Fri Oct 24 00:11:57 JST 2014
```
になります。

---

２. yyyy-MM-dd HH:mm:ss の文字列は全て yyyy-MM-dd 09:00:00 になってしまう。

```:java
import org.apache.solr.common.util.DateUtil;

public class DateTest {
  public static void main(String[] args) throws ParseException {
    String dateStr = "2014-10-24 18:00:00";
    System.out.println(DateUtil.parseDate(dateStr));
  }
}
```

出力結果は
```
Fri Oct 24 09:00:00 JST 2014
```
になります。

---

実装を確認したところ、１.の事象に関しては、EEE MMM d HH:mm:ss z yyyy形式のフォーマットが「EEE MMM d hh:mm:ss z yyyy」で時の部分がAM、PMを区別しない「hh」になっているのが原因と思われます。

２.に関しては、処理するフォーマットが下記のような順番になっているので

```
yyyy-MM-dd'T'HH:mm:ss'Z'
yyyy-MM-dd'T'HH:mm:ss
yyyy-MM-dd
yyyy-MM-dd hh:mm:ss
yyyy-MM-dd HH:mm:ss
EEE MMM d hh:mm:ss z yyyy
EEE MMM d HH:mm:ss yyyy
EEEE, dd-MMM-yy HH:mm:ss zzz
EEE, dd MMM yyyy HH:mm:ss zzz
```

yyyy-MM-dd hh:mm:ss形式(もしくはyyyy-MM-dd HH:mm:ss形式)を処理するより先に「yyyy-MM-dd」形式でパースされてしまうのが原因のようです。

---

現状ではSolrjの日時パーサーは使わない方がよさそうです。
Lollipop(x86)のイメージだとエミュレーターが起動しない


下のようなログを吐いてsystem_serverが落ちて、直後に再起動するものの同じ場所で落ちてを繰り返していつまでたってもブート出来ない

ARMのイメージは起動できるものの案の定もっさりなのであんまり使えない(´・ω・`)

```
I/DEBUG   (  935): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  935): Build fingerprint: 'generic_x86/sdk_google_phone_x86/generic_x86:5.0/LRX09D/1504858:eng/test-keys'
I/DEBUG   (  935): Revision: '0'
I/DEBUG   (  935): ABI: 'x86'
I/DEBUG   (  935): pid: 2040, tid: 2040, name: system_server  >>> system_server <<<
I/DEBUG   (  935): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb7e98d1c
I/DEBUG   (  935):     eax e9f239dc  ebx 0000003f  ecx 00000035  edx 0000000a
I/DEBUG   (  935):     esi b7e98c20  edi a5e4cc00
I/DEBUG   (  935):     xcs 00000073  xds 0000007b  xes 0000007b  xfs 00000007  xss 0000007b
I/DEBUG   (  935):     eip b6ea5e20  ebp a1e00800  esp bfd98dc0  flags 00200282
I/DEBUG   (  935): 
I/DEBUG   (  935): backtrace:
I/DEBUG   (  935):     #00 pc 00048e20  /system/lib/libcrypto.so (bn_mul_mont+1360)
I/DEBUG   (  935): 
I/DEBUG   (  935): Tombstone written to: /data/tombstones/tombstone_03

```

落ちる前にCertificateが取れない旨のエラーメッセージが出ているがこれが関係しているのだろうか???

```
10-24 13:24:02.171  2307  2307 I PackageManager: No settings file; creating initial state
10-24 13:24:08.456  2307  2307 W PackageManager: Failed to parse /system/framework/framework-res.apk: Failed to collect certificates from /system/framework/framework-res.apk
10-24 13:24:08.478  2307  2307 W PackageManager: Failed to parse /system/framework/x86: Missing base APK in /system/framework/x86
10-24 13:24:08.671  2307  2307 W PackageManager: Failed to parse /system/priv-app/BackupRestoreConfirmation: Failed to collect certificates from /system/priv-app/BackupRestoreConfirmation/BackupRestoreConfirmation.apk
```
HexoでGithub Enterpriseの個人ページにブログを書く

#使っていますか？Github Enterprise
かなり便利ですよね。
そんなわけで、、Github Enterprise内でブログを書こうと思ったわけですよ。
Middlemanとか、jekyllとか、Octopressとか、いろいろあるんですが、
とりあえずHexoを試そうと思って、しかし、所々つまづいたところがあったので
とりあえず書いておこうと思います。

#手順

##リポジトリを作成する

Github.comに作るのとは少し違います。
例えば、Github Enterpriseのドメインがexample.com、自分のユーザ名がkumaだったとしたら、
`kuma/kuma.example.com` というリポジトリを作ります。
もしドメイン名なんてねえよ！ッて言う場合は例えば、`kuma/kuma.10.0.0.1` という感じで作ります。

##Hexoをnpmでインストールをする

nodeとnpmがすでに入っている想定ですが、
`npm install -g hexo` これだけで完了です。

##Hexoでブログを生成する

適当なディレクトリで、`hexo init <blog name>` 例えば、 `hexo init kumablog` これだけです！

##設定ファイルをいじる

設定ファイルは生成されたディレクトリの `_config.yml` です。
ここでパスの設定と、デプロイの設定をします。
まずは15行目辺りにある `url` `root` をいじります。例えばこんな感じ。

```yaml
# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://<gheのURL>/pages/<ユーザ名>
root: /pages/<ユーザ名>/
```

上記に出した例だと、

```yaml
# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://example.com/pages/kuma
root: /pages/kuma/
```

とか。

あとはファイルの後ろのほうにある `deploy` も編集する。こんなかんじ。

```yaml
# Deployment
## Docs: http://hexo.io/docs/deployment.html
deploy:
  type: github
  repo: http(s)://<gheのURL>/<ユーザ名>/<さっき作ったリポジトリ名>.git
  branch: master
  message: <メッセージ>
```

例えば、

```yaml
# Deployment
## Docs: http://hexo.io/docs/deployment.html
deploy:
  type: github
  repo: https://example.com/kuma/kuma.example.com.git
  branch: master
  message: Hexo deploy
```

こんな感じ。

##デプロイしてみる

ここまで終わったらデプロイしてみる。
デプロイも簡単で、 `hexo deploy -g` を実行するだけ！
しかし、途中でGHEへのログインが求められるので、ただ単に待ってるだけじゃいつまでたってもデプロイされないので注意！

#まとめ

もっとしっかり使っていきたいと思う。
また、例えば会社のエンジニアブログ的なものをやる場合、
GHEをステージング環境、github.comを本番環境、みたいにして使い分けてもいいかもしれない。
【Mac, 開発環境構築】MacにWeb開発環境を整える


## 前提

MacOS自体がUnix系であるので、Mac自体にApache, MySQLなどをインストールすることができます。
今回はMacOS自体のApacheを利用した、開発環境の構築方法を記述します。

## 環境情報

MacOSX Marvericks(10.9.5)
※ まだYosemiteにしてません、すいません。

## Apacheの設定

### ApacheでPHPの利用を有効化

	$ sudo su -	# rootユーザになります
	# cp /etc/apache2/httpd.conf /etc/apache2/httpd.conf.origin	# オリジナルのhttpd.confをバックアップ
	# vi /etc/apache2/httpd.conf
	・phpモジュールを読み込むように設定を変更
	- #LoadModule php5_module libexec/apache2/libphp5.so
	+ LoadModule php5_module libexec/apache2/libphp5.so
	
	・バーチャルホストの設定を有効化
	- #Include /private/etc/apache2/extra/httpd-vhosts.conf
	+ Include /private/etc/apache2/extra/httpd-vhosts.conf


	# /usr/sbin/apachectl start	# Apacheを起動

### VirtualHostの設定を追記

	# cp /etc/apache2/extra/httpd-vhosts.conf /etc/apache2/extra/httpd-vhosts.conf.origin 	# バーチャルホストの設定ファイルのオリジナルをバックアップ
	# vim /etc/apache2/extra/httpd-vhosts.conf	# バーチャルホストファイルの末尾に下記を追記

	+ <VirtualHost *:80>
	+     DocumentRoot "/Users/knife0125/Develop"
	+     ServerName local-develop.net
	+     ErrorLog "/private/var/log/apache2/Develop-error_log"
	+     CustomLog "/private/var/log/apache2/Develop-access_log" common
	+     DirectoryIndex index.php

	+     <Directory "Users/knife0125/Develop/">
	+         AllowOverride All
	+         order deny,allow
	+         allow from All
	+     </Directory>
	+ </VirtualHost>

### Apacheが参照するディレクトリの権限設定を変更

	# vim /etc/apache2/users/${USERNAME}.conf	# ${USERNAME}は各自自身のユーザ名に置き換えてください
	+ <Directory "/Users/${USERNAME}/Develop/">
	+     Options Indexes MultiViews
	+     AllowOverride None
	+     Order allow,deny
	+     Allow from all
	+ </Directory>

	# /usr/sbin/apachectl restart	# Apacheを再起動してバーチャルホストの設定を読み込ませる


### hostsファイルへ設定を追記

	# vim /etc/hosts	# hostsファイルの末尾に下記設定を追記
	+ 127.0.0.1	local-develop.net	# local-develp.netへのアクセスを127.0.0.1のIP(local IPアドレス)へ向けるように設定


### テストのファイルを作成して動作確認

	$ cd ~/Develop
	$ touch index.php
	$ vim index.php
	+ <?php
	+     echo phpinfo();
	
上記ファイルを作成して、ブラウザからlocal-develop.netへアクセスしてphpinfo()関数の結果が表示されていればOK。
BitbucketからHipchatへの通知が便利になったよ

これまでも連携機能はありました。
http://qiita.com/misopeso/items/ed075cafb5d86b509afc
![before.png](https://qiita-image-store.s3.amazonaws.com/0/25051/4845ddf6-e1df-3e5a-2079-9675f8005e9d.png)
一気にpushしたんですが、全てのコミットが表示されてるので長いですね。
コミットがpushされたという通知しかなく、プルリクエストや課題管理なにそれおいしいの状態。

# 使ってみる

リポジトリ・チームの設定からHipchat Integrationへ（Hipchat側のIntegration一覧からもできます）。
初めて使うときはIntegrationのインストールやアクセスの許可が必要です。
対象のリポジトリと通知先のルームを選択してAddをクリックしたら、お好みで通知項目の設定を。
![config.png](https://qiita-image-store.s3.amazonaws.com/0/25051/1f3183c5-2290-8153-6c90-7503d7a4185e.png)
以前の連携では設定項目なんてなかったので、この時点でちょっと感動ですね。

さて、例えばプルリクエストをマージするとこんな感じに。
![after.png](https://qiita-image-store.s3.amazonaws.com/0/25051/9835ad8f-a3dd-22e3-3fe0-66ff7428318c.png)
課題編集。
![issue.png](https://qiita-image-store.s3.amazonaws.com/0/25051/414079b8-7d31-3419-9929-ae708576685b.png)

# 新しくなった点

* 通知できる項目が増えた
    * プルリクエストの作成・コメント・マージ
    * 課題の作成・更新・コメント
    * コミットへのコメント
    * （ないものはApproveぐらい？）
* HerokuへのPOSTフックという安っぽさがなくなった
* APIv2になったのか、背景色がカラフルになり、アイコンも表示されるように
* 大量のコミットを一度にpush/mergeした時に省略されるように

なにより通知項目の追加がうれしいですね。というかこれまでが少なすぎ……。

# 参考

Use the HipChat integration - Bitbucket - Atlassian Documentation
https://confluence.atlassian.com/display/BITBUCKET/Use+the+HipChat+integration
Atlassian Summit 2014 Keynote
https://summit.atlassian.com/archives/2014/keynotes/confluence-and-hipchat-keynote
http://youtu.be/mz0MY3V58J8?t=12m49s

おまけ：Atlassian Summit 2014のキーノートを見たって話をブログにも書いた
http://d.hatena.ne.jp/unarist/20141024/1414154962
TestFlightのExternal Testersが利用可能になったので使ってみた

Internal Testersについては[こちらの記事](http://qiita.com/koogawa/items/6851669110aa522a088a)をご覧ください。

ずっとComing SoonだったExternal Testers機能ですが、ようやく今日から使えるようになりました！＼(^o^)／

さっそく使ってみたのでメモ。

## 外部テスターの登録

iTunes Connectにログインし、アプリの詳細画面を見ると「外部テスター」リンクが増えています。

![2014-10-24_2132.jpg](https://qiita-image-store.s3.amazonaws.com/0/8292/3a896b71-92a7-2fa6-d203-7b330746c649.jpeg)

(+)ボタンをクリックして、メールアドレス、性、名を入力します。

![スクリーンショット 2014-10-24 9.52.24.png](https://qiita-image-store.s3.amazonaws.com/0/8292/1cf96434-6167-f155-4315-40f544bc5fdb.png)

メッセージをよく読み、「追加」をクリックします。

![スクリーンショット 2014-10-24 9.51.41.png](https://qiita-image-store.s3.amazonaws.com/0/8292/389b72f5-9cdb-1c69-c893-54843e63b556.png)

## アプリをレビューに送信

「ビルド」画面に移動し、「ベータ版App Reviewへの送信」をクリックします。

![スクリーンショット 2014-10-24 9.57.27.png](https://qiita-image-store.s3.amazonaws.com/0/8292/5815c2d7-0508-76af-2e38-689a64f3c05f.png)

テスト対象（テストしてもらいたい機能など）、アプリの概要、フィードバック用のメールアドレス、マーケティングURLなどを入力し、「送信」を押します。

![スクリーンショット 2014-10-24 9.59.04.png](https://qiita-image-store.s3.amazonaws.com/0/8292/21cf2802-4065-79a7-e4bb-89898077710e.png)

すると、ステータスが **レビュー審査待ち** になります。

![スクリーンショット 2014-10-24 10.12.32.png](https://qiita-image-store.s3.amazonaws.com/0/8292/969ea8e4-c5d0-57c2-fe99-e0992b74f352.png)

現在も審査待ちなので、この後どうなるかはわかっていません。何か進捗があり次第、追記します。

ちなみに、1.4時間で審査が完了した人もいるようです。。

[https://twitter.com/mikeyusc/status/525471229990678529](https://twitter.com/mikeyusc/status/525471229990678529)

**2014.10.25追記**

無事、審査通過しました！

申請後、**17時間でIn Review、3時間後に審査通過**、という感じでした。通常の審査よりは早い印象ですね。


審査が完了すると「iTunes Connect: （アプリ名） has been approved for beta testing.」というタイトルのメールが届きます。

ステータスを見ると次のようになっていました。

![スクリーンショット 2014-10-25 9.14.54.png](https://qiita-image-store.s3.amazonaws.com/0/8292/8b5eed7d-c972-ff33-5cc5-c96675ee820b.png)

どうやら審査が完了すると自動的にテスターを招待するのではなく、手動で招待状を送付する必要があるようです。

## テスターを招待

「招待の送信」リンクをクリックし、招待状をテスターに送付します。

![スクリーンショット 2014-10-25 9.15.22.png](https://qiita-image-store.s3.amazonaws.com/0/8292/3a6f449e-1882-0493-7af5-affccbf17032.png)

その後はテスターによるテスト→開発者へのフィードバック→修正版をアップ、を繰り返すかたちになると思います。
MVC(MVVM) JS フレームワークの中でKnockoutJsを選んだ理由


数あるJS Frameworkの中でKnockoutを選んだ理由を紹介します。

# **つくりたかったもの**

ざっくりいうと、、、チームマネジメント用のタスク管理ツール。基本的なtodo機能が人に紐付いていて、マネージャーがそれを一括管理できる。大規模ってほどではないと思います。

DOMへの即時反映＋各々の環境でもリアルタイムに更新したい。リアルタイムはRails-Websocket使うとして・・その他のDOMの動き、通信は何で実装しよう、という感じ。


# **KnockoutJsを選んだ理由**

先にKnockoutを導入したかった理由を上げてみます。

 * （これはフレームワークを使いたかった理由）jQueryでDOMがめちゃくちゃになってよく泣いていたので、ビューをバインドできるMVがあるフレームワークを使いたかった。
 * 学習コストが低い。資料やチュートリアルが豊富。フレームワークをガッツリさわったことがないので最初にはちょうどいいと思った。
 * 機能がシンプルで、どんづまることがなさそう。
 * AngularJsと違って、けっこうJSチックに書ける(そりゃそうだ)。
 * 基本的なbindingなどが簡単に書ける。
 * jQueryも使って問題なさそう。基本的にルールが緩く、書きたいように書ける。
 * 機能が少ないというより、ライブラリを使えばいくらでも拡張可能。
 * 今回の開発規模が中規模だったのでちょうどいいと思った。



# **その他フレームワークへひとこと**


## AngularJs
なんちゃってで使うなら簡単だけど、恩恵をうけるほど使いこなすには学習コストが高い。

## BackboneJs
大規模向けで学習コストが高い。
ビューをガツガツいじる、て感じな印象がなかった。

## VueJs
楽そうではあったが、まだ資料が少ないと思った。フレームワークがでては消えていくご時世で、VueJsを選ぶのは怖かった(これはEmberJsなど他のフレームワークも同様)。




という感じで、今のところ調子いいです。
grunt-bower-installはもう非推奨らしいので


## grunt-wiredepをインストールする事にした。
まずは、 **grunt-bower-install** をアンインストール。

```shell-session
$ npm uninstall grunt-bower-install --save-dev
```

次に、 **grunt-wiredep** をインストール。

```shell-session
npm install grunt-wiredep --save-dev
```

## Gruntfile.jsの修正も忘れずにっ！

```
bowerInstall: {
    app: {
        src: ['<%= config.app %>/index.html'],
        exclude: ['bower_components/bootstrap/dist/js/bootstrap.js']
    }
},

// bowerInstallの代わりに grunt.registerTask()では、wiredepを使う様にする。
wiredep: {
    app: {
        src: ['<%= config.app %>/index.html'],
        exclude: ['bower_components/bootstrap/dist/js/bootstrap.js']
    }
},
```
R で GoogleMaps にプロットする

R で地図を書く方法はいくつかありますが，単にプロットしたいだけなら，Google Maps にプロットするのが楽そうです．

### インストール

`ggmap` パッケージ (http://cran.r-project.org/web/packages/ggmap/index.html) をインストール 

```r
install.packages('ggmap')
library(ggmap)
```

### マップ描画

中心座標を指定してマップオブジェクトを生成，描画します

```r
map <- get_map(c(139.6917, 35.68949))
ggmap(map)
```
![213db56cb364e21b28f602512db852d9.png](https://qiita-image-store.s3.amazonaws.com/0/8597/d44799a8-565a-6ae7-e551-10cce2fe5574.png)


### データをプロット

あらかじめ用意しておいた ↓ のような位置座標データをプロットしてみます

![bd840252b8f998ae3f88ec864a94d77a.png](https://qiita-image-store.s3.amazonaws.com/0/8597/3538237b-1180-aeb6-1247-b0cdd09f85de.png)

```r
locations <- read.csv('locations.csv')
ggmap(map) + geom_point(data=locations, aes(x=経度, y=緯度), color='red')
```

![326393f858be8dd504412e99eb02707c.png](https://qiita-image-store.s3.amazonaws.com/0/8597/7806f5fa-c074-6cbe-c5a4-42cd02675a47.png)

### 日本全体をプロット

```r
center <- geocode('kanazawa')
map <- get_map(c(center$lon, center$lat), zoom = 5, maptype = 'roadmap')
ggmap(map) + geom_point(data=locations, aes(x = geo_coordinates_1, y = geo_coordinates_0), color = 'red', size = 0.7)
```

`geocode()` 便利．

![4c0d8bba79ca10af9419bd3fa51ef8af.png](https://qiita-image-store.s3.amazonaws.com/0/8597/4cb0db06-b293-8b9f-c100-5dbba95b0ee2.png)

中心座標を金沢にしたら収まりが良かったので，日本の中心は金沢．
[KnockoutJs]foreachの中でdata-bindさせたvalueを取得


# 概要

簡単なtodo作成・削除ができるプログラム。todosをforeachさせていて、removeTodoするときにidをとりたい。todo自体は、公式tutorialを参考にしています(http://learn.knockoutjs.com/#/?tutorial=intro )。

```lang:view.html
<ul class="list-unstyled" data-bind="foreach: todos">
	<li class="clearfix" data-bind="value: id">
		<input data-bind="value: content" />
		<a href="#" data-bind="click: $root.removeTodo">Remove</a>
	</li>
</ul>

<form data-bind="submit: addTodo">
    <input data-bind="value: newTodoContent" />
    <button type="submit">Add Task</button>
</form>
```

# 調査

以下のviewmodel.jsで、①②③の実行結果を調べた。

```lang:viewmodel.js
function TodoViewModel() {
    var self = this;
    self.todos = ko.observableArray([]);
    self.newTodoContent = ko.observable();

    // 省略....

    self.removeTodo = function(todo) { 
        self.todos.destroy(todo) 
        console.log(ko.toJSON({ todo: todo.id })); // ①
        console.log(todo.id); // ②
        console.log(todo.id()); // ③
    }
}
```


## ① `console.log(ko.toJSON({ todo: todo.id }));` の結果

結果。

ただしこれはObjectではなく文字列になってしまっているよう。

```
{"todo":3} 
```

## ② `console.log(todo.id);` の結果

結果。

プロパティの値はオブジェクトになっていて、値の取得と設定は普通のプロパティのように行えません。そのままだと関数オブジェクトが返ってきて残念な結果になります(参考：http://blog.shibayan.jp/entry/20111215/1323875100 )。

```
function d(){if(0<
arguments.length)return d.Pa(c,arguments[0])&&(d.X(),c=arguments[0],d.W()),this;a.k.Jb(d);return c}
```

## ③ `console.log(todo.id());` の結果

結果。

そのままだと関数オブジェクトが返ってくるので、これが正解みたいです。

```
3
```
ちょっと便利なコマンド｜nameiでアクセス権を表示

あるファイルにアクセスするには、パスの途中のディレクトリ達にも、全てアクセス権（パーミッション）がなければならない。

いちいち ls -ld しても良いのだけれど、全部一括で表示できるコマンドがあるね。という小ネタ。

例えば `/home/testuser1/public_html/` に対して、「全ディレクトリに o+x が付いていること」を調べてみる。


# ls -ld を使う場合

```shell-session:lsコマンドの利用例
[testuser1@localhost ~]$ ls -ld / /home /home/testuser1 /home/testuser1/public_html
drwxr-xr-x. 17 root      root      4096 Oct 19 13:02 /
drwxr-xr-x.  4 root      root        36 Oct 24 20:28 /home
drwx-----x   3 testuser1 testuser1   97 Oct 24 20:34 /home/testuser1
drwxrwxr--   2 testuser1 testuser1   23 Oct 24 20:58 /home/testuser1/public_html
```

# namei を使う場合

util-linuxに含まれる namei というコマンドを使うと、こんな感じ。

```shell-session:nameiコマンドの利用例
[testuser1@localhost ~]$ namei -m /home/testuser1/public_html/
f: /home/testuser1/public_html/
 drwxr-xr-x /
 drwxr-xr-x home
 drwx-----x testuser1
 drwxrwxr-x public_html
```

わざわざパスを分解しなくても、一目瞭然で確認できた。
少し楽になった。:relaxed: 


### おまけ

途中に symbolic link を含む場合、インデントされ、わかりやすい表示になる。また `-x`オプションでマウントポイントを"D"表示にできる。

```shell-session:nameiコマンドの利用例2（symlink入り）
[root@localhost ~]# namei -m -x /home/testuser1/public_html
f: /home/testuser1/public_html
 Drwxr-xr-x /
 drwxr-xr-x home
 drwx------ testuser1
 lrwxrwxrwx public_html -> public_html.new
   drwxr-x--- public_html.new
```

ういやつじゃ。

※ 上記表示は、CentOS7 で実行した場合のもの。
Grunt で非同期タスクを調べてみたが・・・。

結論
====
まぁ、結論から言うとそらしょうがないけどなんだかなって感じです。 grunt-typescript 作ってるときは意識してなかったから多分ミラクルが起こってたのかと思われます。

で、Grunt のタスクで非同期タスク作ろうとしてあれっ？てなったから調べたって話です。

とりあえず、公式ドキュメントどおりにやってみる
------------------------------------------
http://gruntjs.com/creating-tasks

上を読むとどうやら、`this.async` 使えって書いてある。なので、下のように書いてみる。

```js
module.exports = function(grunt){
  grunt.registerTask("default", "非同期の確認", function(){
    var done = this.async();
  });
};
```

で、動かすとすぐ終わる。以下がコンソールの写し。予想では `done` 呼んでないからずーっと待機されると想像してました。想定外の結果。

```
user@machine /d/Work/TempSrc/gruntAsyncTest
$ grunt
Running "default" task

user@machine /d/Work/TempSrc/gruntAsyncTest
```

setTimeoutを仕掛けてみる
----------------------

ドキュメントでは大抵 `setTimeout` を仕掛けてるので同じように仕掛けてみる。

```js
module.exports = function(grunt){
  grunt.registerTask("default", "非同期の確認", function(){
    var done = this.async();
    setTimeout(function(){
      console.log("終わるよ!");
    }, 1000);
    console.log("仕掛けたよ！");
  });
};
```

動かしてみる。

```
user@machine /d/Work/TempSrc/gruntAsyncTest
$ grunt
Running "default" task
仕掛けたよ！
終わるよ!

user@machine /d/Work/TempSrc/gruntAsyncTest
```

おっ、`setTimeout` の完了を待った模様。予想では、待たずにそのまま最初と同じように終わると思ってた。ちなみに、`this.async` しないで、単純に流すと以下のようになる。

```
user@machine /d/Work/TempSrc/gruntAsyncTest
$ grunt
Running "default" task
仕掛けたよ！

Done, without errors.

user@machine /d/Work/TempSrc/gruntAsyncTest
```

"終わるよ！"ってメッセージが出て無い。で、よく見ると "Done, without errors." ってメッセージが出てる。今までは全く出て無かった。`this.async()` を戻して、 `setTimeout` の中で `done` 呼んでやると、ちゃんと "Done, without errors." ってメッセージが出るらしい。

Grunt 自体終わってる気がする
--------------------------
`this.async`して `done` せずに終わるとメッセージが出ないってことは Grunt は終わったと思ってない。と、思われる。でも、コンソール自体は終わる。ってことは、つまるところ node 側が処理が全部なくなったから終わりだね。って終わらしてるような気がする。ってことは Grunt は `this.async` 呼ばれても `done` を渡すだけで、待機とかはなにもしてないのでは。と思われる。

ってことで、中を見てみた。

https://github.com/gruntjs/grunt/blob/master/lib/util/task.js#L236
`async`が呼ばれたらフラグ立てて、`complete` を実行する関数を返してる。

https://github.com/gruntjs/grunt/blob/master/lib/util/task.js#L253
で、処理実行して終わった後に、フラグ確認して、フラグ立ってなかったら `complete` 実行するけど、フラグ立ってなかったら何もしない。

ってことで、やっぱりそのまま流れていって、 node 的には処理が全部なくなったから終わらせてる感じ。

んー、 grunt が内部的に `setTimeout` かなんかでくるくる回してフラグ確認してくれると使う側からはもっとわかりやすいんやけど、まぁ、パフォーマンスとかいろいろ考えると、何とも言えんとこやけど微妙な気がしないでもない。

クルクル回すとやっぱり終わらない
-----------------------------

ってことで、書いてみた。やっぱり終わらないっす。

```js
module.exports = function(grunt){
  grunt.registerTask("default", "非同期の確認", function(){
    var done = this.async(), 
        //クルクル回す処理
        wait = function(){
          setTimeout(function(){
            console.log("待ってます。");
            wait();
          }, 1000);
        };
      //クルクル開始
      wait();
      console.log("仕掛けたよ！");
  });
};
```

これコールスタック溜まりそう・・・。いや、 `setTimeout` の時点でいったん消えそうやから大丈夫か？
ScalaでJSONをエンコード・デコードしたい


spray-jsonを使ってエンコード・デコードする方法。

```scala:build.sbt
libraryDependencies ++= Seq(
    "io.spray"  %%  "spray-json" % "1.2.6"
)
```

```scala
    // ドメインオブジェクト
    case class Name(firstName: String, lastName: String)
    case class User(id: String, name: Name)

    // JSONのマッピングを定義する
    import spray.json._
    object MyJsonProtocol extends DefaultJsonProtocol {
      implicit val NameFormat = jsonFormat2(Name)
      implicit val UserFormat = jsonFormat2(User)
    }

    def jsonに変換する() = {
      import MyJsonProtocol._
      val user = User("alice", Name("Alice", "Brown"))
      val actualJson = user.toJson.compactPrint
      val expectedJson = """{"id":"alice","name":{"firstName":"Alice","lastName":"Brown"}}"""
      assert(actualJson == expectedJson)
    }

    def jsonから変換する() = {
      import MyJsonProtocol._
      val jsonData = """{"id":"alice","name":{"firstName":"Alice","lastName":"Brown"}}"""
      val actualUser = jsonData.parseJson.convertTo[User]
      val expectedUser = User("alice", Name("Alice", "Brown"))
      assert(actualUser == expectedUser)
    }

    jsonに変換する()
    jsonから変換する()
```
Azure SDK for PHPをComposerでインストールしようとすると404をくらう

oujiのが以前どこかで書いていた気がするが、見つからなかったので書く。


## なんで書いたの？

Microsoft AzureのCloud Services上で動くPHPを書くにはSDKが必要なんだけど、
公式ドキュメントでも、公式リポジトリのREADME.mdでもcomposerでのインストールが掲題の通りうまく行かないので書いた。

[Azure SDK for PHP をダウンロードする - Composer 経由でインストールする](http://azure.microsoft.com/ja-jp/documentation/articles/php-download-sdk/)

[azure-sdk-for-phpのGitリポジトリ](https://github.com/Azure/azure-sdk-for-php)


これらにあるComposer.jsonを使って

```php
php composer.phar install
```

しても「そんなパッケージねぇよ！」って言われちゃう


## Composerを使うなら、Packagistの情報を使ってインストールしよう

https://packagist.org/packages/microsoft/windowsazure

のdev-masterを使用することにした。
いくつかのpearパッケージに依存しているので下記のように書く。

```php:composer.json
{
    "require": {
        "microsoft/windowsazure": "dev-master",
        "pear-pear.php.net/http_request2": "*",
        "pear-pear.php.net/mail_mime": "*",
        "pear-pear.php.net/mail_mimedecode": "*"
    },
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear.php.net"
        }
    ]
}
```

composer.jsonがあるディレクトリで

```php
php composer.phar install
```

するとうまくいきました。

１点だけ補足。

2014/10/22時点でSDKのGithubリポジトリはプライベート設定のため、途中Username/Passwordの入力を求められる場合があります。
GithubのログインUsername/Passwordを入れてやればOK。
[iOS] 同じようにみえる文字が、[NSString isEqualToString:] で false になってしまう



# 編集履歴
* 20170410 原因

#問題
一見同じようにみえる2つの文字列（例：プ）が一致しない。

```Objective-C:Example
NSString*		str1		= @"プ";
NSString*		str2		= @"プ";
			
if([str1 isEqualToString:str2]) {
	NSLog(@"OK");
}else {
	NSLog(@"NG");
}

出力 => NG
```

#原因
* Unicode正規化形式である NFC と NFD による文字列なため
   * 例えば、日本語ファイル名のファイルを iOS 上においた際、ファイルシステム上では NFD。

#解決方法
NSString+Normalize.h/m などのカテゴリを作成し、どちらかに正規化する。

```Objective-C:NSString+Normalize.m
/**
 * "パ" to "ハ゜
 */
-(NSString*)noramlizeFormD {

	NSMutableString* _norstr = [NSMutableString stringWithString:self];
	CFStringNormalize((CFMutableStringRef)_norstr, kCFStringNormalizationFormD);

	return [NSString stringWithString:_norstr];
}
```

```Objective-C:Example
str = [str noramlizeFormD];
```

#参考
* [NSStringの文字列比較はisEqualToStringではなくてcompareメソッドがいいのか](http://iphone-dev.g.hatena.ne.jp/ktakayama/20130809/1376034733)
* [マックっぽい文字の対応](http://iphone-dev.g.hatena.ne.jp/ktakayama/20090113)
* [CoreDataで日本語検索が上手くいかない](http://sygnas.jp/2010/06/22/coredatapredicate/)
xcode6 + Autoresizing mask使用時のバグ

同僚( [ハッカドール](https://hackadoll.com) のiOSエンジニア) に聞いた話をメモっておく。

Xcode6 + autoresizing mask + UITableView でこんなバグがあるらしい
http://stackoverflow.com/questions/26230247/auto-resizing-issue-in-uitableview-in-xcode-6

![スクリーンショット 2014-10-24 19.47.48.png](https://qiita-image-store.s3.amazonaws.com/0/8399/91aa73df-93a0-afba-ebc2-dec41cf904c1.png)

StoryboardでUITableViewのCell上にこんな感じのUILableとAutoresizing maskを設定し、実行してみると・・・

![2c68af5cab38c64e7c628319b9fa9c47.png](https://qiita-image-store.s3.amazonaws.com/0/8399/1fd2ad50-cd68-841a-ed58-1987fc4fb3d0.png)

Autoresizing maskの設定を無視して縦横が意図せず伸びてしまう。

![ab80290e4a3d4ac5789e68484425f8d1.png](https://qiita-image-store.s3.amazonaws.com/0/8399/78e4fb10-4f82-6de2-e759-44969d662748.png)

view構造的にはこんな感じになってる。

このバグを回避するには、コード側でサイズ制御するか、storyboardのソースXMLを直接書き換えるとかしないと駄目っぽい。

**Autoresizing Maskはオワコン**ってことですかね？
ImageMagicでサイズのまちまちな画像を結合する際に背景を透過色にする

CSSスプライトを使うために、画像を一枚にまとめるのにImageMagicを使います。
（SASSでやるときもありますが。）

横幅がまちまちな画像を結合すると、余白部分ができますがそこが白色で透過されない事態に遭遇しました。
あんまりよろしくないので、余白部分の背景を透過する方法を探しました。
いろいろ探してやっと実行できたと思った数日後、
画像を再結合しなければならなくなって、散々調べたやり方をすっかり忘れてしまっていたので、メモ代わりに投稿しておきます。

```bash
convert -background "rgba(0,0,0,0)" -append *.png sprite.png
```

検索してもドンピシャな回答は出てこなくて困った。

``-background``は末尾ではエラーが出ます。
また、色指定をダブルクオテーションで括るのもミソかも。当たり前なんだろうけど。
mod_php だと .htaccess の SetEnv は環境変数にならない

なぜか今までまったく気づかなかった。

次のような `.htaccess` をドキュメントルートに置きます。

```.htaccess:.htaccess
SetEnv http_proxy http://192.0.2.123:8080
```

次のコードをドキュメントルートに置いて表示すると、コメントに記載した通りに出力されます。

```php
<?php
var_dump(getenv('http_proxy'));         // "http://192.0.2.123:8080"
var_dump(trim(`env|grep http_proxy`));  // ""

putenv('http_proxy=http://192.0.2.123:8080');

var_dump(getenv('http_proxy'));         // "http://192.0.2.123:8080"
var_dump(trim(`env|grep http_proxy`));  // "http_proxy=http://192.0.2.123:8080"
```

`putenv` より前の場合、`.htaccess` の `SetEnv` の値が `getenv` なら取得できるにも関わらず `/usr/bin/env` の結果に `http_proxy` が含まれません。

`putenv` の後の場合、`/usr/bin/env` の結果にも `http_proxy` が含まれます。

次のようなコードでも、１回目の `curl_exec` はプロキシを経由しませんが、２回目の `curl_exec` はプロキシを経由します。

```php
<?php
var_dump(getenv('http_proxy')); // "http://192.0.2.123:8080"

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.yahoo.co.jp/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
var_dump(curl_exec($ch));
curl_close($ch);

putenv('http_proxy=http://192.0.2.123:8080');

var_dump(getenv('http_proxy')); // "http://192.0.2.123:8080"

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.yahoo.co.jp/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
var_dump(curl_exec($ch));
curl_close($ch);
```

PHP の getenv は [getenv](http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/getenv.3.html) の単なるラッパーではなく、SAPI によって微妙に異なるようです。

[php-src/basic_functions.c at php-5.6.2 · php/php-src](https://github.com/php/php-src/blob/php-5.6.2/ext/standard/basic_functions.c#L3995 "php-src/basic_functions.c at php-5.6.2 · php/php-src")