OmniAICreator/Qiita-1.07M huggingface dataset:
そのセッションはどんな人？セッションの質（エンゲージメントセッション？）を見たいのー。Part1

藪から棒にセッションの質って何さ？という所。
以前から気になっていた事、「このセッションって有益なセッションなの？」というところ。

GAベースになりますが、セッションの内訳って色々出せますよね。
・デバイス情報？
・初めての訪問か？
・CVしたセッションか？
などなど。
サイト運営上、必要な情報がたっくさんつまってます。ありがたい。

#セッションの質とは？
セッション情報っていろいろ情報があるんですが、思うこと。
「ふらっと来た一見さん、見込み客さん、顧客の方、どれがどのセッションなの？」
という所。
勝手に命名してしまえば、エンゲージメントセッション（見込み客〜顧客との繋がりのセッション）って感じなのですかね。

エンゲージメントセッション、つまり
・新規訪問者から見込み客に変わるには、どこを見てるか？（近しいところはGAでもみれるが）
・見込み客になってる人が次にどの程度見てるのか？
・見込み客の訪問タイミングは？
・見込み客のチャネルは？
・顧客化までに見たページは？
等々見たい所はたくさんあります。
このあたりが知りたい所で実現できるのか？とモヤモヤしてます。
btobサイトを見ることが多いので、とくにこのあたり気になってます。

#解決策の考察
##1.簡易な方法
GAベースで話します。
btobであれば、ユーザー→ユーザーの環境→ネットワークを見てると
「この会社のこの人なのかな？」
というのがネットワークドメインから推測できます。
セグメントをいろいろ切ってみるとさらに絞りこめるので、もう少し推測ポイントが見つけらますし、どこ見たいのか？なんて事も取れます。
さらにいえば、ユーザーエクスプローラーなどを使えば、足跡的に見れるので行動が丸わかりです。
少し解決。

なんですが、もう少し質のようなものを感じ取りたいし、そうするには多数セグメントを作る事になり、結果的に手間が掛かりすぎる。


##2.GA UserID機能の実装
以前からGAではUserID機能ってのはあります。
　意外と知られていない Google Analytics の便利な機能 〜その１〜 「User ID機能」
　http://qiita.com/ssaita/items/ccdda4035fa9c9d595c0
便利な機能です。
作りかた次第ですが、USER-IDを使えばふらっと来た方、見込み客化、顧客化した方などの内訳が見れるようになります。

しかし、いかんせん紐付けが必要なので、ログイン行動が必要となります。
ECサイトでは、ログインを伴うものが多数を占める都合上、これは可能なところではあります。
しかし、btobサイトでそれをやるのはあまり現実的ではありません。。


##結論
当初の
「ふらっと来た一見さん、見込み客さん、顧客の方、どれがどのセッションなの？」
やっぱりできない。というのが結論。
正確には、調べ方が足りないってのはあるかもしれないけど、できません。

残念。








ですが、

#欲しかったのが出来ちゃった！
結論覆しますが、出来ちゃったんです。
無料でできる範囲でいろいろ調べてみたけど、やっぱりできない。
んじゃ有料では？という所。出来ちゃったんです。
時間かけてググってみるもんです。

当然ながら、開発が伴うものや制約はありつつもできました。
素敵プログラマーさんがいると心強い。






長くなるんで、ここらで。
続きは次回。
raspberry pi 3でSSH接続できない？

rasberry pi 3をセットアップし、SSH接続しようとしたがエラーとなる。

＊OSイメージは以下を使用
　　2016-11-25-raspbian-jessie-lite.zip

```
# ssh pi@172.31.10.104
ssh: connect to host 172.31.10.104 port 22: Connection refused
```
リリースノートを確認すると、11/25版で、SSHはデフォルト無効にされたらしい。

raspbianのリリースノート
[http://downloads.raspberrypi.org/raspbian/release_notes.txt](http://downloads.raspberrypi.org/raspbian/release_notes.txt)

```
2016-11-25:
  * SSH disabled by default; can be enabled by creating a file with name "ssh" in boot partition
　　　　：
```


記載の手順のとおり、ブートパーティションに"ssh"というファイルを作成すると、

```
# mount /dev/sde1 /tmp/cf
# touch /tmp/cf/ssh
```

SSH接続ができるようになった！！

```
# ssh pi@172.31.10.104
Could not create directory '/root/.ssh'.
The authenticity of host '172.31.10.104 (172.31.10.104)' can't be established.
RSA key fingerprint is fb:0b:9a:06:f1:6d:24:b8:56:1c:ac:1a:37:d4:f1:4f.
Are you sure you want to continue connecting (yes/no)?
```
aws-sdk-ruby を v1 から v2 にアップグレードする

### 本家

https://github.com/aws/aws-sdk-ruby/blob/master/MIGRATING.md

に書いています。

### が、

結構書いていないことが多かったので、書いておきます。
SQSとS3にフォーカスします。

### 本家にも書いていること

```rb
s3 = AWS::S3::Client.new # version 1
s3 = Aws::S3::Client.new # version 2

# version 1
s3 = AWS::S3.new

# version 2
s3 = Aws::S3::Resource.new

# version 1
s3.buckets['bucket-name'].objects['key'].delete

# version 2
s3.bucket('bucket-name').object('key').delete
```

設定系も変わっています。

```rb
# version 1
AWS.config({
  access_key_id: 'xxxxx',
  secret_access_key: 'xxxxxxx',
  region: 'ap-northeast-1'
})

# version 2
# config は hash になった
Aws.config.update({
  access_key_id: 'xxxxx',
  secret_access_key: 'xxxxxxx',
  region: 'ap-northeast-1'
})
```

### 書いていないこと(S3)

```rb
#--------------------------
# version 1
#--------------------------
bucket = AWS::S3.new.buckets['bucket-name']

s3object = bucket.objects['key']

# download
File.open('output', 'wb') do |f|
  s3object.read do |chunk|
    f.write(chunk)
  end
end

# data
data = s3object.read

# url
p bucket.url # "https://bucket-name.s3-ap-northeast-1.amazonaws.com"

# prefix 指定の一括削除
bucket.objects.with_prefix("prefix").delete_all

#--------------------------
# version 2
#--------------------------
bucket = Aws::S3::Resource.new.bucket('bucket-name') # Resouce ついて、bucket は単数形、[] => ()

s3object = bucket.object('key') # object は単数形、[] => ()

# download
File.open('output', 'wb') do |f|
  s3object.get do |chunk|
    f.write(chunk)
  end
end

# data
data = s3object.get.body.read

# url
p bucket.url # "http://bucket-name.s3.amazonaws.com/" 末尾にslashがつく

# prefix 指定の一括削除
bucket.objects({prefix: "prefix"}).batch_delete!

```


### 書いていないこと(SQS)

```rb
#--------------------------
# version 1
#--------------------------
sqs_queue = AWS::SQS.new.queues.named('queue_name')
sqs_queue.poll do |msg|
  # polling
  p msg.id
end


#--------------------------
# version 2
#--------------------------
client = Aws::SQS::Client.new
result = client.get_queue_url({ queue_name: 'queue_name' })
poller = Aws::SQS::QueuePoller.new(result.queue_url)

poller.poll do |msg|
  # polling
  p msg.message_id
end
```

もっといいやりかたがあるのかも。
ConoHaのお金のお話

Conoha Advent calendar 2016 〜6日目〜 

旧このはから新このはに移行する。


![無題.png](https://qiita-image-store.s3.amazonaws.com/0/101930/fbd094f3-0dd0-3d6c-57f9-5c9dc1785a38.png)

まず前提状況として旧このはにアカウントがあって、チャージが余ってしまってる
状態での移行の話です。

今回は648円を動かします。

ちなみに、物理的に鯖を新このはに移す系のことは、旧このはのイメージを取って
新このはに移動したりする話になりますが、ここでは旧このはのチャージしてある
お金をいかにして移行させるかのお話です。

ちなみに、私は初代このは時代から使っていまして、新型が出ても旧型のほうを使ってました。
理由は移行マンドクセ！！です。

ただ、ワードプレスとかをやるのにKUSANAGI環境凄そうだなーってことだけで軽率に
移行したくなったのでやりました。

でまずやること。

旧このはの環境を新このはに移行したら即座に旧このはのVPSを停止しませう。
そして停止しただけでは課金されっぱなしになるので、VPSを削除します。

そして、移行したい旨をサポートにメールします。詳しいやり方を教えてくれますが、
私の場合はこうでした。

まず、旧このはを止めて、（サーバー削除状態）にして1か月後に利用料金が確定
するのでそこまで待ちます（本来は日割りなのですぐに確定するはずなのですが、
そうでもなくて・・・・・）

旧このはの最終引き落としが終わると、残りのチャージが確認できます。

そこで、旧このはのIDと新このはのIDと一緒にチャージの移行を申し込みます。
これはサポートにメールするしかないようです。

そうすると手動で新このはのほうにチャージが移動します。

これで完成です。


![無題2.png](https://qiita-image-store.s3.amazonaws.com/0/101930/a2a7ee94-695e-d4ea-e6c7-9770e158db68.png)

見事に648円が動いてます。

ちなみに旧このはのIDは消えませんので普通にログインできます。
新しいSSDこのはに飽きたら旧このはに戻ってもいいのかもですね。

ちなみにクーポンが移行できるかどうかは試してません。

ということで、旧このはをご利用の皆様もサポートに頼めばチャージを動かして
もらえるので連絡してみてください。
（ちなみに私がやったときの話ですので、今はNGかもしれません。そこはご了承
ください）
SML#で型付きJSONがサポートされたらしいので試してみた

SML#のJSONサポートについては[[Ohori _et al._, ECOOP'16]](http://2016.ecoop.org/event/ecoop-2016-papers-a-calculus-with-partially-dynamic-records-for-typeful-manipulation-of-json-objects)に詳しく書かれているので，読んで試してみました．
今回はSML# 3.2.0を使用しました．

# パース
`json.smi`に定義されている`JSON`ストラクチャの`import`関数は，JSON文字列をパースして，型付きJSONを計算します．

```sml
val json = JSON.import "[1, 2]"
```

型付きJSONの値である`json`は`JSON.void JSON.dyn`という謎の型を持っていて，このままだと使えません．

# 使いやすい型に変換
`_json e as τ`という構文を使うことで，型`τ`に変換することができます．
型`τ`に変換可能かどうかは動的にチェックされます．

```sml
val list = _json JSON.import "[1, 2]" as int list;
val record = _json JSON.import "{\"foo\": 1, \"bar\": \"2\"}" as { foo: int, bar: string };

val heterogeneousList = _json JSON.import "[42, \"57\"]" as JSON.void JSON.dyn list;
val a = _json List.nth (heterogeneousList, 0) as int;
val b = _json List.nth (heterogeneousList, 1) as string;
```
heterogeneousなリストも扱うことができています．

# パターンマッチ
`_jsoncase e of jp1 => e1 | · · · | jpn => en`という構文を使うことで，型付きJSONの値に対してパターンマッチを行うことができます．

```sml
val heterogeneousList = _json JSON.import "[{\"pi\": 3.141592, \"grothendieck\": 57}, \"42\"]" as JSON.void JSON.dyn list;
val result = map (fn x => _jsoncase x of
                              {pi : real, grothendieck : int} => Real.toString pi ^ " " ^ Int.toString grothendieck
                            | str : string => str
                            | _ => "") 
                 heterogeneousList;
```

# まとめ
型の恩恵を受けつついい感じにJSONを処理できます．
とても良い．
コンサバエンジニアの3つの掟

### 一、動かざることナマケモノのごとし
言われるまでやるべからず
### 一、しゃべらざること囚人のごとし
手詰まりを他人に明かすべからず
### 一、打ち解けざること嫁姑のごとし
デザイナー・QAと仲良くするべからず
StoryBoardで作成したVIewControllerを参照する

#StoryBoardで作成したViewControllerをコード上で参照する

ModalでViewControllerを呼び出すときにNavigationbarが挟まっていると少しはまったのでメモ。
大枠はNavigationControllerを呼んで、TopのViewControllerを取得する。



![スクリーンショット 2016-12-05 19.19.44.png](https://qiita-image-store.s3.amazonaws.com/0/99711/c0bb836e-7c18-022f-961f-8ece24862225.png)


まずNavigationControllerの「Identity　-> StorybordID」をnavとしておく

コード上で参照

```swift:
let navView:UINavigationController =
self.storyboard!.instantiateViewController(withIdentifier: "nav") as! UINavigationController
```

その先のViewControllerを参照するには

```swift:
let TopView = navView.topViewController as! UIViewController
```

これでナビゲーションバー付きのViewControlerを扱える

遷移する場合はnavViewを指定。

```
self.present(navView as UIViewController, animated: true, completion:nil)
```
WordpressのURLから半角英数以外を取り除くフィルター

WordpressでURLにスラッグを使うように設定した場合、URLが

`http://www.ore-no-homepage.com/現場に混乱を招いた件について謝罪してください`

みたいになるの、色んな意味で苦痛なので、半角英数に絞りたいじゃないですか。
そういうときのためのフィルター書きましたんで、使ってください。`functions.php`とかにぶっこめば使えます。

```php
function generate_friendly_slug( $str )
{
  $slug = mb_convert_kana($str, 'as');//全角英数を半角に変換
  $slug = preg_replace('/[ ]/', '-', $slug);//半角スペースを、「-」に変換する
  $slug = preg_replace('/[^0-9a-zA-Z\-_]/', '', $slug);//半角英数以外の文字を省く
  if (!$slug) $slug = uniqid();//半角英数が含まれていない場合、ランダムな文字列を生成する
  return $slug;
}
add_filter('sanitize_title', 'generate_friendly_slug', 9);
```

すべてが全角だった場合は、ランダムな文字列に。

Before:
`http://www.ore-no-homepage.com/現場に混乱を招いた件について謝罪してください`
↓
After:
`http://www.ore-no-homepage.com/584540c50e36c`

一つでも英数文字が含まれる場合は、それがスラッグに。

Before:
`http://www.ore-no-homepage.com/私がFTPでソースをアップロードした件でしょうか？`
↓
After:
`http://www.ore-no-homepage.com/ftp`
MTUの設定


```:bash
ifconfig eth1 mtu 1370
```

Maximum Transmission Unit (MTU)は、ネットワークにおいて1回の転送（1フレーム）で送信できるデータの最大値を示す伝送単位のこと。 

恒久設定

```:bash
vi /etc/sysconfig/network-scripts/ifcfg-eth1
```

```:/etc/sysconfig/network-scripts/ifcfg-eth1
MTU=1370
```
【SceneKit】基本的な使い方

#この記事の概要
iOSアプリでゲームを作る場合、Unityでの開発が主流のようですがXcodeも似たようなインターフェースでの開発ができるようです。SceneKitの基本的な使い方をまとめがてら、AppleがWWDC2016で行ったデモンストレーションを解説したいと思います。

#SceneKitとは
3Dゲームを開発するためのフレームワークです。
Xcode自体にも3Dゲームを開発するためのUIが充実してきたようなので、当記事ではそちらも紹介しています。

#デモンストレーションの内容
簡単に言うと「ジェンガ」をシミュレートすることになります。
と言っても、ジェンガアプリを開発するわけではなく、あくまで「SceneKitを使って開発するとこんなことが簡単にできるよ」と言うデモンストレーションです。

#手順
大まかには以下のような作業を行なっていきます。
1. プロジェクト作成
2. シーンを作成
3. シーンに地面オブジェクトを配置
4. シーンに照明オブジェクトを配置
5. シーンにブロックオブジェクトを配置
6. オブジェクトに適切な物理法則を設定
7. カメラを配置

##

#考察
それなりの挙動をするデモンストレーションが15分くらいで作成できると、そのままコードも書いてiPhoneで動かしてみたくなりました。よくわからないし調べるのも面倒くさいので、できませんが。
Unityのようなアセットストアがあれば、iOSゲームアプリもXcodeで開発する人が増えるかもしれませんね。
単体テストおよび結合テストを作成・実施するときに気をつけたいこと

WithOne AdventCalendar 5日目の記事です。
今回は、ソフトウェアテストを実施する上で私が最近感じたことを書いていきます。

なお、私自身もまだ不慣れであるため、誤った内容を書いている可能性があります。
見つけた際はご指摘いただけると幸いです。

##ソフトウェアテストとは
既にご存知かもしれませんが改めて説明すると、コンピュータのプログラムから仕様には存在しない動作やバグを見つけ出す作業のことを指します。
一言で「ソフトウェアテスト」と言ってしまうと範囲が広すぎるので、今回は単体テストと結合テストに焦点を当ててお話しします。

##単体テストと結合テストの違い
一言に「単体テスト」や「結合テスト」と言われても、実際のところどういったテストがどちらに含まれるか、という点はIT業界に入りたての人にはわかりにくいかもしれません（実際、私自身も曖昧でした）。
なので、まずはここから整理していきましょう。

###単体テスト
まずは単体テストについてです。
単体テストは「UT（Unit Test）」とも呼ばれ、関数やメソッドなどの小さな単位で行うテストのことを指します。
このため、個々の画面や機能で実施される動作を確認することが主たる目的となります。

とはいえ、実際のプログラムとなると、画面や機能が複数存在する場合のほうが圧倒的に多くあるはずです。
それらの連携に関する部分は単体テストでは実施せず、後述の結合テストで行う内容となります。

テストケースについては、下記の観点で考えていきましょう。

- 画面上の表示におかしいところがないか
- リンクやボタンを押した時の動作はどうか
- データベースとの連携(登録、編集、削除)ができているか
- 表示されるメッセージが正しいか
- 想定外の動作をしていないか

単体テストでは基本的に、その画面内でできることはすべて確認する必要があります。

画面上の項目ばかりに気を取られ、データベースとの連携を見落としたり、検索パターンの検討をし忘れたりしないようにしましょう。

###結合テスト
次に結合テストについてです。
結合テストは「IT（Integration Test）」とも呼ばれ、単体テストが完了したプログラムを組み合わせて行うテストのことを指します。
なので、単体テストで確認したひとつの画面内で完結する内容については、省略することができます。

テストケースについては、下記の観点で考えていきましょう。

- 他の機能から必要な情報を取得できているか
- 他の機能で変更を加えたデータが反映されているか

結合テストでは、単体テストでは実施しなかった画面間および機能間の連携に問題がないかを中心に確認していきましょう。
個々の機能に問題がなくても、他の機能との連携で問題が発生する可能性もないとは言い切れません。


##テストケースを作る上で気をつけたいこと
テストケースを作る上で気をつけたいことは、なにも「実施するケースに間違いや漏れがないか」だけではありません。
ケースの意図を正確に伝えることもテストを実施する上で重要なので、以下の項目についても気をつけていきましょう。

#####表記のブレをなくす
ある同じ内容を異なる人に「説明せよ」と言っても、人によって説明の仕方はさまざまです。
文章も同じで、記載方法が変わると受け手の印象は変わるものです。
操作手順や期待結果など、似たような文言が多くなる部分については、作成する前に方向性を決めておくといいでしょう。

#####「誰が」「どこで」「何を」「どうする」「どうなる」をしっかりと表す
操作手順に「～される」と書かれていたり、期待結果に「～すること」なんて書かれていると、何となく違和感を覚えませんか？
また、操作する場所が明記されていないと、どの画面のどの部分なのかがわかりにくくなります。
なので、ケースを作成するときは「テストを実施する人は、その機能について全く知らない人なのかもしれない」と思いながら作ってみましょう。


##テストを実施する上で気をつけたいこと
テストケースができたら、あとはそれに沿って実施するだけ･･･！、ではありません。
何かしらのバグが見つかった場合は、それについてしっかりと報告する必要があります。
これについても、以下の項目には気をつけていきましょう。

#####バグの内容を「わかりやすく」報告する
ただ一言「表示されるメッセージが違う」なんて報告されたら、直す側も一から調べる必要があるので面倒です。
これもテストケースを作る時と同じく「どこで」「何を」「どうした」ときに出たものかを書いてみましょう。

#####見つけたバグには責任を持つ
何らかのバグを見つけた時、見つけたら終わりではありません。
しっかりと報告することはもちろん、直っているかを確認する必要があります。
発生したバグを管理している場合は、管理簿への起票はもちろん、修正結果の確認とその結果を管理簿に反映するところまでは責任をもって対応しましょう。

##終わりに
以上、ソフトウェアテストの中から単体テストと結合テストについて書いてきました。
作成したプログラムの品質に直結する重要な部分であるだけに、規模が大きくなればなるほど確認すべき項目もどんどん増えてしまいます。
しかし、大変かもしれませんが面倒だとは思わず取り組んでみましょう。
MessagePack形式のデータをMySQLに保存する方法

MessagePackとは、オブジェクトをシリアライズしたり、それを戻したりする事が出来るライブラリの一つです。
[MessagePack](http://msgpack.org/)

今回は、このMessagePackでpackしたデータをMySQL上にどうすれば保存出来るのか？を紹介したいと思います。
連想配列などをMessagePackを使ってシリアライズするコードは以下のようになります。

`$pack = msgpack_pack($value);`

上記の戻り値$packは、一見はただの文字列なので、あまり深く考えずに、text型のカラムに放り込めばいいんじゃないの？と思うんですが、それだと以下のようなMySQLのエラーになってしまいます。

`General error: 1366 Incorrect string value: ~省略~`

エラー内容で調べると、文字コードがutf8ではない場合等に発生するエラーらしいのですが、PHPのmb_detect_encoding()という関数で調べたら、文字コード自体はutf8と判断されている模様。

そもそも、別にtext型ではなくとも、保存して取り出して復元出来ればOK・・・。
という事で、text型ではなく、バイナリ型のカラムであれば保存可能です。
MySQLでバイナリを扱うカラムといえばbinary、varbinary、blobといくつかあるようですが、適切なサイズが設定されていないと、サイズ不足でエラーになります。
MessagePackでパックした後の文字列長が不定であれば、blob型がよいかと思います。

連想配列やstdClass型の情報をMessagePack形式にしてDBに保存しておけば、後で必要なときにDBから取り出して以下のコードで復元して使える事になります。

`$value = msgpack_unpack($pack);`

色々な情報を保存したいけど、別に検索条件に使うわけでもないし、一つ一つをテーブルにカラム追加していくのは面倒だな・・・的な情報は、個別のカラムに持たせるまでもなく、ひとまとめにして管理しておく事が可能になります。
[JAWS-UG CLI] EC2 #9 タグの作成

前提条件
========


EC2への権限
-----------

EC2に対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.24

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.19 Python/2.7.10 Darwin/15.6.0 botocore/1.4.76

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定:
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

結果(例):

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       ec2as_full-prjZ-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION


0.3. インスタンスIDの指定
-------------------------

既存のインスタンスに割り当てられているIPアドレスを確認します。

ここでは、10.192.0.8を割り当てられているインスタンスを選択します。

```bash:変数の設定:
EC2_PRIVATE_ADDR='10.192.0.8'
```

インスタンスIDを取得します。

```bash:コマンド:
EC2_INSTANCE_ID=$( \
        aws ec2 describe-instances \
          --filters Name=private-ip-address,Values=${EC2_PRIVATE_ADDR} \
          --query 'Reservations[].Instances[].InstanceId' \
          --output text \
) \
        && echo ${EC2_INSTANCE_ID}
```

結果(例):

      i-xxxxxxxxxxxxxxxxx


1. 事前作業
===========


1.1. タグキーの決定
-------------------

```bash:変数の設定:
EC2_TAG_KEY='Name'
```


1.2. タグ値の決定
-----------------

```bash:変数の設定:
EC2_TAG_VALUE="handsonInstance-$( date +%Y%m%d)" \
        && echo ${EC2_TAG_VALUE}
```


2. タグの作成
=============

```bash:変数の確認:
cat << ETX

        EC2_TAG_KEY:     ${EC2_TAG_KEY}
        EC2_TAG_VALUE:   ${EC2_TAG_VALUE}
        EC2_INSTANCE_ID: ${EC2_INSTANCE_ID}

ETX
```

```bash:コマンド:
aws ec2 create-tags \
        --resources ${EC2_INSTANCE_ID} \
        --tags "Key=${EC2_TAG_KEY},Value=${EC2_TAG_VALUE}"
```

結果(例):

      (戻り値なし)


3. 事後作業
===========


タグの確認
----------

```bash:コマンド:
aws ec2 describe-tags 
```

結果(例):

      {
        "Tags": [
          {
              "ResourceType": "instance",
              "ResourceId": "i-xxxxxxxxxxxxxxxxxx",
              "Value": "Name",
              "Key": "HandsonInstance-20161205"
          }
        ]
      }


完了
====
[JAWS-UG CLI] EC2 #8 UserDataの作成 (sample):


前提条件
========


0. 準備
=======


1. 事前作業
===========

```bash:変数の設定:
FILE_EC2_USERDATA='userdata.bash'
```


2. 作成
=======

```bash:コマンド:
cat << EOF > ${FILE_EC2_USERDATA}
#!/bin/bash
sudo yum -y update
sudo yum install -y httpd
sudo service httpd start
sudo chkconfig httpd on
EOF

cat ${FILE_EC2_USERDATA}
```


3. 事前作業
===========


完了
====
誕生日にやろう、ETロボコン2016個人的リフレクション

これは「[ETロボコン Advent Calendar 2016](http://qiita.com/advent-calendar/2016/etrobo)」12/5の記事です。

どうもみなさんおばんです、本部技術委員走行体の人です。今年は何と言ってもHackEVを世に出したことが大きかったですが、えぇと今からこの場で宣言しますと、来年度デベロッパークラスの走行体は変更ありません。EV3way-ETはまんまそのまんまです。HackEVは今年出す出すサギをしてしまったアームモーターマウントの補強はしますが、ほぼほぼそのまんまです。機能に関しては今年度ほぼ遊び尽くされた感もあり、優秀モデルを観て試して頂ければ来年度への準備もバッチリかと思いますが、このエントリーでは個人的なリフレクションをしたいと思います。
#HackEV誕生の背景
最終的に大きく変更されましたが、今年度のアドバンストは「ゴルフをしよう」というのが最初にありました。ボールを運んだり打ったりできる走行体。個人的にはコース上をボールが暴れるのは運営上どうかと思いまして、結果的には円柱で落ち着いたのは良かったと思います。あと、NXTrike→ETrikeVで採用したフロントステアリング機構ではなく、もっと制御難易度の低い走行体にしてほしいというオーダーがあったので、駆動系はEV3way-ETと全く同じにしました。
#(旧)EpsilonViper爆誕
フロントにアームを取り付けてカラーセンサーを可動式にするアイデアは最初期段階からありまして。僕はモーターをメインフレームにするので、この条件を満たすモーターの組み方は限られるため、車体前方は比較的サクッと完成しました。
問題はリアで、ETrikeV同様ボールキャスターを使った「EpsilonViper」と、タイヤキャスターを使った「EpsilonHopper」の2種類を試し、最終的には全国会議で決めました。ボールキャスターだと段差が乗り越えられないということでタイヤキャスターにしてほしいと依頼があって用意したんですが、Hopper、めっちゃ後ろ上方向に脚が伸びててですね、マジHopper。かわいくない。さらに構造上どうしても上下動が大きくなってしまうのでマジHopper。最終的にはEpsilonViperが次期走行体に採用されました。
#コードネーム「どすこい」に
走行体の名前、僕の中では完全「EpsilonVip3r」だったんですが、作成中の走行体を観て嫁が一言。

「なんか　**どすこい**　って感じ」

からコードネーム「イプシロン」がコードネーム「どすこい」に変化し、もうなんだか「どすこい」でいいじゃん「EpsilonVip3r」とか訳がわからないじゃん何か考えてもらってよ**嫁に**、ってなわけで考えてもらったんですが、「Yorikiri」とか「Wazamae」とか「Gaburiyoriのガブリー」とか「Hakkeyoi」とかなんか自分でも「もういっそ　どすこい　でいいじゃん」とか思うのをぐっとこらえて「HackEV」にしました。よかったよかった。
#謎のしっぽ
よく聞かれたんですが、しっぽはですね、もう走行体fix時点ではボールを打つ必要はなくて、完全飾りで作っていたんですけど、土壇場で【懸賞】の持ち運びにしっぽを使いたい、という話になりまして急遽構造をシンプルにして、【懸賞】本体も改造しました。はい、最初から【懸賞】を運ぶことを想定していました。ただ、僕はそんなリスキーなことをする人はいないだろうと思っていたんですけど、チャンピオンシップでも複数のチームがしっぽ懸賞を決めてまして、やはりETロボコン参加者はすごいと心から思いました。いや結構【懸賞】本体も走行体と同じくらい時間かけましたね作るの。
#新幹線停止
新幹線停止は昨年度からの僕の夢でした。超音波センサで衝立を検出して渡る、なんて正直スマートじゃないです。停止させて安全に踏破っすよやっぱ。それを可能にするために規約の文言も工夫しました。結構「新幹線停止させてもいいなら停止できますって明示したほうが良い」とも言われました。が、それは**断固拒否**ということで。
#ふにゃふにゃ問題
HackEVは挙動が不安定で、とにかく暴れます。わかってます。これに関しては、そりゃ急発進急制動させれば挙動が乱れて当然と思っていまして、上位チームさんはやはりこの辺きちんと対策されているようで、試走のときの走行体の挙動でそのチームの実力がわかるような気さえしました。ボールキャスター式で段差を乗り越えなければいけないという無茶振りに対応すべく、キャスターガードは付けていたんですが、レゴのボールキャスターはすぐ壊れるという前情報もあったので、わざとリアはペグがせん断するんじゃね？ってぐらいふにゃふにゃにしました。ただ、モーターマウント自体が破断するというのはちょっと正直想定外で、僕としてもご迷惑をおかけしました、と思っているのですが、あえてここではこう言わせて下さい：

**無茶すればどんな構造でも壊れます。**

でも、僕達としてはみなさんになるべく無茶して欲しいと思っている節があるので、ここは来年度対策版を出したいと思います。今年は出す出すサギですみませんでした←ここ一番の反省点
#M◯TL◯B
一番残念だったのはここかも、実は頑張って頑張ってM◯TL◯B系の環境でも参加できるように色を調整したりとかプラットフォーム周りの規定も整備しておいたんですけど... 
僕達としては、特定のプラットフォームに対して肩入れをするということはしませんので、M◯TL◯Bの問題はM◯TL◯Bさんで解決していただかないと、という感じになるのですが、やはりこの辺の柔軟性にまつわる部分がツールに依存する際の問題になっていくのかなぁと言うことぐらいしか言えません。がうあん。


そんな訳で、今日はこのへんで。多分少なくとももう一回ぐらいプラットフォームで書きます。
ソシャゲのサーバーサイドでif文と結合度を減らせるかもしれない設計

※本記事はあくまでゲームの内部設計に関する考察です。実際のゲームとは関係ありません。

## よくある光景
よくあるゲームのプレゼントボックスを考えます。

|アイテム名|取得理由|受け取り期限|
|:-----------------|:------------------|:------------------|
|薬草 × 10|ダンジョン4のクリア報酬です|あと100日|
|魔石|4日目のログインボーナスです|あと100日|
|10000ゴールド|6日目のログインボーナスです|あと99日|
|薬草 × 5|ダンジョン3のクリア報酬です|あと99日|
|5000ゴールド|3日目のログインボーナスです|あと96日|
|戦士キータ|1日目のログインボーナスです|あと93日|

このDBのスキーマはこんな感じでしょうか。
<img width="215" alt="スクリーンショット 2016-12-02 18.53.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/3147/ab32c6b0-003f-1719-1fab-953a45aab8e0.png">

item_type によってアイテムやお金等の区別をします。
仮にこうなっているものとします。

|item_type|内容|
|:-----|:-----|
|1|お金|
|2|アイテム|
|3|キャラ|
|4|魔石|

これを受け取る時(プレゼントボックスから手持ちに移す時)のコードはこうなるでしょうか。

```
def acquire_present(user, present):
  if present.item_type == 1:
    """お金を受け取る処理"""
  elif present.item_type == 2:
　  """アイテムを受け取る処理"""
  elif present.item_type == 3:
    """キャラを受け取る処理"""
  ...
  else:
     raise Exception()
```

if文地獄です。
しかもそれぞれの受け取り処理で色々やる可能性大です(手持ち確認とかログとか)。
そうなると acquire_present関数とそれぞれのデータクラスでがっちり結合度が高まります。

さらに今後のゲームの拡張によってitem_typeが増えればさらに長くなります。
長いif文と密結合はメンテナンス性がよろしくないのでなんとかしたいです。

## 受け取り処理の分離
そこでプレゼントの受け取り処理を委譲するクラスを考えます。

```
class AqruireDalegatorBase(object):
  """受け取り処理委譲ベースクラス"""
  @classmethod
  def acquire(user, present):
     raise NotImplementedError()
```

受け取りの共通インターフェースを定義しました。
継承してそれぞれの受け取り処理委譲クラスを実装します。

```
class MoneyAqruireDalegator(AqruireDalegatorBase):
　"""お金の受け取り処理委譲クラス"""
  @classmethod
  def acquire(user, present):
     user.add_money(present.item_quantity)

class ItemAqruireDalegator(AqruireDalegatorBase):
　"""アイテムの受け取り処理委譲クラス"""
  @classmethod
  def acquire(user, present):
     user.add_item(present.item_id, present.item_quantity)

... その他に続く
```

実際に受け取り関数に組み込んでみます。

```
def acquire_present(user, present):
  if present.type == 1:
    MoneyAqruireDalegator.acquire(user, present)
  elif present.type == 2:
    ItemAqruireDalegator.acquire(user, present)
  elif ...
```

それぞれのタイプごとの受け取るロジックを切り出したことで疎結合感が出てきました！

## 拡張も楽になるようにしてみる

でもまだif文が長くなるしタイプが追加される度にこの関数を修正しないといけないので、

```
DELEGATOR_MAP = {
  1: MoneyAqruireDalegator,
  2: ItemAqruireDalegator,
  ...
}
```

とタイプと委譲クラスのマッピングをします。

```
def acquire_present(user, present):
  delegator_class = DELEGATOR.get(present.item_type)
  delegator_class.acquire_present(user, present)
```

かなり短くなりました！
そしてこれでタイプが増えた場合でも、

0. AqruireDalegatorBaseを継承した受け取り委譲クラスを実装する
1. DELEGATOR_MAPに追加する

で拡張可能です。acquire_present 関数を修正する必要はありません！
テストも追加した委譲クラス分だけすればOKです！

## まとめ(?)
長いif文は不具合調査時も拡張時も厄介なので疎結合な感じになっていると現在と未来の人達に優しいですね！

(これはファサードパターンなのだろうか・・・？若干DIっぽい気もする)
ActiveRecordのログを取るgemを作りました。

HasLogsというActiveRecordのログを取るgemを作りました。
https://github.com/isuke/has_logs

**このgemはベータ版です。バグや破壊的な仕様変更があるかもしれません。**

## 動機

ActiveRecordのログを取るgemは[audited](https://github.com/collectiveidea/audited)や[paper_trail](https://github.com/airblade/paper_trail)などありますが、いずれもymlやjsonにシリアライズして保存しているので、ログの検索機能がほしいときに困りますよね。
そこで、ログテーブルにログを取るgemを作りました。

## Usage

articlesというテーブルのログを取るとして、以下のようなmigrationを書きます。

```rb
class CreateAllTables < ActiveRecord::Migration
  def self.up
    create_table(:articles) do |t|
      t.timestamps
    end

    create_table(:article_logs) do |t|
      t.integer :article_id, null: false
      t.string :title, null: false
      t.text :content
      t.boolean :public, null: false, default: true
      t.datetime :created_at
    end
    add_index :article_logs,  :article_id
    add_index :article_logs, [:article_id, :created_at], unique: true
  end
end
```

articlesテーブルが(timestamps以外)からっぽなのがポイントです。

次にModelを以下のようにします。

```rb
class Article < ActiveRecord::Base
  has_logs
end

class ArticleLog < ActiveRecord::Base
  act_as_log
end
```

使って見ましょう。

```
article = Article.create(title: 'test1', content: 'demo1', public: false)
article.attributes =   { title: 'test2', content: 'demo2', public: false } ; article.save!
article.attributes =   { title: 'test3', content: 'demo3', public: true  } ; article.save!

article.title
=> 'test3'

article.logs
=> [#<ArticleLog id: 1, article_id: 1, title: "test1", content: "demo1", created_at: "2015-01-04 03:36:51">,
 #<ArticleLog id: 2, article_id: 1, title: "test2", content: "demo2", created_at: "2015-01-04 03:36:51">,
 #<ArticleLog id: 3, article_id: 1, title: "test3", content: "demo3", created_at: "2015-01-04 03:36:51">]

article.oldest_log
=> #<ArticleLog id: 1, article_id: 1, title: "test1", content: "demo1", created_at: "2015-01-04 03:36:51">

article.latest_log
=> #<ArticleLog id: 3, article_id: 1, title: "test3", content: "demo3", created_at: "2015-01-04 03:36:51">

article.oldest_log.next
=> #<ArticleLog id: 2, article_id: 1, title: "test2", content: "demo2", created_at: "2015-01-04 03:36:51">

article.latest_log.prev
=> #<ArticleLog id: 2, article_id: 1, title: "test2", content: "demo2", created_at: "2015-01-04 03:36:51">
```

いい感じです。

DB上は以下のようになっています。

##### articles

| id | title |
|---:|-------|
| 1  | title |

##### article_logs

| id | article_id | title | content | public |
|---:|-----------:|-------|---------|-------:|
|   1|           1| test1 | demo1   |       0|
|   2|           1| test2 | demo2   |       0|
|   3|           1| test3 | demo3   |       1|


以上です。よかったら使ってみてください。
[JAWS-UG CLI] VPC #15 サブネットの属性変更 (パブリックIP)

前提条件
========


EC2への権限
-----------

EC2に対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.19 Python/2.7.10 Darwin/15.6.0 botocore/1.4.76

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


AWSアカウントの属性
-------------------

AWSアカウントがEC2-Classicに対応していないこと。

```bash:コマンド:
AWS_SUPPORT_PLATFORMS=$( \
         aws ec2 describe-account-attributes \
           --query 'AccountAttributes[?AttributeName == `supported-platforms`].AttributeValues[].AttributeValue' \
           --output text \
) && echo ${AWS_SUPPORT_PLATFORMS}
```

結果:

      VPC

注釈: 'VPC'の他に'EC2'が表示される場合、別のアカウントを作成もしくは
  利用し てください。


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定:
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

結果(例):

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       ec2as_full-prjZ-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION


0.3. 変数の初期化
-----------------

```bash:変数の設定
ARRAY_VPC_SUBNET_IDS=''
```


0.4. サブネットの指定
---------------------

```bash:変数の設定:
VPC_SUBNET_CIDR='10.192.0.0/24'
```

```bash:コマンド:
VPC_SUBNET_ID=$( \
        aws ec2 describe-subnets \
          --filters Name=cidrBlock,Values=${VPC_SUBNET_CIDR} \
          --query 'Subnets[].SubnetId' \
          --output text \
) \
        && echo ${VPC_SUBNET_ID}
```

結果(例):

      subnet-xxxxxxxx

```bash:変数の設定
ARRAY_VPC_SUBNET_IDS="${VPC_SUBNET_ID} ${ARRAY_VPC_SUBNET_IDS}" \
        && echo ${ARRAY_VPC_SUBNET_IDS}
```


1. 事前作業
===========

```bash:コマンド:
VPC_SUBNET_ATTR_MAP_PUBLIC_IP_ON_LAUNCH=$( \
        aws ec2 describe-subnets \
          --filters Name=cidrBlock,Values=${VPC_SUBNET_CIDR} \
          --query 'Subnets[].MapPublicIpOnLaunch' \
          --output text \
) \
        && echo ${VPC_SUBNET_ATTR_MAP_PUBLIC_IP_ON_LAUNCH}
```

結果(例):

      False


2. サブネットの属性変更
=======================

```bash:変数の確認:
cat << ETX

        VPC_SUBNET_ID: ${VPC_SUBNET_ID}

ETX
```

```bash:コマンド:
aws ec2 modify-subnet-attribute \
        --subnet-id ${VPC_SUBNET_ID} \
        --map-public-ip-on-launch
```

結果(例):

      (戻り値なし)


3. 事後作業
===========

```bash:コマンド:
VPC_SUBNET_ATTR_MAP_PUBLIC_IP_ON_LAUNCH=$( \
        aws ec2 describe-subnets \
          --filters Name=cidrBlock,Values=${VPC_SUBNET_CIDR} \
          --query 'Subnets[].MapPublicIpOnLaunch' \
          --output text \
) \
        && echo ${VPC_SUBNET_ATTR_MAP_PUBLIC_IP_ON_LAUNCH}
```

結果(例):

      True


完了
====
[JAWS-UG CLI] VPC #9 VPCの作成


前提条件
========


EC2への権限
-----------

EC2に対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.19 Python/2.7.10 Darwin/15.6.0 botocore/1.4.76

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


AWSアカウントの属性
-------------------

AWSアカウントがEC2-Classicに対応していないこと。

```bash:コマンド:
AWS_SUPPORT_PLATFORMS=$( \
         aws ec2 describe-account-attributes \
           --query 'AccountAttributes[?AttributeName == `supported-platforms`].AttributeValues[].AttributeValue' \
           --output text \
) && echo ${AWS_SUPPORT_PLATFORMS}
```

結果:

      VPC

注釈: 'VPC'の他に'EC2'が表示される場合、別のアカウントを作成もしくは
  利用し てください。


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定:
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認:
----------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

結果(例):

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       ec2as_full-prjZ-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION


1. 事前作業
===========


1.1. アドレスブロックを決める
-----------------------------

作成するVPCに割り当てるアドレスブロック(プライベート)を決めます。

まず、既に割り当てられているCIDRブロックを確認します。

```bash:コマンド:
aws ec2 describe-vpcs \
        --query 'Vpcs[].CidrBlock'
```

結果(例):

      [
        "172.31.0.0/16"
      ]

上記と重複しないアドレスを以下の範囲から選択します。

- プライベートIPアドレスの範囲

  - 10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
  - 172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
  - 192.168.0.0/16 (192.168.0.0 - 192.168.255.255)

今回は、10.192.0.0/16をVPCに割り当てます。

```bash:変数の設定:
VPC_CIDR='10.192.0.0/16'
```


2. VPC の作成
=============

```bash:変数の確認:
cat << ETX

        VPC_CIDR: ${VPC_CIDR}

ETX
```

```bash:コマンド:
aws ec2 create-vpc \
        --cidr-block ${VPC_CIDR}
```

結果(例):

      {
          "Vpc": {
              "InstanceTenancy": "default",
              "State": "pending",
              "VpcId": "vpc-XXXXXXXX",
              "CidrBlock": "10.192.0.0/16",
              "DhcpOptionsId": "dopt-XXXXXXXX"
          }
      }


3. 事後作業
===========

```bash:コマンド:
aws ec2 describe-vpcs \
        --filters Name=cidr,Values=${VPC_CIDR}
```

結果(例):

      {
        "Vpcs": [
          {
              "VpcId": "vpc-xxxxxxxx",
              "InstanceTenancy": "default",
              "State": "available",
              "DhcpOptionsId": "dopt-xxxxxxxx",
              "CidrBlock": "\ |VPC_CIDR|\ ",
              "IsDefault": false
          }
        ]
      }


完了
====
交差確率と組換確率

2つのマーカー間で平均1回交差(cross over)が起こる状況を考える。この状況において2つのマーカーについて組み換え(recombination)が起こる率は、2つのマーカー間での交差が奇数回起こることの合計になる。  

ポアソン分布の確率密度関数は

```math
P(X, \lambda) = \frac{\lambda^Xe^{-\lambda}}{X!}
```

なので、求める確率は

```math
\begin{align}
P_{odd} &= \sum_{X=1,3,5 \cdots}P(X,\lambda)
\frac{\lambda^1e^{-\lambda}}{1!} + \frac{\lambda^3e^{-\lambda}}{3!} + \frac{\lambda^xe^{-\lambda}}{5!} \cdots  \\
&=e^{-\lambda}(\lambda+\frac{\lambda^3}{3!}+\frac{\lambda^5}{5!} \cdots)
\end{align}
```

ここで、$e^\lambda$と$e^{-\lambda}$のマクローリン展開より

```math
\begin{align}
e^{\lambda} &= \frac{\lambda^0}{0!} + \frac{\lambda^1}{1!} + \frac{\lambda^2}{2!}+ \frac{\lambda^2}{3!}  \cdots\\
&= 1 + \lambda + \frac{\lambda^2}{2!}+ \frac{\lambda^3}{3!}  \cdots\\
\\
e^{-\lambda} &= \frac{(-\lambda)^0}{0!} + \frac{(-\lambda)^1}{1!} + \frac{(-\lambda)^2}{2!}+ \frac{(-\lambda)^2}{3!}  \cdots\\
&= 1 - \lambda + \frac{\lambda^2}{2!} - \frac{\lambda^3}{3!}  \cdots\\
\end{align}
```

差を取ると

$$
e^{\lambda} - e^{-\lambda} = 2\lambda  + 2\frac{\lambda^3}{3!} + 2\frac{\lambda^5}{5!}  \cdots\\
$$

両辺2で割って$e^{-\lambda}$をかけて

$$
e^{-\lambda}\frac{e^{\lambda} - e^{-\lambda}}{2} = e^{-\lambda}(\lambda  + \frac{\lambda^3}{3!} + \frac{\lambda^5}{5!}\cdots)\\
$$

$$
P_{odd} = \frac{1-e^{-2\lambda}}{2}
$$

Rで計算すると

```{R}
> oddPois <- function(x) (1-exp(-2*x))/2
> oddPois(1)
[1] 0.4323324
```
【Coldfusion】リストから余分なカンマを削除

リストから余分なカンマを削除するには
listToArrayで一旦配列に変換してarrayToListでリストに戻す

```cfm
<cfscript>
str = "abc,,,efg,gg,,,,";
WriteOutput(arrayToList(listToArray(str)));
// abc,efg,gg とカンマが取れる
</cfscript>
```
シングルトンのクラスのメンバ関数内で内部関数を定義する際の注意（追記あり）

**※ 下の方に追記があります**

シングルトンのクラスのメンバ関数の中に内部関数を定義する場合、
既に定義されてるかチェックしないと、再宣言でエラーになるので、
内部関数の宣言前に function_exists()　でチェックしましょう。

```php
class Singleton
{
    private static $instance;
    
    private function __construct()
    {
    }
    
    public static function getInstance()
    {
        if (!self::$instance) self::$instance = new Singleton;
        return self::$instance;
    }

    public function memberFunction()
    {
        // 内部関数を定義する場合は関数が定義されてないかチェック
        if (!function_exists('innerFunction')) {
            function innerFunction()
            {
                echo 'Hello';
            }
        }
        
        innerFunction();
    }
    
    final function __clone()
    {
        throw new \Exception('Clone is not allowed against' . get_class($this)); 
    }
}

class Test extends Singleton
{
}

$test = Test::getInstance();
$test->memberFunction();
$test->memberFunction();   // チェックしていないと、"PHP Fatal error:  Cannot redeclare innerFunction()"

```

というか内部関数はメンバ関数として宣言したほうが安心ですね。

#追記

コメント欄にて情報をいただいたのですが、
内部関数はクロージャとして定義すると関数定義がスコープの中に入るので、再定義にならずに済みそうです。

↓シンプルになり良いですね。

```php
class Singleton
{
    private static $instance;
    
    private function __construct()
    {
    }
    
    public static function getInstance()
    {
        if (!self::$instance) self::$instance = new Singleton;
        return self::$instance;
    }

    public function memberFunction()
    {
        // 内部関数を定義する場合は関数が定義されてないかチェック
        $innerFunction = function()
        {
            echo 'Hello';
        };
        
        $innerFunction();
    }
    
    final function __clone()
    {
        throw new \Exception('Clone is not allowed against' . get_class($this)); 
    }
}

class Test extends Singleton
{
}

$test = Test::getInstance();
$test->memberFunction();
$test->memberFunction();
```
dd-agentや各種インテグレーション関連に関連した問題のデバッグ方法(基礎知識編）

dd-agentをインストールした直後や新しくインテグレーションを追加した際に、メトリクスが送信できない状況が発生することがあります。こうした際にデバッグ方法を知っていると非常に便利です。今回2本立てで、dd-agentに関連したトラブルの簡単なデバッグ方法をまとめてみたい思います。


## dd-agentの構成要素
dd-agentは、下記の4つの要素から構成されています。
1. **Collector:** dd-agentにインストールされているintegrationの種類に基づいてメトリクスを収集します。
2. **Dogstatsd:** アプリのコードからわたれるカスタムメトリクスを集計用をするためのバックエンドサーバです。
3. **Forwarder:**　CollectorやDogstatsdから送信される情報を中継(bufferを含む)してDatadogのバックエンドに送信します。
4. **Supervisord:** 上記の3つのプロセスの起動を管理する[supervisor process](http://supervisord.org/)。


##### dd-agent内のコードとの対応:

| 構成機能名 | コード |
|--------|--------|
| **Collector** | [agnet.py](https://github.com/DataDog/dd-agent/blob/master/agent.py) |
| **Dogstatsd** | [dogstats.py](https://github.com/DataDog/dd-agent/blob/master/dogstatsd.py) |
| **Forwarder** | [ddagent.py](https://github.com/DataDog/dd-agent/blob/master/ddagent.py) |
| **Supervisord** | [supervisor process](http://supervisord.org/) |

＊実際のソースコードは、[次のgithubレポジトリ](https://github.com/DataDog/dd-agent)になります。

##### 構成図:

上記に紹介した構成要素を図に書くと以下の様になります。
(外側の四角がSupervisordに当たります)

![dd-agent構成図](https://help.datadoghq.com/hc/en-us/article_attachments/202186415/Agent_Architecture_-_B.jpg)


＊詳しくは、Datadogが提供している、[次のドキュメント](https://help.datadoghq.com/hc/en-us/articles/203034929-What-is-the-Datadog-Agent-What-resources-does-it-consume-)を参照してください。


## logの保存先
以下に、デバッグに必要な情報が記録されているログファイルの保存先をリスト化します。

#### Debian/Ubuntu

- /var/log/datadog/collector.log
- /var/log/datadog/dogstatsd.log
- /var/log/datadog/forwarder.log
- /var/log/datadog/supervisord.log (since 3.8.0)

#### RHEL/CentOS/Fedora/Amazon Linux

- /var/log/datadog/collector.log
- /var/log/datadog/dogstatsd.log
- /var/log/datadog/forwarder.log
- /var/log/supervisor/datadog-supervisord.log (since 3.8.0)

#### Windows

##### v3.9.1以降のdd-agent

**Windows Server 2008, Vistaと、それ以降のバージョン:**
- C:\ProgramData\Datadog\logs\collector.log
- C:\ProgramData\Datadog\logs\ddagent.log
- C:\ProgramData\Datadog\logs\dogstatsd.log
- C:\ProgramData\Datadog\logs\forwarder.log 

**Windows Server 2003, XPと以前のバージョン:** 
- c:\Documents and Settings\All Users\Application Data\Datadog\logs\collector.log
- c:\Documents and Settings\All Users\Application Data\Datadog\logs\ddagent.log
- c:\Documents and Settings\All Users\Application Data\Datadog\logs\dogstatsd.log
- c:\Documents and Settings\All Users\Application Data\Datadog\logs\forwarder.log

#### Mac OS X

- /var/log/datadog/collector.log
- /var/log/datadog/dogstatsd.log
- /var/log/datadog/forwarder.log
- /var/log/supervisor/datadog-supervisord.log (since 3.8.0)

#### SmartOS

- /opt/local/datadog/logs/supervisord/collector.log
- /opt/local/datadog/logs/supervisord/dogstatsd.log
- /opt/local/datadog/logs/supervisord/forwarder.log

#### ソースからagentをインストール (raspbianなど)

- ~/.datadog-agent/supervisord/logs/supervisord.log
- ~/.datadog-agent/supervisord/logs/collector.log
- ~/.datadog-agent/supervisord/logs/dogstatsd.log
- ~/.datadog-agent/supervisord/logs/forwarder.log


＊詳しくは、Datadogが提供している、[次のドキュメント](https://help.datadoghq.com/hc/en-us/articles/203037159-Log-Locations)を参照してください。
org.bukkit.plugin.InvalidPluginException: Cannot find main classの解決方法

minecraftのプラグイン開発で
`org.bukkit.plugin.InvalidPluginException: Cannot find main class`
というエラーに遭遇したので解決方法をメモ

# 結論

ymlファイルの**mainの記述の仕方**が間違っている

正しい状態

```yml:plugin.yml
name: SpigotTutorial
main: me.reyad.SpigotTutorial.Main
version: 0.0.1
author: ReyAD
```

ファイルのパス

![スクリーンショット 2016-12-05 13.28.33.png](https://qiita-image-store.s3.amazonaws.com/0/152986/e301933a-9c70-434e-9a73-ddd010c14cad.png)

# 間違った方法

間違った記述方法
`me.reyad.SpigotTutorial.Main`と書くべきところを`me.reyad.SpigotTutorial`という存在しないファイルを指定してしまっているのでエラーが発生する。

```yml:plugin.yml
name: SpigotTutorial
main: me.reyad.SpigotTutorial
version: 0.0.1
author: ReyAD
```

mainが間違っていると以下のようなエラーメッセージがサーバーログに出てくる

```
Could not load 'plugins/SpigotTutorial.jar' in folder 'plugins'
org.bukkit.plugin.InvalidPluginException: Cannot find main class `me.reyad.SpigotTutorial'
```

これによってプラグインが正しく読み込むことができない

# 参考
* [Creating a blank Spigot plugin in IntelliJIDEA | SpigotMC - High Performance Minecraft](https://www.spigotmc.org/wiki/creating-a-blank-spigot-plugin-in-intellijidea/)
* [Solved - [HELP] Java Bukkit Plugin - Cannot find main class - Could not load plugin | Bukkit Forums](https://bukkit.org/threads/help-java-bukkit-plugin-cannot-find-main-class-could-not-load-plugin.305737/)
pythonのソートで複数キーを指定するとき

list.sort()とsorted()の違いについては触れない。
ソートするキーの指定について、こういう感じに書けるっぽい。2.7、たぶん3以降も同じ。

```python2.7
from pprint import pprint

items = [
  {'id':2, 'book': {'type':'zassi', 'name': u'bbb' }},
  {'id':3, 'book': {'type':'manga', 'name': u'ccc' }},
  {'id':4, 'book': {'type':'zassi', 'name': u'ddd' }},
  {'id':1, 'book': {'type':'manga', 'name': u'aaa' }},
  {'id':5, 'book': {'type':'manga', 'name': u'eee' }},
]

# ソートキーが１つ
sorted_items = sorted(
  items,
  key = lambda x: x['id']
)
pprint(sorted_items)

#=>
#[{'book': {'name': u'aaa', 'type': 'manga'}, 'id': 1},
# {'book': {'name': u'bbb', 'type': 'zassi'}, 'id': 2},
# {'book': {'name': u'ccc', 'type': 'manga'}, 'id': 3},
# {'book': {'name': u'ddd', 'type': 'zassi'}, 'id': 4},
# {'book': {'name': u'eee', 'type': 'manga'}, 'id': 5}]


# ソートキーが２つ以上
sorted_items = sorted(
  items,
  key = lambda x: (x['book']['type'], x['id'])
)
pprint(sorted_items)

#=>
#[{'book': {'name': u'aaa', 'type': 'manga'}, 'id': 1},
# {'book': {'name': u'ccc', 'type': 'manga'}, 'id': 3},
# {'book': {'name': u'eee', 'type': 'manga'}, 'id': 5},
# {'book': {'name': u'bbb', 'type': 'zassi'}, 'id': 2},
# {'book': {'name': u'ddd', 'type': 'zassi'}, 'id': 4}]

```

<del>後書いてて気づいたのは、itemgetterとかattrgetterは同じ階層のしかみないっぽいので例えば ``[{book:{},shelf:{}}, {book:{},shelf:{}}]`` みたいな構造だとbookのこれとshelfのこれみたいなキーの指定はできないっぽい気がする。</del> -> これらは使わずにタプルで指定すればいける
初心者でもできた3Dプリント

ひょんな事から3Dプリンターを使ったモノ作りに関わりました。
兼ねてより興味はあったのですが、いざやってみるとわからない事だらけで苦労しました。

##そもそも何で作るの?
3Dデータの作成は、3D-CADソフトや3D-CGを使って作ります。
3D-CADと3D-CGソフトはそれぞれ得意な分野があるので、用途に応じて使用しましょう。

3D-CAD|3D-モデリング
---|---
寸法を明確に定義する必要があるものに適している。|人物など複雑な面を多用するものに適している。

##初心者にオススメのソフトは?
3D-CADでは[AUTOCAD](http://www.autodesk.co.jp/products/autocad/overview)(有料)が有名ですね。
3D-CGは様々なソフトがありますが、オープンソースのフリーウェア[Blender](https://blender.jp/)がチュートリアルも多く導入しやすいと思います。(操作はクセがありますが…)

ですが、高度な機能が多ければ多いほど何をすれば良いのかわかりません。
今回は精密な寸法が必要だったので、3D-CADソフトを探しました。
その中でズブの素人の私が一番わかりやすかったのが同じくAutodeskの[123D Design](http://www.123dapp.com/design)でした。

AUTOCADを作っているAutodeskの初心者向けソフトといった立ち位置なので、高度な操作はできませんが、板状の物、箱状の物、球状の物を組み合わせれば少し複雑な形も作れそうです。
パスを書いて立体物にする事も出来るので、Illustratorを使える人は何となく操作できると思います。
あと日本語に対応しています。

![cool-robot-123d-design-autodesk.jpg](https://qiita-image-store.s3.amazonaws.com/0/59171/d93ca59b-df51-885a-1adf-4dcb54b16eec.jpeg "cool-robot-123d-design-autodesk.jpg")


##123D Designで簡単にできる事
初心者にも使いやすかった主な機能は以下の通りです。


###オブジェクトをつくる
ブロック、球などをドラッグするだけで作れます。
![01_create.png](https://qiita-image-store.s3.amazonaws.com/0/59171/aed2b1c3-378e-5420-3fdd-bfe248b950b3.png "01_create.png")

###サイズを変更する
数値入力でサイズを変更できるのでしっかりと寸法を指定できます。
![02_size.png](https://qiita-image-store.s3.amazonaws.com/0/59171/158d6495-6aff-49a6-844f-790433aa29a9.png "02_size.png")


###位置を揃える
複数の要素を任意の位置で揃える事ができます。
![03_soroeru.png](https://qiita-image-store.s3.amazonaws.com/0/59171/3402366d-3d6f-6fb7-623e-0523d99d326e.png "03_soroeru.png")


###複数オブジェクトの結合・切除
複数のオブジェクトを1つにしたり、重なっている部分を取り除いたりできます。
![04_ana.png](https://qiita-image-store.s3.amazonaws.com/0/59171/3710608c-38d0-1070-85f7-32bf76eb2e70.png "04_ana.png")

###エッジを丸める
オブジェクトのエッジ部分を選択して数値を入力するだけで角丸になります。
![05_r.png](https://qiita-image-store.s3.amazonaws.com/0/59171/4003bdce-4da6-d22f-c8ac-f646fc37111b.png "05_r.png")

###面を押し出す
面を選択して引っ張ると面が押し出されます。
![06_oshidasi.png](https://qiita-image-store.s3.amazonaws.com/0/59171/f20ec2a7-5fe4-ae8b-20b2-acd08df6a09f.png "06_oshidasi.png")

これらの機能を組み合わせれば簡単に3Dデータが作れます。


##3Dプリントするには?
123D Designの作業ファイルは```.123dx```という形式で、そのままでは3Dプリントできません。
ですが、多くの3Dプリントサービスで対応しているSTL形式で書き出せるので、```左上のメニュー(ロゴのところです)```から```3Dでエクスポート```→```STL```で書き出して入稿ファイルにしましょう。



STL形式にしたら[DMM.make](http://make.dmm.com/)のような3Dプリントサービスに入稿しましょう。
DMM.makeのサイトには[123D Designでのデータの作り方](http://make.dmm.com/print/howtomake/cad/autodesk123ddesign/)も載っているので親切です。


##補足
3Dプリントでモノを作る時には素材選びも重要だと思いました。
素材によって得意なジャンル、再現度、強度などが違います。
作りたい形状と質感(とお財布事情)から最適な素材を選びましょう。
[DMM.make 選べる素材一覧](http://make.dmm.com/print/material/)

3Dプリントは難しそうなイメージですが、初心者の私でも何とか最後までこぎつけられました。
次は違う素材で複雑なものが作れたらもっと楽しそうです。
Mac で3270エミュレーターを使ってみる

##はじめに
会社で貸与されるパソコンのラインアップに従来のThinkPadの他にMacBook Airが追加され、選択肢が広がりました。２０年以上ThinkPadのトラックポイントに慣れ親しんだ身としては躊躇いもありましたが、新たな世界を体験をしてみようと思いMacBook Airを選ぶことにしました。

新しい使い勝手に心踊る一方で大きな疑念が一つ脳裏をよぎりました。それは、職業柄必要となるメインフレーム接続のための伝統的手段、そう、***3270エミュレーター***です。そもそも、3270エミュレーターは使用可能なのだろうか？無骨なキャラクター・ベースのユーザー・インターフェースである3270画面のスタイリッシュなMac画面への収まり具合はいかがなものだろうか？

調べてみると、

+ Brown University tn3270 X 

+ Mocha TN3270 for macOS

- PowerTerm InterConnect for Mac OS X

- ZOC terminal for Mac OS
…

等々、世の中にはMac OSで稼働する無償・有償の3270エミュレーターがそこそこ存在することが判明し、メインフレーム世界の広がりを少し感じたりします。当然と言えば当然ですが、接続はいずれもtn3270プロトコルを使用します。

本稿では、Brown University tn3270 Xの使い勝手、操作感について綴ります。その他のものについては追々、時間があれば。
##本編
まずはソフトウェアを[ Brown University tn3270 X ](https://www.macupdate.com/app/mac/8193/brown-university-tn3270-x)からダウンロードして入手します。起動はダウンロードしたdmgファイルをダブル・クリックするだけですので特筆することはありません。開いたフォルダーでtn3270 Xをクリックし、
![スクリーンショット 2016-12-02 15.43.15.png](https://qiita-image-store.s3.amazonaws.com/0/152195/4b25c476-30be-40b4-4da2-7fcf3e349337.png)
ポップアップに接続サーバー情報を入力します。
![スクリーンショット 2016-12-05 14.57.50.png](https://qiita-image-store.s3.amazonaws.com/0/152195/8477f1c6-3225-b377-efae-4f1366d8a3e7.png)

するとこんな（↓）感じで、
![スクリーンショット 2016-12-05 14.39.55.png](https://qiita-image-store.s3.amazonaws.com/0/152195/aaade0b0-323a-028b-35cb-b14da744de16.png)
違和感のない見栄えです。
![スクリーンショット 2016-12-05 15.33.16.png](https://qiita-image-store.s3.amazonaws.com/0/152195/92e49dea-c757-73fd-c5ea-14b73b2fce64.png)
ここで大きな壁に一つ遭遇します。この画面から先に操作を進めるにはclearキーを押下しなければならないのですが、MacBook Airにはそれがありません。そこでメニューバーをよく見るとFKeysが表示されており、ソフト・キーボード入力ができそうです。
![スクリーンショット 2016-12-01 19.03.01.png](https://qiita-image-store.s3.amazonaws.com/0/152195/8dcd0337-9efc-c1ea-91b6-11bfc0f4c533.png)
が、FKeysを選択しても空白のキーボード・マップが表示されるだけでキー・アサインが非表示のため、各キーの機能が判らない混沌とした状況です。
![スクリーンショット 2016-12-05 15.14.40.png](https://qiita-image-store.s3.amazonaws.com/0/152195/4f064370-07ea-1add-bb19-1f76f2fab6e0.png)

神経衰弱のような感覚のトライ＆エラーでキー・アサインを調べると、大体、
![スクリーンショット 2016-12-05 16.13.10.png](https://qiita-image-store.s3.amazonaws.com/0/152195/e3a21504-0655-c69d-623d-7ea09e21aa86.png)

ということが分かりました（空白部分についても追々、時間があれば）。その他キーボード操作で気がついたのは以下の通り。

|3270キーボード          |MacBook Airキーボード|備考|
|:--------------------:|:----------------------:|:---------|
|改行キー   |shift+return| - |
|エンター・キー|return| - |
|PF1~12キー|fn+F1~F12|但し、PF11はMac OSに先に処理されデスクトップ表示となる。前述のソフト・キーボードを使用するかMac OSレベルでのキーボード・カストマイズの必要あり|
##まとめ

使用感をまとめると、

- キーボード・マッピングが最大の関門でしょうか。職業柄、画面右スクロールは多用するので、前述のPF11のディフォルト動作はやや影響あり
- 日本語表示は確認していませんが、不可かと

といったところです。基盤系業務操作には、総じて**使えそう**かなという感触です。
Gulpで遭遇したエラーのメモ

# GulpUglifyError: unable to minify JavaScript
Gulpを走らせてたら、急になぞのエラーがでた。
いじっていたJSをコメントアウトして原因を追求したものの、よくわからない。
他のファイルは特にいじってない。なにがあった。

```
events.js:141
      throw er; // Unhandled 'error' event
      ^
GulpUglifyError: unable to minify JavaScript
```

結局bulidファイルのJSファイルを消してもう一度`gulp`したらなおった。
Macにphpbrewを入れる

コマンドログ

```
$ curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew
$ chmod +x phpbrew
$ mv phpbrew /usr/local/bin/phpbrew

$ phpbrew init

$ brew link curl --force
$ brew link icu4c --force
$ brew link libxml2 --force
$ brew link openssl --force
$ brew install libiconv libzip
$ xcode-select --install

$ phpbrew install 7.1.0 +default +dba +fpm +openssl +intl +iconv +gettext -- --with-iconv=`brew --prefix libiconv` --with-zlib-dir=`brew --prefix libzip`
$ phpbrew use php-7.1.0
```
bashでjqを使ってJSONのオブジェクトをループさせる


```json:map.json
{
  "key1": "val1",
  "key2": "val2"
}
```

```sh
#!/bin/bash

json=$(cat map.json)
for key in $(echo $json | jq -r keys[]); do
  echo "$key: $(echo $json | jq -r .$key)"
done
```

# 参考

[bashでjqを使ってJSONの配列をループさせる](http://qiita.com/ryo0301/items/2ac9d11f355f1cf52ea5)
Knockout.js + Material Design Lite で調べたこと

KnockoutJS+MDLでハイブリッドアプリ開発〜apkファイル作成にあたって調べたことメモ。

### 動的IDを振りたい
[Dynamic ID in KnockoutJS code block](http://stackoverflow.com/questions/12859917/dynamic-id-in-knockoutjs-code-block "Dynamic ID in KnockoutJS code block")

### MDLが動作しない
下記+mdl.jsの読み込みを末尾で行う。
[双方向データバインディングjsフレームワークでmaterial-design-liteを使用する方法](https://github.com/google/material-design-lite/issues/917 "双方向データバインディングjsフレームワークでmaterial-design-liteを使用する方法")

```JavaScript
var observer = new MutationObserver(function(mutations) {
        var upgrade = false;

        for (var i = 0; i < mutations.length; i++) {
            if (mutations[i].addedNodes.length > 0) {
                upgrade = true;
                break;
            } 
        }
        if (upgrade) {
            // If there is at least a new element, upgrade the DOM.
            // Note: upgrading elements one by one seems to insert bugs in MDL 
            window.componentHandler.upgradeDom();
        }
    });
observer.observe(document, {
    childList : true,
    subtree : true
});
```

[Material Design Lite with ReactJS](http://stackoverflow.com/questions/36809425/material-design-lite-with-reactjs-import-require-issue/36812136#36812136 "Material Design Lite with ReactJS")

### Knockout.jsとMDLを組み合わせたsample
[KnockoutJS and MDL](http://codepen.io/steamonimo/details/aOeOVg/ "KnockoutJS and MDL")

### Cordova 任意のemulatorを選択する
[Can I select a particular Android Device Emulator from AVD using Apache Cordova?](http://stackoverflow.com/questions/23777337/can-i-select-a-particular-android-device-emulator-from-avd-using-apache-cordova "Can I select a particular Android Device Emulator from AVD using Apache Cordova?")

```
cordova emulate --target=your-emulator android
```

### Cordova でAndroidリリース用apkの作成
[Cordova で Android リリースビルドして Google Play リリース用 apk を作る方法](http://phiary.me/cordova-android-release-build-apk-for-google-play/ "Cordova で Android リリースビルドして Google Play リリース用 apk を作る方法")

### zipalign のパス通す
[Android sdkのパスが通っているのに、zipalign not foundが発生する](http://qiita.com/m-sugawara/items/4b795a3f629098ceda91 "Android sdkのパスが通っているのに、zipalign not foundが発生する")

### apkファイルはDropbox使うとインストールが便利
[Dropboxを使って、Androidアプリをいとも簡単にインストールする方法](http://www.lifehacker.jp/2010/07/100728dropboxandroid.html "Dropboxを使って、Androidアプリをいとも簡単にインストールする方法")

### apkファイル インストール方法いろいろ
[apkファイルをAndroid端末（実機）にインストールする方法](http://phpjavascriptroom.com/?t=mobile&p=android_apk_install "apkファイルをAndroid端末（実機）にインストールする方法")