OmniAICreator/Qiita-1.07M huggingface dataset:
ActiveRecord 1対多、多対多の表現

パーフェクトRoRの勉強メモです。
Active Record周りの整理。どういうSQLが流れるか、常に意識していきたい。

#モデル

##一対多の関係

例）User(一)は複数のTicket(多)を持つ

![image](https://qiita-image-store.s3.amazonaws.com/0/20721/50b8af6b-2e01-fb21-7a74-d7aecb88b2a8.png)

```rb

class User << ActiveRecord::Base
  has_many :tickets
...

end

```

```rb

class Ticket << ActiveRecord::Base
  belongs_to :user
...

end

```

上記の設定を入れることで、Ticketモデルのuser_idが外部キーであり、Userモデルの idが参照キーであると、Active Recordが解釈してくれる。

```irb

irb(main):007:0> user = User.find(1)
  User Load (0.7ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1 LIMIT 1

#user(id=1)の持つ全チケットを表示
#where句でuser_id = 1が条件に入る　　　
irb(main):008:0> user.tickets
  Ticket Load (1.3ms)  SELECT `tickets`.* FROM `tickets`  WHERE `tickets`.`user_id` = 1



irb(main):023:0* ticket = Ticket.find(4)
  Ticket Load (0.4ms)  SELECT  `tickets`.* FROM `tickets`  WHERE `tickets`.`id` = 4 LIMIT 1

#ticket(id=4)を所有するユーザ(1つ)を表示
#where句でuser.id = ticket.user_id(1)が入る
irb(main):024:0> ticket.user
  User Load (0.7ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1 LIMIT 1

```

##多対多の関係
User(一)は複数のEventに参加している。
Event(一)には複数のUserが参加する。

![image](https://qiita-image-store.s3.amazonaws.com/0/20721/cb4e553e-f4ff-d957-a137-2e6354668de3.png)

これを、例えばeventsにuser_id, usersにevent_idを持たせた場合、同じUserが、違うevent_idで複数存在するなどの問題が起きる。

解決方法として、中間モデル(Ticket)で表現をする。

![image](https://qiita-image-store.s3.amazonaws.com/0/20721/7ef288d7-2436-196a-a50c-235e91f37617.png)


```rb
class User < ActiveRecord::Base
 has_many :tickets
 has_many :events, through: :tickets #EventとTicketをevent_idで内部結合し、ticket.user_id=ユーザIDで絞りこみしてEventへアクセス
...

end
```


```rb
class Event < ActiveRecord::Base
  has_many :tickets
  has_many :users, through: :tickets #UserとTicketをuser_idで内部結合し、ticket.event=id=イヴベントIDで絞り込みしてUserへアクセス
...

end
```

```rb

class Ticket < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
...

end
```

```irb
irb(main):001:0> u = User.find(1)
  User Load (0.3ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1 LIMIT 1
irb(main):002:0> u.events
  Event Load (0.5ms)  SELECT `events`.* FROM `events` INNER JOIN `tickets` ON `events`.`id` = `tickets`.`event_id` WHERE `tickets`.`user_id` = 1

irb(main):007:0* event=Event.find(1)
  Event Load (1.1ms)  SELECT  `events`.* FROM `events`  WHERE `events`.`id` = 1 LIMIT 1
irb(main):008:0> event.users
 User Load (0.4ms)  SELECT `users`.* FROM `users` INNER JOIN `tickets` ON `users`.`id` = `tickets`.`user_id` WHERE `tickets`.`event_id` = 1

```
Go言語でTwitterのStreamingAPIっぽいのを作る


# Server側

普通にhttpで受けて`http.ResponseWriter`をwriteしてすぐに`w.(http.Flusher)Flush()`するだけ。


```go:main_server.go
package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	http.HandleFunc("/", helloStreaming)
	http.ListenAndServe(":8000", nil)
}

func helloStreaming(w http.ResponseWriter, req *http.Request) {
	w.WriteHeader(200)

	// TODO: 5秒helloを繰り返す適当なコード
	for i := 0; i < 5; i++ {
		w.Write([]byte("hello\n"))
		w.(http.Flusher).Flush()
		time.Sleep(1 * time.Second)
	}

	fmt.Fprintf(w, "hello end\n")
}
```

# Client側

クライアント側は、さっきのサーバーへ普通に`http.Get()`して`http.Response.Body`に書き込みがあったら反応するようにするだけ。

```go:main_client.go
package main

import (
	"fmt"
	"net/http"
	"log"
	"bufio"
)

func main() {

	res, err := http.Get("http://localhost:8000")
	if err != nil {
		log.Fatalln(err)
	}

	scanner := bufio.NewScanner(res.Body)
	for scanner.Scan() {
		fmt.Println(string(scanner.Bytes()))
	}
}
```

# 実行結果

![952d4d28418b90aa35038a4fec3813d3.gif](https://qiita-image-store.s3.amazonaws.com/0/40887/698e0615-fb86-6e7f-7ec4-ff2982c41b6f.gif "952d4d28418b90aa35038a4fec3813d3.gif")


# おわり
色々エラーのハンドリングとか考えることは色々ありそうですが、思った以上に簡単に作れました。
ec2でpostfixを立てたらメール受信はできるけど送信ができない事案発生

ec2を立ち上げてpostfixとdovecotでメールサーバを立ち上げたんけど、ローカルのマックで
メール受信はできるんだけど、送信はできない現象がでて困っている。

でもmailコマンドで送信したらメールできるからmailアプリの設定の問題なのかなー？
CocoStudio2 for Macで書き出したcsbファイルをCocos2d-xで表示しタイムラインアニメーション再生をさせる

#Cocos2d-x3.3でCocoStudioのタイムラインアニメーションの再生方法
![alt](http://qiita-image-store.s3.amazonaws.com/0/42528/ee09bd9d-266e-463c-204a-9d50b8018128.png)

##\#include

```lang:xxx.h
#include "cocostudio/CocoStudio.h"
#include "cocosGUI.h"
using namespace cocostudio;
using namespace timeline;
```


##csbファイルを読み込み表示させる
```lang:xxx.cpp
Node *node = CSLoader::getInstance()->createNode( "UI/MainScene.csb" );
this->addChild( node );
```

##タイムラインアニメーションを再生する
```lang:xxx.cpp
ActionTimeline* action = CSLoader::createTimeline( "UI/MainScene.csb" );
node->runAction( action );
action->gotoFrameAndPlay( 5, false );
```

action->gotoFrameAndPlay( 5, false )の第1引数で開始するフレームインデックスの指定と第2引数でリピートの指定が可能。
node.js + CoffeeScriptでコールバックにエラーを渡す正しい方法

node.jsでコードを書いていると例外が出た時にコールバックにエラーを渡して呼び出し元に処理を任せるということがよくあります。

```coffee
# 呼び出した関数
  @error1:(val,cb)->
    console.log 'start'
    if val
      cb new Error('error Test')
    cb null,'ok'
    console.log 'end'

# 呼び出し元
ReturnTest.error1 1, (err,result)->
  if err
    console.log 'Error'
  else
    console.log result
```

しかしこの書き方では以下の結果になります。

```
start
Error
ok
end
```
コールバックを返した後もerror1メソッドの処理は続いてしまうので、`console.log 'end'`まで処理されてしまいます。  
ポイントは

- Errorオブジェクトをthrowすれば処理は止まる
- コールバックにErrorオブジェクトを渡しても処理は止まらない

ということです。

new Error()してもthrowしているわけじゃないので止まりません。



正解はこちらです。

```coffee
  @error2:(val,cb)->
    console.log 'start'
    if val
      return cb new Error('error Test')
    cb null,'ok'
    console.log 'end'
```

もしくは

```coffee
  @error2:(val,cb)->
    console.log 'start'
    if val
      cb new Error('error Test')
      return 
    cb null,'ok'
    console.log 'end'
```

明示的にreturnして関数内の処理を終えなければいけません。

ちなみに一行ifはこんな感じ。

```coffee
  @error3:(val,cb)->
    console.log 'start'
    return cb new Error('error Test') if val
    cb null,'ok'
    console.log 'end'
```

コールバック関数をラップしてコールバック関数を作る場合も多いと思いますので、スニペットを作っておくと便利です。  
以下はatomの場合です。
atomメニュー -> Open Your Snippetsから編集できます。

```
'.source.coffee':
  'throw err if err':
    'prefix': 'errt'
    'body': 'throw err if err'
  'cb err if err':
    'prefix': 'errc'
    'body': 'return cb err if err'
```
javaのメモリーリークを調査する

# VisualVMを使う

```
<jdkのインストールディレクトリ>/bin/jvisualvm
```

基本的にはこれでOK
ただし、AmazonLinux等を使っていてCUIのみの環境の場合、その場で使えない。
その場合は以下

# GCを起こす

```
$JAVA_HOME/bin/jcmd <プロセスID> GC.run
```

# Heapdumpを取得する

Java仮想マシーン(jvm)のメモリ上の内容を取得する。複数回取得します。

```
$JAVA_HOME/bin/jmap -dump:format=b,file=HogeHeapDmp <プロセスID>
```

バイナリ形式で HogeHeapDmpという名前のファイルが作成される

### jvmのプロセス IDの調べ方

```
$JAVA_HOME/bin/jps -l
```

# Threaddumpを取得する

```
$JAVA_HOME/bin/jstack <プロセスID> > HogeThreadDmp
```

HogeThreadDmpという名前のファイルが作成される。複数回取得します。


# 後は・・・

各ファイルをローカルに持ってきてvisualvmで「ファイル」->「読み込み」で読み込めます

Heapdmpは｢別のヒープダンプと比較」で増加しているインスタンスを調べる事が出来ます。
Threaddmpはずっと動いてたり(Runnable)、ロックの開放待ち状態のまま(waiting for monitor entry)
想定外のスレッドが無いか確認します。
Swiftでマテリアルデザインのボタン

# Material Button with Swift

冬季休暇の勝手宿題として使えそうなライブラリでも作ってみようと思いたち、第二弾として
AndroidのMaterialデザインで採用されているボタンのアニメーションをiOSで利用出来る様にSwiftで作成しました。

![material_button_cross.gif](https://qiita-image-store.s3.amazonaws.com/0/2846/9387fdcb-e4e1-ed5b-2679-371d2dc81618.gif)

![material_button_arrow.gif](https://qiita-image-store.s3.amazonaws.com/0/2846/2148b4a8-a5fd-e762-1525-62eaaa040190.gif)


## Ripple button usage

```Swift
self.rippleButton = RippleButton()
self.rippleButton.setTitle("Ripple Button", forState: UIControlState.Normal)
self.rippleButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
self.rippleButton.backgroundColor = UIColor(red: 240.0 / 255.0, green: 240.0 / 255.0, blue: 240.0 / 255.0, alpha: 1.0)
self.rippleButton.frame = CGRect(x: 30.0, y: 100.0, width: 200.0, height: 40.0)
self.view.addSubview(self.rippleButton)
```

## Animation button usage

```Swift
var materialButton1 =  MaterialButton(type: MaterialButtonType.ArrowLeft)
materialButton1.delegate = self
self.navigationItem.leftBarButtonItem = materialButton1

var materialButton2 =  MaterialButton(type: MaterialButtonType.ArrowRight)
materialButton2.delegate = self
self.navigationItem.rightBarButtonItem = materialButton2
```

| MaterialButtonType |
|--------------------|
| Cross              |
| ArrowLeft          |
| ArrowRight         |

ソースコードは[こちら](https://github.com/fromkk/SwiftMaterialButton)です
centos7 に elasticsearch 導入


## jdk をインストールします。
oracle のサイトから以下をDLしてきます。

jdk-8u25-linux-x64.rpm

```
sudo rpm -ivh jdk-8u25-linux-x64.rpm
```

```
java -version
```

```
$ java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
```

無事インストールされました。

## elasticsearch をインストールします。
http://www.elasticsearch.org/overview/elkdownloads/
こちらは公式から tar を落としてきます。

tar 解凍後

```
cd elasticsearch-1.4.2
./bin/elasticsearch
```

```
[2014-12-30 00:28:43,765][INFO ][node                     ] [Everett Thomas] version[1.4.2], pid[28778], build[927caff/2014-12-16T14:11:12Z]
[2014-12-30 00:28:43,765][INFO ][node                     ] [Everett Thomas] initializing ...
[2014-12-30 00:28:43,770][INFO ][plugins                  ] [Everett Thomas] loaded [], sites []
[2014-12-30 00:28:49,100][INFO ][node                     ] [Everett Thomas] initialized
[2014-12-30 00:28:49,100][INFO ][node                     ] [Everett Thomas] starting ...
[2014-12-30 00:28:49,520][INFO ][transport                ] [Everett Thomas] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.0.2.15:9300]}
[2014-12-30 00:28:49,708][INFO ][discovery                ] [Everett Thomas] elasticsearch/dsBywZVwSZ2dsd786xcNSA
[2014-12-30 00:28:53,633][INFO ][cluster.service          ] [Everett Thomas] new_master [Everett Thomas][dsBywZVwSZ2dsd786xcNSA][localhost.localdomain][inet[/10.0.2.15:9300]], reason: zen-disco-join (elected_as_master)
[2014-12-30 00:28:53,659][INFO ][http                     ] [Everett Thomas] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/10.0.2.15:9200]}
[2014-12-30 00:28:53,660][INFO ][node                     ] [Everett Thomas] started
[2014-12-30 00:28:53,710][INFO ][gateway                  ] [Everett Thomas] recovered [0] indices into cluster_state
```

起動したようです。
コマンドを叩いて確認します。

```
curl -X GET http://localhost:9200/
```

```
{
  "status" : 200,
  "name" : "Everett Thomas",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}
```

成功しました。

以上です。
VagrantとChef-Soloのセットアップ


## 環境

1. MacOSX Mavericks
2. Vagrant最新版（現時点では1.7.1）をインストール済み
3. Virtual Box最新版をインストール済み
4. 下記のディレクトリ構成を想定

```
project/
	chef/
	vagrant/
		www/
``` 

## 下準備

### Rubyのセットアップ

rbenvでインストールしておく。
Berkshelfを使いたい場合はRubyバージョン2.0.0以上でないとGemのバージョンの関係から面倒。

[Homebrewのインストールとrbenvのインストール Mac編](http://qiita.com/issobero/items/e0443b79da117ed48294#rbenv%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB "Homebrewのインストールとrbenvのインストール Mac編")

### Bundlerのセットアップ

Chef-SoloだけではなくGemの管理をするために必須。

```bash
gem install bundler
```

## Chef/Knife-soloのセットアップ

Bundlerを使ってインストールを行う。

### Gemfileの作成

```bash
bundle init
```

### Gemfileの編集

```ruby
source "https://rubygems.org"

gem "chef"
gem "knife-solo"
```

### インストール

```bash
bundle install --path vendor/bundle
```

#### --path引数について

`--path` 引数によりカレントディレクトリの `vendor/bundle` ディレクトリにGemをインストールする。

### Chefリポジトリのセットアップ

Chefのリポジトリを作成。
`project/chef` をリポジトリとして指定。

```bash
bundle exec knife solo init ./chef
```

## Vagrantのとりあえずの設定

Vagrantファイルを生成。
ここからは `project/vagrant` ディレクトリで実行。

```bash
vagrant init
```

生成されたVagrantfileを下記のように編集。

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.ssh.insert_key = false
  config.vm.box = "chef/centos-6.5"
  config.vm.network :private_network, ip: "192.168.33.10"
  config.vm.synced_folder "./www", "/var/www"
end
```

### Insecure Private Keyの有効化

Vagrant 1.7.0以上のみ。
これをしないと仮想マシン毎にPrivate Keyが生成されてしまうため、後述するSSHの設定が共通化できない。

```ruby
config.ssh.insert_key = false
```

### 利用するboxの設定

とりあえずCentOS 6.5。
BOXは事前に追加しておくこと。

```ruby
config.vm.box = "chef/centos-6.5"
```

### ネットワーク

ホストマシンからのみアクセスを許可する。

```ruby
config.vm.network :private_network, ip: "192.168.33.10"
```

### ホストとの共有ディレクトリ設定

```ruby
config.vm.synced_folder "./www", "/var/www"
```

ホスト側のディレクトリ `project/vagrant/www` は最初に作成しておかないとエラーが発生。
ゲスト側のディレクトリは再帰的に生成される模様。

## Vagrant起動

とりあえず仮想環境を起動。

```bash
vagrant up
```

### SSHの設定
`vagrant ssh` ではなく通常のsshで仮想環境に接続できるように。

```vim:~/.ssh/config
Host 192.168.33.*
	User				vagrant
	IdentityFile		~/.vagrant.d/insecure_private_key
	IdentitiesOnly		yes
```

Vagrantfileに `config.ssh.insert_key = false` が設定されていないと、IdentityFileが仮想マシン毎に異なるので、上記だけでは接続出来なくなるので注意。

### SSHで接続確認

```bash
ssh 192.168.33.10
```

接続かくにん！よかった

## Knife-Soloの実行

`project/chef` ディレクトリに移動。

```bash
bundle exec knife solo prepare 192.168.33.10
```

これで仮想環境にChef-soloがインストールされ、`project/chef/nodes/192.168.33.10.json` が自動生成される。

- - -

CookbookやRecipeの制作は次。
UITableView.tableHeaderViewとUITableView.tableFooterViewとAutolayoutの関係

   Autolayoutを使ったヘッダー、フッタービューについて、translatesAutoresizingMaskIntoConstraintsをNOにして設定するとレイアウトが崩れる事があります。
 
 translatesAutoresizingMaskIntoConstraintsをYESにしてAutoresizingをエミュレートする制約を入れた方がいいでしょう。
nagiosの状態変更をIRCに通知(nagircbot)

```bash:
apt-get install -y inspircd weechat
```

* znc 後で調べてみよう。

## ircd

```diff:/etc/default/inspircd
- #INSPIRCD_ENABLED=0
+ INSPIRCD_ENABLED=1
```

```diff:/etc/inspircd/inspircd.conf
- <bind address="127.0.0.1" port="6667" type="clients">
+ <bind address="0.0.0.0" port="6667" type="clients">
```

```bash:
/etc/init.d/inspircd restart
```

* /var/log/inspircd.log

### 認証

* [Annotated Configuration - InspIRCd](https://wiki.inspircd.org/Annotated_Configuration)

```diff:/etc/inspircd/inspircd.conf
+<oper name="users"
+      password="Foal0tha"
+      host="*"
+      type="NetAdmin">
```

* 任意のユーザ名 : Foal0tha で接続ができるようになる。

## weechat

[IRC - weechat のススメ（導入〜設定） - Qiita](http://qiita.com/taketin/items/dd91ba59dceda96c94aa)を参考に以下実施

`weechat-curses`

* buffer切り替え
  * Alt+up,down

```bash:
/server add rpi localhost/6667
/connect rpi
/join #memo

/save

/close #memo
/disconnect rpi
/server del rpi
```


## nagiosをIRCボットに参加させる

[【CentOS】nagiosの通知をIRCに吐く - Studio3104::BLOG.new](http://studio3104.hatenablog.com/entry/2011/12/07/163216)

```bash:
apt-get install -y nagircbot
```

```diff:/etc/default/nagircbot
- ENABLE=no
+ ENABLE=yes

- SERVER=irc.example.com:6667
+ SERVER=localhost:6667

- CHANNEL='#mychannel'
+ CHANNEL='#nagios'

- OPTIONS=
+ OPTIONS="-S -C"
```

![スクリーンショット 2014-12-30 14.54.38.png](https://qiita-image-store.s3.amazonaws.com/0/25728/b122283d-3786-6226-8280-5adbfd0e78ca.png)


> -i     check interval (in seconds - default 60)

60秒周期でbotがチェックしてくれます。

> -S

これがないと`CRIT`を通知しなかった。

> -C

色付けしたメッセージをIRCに投稿してくれます。
uploadされた写真をリサイズする方法


#目的：
　formを使いuploadされた写真をrevel側で受け取り、その後リサイズする方法
#環境：
Mac 10.10.1
go version 1.3.1
revel
#実装内容：
　formのinputから写真をuploadする。その後revel側で受け取りDecodeする。そのごresizeした写真を書き出すまでを実装する。resizeに関してはrevel及び標準パッケージではなくnfntのライブラリーを使わせていただく
#参考文献
https://github.com/nfnt/resize
http://tt-house.com/2014/07/golang-image-resize-onmemory.html
非常にわかりやすい説明とサンプルがあり大変助かりました。
ありがとうございます。
#ソースコードと説明：
まずはformから写真データを受け取ります。一部抜粋なので適宜内容は変更願います。

```photo.html
<label><strong>Photo Image</strong></label>
<input id="uploadImage" type="file" name="image">
```

次にencodeし、resizeして書き出すところまでします。

```photo.go
func (c *Shop) BytesDataOfImage(data *os.File){
	var img image.Image
	var err error

	// make decode image data
	img, _, err = image.Decode(data)
	c.errorHandler(err)

	resizedimg := resize.Resize(680, 0, img, resize.Lanczos3)

	// make bytes data
	buf := new(bytes.Buffer)
	err = jpeg.Encode(buf, resizedimg, nil)
	out, err := os.Create("resizedTest.jpg")
	c.errorHandler(err)
	defer out.Close()
}
```

　resize.Resizeでサイズを指定しencodeしたimgを加工します。resize.Lanczos3は圧縮する際のアルゴリズムです。詳しくはGithubご参照ください。モアレが結構発生しているので縦線なんかは偽色が発生するかも？
　resize後のデータはjpegにencodeし別名で保存しています。非常に簡単にできました。
Ubuntu14.04でホスト名を変更する


Ubuntu14.04でホスト名を変更した時の手順メモ。

## 1. /etc/hostnameの編集
/etc/hostnameに変更したいホスト名をエディタ等で書く

```
$ sudo vim /etc/hostname
```

## 2. /etc/hostsの編集
/etc/hostsで、現在のホスト名が書かれている箇所を変更したいホスト名に修正する

```
$ sudo vim /etc/hosts
```

## 3. 再起動
rebootする

```
$ sudo reboot
```

再ログイン後、ホスト名が変わっている

※ 参考
- [Debian/Ubuntu でインストール後にホスト名を変更する方法 - tatsuyaoiw.hatenablog.com](http://tatsuyaoiw.hatenablog.com/entry/2012/07/13/003954)
- [Linux:ホスト名の変更方法 | サイト運営の私的メモ](http://mymemo.weby117.com/develop/linux-hostname.html)
私的 Raspberry Pi活用案

## 注意点

> E: Unable to synchronize mmap - msync (5: Input/output error)

apt-getで大量にパッケージをインストールして書き込みすぎるとerrorになるので、インストールが終わったら書き込みしなくてもすむように心がける。

## 案

* IRCサーバ
  * nagios3 + nagircbot
* Asterisk
* proxy
* sshd + portforwarding
* ダイナミックDNS更新
* Samba
  * プリントサーバ
  * 外付けDVDドライブの共有
  * よくインストールするファイルの置き場
* wikitten + Apache
* TFTPサーバ
* 定点カメラ (motion)
* なにかしら定期的にチェックする君を仕込む
* 滅多に実行しないがどこかで使えるようにしておきたいものを入れておく。

## 管理ツールとして

* virt-manager (+ vncserver)
* expect + (telnet or ssh)でネットワーク機器管理

## USBメモリをつかう

USB-HDDだと電力が足りないので。

* rsyslog
  * `/var/log/` を USBメモリに逃す。
* torrentクライアント
  * USBメモリに読み取り・書き込みするように設定。
* リポジトリのミラーサイト構築


## とりあえず

```bash:
dpkg-reconfigure tzdata
apt-get install -y vim screen ack-grep w3m wget nkf build-essential telnet
apt-get install -y sudo git tig etckeeper
apt-get install -y postfix
apt-get install -y nagios3 nagios3-cgi
```

```bash:filtering
wget -o bt_level1.p2p.gz http://list.iblocklist.com/?list=bt_level1
gzip -d bt_level1.p2p.gz
```

* [nagios3を入れてみた - Qiita](http://qiita.com/tukiyo3/items/ab29b2ff47d00a88a444)
Compass

Compassをインストール

`$ sudo gem install compass`

`$ compass -v`でcompassのバージョンを確認する

`$ compass create test`でtestというプロジェクトを作成する。

```
$ cd test
$ tree -L 2
.
├── config.rb
├── sass
│   ├── ie.scss
│   ├── print.scss
│   └── screen.scss
└── stylesheets
    ├── ie.css
    ├── print.css
    └── screen.css

2 directories, 7 files
```
多倍精度整数の確率的素数判定

## 動機
現代のコンピューターで $2^{64} = 18446744073709551616$ を超える様な巨大な数に対して素数かどうかを判定する際に試し割りやエラトステネスの篩を実行する事は現実的に不可能なので [Miller-Rabin の確率的素数判定](http://ja.wikipedia.org/wiki/ミラー-ラビン素数判定法)の実装を紹介する.
多倍精度整数の基本的な実装は以下より.
[多倍精度整数の基礎 ( 四則演算編 )](http://qiita.com/marionette-of-u/items/f27ba0c5b03bbb8b87d8)
[多倍精度整数の基礎 ( Karatsuba乗算編 )](http://qiita.com/marionette-of-u/items/ec1a47e4b7701de75b63)
[多倍精度整数の基礎 ( Karatsuba除算編 )](http://qiita.com/marionette-of-u/items/42aa765d17662ecce0f7)

## 実装
```cpp
// Miller Rabin's Primality Test.
static bool miller_rabins_test(const integer &n, std::size_t s){
    static std::mt19937 g(0xABABABABu);
    integer a, m = n - 2;
    for(std::size_t i = 0; i < s; ++i){
        if(witness(m.random(g) + 1, n)){
            return false;
        }
    }
    return true;
}

static bool witness(const integer &a, const integer &n){
    integer b = n - 1, d = 1, x, t;
    for(int i = static_cast<int>(b.bit_num()) - 1; i >= 0; --i){
        x = d;
        d = (d * d) % n;
        if(d == 1 && x != 1 && x != b){
            return true;
        }
        t = b >> static_cast<UInt>(i);
        if(t > 0 && t.data[0] % 2 == 1){
            d = (d * a) % n;
        }
    }
    return d != 1;
}

// Random Number
template<class Generator>
integer random(Generator &g) const{
    std::size_t s = g() % data.size() + 1;
    integer x;
    x.data.resize(s);
    for(std::size_t i = 0; i < s - 1; ++i){
        x.data[i] = g() & base_mask;
    }
    if(s == data.size()){
        x.data.back() = g() % data.back();
    }
    x.normalize_data_size();
    return x;
}
```

### 実行してみる
実装した `miller_rabins_test` 関数の第一引数には判定したい数を, 第二引数には何度判定を繰り返すかを指定する.

```cpp
int main(){
    multi_precision::integer<> a("1111111111111111111111"), b("11111111111111111111111");
    std::cout << multi_precision::integer<>::miller_rabins_test(a, 64) << std::endl;
    std::cout << multi_precision::integer<>::miller_rabins_test(b, 64) << std::endl;

    return 0;
}
```

```
is_prime[1111111111111111111111] = false
is_prime[11111111111111111111111] = true
```

## 全体像
[marionette-of-u  / integer.hpp](https://gist.github.com/marionette-of-u/ad3f26594f48ab7deb61)

## 参考
アルゴリズムイントロダクション第 1 版, 33.8節.
MongoDBから読み出したDataをModelにマッピングする方法


#目的：
　使用しているMongoDBからデータを引き出して、Modelにマッピングする
#環境：
Mac 10.10.1
go version 1.3.1
revel
MongoDB
#実装内容：
　MongoDBからDataを引き出し終了した時点を想定する。つまりbsonデータが手元にある状態。このデータをJSON形式に変換します。次にJSON形式のDATAをModelにmappingします。mappingしたデータをRender引数で渡してhtmlのTableで表示するまでを実装します。
#ソースコードと解説：
 bsonデータが複数入っている配列を想定します。配列内の各要素をobjとして、objを引数にする関数を定義します。

```jsonserializer.go

package controllers

import (
	"AirNavigator/app/models"
	"encoding/json"
)

type JSONSerializer struct {
	err  error
	data []byte
}

func (c *JSONSerializer) encoding(entity interface{}) []byte {
	var err error
	var data []byte

	data, err = json.Marshal(entity)
	c.errHandler(err)

	return data
}

func (c *JSONSerializer) MappingToShop(entity interface{}) *models.Shop {
	var shop *models.Shop

	c.err = json.Unmarshal(c.encoding(entity), &shop)
	c.errHandler(c.err)

	return shop
}

func (c *JSONSerializer) errHandler(err error) {
	if err != nil {
		panic(err)
	}
}
```
　ERRORハンドリング用と中間処理結果を保持するようにbufferとしてdataを持っています。encoding関数はbsonデータを引数として受け取りjson.MarshalでJSONデータに変換します。
　次にMappingToShop関数はJSONデータをShopモデルにマッピングしていきます。この時json.Unmarshalを使います。Mappingするときに重要なのはShop Model自体にMapping用Tagをつけておくことです。私は以下のようにTagをつけました。

```shop.go
type Shop struct {
	Name      string   `bson:"name" json:"name"`
	Terminal  string   `bson:"terminal" json:"terminal"`
	Floor     int      `bson:"floor" json:"floor"`
	Comment   string   `bson:"comment" json:"comment"`
	Keyword   string   `bson:"keyword" json:"keyword"`
	ImageURL  string   `bson:"imageurl" json:"imageurl"`
	uuid      string   `bson:"uuid" json:"uuid"`
	update    string   `bson:"update" json:"update"`
	Keywords  []string `bson:"keywords" json:"keywords"`
	ImageURLs []string `bson:"imageurls" json:"imageurls"`
	Airport   *Airport
}
```
意地悪に、入れ子でかつ、配列を持つModelですがなんの問題もなくMappingすることができました。
プライベートyumリポジトリの作成

## Install
```bash
$ yum -y install createrepo
$ yum -y install --enablerepo=epel repoview
```

## Setup

```bash
$ mkdir amzn/RPMS/2014.09
# amzn/RPMS/2014.09 へ作成したRPMを置く
$ createrepo amzn/RPMS/2014.09
```

## Build

```bash
$ repoview --title="Private binary package for Amazon Linux" \
   --url="<private url>/amzn/RPMS/2014.09" \
   ./amzn/RPMS/2014.09/
$ tree -I '*.html|*.rpm' amzn/RPMS/x86_64/
amzn/RPMS/x86_64/
├── repodata
│   ├── 099b49f620f4f7a54ec082303e93d6b3a21364dbe1acaa7c51f0c34643f0b657-primary.xml.gz
│   ├── 11812ceb52190748d0bc191d1c6bf62e3590439938bb77612a09ea001c8da5f7-primary.sqlite.bz2
│   ├── 219bee792ce44c7128bff6ee7f0d62bfc9575f41d2808f8d1c587d739e937543-filelists.xml.gz
│   ├── 4ade99f9fc01966e8eaa8cd6e192470a4492d32aa68cc484ad230b793dace4e0-filelists.xml.gz
│   ├── 555cb5c8976145f92541f68d2c6d124a595ebe7056bf99e382b55ace29f039ec-filelists.sqlite.bz2
│   ├── 6556d255f7fbc62ae724e766ab8dd7fdeef3b740f56217a15d7bf45c6025ea73-primary.sqlite.bz2
│   ├── 74e65497632d24e2017cd6ad0d01a4ad3b4f980d2cf84206db45933ace86e1bd-other.xml.gz
│   ├── 9173d0b3970896d99527f420281a0f79db350eec459b044dab77514f16233065-other.sqlite.bz2
│   ├── 977b7bf8f3f4f138676f3ce54ff8d2edc1cfaa672f2c7b9dabecfdcc660c0393-other.sqlite.bz2
│   ├── aa48c1ffea66fe0ac929fc05b4b735f3b902d18171e88c8c46db05e8246ab4bc-other.xml.gz
│   ├── b4eea0f3be57d7b5c428c8878a3ff2d755c83124830e91f541f6a961145bdd9f-filelists.sqlite.bz2
│   ├── d09fc3f385fc7d095bc7ca3b61f500e0ac552bced386ff1140cbe89453b80e38-primary.xml.gz
│   └── repomd.xml
└── repoview
    ├── latest-feed.xml
    ├── layout
    │   └── repostyle.css
    └── state.sqlite
```

```repoview/``` 以下に静的なHTMLが作成されるのでブラウザから参照可能になるます。

## How to use

```bash
$ cat /etc/yum.repos.d/private.repo 
[private]
name=Private binary package - $basearch
baseurl=<private url>/amzn/RPMS/2014.09
enabled=0
gpgcheck=0
```
※ GPGKeyを作成していないのはよろしくないです
Go + Revel環境でCSVファイルをOPENして内容を表示する


#目的：
　Revel+Goで事前に準備したCSVファイルをOPENして、内容を選択リスト形式で表示する

#環境：
Mac 10.10.1
go version 1.3.1
revel

#実装内容：
　標準パッケージを利用して、CSVファイルをOPENします。得られたDataをそのままRenderの引数として渡します。その後html内でルーチンで処理しています。共通性が高い関数なので個別でcontrollerとして実装しました。

#ソースコード

```csvreader.go
package controllers

import (
	"encoding/csv"
	"io"
	"log"
	"os"
)

type CsvReader struct {
	IATACode []string // airport iata code
	ICAOCode []string // airport icao code
	JPname   []string // japanease name
	ENname   []string // english name
}

func (c *CsvReader) failOnError(err error) {
	if err != nil {
		log.Fatal("Error", err)
	}
}

func (c *CsvReader) OpenCSV(filePath string) {
	file, err := os.Open(filePath)
	c.failOnError(err)
	defer file.Close()
	reader := csv.NewReader(file)

	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else {
			c.failOnError(err)
		}

		// --- Update read csv data
		c.IATACode = append(c.IATACode, record[IATA])
		c.ICAOCode = append(c.ICAOCode, record[ICAO])
		c.JPname = append(c.JPname, record[JPname])
		c.ENname = append(c.ENname, record[ENname])
	}
}
```

　ERRORハンドラーを実装して、返り値として得られるerrを一括処理させています。
とりあえずErrorをLogに出すだけなので復帰までは実装していません。
　次に、展開するCSVファイルのfilepathを引数にするOpenCSVを定義します。defer file.Close()は忘れないように！！
　forループの中でCSVファイルを1行づつ読み込みます。配列はrecordです。その後record[xxx]で要素の値を取得し個別の配列にappendしていきます。IATAcode等はPublicなので外からアクセス可能です。
使うときは以下のような方法で使います。

```sample.go
// --- make IATA code list for view
	csvReader := new(CsvReader)
	csvReader.OpenCSV(AirportListCSVFilePath)

	iatacodes := csvReader.IATACode

	//results := c.db.Find(bson.M{})
	//println(results)

	return c.Render(iatacodes)
```

iatacodesをRenderの引数として渡しています。これは次に示すHTMLないで表示させるためです。

```sample.html
<label> <strong> Airport IATA Code</strong></label>
  <select name="IATAcode">
	{{range $index, $code := .iatacodes}}
	  <option value={{$code}}>{{$code}}</option>
	{{end}}
  </select>
```
このようにすることで、iatacodesの中身を表示させています。
selectにname="xxx"をつけている理由は、Userに選択させた結果を後ほどサーバー側へ送付させるためです。
AWS Elastic Beansalkでのデプロイ戦略

======

# 前置き
日本語でのElastic Beanstalk (以下単にBeanstalkと長いので呼びます。)の情報が意外とまだまだ少ないようなので、自分の中でのレビューも兼ねてまとめておきます。(node.jsアプリですが、他の場合も基本は一緒なはずです。)

# Beanstalkでのデプロイ方針の全体像
現状自分の関わっているBeanstalkを使用しているアプリケーションでは、以下の流れでデプロイを行っています。基本AWSからデフォルトで提供されている機能しか使っていません。

- S3にビルドをアップロード
- API / CLI経由でのデプロイ
- Blue / Greenデプロイメント

以下、個別に詳細を見ていきます。

## デプロイ準備: S3にビルドをアップロードする
現状以下のステップでビルドの作成／アップロードを行っています。

- npm install
- 対象フォルダをzipでまとめる
- ビルド用S3バケットにアップロードする

ここでは注意点が２つほど：
- npm installはBeanstalkのインスタンスでも再実施されるので、ビルド作成時には必要ないのですが、プライベートリポジトリへのアクセスを開けるのが面倒なことや、スケールアップの時間短縮のためにビルド作成時に実施しています。
- ビルド用S3バケットは対象Beanstalk Applicationと同じリージョンにある必要があります。

## 実際のコードのデプロイ: API/CLIでのデプロイ

初期の頃は、AWS CLIで```aws elasticbeanstalk create-application-version```と```aws elasticbeanstalk update-environment```の組み合わせで行っていたのですが、もう少し細かく制御するために最終的にPythonでのスクリプトを書いています。ただし、やっているい事は、create applicationでS3にアップロード済みのzipファイルの紐付け／ラベルを作成し、そのラベルを指定して既存の環境を更新することだけなので、CLIと大きくは変更はないです。

## Blue / Green デプロイメント

現状フローは、Code Deployの機能追加前に確定されたものなので、Code Deployの機能を使わず、以前から存在するBeanstalkの機能しか使っていません。その上で、Blue Green的なデプロイを実現させています。事前準備として、以下のものをセットアップします：

- メインの本番環境(URL例: main-app.elasticbeanstalk.com)
- デプロイ用環境(URL例: main-app-deploy.elasticbeanstalk.com)

流れとしては、以下になります。

- デプロイ用環境に新バージョンをデプロイ (この際、数秒〜数十秒間ながらダウンタイムが発生するが、デプロイ専用URLなので、ユーザーへの影響はなし。)
- 必要であればメイン環境と同じ台数にスケールアップ
- メインの本番環境とDNSネームを交換する。(Beanstalkの SWAP URLsという機能です。)

この流れによって、ユーザーへの影響は一切なく新コードをデプロイすることができます。二度目移行のデプロイは、その段階でデプロイ用になっている環境に対して更新をして同じことをするだけで、問題ないです。
この方式のデメリットとしては、最低1台デプロイ専用にインスタンスを遊ばせておく必要があること、DNSネーム交換でのデプロイなため瞬時には切り替わらないこと、などがありますが現状大きな問題にはなっていません。

## その他

いずれはCode Deployを使用したDNSに頼らないデプロイに切り替えたいのですが、30%〜50%の余裕を本番クラスターに持たせるのももったいないので検討だけで終わってます。。
Androidで自動テストがどんな感じで動くのか

## はじめに

皆さんテスト書いてますか？私は（正直面倒臭いけど）最低限でも申し訳程度には書くようにしています。テストを書いておかないと自分の書いたコードであっても３日もすれば忘れて何が正しいか自身が無くなってしまうからです。そして何が正しいかわからなくなると、機能追加やバグ修正のたびに解析を行わなければならなくなり、更に面倒臭いことになるからです。

Androidアプリの開発ではEclipseでもAndroid Studioでも、標準でJUnitがサポートされています。これを使わない手は無いでしょう。しかし、実際にテストとなると書くが面倒臭かったり、意外にテストを書くのが難しいかったりして、敷居が高かったりもします。私はその辺りをゴニョっとして回避してゴリゴリとテストを書いていたしますので、これから数回、その方法をご紹介できればと思います。

## 自動テストの雰囲気

次の動画はAndroid StudioでJUnitを実行した時の動画です。

クリックすると再生されます。
[![JUnit example with Android Studio ](http://img.youtube.com/vi/nD3RSrnr0DI/0.jpg)](https://www.youtube.com/watch?v=nD3RSrnr0DI)

この動画ではテスト用のコードがあるディレクトリを右クリックし、そこから[Run 'All Tests']を選択して自動テストを開始しています。テストが始まると、エミュレーター側の画面がペコペコ動いてテストが実行されているのがわかります。画面左下にはPASSしたテスト項目は緑色で表示され、FAILしたテスト項目は赤色で表示されます。

## 実際に実行する手順

前述の動画で使用しているアプリは次のURLで公開しています。

- https://github.com/cattaka/FastCheckList

これから、このアプリを使ってどうやって実行するかを説明します。ソースコードの取得には次の様にgitコマンドを使用して取得してください。

```bash
$ git clone https://github.com/cattaka/FastCheckList.git
```


### Android Studioから自動テストの実行

Android Studioから自動テストを開始するには、テスト用のコードがあるディレクトリを右クリックし、そこから[Run 'All Tests']を選択します。また、単一のテストクラスを実行したい場合は、１つのテストのJavaファイルを選択することで実行することもできます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/721b3edf-61b6-0584-3599-3e2cc06e404f.png)


### コンソールから自動テストの実行

コンソールから実行するときはプロジェクトのルートディレクトリで次のコマンドを実行します。

```bash
$ ./gradlew connectedAndroidTest
```

このコマンドを実行するとAPKの作成とテストの実行までを一挙に行なってくれます。ただし、実機を接続していなかったり、エミュレーターを起動していない場合は"No connected devices!"というエラーがでますのでご注意ください。

なお、build.gralde内でBuild Flavorを指定している場合は若干コマンドが変わりますので、その場合は

```bash
$ ./gradlew tasks
```

でコマンドを確認するようにしてください。


## おわりに

簡単にですがAndroidで自動テストを行なう流れを紹介しました。なんとなくどのように動くのかが伝わりましたでしょうか。少しでも自動でテストをすることの敷居を下げれたらと思います。

[次回](http://qiita.com/cattaka/items/901432bcbfce12016961)は自動テストのレポートがどんな感じかをご紹介します。
たぶんすごくわかりやすい、iAd導入サイト＋α。

　現役の薬剤師でもある私が、医療情報システム（電子カルテや看護支援システム等）の提案営業の経験を活かして開発した画期的な医療用語入力アプリ
【ICF inputter】
iOS　→　http://bit.ly/ICFinputteriOS
Android　→　http://bit.ly/ICFinputAndr
なのだが、画期的すぎるのか！？！？

ダウンロードしてくれたのは、知り合いをのぞいて一人だけ…。
※ダウンロードしてくれているのかもしれないが、
　今Appleがお休みで状況が見えないのだ

なぜか。

おそらく、有償なのが一番ネックになっているのでは…？と推論。

　とある薬剤師向けのコンテスト（11月末日〆切）に向けて急ピッチで開発したため、当時私はまだ広告の付け方を知らなかったのだ。
　後日Androidについてはすぐ導入できたのだが、iOSのやり方が、よくわからない…。
　自分なりに調べてやってみることにした。

iPhoneプログラミング広場さまを参考にさせていただいた。
iAdに特化したサンプルコードのダウンロードまでできる！本当に感謝！
https://sites.google.com/site/propicaudio/sample-code/iad-test

ただ、

なぜかlandscapeのときに、
広告が
クリックするたび下がっていく！？！？

コードをみると
「ADBannerView を移動する。」のところに
iadFrame = subview.frame;       // ADBannerView のフレームサイズを取得
iadFrame.origin.y += 20 - 2;    // ADBannerView の垂直方向の位置を下げる。
[subview setFrame:iadFrame];    // 変更したフレームサイズを ADBannerView に反映させる。
というくだりがあったので

20　-　２じゃ下がっていくよなと思い
iadFrame.origin.y +=0;
にしてみたところ、下がらなくなった！

この方が記事を書かれたときと、iAdの仕様が変わったのかもしれない。
これからiAdに初めてとりかかる方の助けになればと思い筆をとる。

Kaori SHIGE@BlueRoy Inc.
https://www.facebook.com/BlueRoyInc
【デモはこちらを！】
http://bit.ly/BlueRoyYouTube
【開発の経緯】
http://bit.ly/ICFinputterSlideShare
Konashi 2.0 でルンバをBLEリモコン化する

iRobot社のロボット掃除機ルンバにKonashi 2.0を接続することで、簡単にルンバをBLEリモコン化することが出来ます。
接続方法は色々考えられますが、私の行った方法を公開します。

## 免責事項
本記事の実行は、各自の責任において行って下さい。
なんらかの損害等が発生しても、著者は一切の責任を負わないものとします。

## 使用機材
・ルンバ
・Konasi 2.0
・ロジックレベル双方向変換モジュール
・ミニDIN８ピンコネクタ
・２極PHコネクタ
・ブレッドボード
・リード線etc

## ミニDIN８ピンコネクタの準備
ルンバのインタフェース規格はiRobot社により公開されています。
http://www.irobot.lv/uploaded_files/File/iRobot_Roomba_500_Open_Interface_Spec.pdf

シリアルポートのコネクタ図、iRobot社の資料より引用
![roombaOI.png](https://qiita-image-store.s3.amazonaws.com/0/26936/28bb7d18-9c95-2cf1-c16d-7581a0bae577.png)

シリアルポートのコネクタはミニDIN7ピンの形上ですが、８ピンのコネクタでも接続できます。
以下の四本を使用します。
・１もしくは２番ピンVpwr、Konashi 2.0への電源供給
・３番ピンRXD
・４番ピンTXD
・６もしくは７番ピンGND

５番ピンのBRCは通信速度の切り替えですが、今回はデフォルトの115200で通信するため、使用しません。
ミニDIN８ピンコネクタの該当する端子にリード線をハンダ付けしておきます。

## Konashi 2.0 の使用
Konashi 2.0の仕様は、ユカイ工学株式会社のサイトを参照して下さい。
http://konashi.ux-xu.com/documents/#specs-appearance
Konashi 2.0からは以下の端子を使用します。
・CN2バッテリ電圧、ルンバのVpwr端子から電源を供給します。
・UART RX
・UART TX
・DC5.0V、ロジックレベル双方向変換モジュールへ電源供給
・DC3.0V、ロジックレベル双方向変換モジュールへ電源供給
・GND
CN2は２極のPHコネクタになっているので当該コネクタにリード線を取り付けておきます。
短い辺に近い側がGNDになります。

UART RXをルンバのTXD、UART TXをルンバのRXDに接続しますが、電圧が違うため変換モジュールをかまします。

## ロジックレベル双方向変換モジュールの使用
電圧の変換にsparfunのロジックレベル双方向変換モジュールを使用します。
https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide
ロジックレベル双方向変換モジュールの端子は以下のように接続します。
・LV1 - Konashi 2.0 TX
・LV2 - Konashi 2.0 RX
・LV  - Konashi 2.0 DC3.0V
・HV1 - ルンバ RXD
・HV2 - ルンバ TXD
・HV  - Konashi 2.0 DC5.0V
・GND - GND

## 回路図
準備中＼(IoT)／

## 配線
ブレッドボードでの配線例です。
![IMG_0287.JPG](https://qiita-image-store.s3.amazonaws.com/0/26936/f4f7e414-540c-5055-634f-d5dcafdb1b18.jpeg)

## iPhoneからの制御
とりあえず、ユカイ工学株式会社が提供しているKonashi 2.0のサンプルプロジェクトから、UartSampleを改造して使用します。

readyメソッド内で通信速度の設定をルンバに合わせて115200に変更します。

```objc:
//    [Konashi uartBaudrate:KonashiUartBaudrateRate9K6];
    [Konashi uartBaudrate:KonashiUartBaudrateRate115K2];
```
sendメソッドを以下のように書き換えて前進コマンドを送信するようにします。
また、停止用のボタンを追加しておきます。

```objc:
// 前進
- (IBAction)send:(id)sender {
    [Konashi uartWrite:128];    // Start
    [Konashi uartWrite:132];    // Full
    [Konashi uartWrite:146];    // Drive PWM
    [Konashi uartWrite:0];      // [Right PWM high byte]
    [Konashi uartWrite:50];     // [Right PWM low byte]
    [Konashi uartWrite:0];      // [Left PWM high byte]
    [Konashi uartWrite:50];     // [Left PWM low byte]
}

// 停止
- (IBAction)sendStop:(id)sender {
    [Konashi uartWrite:128];    // Start
    [Konashi uartWrite:132];    // Full
    [Konashi uartWrite:146];    // Drive PWM
    [Konashi uartWrite:0];      // [Right PWM high byte]
    [Konashi uartWrite:0];      // [Right PWM low byte]
    [Konashi uartWrite:0];      // [Left PWM high byte]
    [Konashi uartWrite:0];      // [Left PWM low byte]
}
```

コマンドの詳細については、iRobot社の仕様書を参照して下さい。

## 実行方法
本モジュールをルンバのシリアルポートに接続して、ルンバの電源を入れます。
iPhoneでさきの改造したUartSampleを実行します。
BLE接続後、sendボタン押下でルンバが前進したら成功です。停止用のボタンで止めましょう。
HubotでCronがSlackに流れなくてハマった


各所のサンプルを見ながらやってみてローカル上では上手く動いているのに、Slack上にメッセージが流れなくてハマった。
最近のバージョンでroom名の'#'は不要になったっぽい。

```javascript:cron-test.coffee
CronJob = require('cron').CronJob

module.exports = (robot) ->
  new CronJob '0 * * * * *', () =>
    # これだとSlack#generalにメッセージが流れない
    # robot.messageRoom "#general", "テスト"

    # これならおっけー☆
    robot.messageRoom "general", "テスト"
  , null, true, "Asia/Tokyo"
```

# 参考

[hubot-slack アダプタ v2 から v3 へ | 半月記](http://pasero.net/~mako/blog/s/689)
ConoHaオブジェクトストレージ(OpenStack Swift)でWEB公開した超長いURLを短くする方法

##ConoHaオブジェクトストレージのURLの問題点

ConoHaのオブジェクトストレージ(OpenStack Swift)で公開したURLは絶望的に長いURLになることが下記の前回の記事で分かりました。
[ConoHaオブジェクトストレージの静的WEBページ公開機能でイメージギャラリーを作る](http://qiita.com/AKB428/items/a1cc8fff2346c0f12029)

糞長いURLの例
https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/bgi_sample/index.html
https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/bgi_sample/images/DSC02403.JPG

リンクタグ、イメージタグなどHTMLに埋め込むタイプの用途に使うならこの長いURLでもいいのですが、この長いURLにはいくつか問題があります。

* あなたのサーバーがConoHaのオブジェクトストレージを使用していることがバレてしまう
* あなたのオブジェクトストレージエンドポイント(93a6500c0a1e4c68b976e5e46527145cの部分)が丸見えになる
* 糞長いURLのためそのままSNSや掲示板などに貼ると長ったらしくてみんなから嫌がられる

・・・とセキュリティ的にも利便的にもあまりいけてない仕様になってしまいます。

この問題はNginxでリバースプロキシで解決できます。

##Nginxを使ってConoHaオブジェクトストレージのURLを短くする


![conohaw.png](https://qiita-image-store.s3.amazonaws.com/0/36931/462180a6-d7d3-d1db-f629-72c5b0a262ea.png)


###必要なもの
* オブジェクトストレージのWEB公開しているコンテナ
* Nginxがたてられるサーバー(ConoHa VPSやさくらサーバーなど）説明ではホスト名をhoge.comとする。
* 短いドメイン（任意)　ここでは hoge.com のドメインを取得してるものとする

###ConoHaのオブジェクトストレージにweb_pub_testフォルダ(コンテナ)を作成しWEB公開モードにする
swiftコマンド等を使ってweb_pub_testフォルダを作成する

[chinoコマンド](https://github.com/AKB428/Chino)の場合は以下
``mkdir web_pub_test``
``echo "Hello" > web_pub_test/test_file.txt``
``bundle exec ruby chino.rb -w -s ./web_pub_test/ -d /web_pub_test``

### VPSサーバーにNginxをインストール
CentOSの場合
``yum install nginx`` 
もしくは以下のサイトから最新版をとってきて
http://nginx.org/packages/rhel/6/x86_64/RPMS/
``curl -O XXXX.rpm ``
``rpm -ivh XXXX.rpm ``

インストールするとかってにnginxサーバーは起動しているはず。

### 設定ファイルを書き換える
```nginx:/etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location /x/ {
        proxy_pass https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/web_pub_test/;
    }
}
```

location以降がプロキシーサーバーの設定になります。
 http://hoge.com/x 以降にリクエストが来たときにConoHaのオブジェクトストレージ(web_pub_testフォルダ)にリクエストを受け渡すように設定する。

###Nginxをリロード
``nginx -s reload``


###ConoHaのオブジェクトストレージに短いURLでアクセスできる

上記の設定でブラウザから
http://hoge.com/x/test_file.txt にアクセスするとリバースプロキシされて
https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/web_pub_test/test_file.txt
の内容が表示されます。


### ConoHaオブジェクトストレージ+Nginxリバースプロキシの使いどころ
ConoHaのオブジェクトストレージ、またはOpenStackのSwiftを使用しファイルをWEB公開する場合、本格的に使用しようとすると
URLが長い問題に必ず突き当たると思われます。
そんな時はサクっとNginxのリバースプロキシ機能でURLを短くしちゃいましょう。
【Windows】gem updateでSSL_connect returnedエラーが起こる

WindowsにSCSSのビルド環境を作るために、rubyコマンドの実行環境を作りましたが、最新版rubyインストーラー（2014.12.30 時点）でちょっと苦労したことがありました。
	
Windows版 rubyインストーラーを「 http://rubyinstaller.org/downloads/ 」からダウンロードして、rubyコマンドを実行できるところまで環境を作ったが、その後の「gem update --system」コマンドのところでSSLエラーが表示されてしまいました。

## Windows版 rubyインストーラー
今回使用したインストーラーはこれです。
rubyinstaller-2.1.5-x64.exe

## 問題のSSLエラーメッセージ
こんなSSLエラーが表示されました。

````
gem update --system
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)
````

原因を調べてみたら、インストーラーに含まれているSSL証明書が古いことが原因らしいです。
参考ページ） https://gist.github.com/luislavena/f064211759ee0f806c88


しかしこれ、インストーラーをビルドするときにチェックしなかったんでしょうかね。


## SSLエラーを解消して、gemを最新版にする方法

とりあえず、参考ページに書いてあることを実践して、SSLエラーを解消します。

`````
gem --version
> 2.2.2
gem which rubygems
> C:/Apps/ruby/lib/ruby/site_ruby/2.1.0/rubygems.rb
cd C:\Apps\ruby\lib\ruby\gems\2.1.0
`````

ここから修正版RubyGemsファイルを取得する。
https://github.com/rubygems/rubygems/releases/tag/v2.2.3
緑色の［rubygems-update-2.2.3.gem］ボタンを押してダウンロードする。

そしたら下のパスへ保存する。
C:\Apps\ruby\lib\ruby\gems\2.1.0\rubygems-update-2.2.3.gem

`````````
gem install --local rubygems-update-2.2.3.gem
gem --version
> 2.2.3
update_rubygems --no-ri --no-rdoc
gem uninstall rubygems-update -x
gem which rubygems
> C:/Apps/ruby/lib/ruby/site_ruby/2.1.0/rubygems.rb
start C:/Apps/ruby/lib/ruby/site_ruby/2.1.0/rubygems.rb
`````````

以下パスのpemファイルをダウンロードする。
https://raw.githubusercontent.com/rubygems/rubygems/master/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem
保存先はこちら。（自分の場合は、ssl_certsフォルダが無かったので作りました）
C:\Apps\ruby\lib\ruby\gems\2.1.0\gems\ssl_certs\AddTrustExternalCARoot-2048.pem

`gem update --system`

そうすると、Updating rubygems-update と表示されて無事にアップデートが始まります。

```
gem --version
>2.4.5
```

以上、無事にgemを最新版にアップデートできました。
ターミナルからSublime Text2を起動する方法

前提条件 : .bash_profile,.bashrcファイルが存在する

(1) .bash_profileに以下の記述を追加し
　　 bashrcを自動読み込みするように設定

　　if [ -f ~/.bashrc ]; then
 　 　  . ~/.bashrc
　　fi

(2) .bashrcに以下の記述を追加

　　alias subl='open -g -a Sublime\ Text\ 2'

(3) ターミナル再起動
(4) 「subl [ファイル名]」でSublimeを起動
std::unique_ptrには ->* 演算子がない！

タイトルの通りです。
~~正直誰得です。~~

なんと、std::unique_ptrには->\*演算子が定義されておらず、メンバ関数ポインタを使ってメソッドを呼び出すにはget()関数を挟む必要があります。これはいけない！！　みんな困っている！！！　これを解決しなければならない！！

```cpp
std::unique_ptr < foo > pFoo( new foo() );
( pFoo.get()->*&foo::bar )(); // メンバ関数ポインタを使ってbarメソッドを呼び出す。
```

しかしこれでは直感的ではありませんし、そもそもどうしてもどこかへ生のポインタを渡したいときだけしかget()関数を使うべきではありません。そのためにアロー演算子もオーバーロードされていますしね。

そこで、->\*演算子を足したunique_ptrを作ることにしました。

```cpp
#include <functional> // for std::bind
#include <memory> // for std::unique_ptr

template < class Ty1, class Ty2 = std::default_delete < Ty1 > >
class unique_ptr
  : public std::unique_ptr < Ty1, Ty2 >
{
public:
  using base = std::unique_ptr < Ty1, Ty2 >;
  using base::unique_ptr;
  
  template < class ret, class... args >
  auto operator ->* ( ret( Ty1::*mem_ptr )( args... ) )
  {
    return std::bind( mem_ptr, *this->get() );
  }
};
```

std::unique_ptrをごっそり流用しているのでこの通り演算子だけを定義すれば済みます。
->*演算子はかなり特殊な演算子でそのまま関数の戻り値にはできない(値ではない)ので、std::bindで束縛したものを返しています。

```cpp
unique_ptr < foo > pFoo( new foo() );
( pFoo->*&foo::bar )(); // 直感的
```

直感的かどうかは微妙なところ、というか->\*演算子(間接メンバポインタというらしいです)自体使うことが滅多になく、存在も知らなかったという人もいそうなものなので直感的もへったくれもないかもしれません。
演算子の優先順位が低くてカッコでくくらなきゃいけないんですよね。

```cpp
auto baz = &foo::bar; // 本当はこのように一度どこかへ代入されたり関数の引数を経たりする
( pFoo->*baz )(); // baz経由でbarメソッドを呼び出す
```

ここまで読んでいただいて恐縮なのですが、実はこれ、重大な欠陥がありまして、引数を取るものに対応していません。std::bindにプレースホルダーを置かないとならないからであり、それを解決していないからです。プレースホルダーはstd::placeholders::_1から_20まであり、最大20の引数に対応させることができます。テンプレートメタプログラミングを駆使すれば解決することができそうですが、割に合わない手間がかかりそうなのでやめました。ごめんなさい。

ネタ記事でした。

わたし自身あまりメンバ関数ポインタ周りは詳しくないので、間違い等ございましたらコメントのほうへお願い致します。

=> @kktk-KO さんより、C++14のラムダを使えば簡単に解決できることを教えてもらいました。ありがとうございます！

```cpp
template < class Ty1, class Ty2 = std::default_delete < Ty1 > >
class unique_ptr
  : public std::unique_ptr < Ty1, Ty2 >
{
  /* 省略... */
  template < class Ret, class... Args >
  auto operator ->* ( Ret( Ty1::*mem_ptr )( Args... ) )
  {
    return [this , mem_ptr] ( Args&&... args )
    {
      return ( this->get()->*mem_ptr )( std::forward < Args... > ( args )... );
    };
  }
};
```
[JavaScript] 特定のブラウザを判別して、処理を書く 

## 目的
Chromeとか、Firefoxだけにはこうしたいとか、こうしたくないとかがある。
そんなときに、特定のブラウザを判別する方法。

```js
//navigotorはブラウザの情報を持ったオブジェクト
//プロパティであるuserAgentはブラウザを識別するための文字列が格納されている
window.navigator.userAgent
>>> "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"

// userAgentに入っている文字列を識別すればいい。
if (navigator.userAgent.index0f('Chrome') !== -1) {
 // 処理
}
```

どうでもいいけど、FirefoxのTransformプロパティに対する弱さは何なんですかね。
いい加減、対応してほしい。
LightningのJavaScriptの調べ方

# 外部リソース
- [Lightning コンポーネント開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.lightning.meta/lightning/) 読んでいるかと思いますが、一箇所だけに簡単にしか触れられていないような内容もあるので注意が必要です。Winter '15だと、ドキュメント通りに記述しても動かない部分もあります。
- [auraのソース](https://github.com/forcedotcom/aura/) コンポーネントのソースがためになりそうですが、かなり読み応えがあります…。
- [aura Reference Documentation](http://documentation.auraframework.org/auradocs#reference) 一部オブジェクトのリファレンスが簡単にわかります。ただし、呼び出し方がわかりにくいものや、プライベートメソッドなども記述されているので要注意です。

# JavaScriptコンソールでの調査

JavaScriptでの調査に慣れている方にとっては普通のやり方です。Salesforce側の開発コンソールではなく、ブラウザーのデベロッパーツールなどにあるものです。

まずは`$A.`のように、適当なグローバル変数を入力し、ピリオドを打ちましょう。すると、呼び出せるメソッドが出てくると思います。あとはリファレンスに記載してあるクラスなどもグローバル変数になっているものも幾つもあります（グローバル汚染し過ぎでは…）。

適当なソースの実装を見たい場合、例えば`$A.error`というメソッドの実装を見たい場合、コンソールに`$A.error`と入力しエンターを押しましょう（括弧は不要です）。そうすると、コンソールに当該関数のソースが出力されます。

![スクリーンショット 2014-12-30 1.41.38.png](https://qiita-image-store.s3.amazonaws.com/0/44645/0ce7b3d1-f82f-989b-fc19-50c763592b9d.png)

更に中身を見たい場合は、そのソースの右上に表示されているファイル名 `aura_proddebug.js:11018` などというところをクリックしましょう。そうするとソースコードの当該部分を見ることができます（デバッグモードが有効化されていない場合、難読化されたソースが表示されます）。ここで、ブレークポイントを設定することも可能です。

![スクリーンショット 2014-12-30 1.40.21.png](https://qiita-image-store.s3.amazonaws.com/0/44645/2669a35a-6943-0168-38c1-1d1c6d0c8c0a.png)

`aura_proddebug.js`は全文ローカルにも保存しておくと良いでしょう。

# Componentの確認

Componentオブジェクトのインターフェイスを手軽に見るには、$A.getRoot()を使うと良いでしょう。

特定のコンポーネントの確認をする場合は、当該コンポーネントのinitイベントを`<aura:handler name="init" value="{!this}" action="{!c.doInit}" />`のようにフックした上で`doInit`内で`debugger;`で止めるか、`window.component = component;`としておいて、後でJavaScriptコンソールからゆっくり解析するのが良いと思います。

# その他

`console.log();`、`$A.trace();`や`debugger;`辺りを使って頑張って行きましょう。
browserifyやwebpackを使おうとしたけど、やっぱりRequireJSを使わざるを得ない

結論
====

TypeScriptでSourceMapを使ってガシガシデバッグしたければRequireJS使うしか択が無いです。
AMDさん優秀。

----

browserifyの対抗馬としてwebpackが現れ、RequireJSオワコン説はますます強まるばかりです。私はこれまでRequireJSを使い続けていたので、乗り換えられるか調査してみました。
結果としては冒頭の通りなのですが、具体的には**多段ソースマップ問題を解決できない**ことと、**それを解決して得られるメリットが少なくデメリットすらある**ことにより、これ以上の調査を打ち切ることとしました。（なのでbrowserifyやwebpackの知識が十分じゃないところがあるのをご理解ください）

----

browserifyやwebpackはJavaScriptモジュールを変換して一つ（webpackは複数にもできる）のファイルにします。
TypeScriptからブラウザで使用するJavaScriptを作るためには、**TypeScript -> JavaScript -> 一本化JavaScript** の2段階のトランスパイルが必要です。。

TypeScriptからトランスパイルされたJavascriptをデバッグするにはSourceMapが必要です（まあぶっちゃけ無くてもできますが。）。この2段階のトランスパイルでは2つのSourceMap（多段SourceMapと呼ぶそうです）が得られますが、これをそのまま使うことはできません。

このことは、↓のリンクで詳しく述べられています。多段SourceMapを一つのSourceMapに変換するライブラリもあるのですが、これはwebpackなどの複数ファイルを一つにまとめるSourceMapには使用できないようでした。
[多段SourceMapの対応方法とライブラリ | Web Scratch](http://efcl.info/2014/09/03/multi-stage-sourcemap/ "多段SourceMapの対応方法とライブラリ | Web Scratch")

一方RequireJSは、一つのファイルにすることもできますが、**変換せずそのまま使う事もできます**。TypeScriptからトランスパイルしたJavaScriptをそのままブラウザで使うので、SourceMapは何の問題なく使用できます。
ついでに、**一本化に必要なビルド時間も不要です**。

----

ところで何でbrowserifyやwebpackを使うのでしたっけ？
AMDでなくCommonJSで書けるところは、TypeScriptで書けばどちらにも出力できるわけですし、うーん。。。

まとめ
----

### TypeScripterがRequireJSからbrowserify or webpackに移行するメリットとデメリット
#### メリット
* 最小構成では覚えることが少ない
* 最終的に完全に1つのJavaScriptにまとまるのでネットワーク負荷が小さい

#### デメリット
* SourceMapを使うのが大変、もしくは無理
* ビルドが余計に時間がかかる

なもんで、私はこれ以上調査するのをやめて、RequireJSでgulp+TypeScriptのテンプレートを書き直す事にしました。
【Numpy】ndarrayをシャッフルする

# What's this
Numpyのndarrayをシャッフルする方法。
ndarrayのインデクシングは参照のため、コピーを作ってから代入する必要があります。

#コード
```py:shuffle_ndarray.py
import numpy
import random

# まず適当に行列を作成
a = [
		[1, 2, 3],
		[5, 6, 7],
		[9, 10, 11],
		[12, 13, 14]
	]
nda = numpy.array(a)

# シャッフル（行数の２倍回）
for i in range(nda.shape[0] * 2) :
	index_a = random.randint(0, nda.shape[0]-1)
	index_b = random.randint(0, nda.shape[0]-1)

	# 参照のため、共に同じ要素になってしまう
	#nda[index_a], nda[index_b] = nda[index_b], nda[index_a]
	
	# コピーを作ってからそれぞれ代入
	nda[index_a], nda[index_b] = numpy.array(nda[index_b]), numpy.array(nda[index_a])
Linuxのコマンドラインから外部SMTPサーバを指定してメール送信

会社のワークステーションからコマンドラインでメールを送りたかったのですが、
意外とコマンド1発じゃないんですね。
メールアドレスとかSMTPサーバーの名前は適宜修正のこと。

```sh:send_mail
#!/bin/sh
 
SUBJECT=$1
BODY=$2
 
(
echo HELO my.domain.com;                  sleep 1;
echo MAIL FROM: myself@my.domain.com;     sleep 1;
echo RCPT TO: my_mobile_phone@mobile.com; sleep 1;
echo DATA;                                sleep 1;
echo From: myself@my.domain.com;          sleep 1;
echo To: my_mobile_phone@mobile.com;      sleep 1;
echo Subject: ${SUBJECT};                 sleep 1;
echo ;                                    sleep 1;
echo ${BODY};                             sleep 1;
echo .;                                   sleep 1;
echo QUIT;                                sleep 1;
) | telnet 12.34.56.78 25 
```

シンプルに件名、内容のみ

```bash
$ foo ; send_mail NOTIFY end_of_job
```

目的は時間のかかる処理が終わったらメールを送信して通知することだったので、この程度で。
Android 5.0のtickerText


こんにちは、あんどろいどりんご([@mstssk](https://twitter.com/mstssk))です。

Android 5.0 Lollipopで、Notification関係が色々変わりました。
Material Design化、アイコンの自動脱色、アクセントカラー、設定へのショートカット、ロックスクリーン上の表示、publicVersion、Heads-up Notification、重要モード、カテゴリの設定、連絡先の紐付け、MediaStyle…という風に列記しただけでも気が遠くなります。
それらNotificationの変更点について、C87で頒布した[TechBooster](techbooster.org)のAndroid本「[甘味アンドロイドパーク](http://techbooster.github.io/c87/#park)」の第5章「Android 5.0でのNotification」にて一通り解説しています。

Notificationの変化の中で、tickerTextの役割も大きく変更されました。
本記事では「甘味アンドロイドパーク」で解説できなかった(というか間違えた)tickerTextの変更について解説します。エラッタも兼ねています。

エラッタ(正誤表)
--------------

甘味アンドロイドパーク 67ページ(電子版:70ページ)

|    | 内容                                                 | 
|:---|:----------------------------------------------------|
| 誤 | Ticker textがDeprecatedになり、表示すらされなくなりました。|
| 正 | Ticker textはステータスバーに表示されなくなり、アクセシビリティサービスにNotificationの内容をテキストで知らせるものになりました。 |

解説
---

### tickerTextはアクセシビリティサービスが使う

Android 5.0でtickerTextはステータスバーに表示されなくなりました。
しかし、Deprecatedになったわけではありません。
「アクセシビリティサービスにNotification内容をテキストで知らせるもの」という役割に変更されています。

公式ドキュメントの Notification#tickerText についての説明は、
「もう画面に表示されません。しかしアクセシビリティサービスにとって有用です（Notificationの読み上げなど）。」
という内容に更新されています。

> As of the L release, this text is no longer shown on screen, 
but it is still useful to accessibility services (where it serves as an audible announcement of the notification's appearance).
https://developer.android.com/reference/android/app/Notification.html#tickerText

Notification.BuilderのsetTicker(CharSequence)メソッドも同様です。
「アクセシビリティサービスに送信するテキストを設定する」という説明になっています。

> Set the "ticker" text which is sent to accessibility services.
https://developer.android.com/intl/ja/reference/android/app/Notification.Builder.html#setTicker(java.lang.CharSequence)

### tickerViewはDeprecated

Deprecatedではないのは、あくまでtickerTextです。
ステータスバー表示のためのtickerViewはDeprecatedになっています。

https://android.googlesource.com/platform/frameworks/base/+/android-5.0.2_r1/core/java/android/app/Notification.java#237

`Notification.Builder#setTicker(CharSequence, RemoteViews)` も恐らく同じ理由でDeprecatedです。
※tickerTextとtickerViewを一緒に設定するメソッド

https://android.googlesource.com/platform/frameworks/base/+/android-5.0.2_r1/core/java/android/app/Notification.java#2193

### tickerTextの今後の役割

※あくまで想像。Android Auto関係は調べてないので的はずれかも。

何故tickerTextをDeprecatedにせず、あくまでアクセシビリティサービスに通知する、という役割を残したのでしょうか。
以下の様な理由があると考えています

- Notificationはユーザーを煩わせるもの、という思想の反映によるtickerTextの非表示化
- 一方でAndroid Autoへの対応のため通知の読み上げという道を残した
  - 車載の画面にずらずらテキストが表示されるのは余所見の原因になり危ない
  - 運転中はNotificationの要約(tickerText)を読み上げる利用ケースを想定している

Notificationについての公式のドキュメントでは「ユーザーの注意や関心はユーザーにとってのリソースであり、それを徒に着信音やバイブレーションで消費する事は避けるべき」といった事が書いてあり、ユーザーの邪魔をしないようなNotificationを実装するべきだと結構強い感じで解説しています。

http://developer.android.com/intl/ja/design/patterns/notifications.html#building_notifications_that_users_care_about

Android 5.0では、Notificationでユーザーを極力煩わせないようにしつつ、重要なもののみHeads-up Notificationで表示する、という思想となっているようです。
（とはいえ、今回のNotification周りの変更はあんまりユーザーフレンドリーじゃないと思うのでもんにょりするんですが、それはこことは別の話）