OmniAICreator/Qiita-1.07M huggingface dataset:
[MEMO]Ubuntu14.04初期設定まとめ

立て続けに14.04導入して，毎回だいたい同じことググって同じサイト見て設定してると，ググるのが面倒になってきたため，個人的にここでまとめる．
書き終えてから見返すと粒度のバラつきがひどいけどそこは見ないこととする．

## グラフィックドライバ
Nvidiaのときは，

```
$ sudo apt-add-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
```
でPPAを追加して，システム設定→ソフトウェアとアップデート→追加のドライバーから適当なドライバを入れる．


## terminalからユーザネームを消す
~/.bashrcの62行目(14.04では)の
```PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '```
を
```PS1='${debian_chroot:+($debian_chroot)}\w\$ '```
にする.

## Mozc(IME)導入
```
$ sudo apt-get install ibus-mozc
$ killall ibus-daemon
$ ibus-daemon -d -x &
```
左上のIMEのアイコンからテキスト入力設定．
使用する入力ソースに「日本語」「日本語(Mozc)」を追加し，「日本語(Anthy)」を削除．
次のソースへ切り替えを「全角半角」にする．

Mozcのプロパティで句読点を「，．」に変更．
辞書タブ→ユーザ辞書の編集で，
よみ「あどれす」単語「自分のメールアドレス」
よみ「でんわばんごう」単語「研究室の電話番号」
とかを追加．

## ユーティリティ系
```
$ sudo apt-get install clipit easystroke indicator-multiload
```
clipit起動して，設定から「選択アイテムを自動的に貼り付ける」をチェックして，ホットキータブから「履歴のホットキー」に\<Ctrl>\<Shift>Vを設定．

easystrokeは，いつものマウスを使うときに設定する．設定タブ→ジェスチャ・ボタンでzoomボタンを追加し，アクションタブでアクションを追加，名前を適当につけて，種類をキーに詳細でEnterキーを押して登録し，ストロークをダブルクリックしてzoomボタンのシングルクリックを設定．設定タブの「ポップアップを表示」のチェックを外す．

起動時に実行されなければ，「自動起動するアプリケーション」に登録．(デフォでは勝手に自動起動するはず)

## ホームのファイル名の英語小文字化
```
$ LANG=C xdg-user-dirs-gtk-update
```
して，```~/.config/user-dirs.dirs```を編集して頭を全て小文字にする.
実際のフォルダ名も編集して小文字にする．


## もろもろの設定
システム設定→外観→挙動タブでウインドウのメニューを表示をタイトルバーの中にする．

```$ sudo apt-get install unity-tweak-tool```
でUnity Tweak Tool入れて，
Panelで日付・曜日表示する
Workspace SettingでワークスペーススイッチャをON

ターミナルの編集→プロファイルの編集→背景タブで透明度を設定する．
編集→キーボードショートカットから貼り付けをCtrl+Vにする．

Gitを設定
```
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"
```


## その他導入するソフトなどのメモ
* [pycharm](https://www.jetbrains.com/pycharm/download/)
* [clion](https://www.jetbrains.com/clion/buy/)
* [webstorm](https://www.jetbrains.com/webstorm/buy/)
* [qt(+qtcreator)](https://download.qt.io/official_releases/qt/)
* [smartgit](http://www.syntevo.com/smartgit/)
* [android studio](https://developer.android.com/sdk/index.html)
* [ROS](http://wiki.ros.org/ja/indigo/Installation/Ubuntu)


## 参考
http://ubuntuapps.blog67.fc2.com/blog-entry-498.html
http://symfoware.blog68.fc2.com/blog-entry-1397.html
http://tech.motop3j.net/archives/14
moreutils について

# moreutils とは

Unix 初期の時代には誰も書こうとは考えなかった、日々拡大を続ける Unix ツール集

## この投稿の趣旨
moreutils は便利なのにあまり知られていないので、知名度を上げるためにまとめました。
moreutils が提供するコマンドは数多くありますが、その中で特に私自身が便利だと思うものを使い方とともに紹介します。

## chronic

下記を
```
$ backup >/dev/null 2>&1
```

下記のように

```
$ chronic backup
```

と書くことができる。
`>/dev/null 2>&1` の順番を覚えるのが大変なので、便利。

## combine

2つのファイル中の行を論理演算して出力できる。
（例）

```
$ cat lang.txt
Ruby
Perl
Python
PHP

$ cat gemstones.txt
Ruby
Peridot
Sapphire
Opal
Topaz

$ combine lang.txt and gemstones.txt
Ruby

$ combine lang.txt not gemstones.txt
Perl
Python
PHP

$ combine gemstones.txt not lang.txt
Peridot
Sapphire
Opal
Topaz
```

## ifdata
ifconfig や ip a を文字列処理しなくても、ネットワークのいろんなデータを取得可能

```
$ ifdata -pa lo
127.0.0.1
```

## ifne
標準入力が空でないとき、後続の処理を実行する。

man ページに掲載されていた例（core があれば root にメールする）

```
find . -name core | ifne mail -s "Core files found" root
```

## isutf8
引数のファイルが UTF8 かどうかを判定する。

```
$ isutf8 README.md && echo UTF-8
UTF-8
```

## Sponge
標準入力をすべて受け取ってから、引数のファイルに書き出す。

（例）

```
$ cat lang.txt
Ruby
Perl
Python
PHP

$ egrep ^P lang.txt > lang.txt
grep: 入力ファイル `lang.txt' が出力にもなっています

$ egrep ^P lang.txt | sponge lang.txt
$ cat lang.txt
Perl
Python
PHP
```

## vidir
テキストエディタを使って、カレントディレクトリを編集できる。
ファイル名を一括置換するときや、一部のファイルを削除したいときなどに便利。

```
$ vidir

$ find -type f | vidir
```

## vipe
パイプの途中にテキストエディタを利用できる。

例として、DB のダンプ内容を加工して、リストアするときは下記のようにしたりできる。

```
$ mysqldump --host=srchost -uroot -p srcdb | vipe | mysql --host=dsthost -uroot -p dstdb
```

# 参考文献
* https://joeyh.name/code/moreutils/
* http://stackoverflow.com/questions/10686183/pipe-vim-buffer-to-stdout
* http://stackoverflow.com/questions/3219479/how-to-write-buffer-content-to-stdout
* https://packages.debian.org/ja/sid/moreutils
* http://unix.stackexchange.com/questions/207919/sponge-from-moreutils-whats-the-difference-to-shell-redirect-useful-examples
* http://devblog.nestoria.com/post/110168998173/moreutils-basic-unix-tools-that-ought-to-be
JavaScriptでよく使うDOM操作とか

よく使うやつのおさらい。

# class操作
classを追加する

```
document.getElementById(id).classList.add(class);
document.getElementById(id).classList.add(class1, class2); //複数クラスを追加したい時

$(selector).addClass(class); //jQuery
```

classを削除する

```
document.getElementById(id).classList.remove(class);

$(selector).removeClass(class); //jQuery
```

classをもっているか判定

```
document.getElementById(id).classList.contains(class);

$(selector).hasClass(class) //jQuery
```

classをとぐる。そのクラスをもっていれば消す、もっていなければ追加

```
document.getElementById(id).classList.toggle(class);
```

# DOM要素取得
querySelectorが便利。最初にヒットしたDOM要素を返す。getElementByIdもいいけどidをわざわざ指定したくはない時とか

```
var ele = document.querySelector(selector);
```

複数要素を取得したい場合はquerySelectorAllを使用

```
var eleList = document.querySelectorAll(selector);

//全部に共通のclassを追加したい。
for (var i = 0; i < eleList.length; ++i) {
  eleList[i].classList.add(class);
}
```

querySelector しか使わなくなってきた…

#カスタムデータ属性を扱う

data-* の取得。自分で値をつくることができるカスタムデータ属性は使いはじめると止まらない。

```
document.getElementById(id).getAttribute('data-*');
```

data-* のセットとリセット

```
document.getElementById(id).setAttribute('data-*', data);

// リセットしたい時は空文字を指定
document.getElementById(id).setAttribute('data-*', '');
```

#targetとcurrentTarget
下のような場合を考えてみるとわかりやすい

```
<a href='#' id='target-test' data-sample='1'>
  <span data-sample='2'>Hello World!!</span>
</a>
```

a要素に onclick イベントを追加して data-sample の値を出力してみると a>span を click した場合の出力結果が違う。

```
document.getElementById('target-sample').onclick = function (e) {
  e.preventDefault(); // link で飛んでかないように
  console.log(e.target.getAttribute('data-sample'));         // 2
  console.log(e.currentTarget.getAttribute('data-sample'));  // 1
}
```

イメージとしては target は押下された DOM要素を取得し、currentTarget はイベントが関連付けられている DOM要素を取得する

# onclick と addEventListener('click') の違い

要するに上書きされるかどうか。onclick は上書きされるが、addEventListener で click イベントを拾う場合、その前に関連付けられていた処理も残っている。

この場合、要素がクリックされると 2 が出力される

```
document.getElementById(id).onclick = function () {
  console.log('1');
}

document.getElementById(id).onclick = function () {
  console.log('2');
}
```

addEventListener では 1 2 が出力される。

```
document.getElementById(id).addEventListener(function () {
  console.log('1');
}, false);

document.getElementById(id).addEventListener(function () {
  console.log('2');
}, false);

```
【頻出】個人的に困った時の MySQL trouble shooting

# ユーザ作りたい＆権限付与したい

```sql
CREATE USER #{user_name} IDENTIFIED BY '#{password}'; 
-- or UPDATE mysql.user SET Password=PASSWORD('#{password}') WHERE User='#{user_name}';
GRANT ALL PRIVILEGES ON #{database_name or *}.#{table_name or *} TO #{user_name};
-- FLUSH PRIVILEGES; -- GRANT 時は不要
```

# （レア）ユーザ作ったのに入れねぇんだけど(怒)

```bash
$ mysql -u hoge -p # さっき作ったユーザ hoge
Enter password: 
ERROR 1045 (28000): Access denied for user 'hoge'@'localhost' (using password: YES)
```

1. 権限周りの確認
2. 権限も正しい場合は、ワイルドカードユーザがいる可能性大

```sql
-- root でログイン後
SELECT * FROM mysql.user;
+-----------+--------------+-------------------------------------------+
| Host      | User         | Password                                  |
| localhost | root         | *81Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| localhost |              |                                           | -- ←コイツ 
| %         | hoge         | *46xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
+-----------+--------------+-------------------------------------------+
```

どうやら、先にこっちがひっかかって `hoge` ユーザまで辿りつけてないみたい。
ユーザを消して上げればOK。

```sql
-- root でログイン後
DROP USER ''@localhost;
```


# MySQL 立ち上がらない＼(^o^)／

よく見る光景↓

```bash
$ mysql -u root -p
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

その場合は、
1. MySQL が立ち上がってるか確認
2. 立ち上がってるのに出る場合は、`/tmp/mysql.sock` に symlink 貼ってやる↓

```bash
$ sudo ln -s /path/to/socket /tmp/mysql.sock
```

# ユーザ一覧見たいんですけど

```sql
SELECT * FROM mysql.user;
```

# ページャきれいにしたい

```sql
pager less -SinFX;
```

# ポート何番やねん

```sql
SHOW variables like 'port';
```

# dump でバックアップしたい

```bash
$ mysqldump -h $HOSTNAME -u $USER_NAME -p $DBNAME > mysqldump_`date +%Y%m%d`.sql  
# $DBNAME の前に -B を付けると "CREATE DATABSE ..." も出力される＆複数DB指定可
```

# `my.cnf` 何処の読み込んでる？

```bash
$ mysql --help | grep my.cnf
(略)
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
```
BetterTouchToolでアプリ再起動コマンド作成

BTTを用いて、macのウィンドウの赤いボタンを右クリックすると最前面のアプリが再起動するように設定してみました。

需要がまるで不明ですがメモ。
## 設定手順
1. BetterTouchToolの設定画面を開き、Otherタブを選択
2. トリガーとして「Rightclick Red Window Button」を選択
3. Predefined Actionとして「Open Application / File / Apple Script ...」を選択
4. 以下のAppleScriptを指定する(下のリンク先のものをまるまる引用している)

>[Applescript to Relaunch Frontmost App - Nerdy Thoughts](https://nickprokesch.wordpress.com/2012/10/10/applescript-to-relaunch-frontmost-app/)

> ```lang:relaunchapp.scpt
tell application "System Events" to set theApp to the name of the first process whose frontmost is true
tell application theApp
quit
set isRunning to true
repeat while (isRunning)
delay 1
tell application "System Events"
set isRunning to ((name of processes) contains theApp)
end tell
end repeat
do shell script "open -a " & quoted form of theApp
end tell
```

## 使用時の注意
赤ボタンの右クリックは最前面でないアプリに対しても有効ですが、あくまで再起動されるのは最前面のアプリです。
本当はマウスオーバーしているアプリの名前を取得するか、先に最前面に持っていくかしようと思ったのですが、方法がわかりませんでした。

というか無理という結論がちらほら見えているので([ここ](http://xahlee.info/linux/mouse_hover_auto-raise_window.html)とか[ここ](http://www.mac-forums.com/switcher-hangout/147916-mouse-click-window-activate-window.html)とか)、半ば諦めています。

ということで中途半端ですが、使うときにはそのアプリが最前面に出てるか確認してから使いましょう。
CSSで複数の属性セレクタを指定する

CSSで属性セレクタを指定する。

## 属性が一つの場合

```css
div[data-color="red"]{
    background-color: red;
}
```

## 属性が2つの場合

```css
div[data-color="red"][data-size="small"]{
    background-color: red;
    font-size: 10px;
}
```

### JSでも使える

```js
var colorVal = 'red';
var sizeVal = 'small';

$('div[data-color="' + colorVal + '"][data-size="' + sizeVal + '"]').show();

```
数字を金額表示する【JavaScript】

JavaScriptで金額表記する。

```js
var num = 12345;
changeYen(num); //¥12,345

function changeYen(num){
    return Number(num).toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' });
}
```

しかし、モバイルにはほとんど対応していなかった・・・
http://js.studio-kingdom.com/javascript/date/to_locale_string

しょうがない。。。

```js
var num = 12345;
changeYen(num); //¥12,345

function changeYen(num){
    return '¥' + String(num).split("").reverse().join("").match(/\d{1,3}/g).join(",").split("").reverse().join("");
}
```
[Rails]ActiveRecordのインスタンスをキャストする



このような，Aモデルを継承したBモデルがあるときに，AモデルのインスタンスをBにキャストしたいことがあると思います．


```ruby
class A < ActiveRecord::Base
	
end

class B < A

end

```

このようなActiveRecordのキャストには`becomes()`メソッドが使えます．

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-becomes



AのインスタンスをBにキャストしたいときは次のようになります．

```ruby
a = A.new()
b = a.becomes(B)
```

簡単ですね！

Javaとかの様に`b = (B)a`でキャストが出来なかったので，困っていました．
Capybara::Poltergeist::TimeoutError の対策


テストで poltergeist + phantomjs のエラーにはまったときのメモ

visit するときに以下の感じでエラーがでた。

```
 Capybara::Poltergeist::TimeoutError:
       Timed out waiting for response to {"name":"visit","args":["http://127.0.0.1:58884/xxx/yyy/new"]}. It's possible that this happened because something took a very long time (for example a page load was slow). If so, setting the Poltergeist :timeout option to a higher value will help (see the docs for details). If increasing the timeout does not help, this is probably a bug in Poltergeist - please report it to the issue tracker.
```

指示の通り timeout をのばしたらOKだった。
初期値は 30秒だが、assets のコンパイルが遅い環境などでエラーになる、みたい。

```Ruby:spec/support/capybara.rb
Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, phantomjs: Phantomjs.path, timeout: 50)
end
```
webapiにて生じた問題

やりたいこと Web APIを用いて、HTTPリクエストでjsonデータを取得すること


```
問題のあるコード

  private func showSongs() {
        let urlString = "https://itunes.apple.com/search?term=Ryuichi+Sakamoto&entity=musicTrack&limit=3&lang=ja_jp&country=JP"
        let url = NSURL(string: urlString)
        let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
        let dataTask = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
            if (error == nil){
            //ここから
                let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil) as! [String:AnyObject]
            //ここまでがExtra argument 'error' in call、つまりエラーになります。
                let results = json["results"] as! [[String:AnyObject]]
                for song in results {
                    let trackName = song["trackName"] as! String
                    println(trackName)
                }
            }
        })
        dataTask.resume()
    }
```



```

基本形(この形式だとerrorをはかないらしい) by stackoverflow

やりたいこと
jsonデータに形式を変更した値を取得し、出力する。
errorが空だったたら、処理を開始する。

書いたコード

func showSong(){
    do{
       let json =  NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments) as! [String:AnyObject] 
       let results = json["results"] as! [String:anyObjects]
       for song in results {
           let trackName = song["trackName"] as! String
           print(trackName)
    }
    catch{
      //ここは失敗した時のコードを記述する。
    }
}

```

```
基本形を土台に書き換えたコード
やはり、jsonのコードのところでbuildエラーする。

 
    private func showSongs(){
        let urlString = "https://itunes.apple.com/search?term=Ryuichi+Sakamoto&entity=musicTrack&limit=3&lang=ja_jp&country=JP"
        let url = NSURL(string: urlString)
        let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
        let dataTask = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
            do{
                let json =  NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments) as! [String:AnyObject]
                let results = json["results"] as! [String:anyObjects]
                for song in results {
                    let trackName = song["trackName"] as! String
                    print(trackName)
                }
        }
    })
    dataTask.resume()
}

```
Kinesis Firehose メモ


調べてちょいちょい追記する予定


## SDK (boto3) からputする

```python
import boto3

client = boto3.client('firehose')

data   = "1|1|1|2015-10-16\n"

response = client.put_record(
    DeliveryStreamName='my-stream-name-here',
    Record={
        'Data': data
    }
)

print(response)
```

## 制限など

* Buffer interval の最小値が 60秒なので、put_record してからS3に置かれるまで最大60秒かかる


## 資料

* [Developper Guide](http://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html)
* [APIリファレンス](http://docs.aws.amazon.com/firehose/latest/APIReference/Welcome.html)
* [re:Invent 2015 Youtube](https://www.youtube.com/watch?v=lkRoQlhWDXA)
* [re:Invent 2015 Slideshare](http://www.slideshare.net/AmazonWebServices/bdt320-new-streaming-data-flows-with-amazon-kinesis-firehose)
AWS LambdaのSchedule Eventを使ってSORACOM Airのステータスをコントロールしてみる


AWSのグローバルイベントre:Invent中にAWS Lambdaに様々な機能が追加されました。
中でもPython2.7対応やSchedule Eventは様々な方に影響があったのではないでしょうか。
Schedule Eventは、最小5分から設定して時刻イベントとしてLambda Functionを実行することができます。
時刻指定の方法は、CRONの表現で設定できます。

```
cron(Minutes Hours Day-of-month Month Day-of-week Year)
```

例えば、

毎日10:00amに実行したい場合

```
cron(0 10 * * ? *)
```

月曜日から金曜日の6:00pmに実行したい場合

```
cron(0 18 ? * MON-FRI *)
```

ちなみに、時刻はすべてUTCでの指定になります。
この機能は、CRONで実行している"よくある"バッチシステムで活用できる画期的な機能だと思っております。
もちろん、IoTの世界でもこの機能は使えます。
例えば、エネルギーシステムで、日の出から日の入りまでの間だけデータをクラウドにあげて夜は無駄な通信を抑制することが可能です。これをAPIで実行できるのがSoracomのパワーだと思います。
そこで、Lambdaの新機能（Python2.7とSchedule Event）とSoracom APIを使ってみます。

**AWS Lambda**

Pythonのコードは以下のとおりです。

```
import requests
import json

def handler(event, context):
    data = {}

    headers = {'Content-Type': 'application/json'}
    payload = {'email': 'YOUR MAIL ADDRESS', 'password': 'YOUR PASSWORD'}
    res = requests.post("https://api.soracom.io/v1/auth", headers=headers,data=json.dumps(payload)).text
    data = json.loads(res)
    apiKey = data['apiKey']
    token = data['token']

    print('apiKey: ' + apiKey +'/' + 'Token: ' + token)

    headers = {
      'Accept': 'application/json',
      'X-Soracom-Api-Key': apiKey,
      'X-Soracom-Token': token
    }

    res = requests.get("https://api.soracom.io/v1/subscribers?tag_value_match_mode=exact",headers=headers,data=json.dumps(payload)).text
    data = json.loads(res)
    imsi =  data[0]['imsi']
    status = data[0]['status']
    url = 'https://api.soracom.io/v1/subscribers/' + imsi + '/'

    if status == 'inactive':
        url = url + 'activate'
        print 'URL: ' + url
        res = requests.post(url,headers=headers).text
    else:
        url = url + 'deactivate'
        print 'URL: ' + url
        res = requests.post(url,headers=headers).text

    data = json.loads(res)
    return data['status']
```

現状のステータスに応じてActivateとInactivateにするとてもシンプルなものです。
マネジメントコンソールで、Python2.7を選択してzip化したファイルをアップロードします。

![1-1.png](https://qiita-image-store.s3.amazonaws.com/0/60724/88c792e2-1bec-2a0b-9879-7be77efc94df.png "1-1.png")

Event sourcesタブを選択します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/60724/a06fc148-c7d0-55cb-8097-df00a60b4b21.png "2.png")

Add event sourceをクリックして、Event source typeからScheduled Eventを選択します。
必要な情報を入力します。今回は、テストとして5分単位で実行するようにしてます。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/60724/8d197b27-d75e-0183-5e9d-0e4030830332.png "4.png")

これで設定は終わりです。
実行されているかSoracomコンソールで確認してみましょう。

最初は、Inactiveだったのですが、5分後は、Activeに変わってます。

![5−1.png](https://qiita-image-store.s3.amazonaws.com/0/60724/fb90d1f6-01b7-7566-b7e7-456c46305873.png "5−1.png")


![6−1.png](https://qiita-image-store.s3.amazonaws.com/0/60724/0069e5a5-6770-422e-eebc-e99d440787b8.png "6−1.png")

##最後に
APIでコントロールできるキャリア、とてもパワフルであることを実感できます。
また、AWS LambdaにSchedule Eventはとてもインパクトが有ると思ってます。


# 免責
こちらは個人の意見で、所属する企業や団体は関係ありません。
Sqlite 3.9 の Json1を試した

Sqlite 3.9 から、~~カラム型としてJSONが追加されたので、~~ (※)JSON文字列をデータとして扱えるようになったので、基本的な書き方を試してみた。
https://www.sqlite.org/json1.html

※ 初稿の表現に誤りがありました。
　sqlite3におけるカラム型は、それ自体が値の性質を決定するものではありません。
　(参照：https://www.sqlite.org/datatype3.html の最初の方)

## CREATE TABLE

```sql
CREATE TABLE json_test_table (
    id   INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR UNIQUE,
    json JSON -- NEW!
)
```

## INSERT

__json1 関数を利用したINSERT__

```sql
INSERT INTO json_test_table (
    name,
    json
)
VALUES (
    'test_name_1',
    json(json_object( -- objectは{}で囲うオブジェクト型のこと
        'key_for_int', 1,
        'key_for_str', 'test_str',
        'key_for_arr', json('[1, "a", 2, "b"]'), -- json()で囲わないと文字列として保存される
        'key_for_obj', json('{"c":3, "d":4}'),
        'attr_a',      'nice_attr'
    ))
);
```

__json文字列でINSERT__

```sql
INSERT INTO json_test_table (name, json)
VALUES (
    'test_name_2',
    json('{ -- json()は文字列も評価できる
        "key_for_int":2,
        "key_for_str":"test_str2",
        "key_for_arr":[5, "e", 6, "f"],
        "key_for_obj":{"g":7, "h":8},
        "attr_b":"good_attr"
    }')
);
```

## SELECT

__jsonの値を個別に取得__

```sql
SELECT 
    json_extract(json, '$.key_for_int')    as json_int, -- ルートを$として、jsのアクセサの記法で値を取得する
    json_extract(json, '$.key_for_str')    as json_str,
    json_extract(json, '$.key_for_arr[1]') as json_array_element_2,
    json_extract(json, '$.key_for_obj.d')  as json_array_object_d
FROM
    json_test_table
WHERE
    name = 'test_name_1'
```

__jsonの値を条件に使用する__

[_json_tree_](https://www.sqlite.org/json1.html#jtree)を利用した例。
値は_json_tree.value_で取得できる。

```sql
SELECT
    tree.value as attr_b
FROM
    json_test_table,
    json_tree(json_test_table.json, '$.attr_b') as tree -- attr_bをjson_treeとして取得する
WHERE
    tree.value IS NOT NULL
```

[_json_extract_](https://www.sqlite.org/json1.html#jex)を利用した例。

```sql
SELECT
    json_extract(json_test_table.json, '$.attr_b') as attr_b
FROM
    json_test_table
WHERE
    json_extract(json_test_table.json, '$.attr_b') IS NOT NULL
```

__JSON型カラムのデータをjson文字列として取得する__

[json_tree](https://www.sqlite.org/json1.html#jtree)にはjson文字列が_json_カラムに保存されている。

```sql
SELECT
    tree.json
FROM
    json_test_table,
    json_tree(json_test_table.json) as tree
WHERE
    name = 'test_name_1'
```

__jsonの値でORDER BYする__

```sql
SELECT
    name
FROM
    json_test_table
ORDER BY
    json_extract(json, '$.key_for_str') DESC
```

## 所感

__pros__

- json文字列が用意できれば保存するのは簡単
- JSONでもソートや検索条件が指定できたり、他のデータと結合できるのは利点

__cons__

- JSONデータの扱い方が簡便でない
- アプリ向けにラッパーAPIを用意するのが大変そう

__both__

- スキームを無視してキーが可変長なデータを扱える
Ruby で EC2インスタンスにつけた tag の値をサーバー内から取得する

## 背景
* AWS のタグを Ruby で取得したい
* AWS のアクセス用クレデンシャルとかの面倒な設定はヤだ
* カンタンに取得したい

## やったこと
* IAM ロールを使って、EC2 のアクセス権を設定
  * AWS クレデンシャルとかの環境変数は設定せず
  * AWS-CLI を内部的に利用する
* タグの値を切り出すのは JMESPath を利用
* 内部的に `ec2-metadata` コマンドを利用
  * リージョンの取得
  * インスタンスID の取得
  * http://169.254.169.254/latest 以下にアクセスするより速い
* リージョンは Availability Zone から最後の1文字を除去
* `describe-instances` か `describe-tags` かは悩んだ
  * 結局エイヤと `describe-instances` を使うことに決めた。

## 実装の詳細

```
# module to retrive AWS EC2 tag
module AwsMetaData
  def self.availability_zone
    `ec2-metadata --availability-zone | sed 's/placement: //'`.chomp
  end

  def self.region
    availability_zone[0...-1]
  end

  def self.instance_id
    `ec2-metadata --instance-id | sed 's/instance-id: //'`.chomp
  end

  def self.ec2 command
    commandline = "aws --region #{region} --output text ec2 #{command}"
    `#{commandline}`.chomp
  end

  def self.tag key
    jamespath = "Reservations[].Instances[].Tags[?Key=='#{key}'].Value"
    instance = "--instance-ids #{instance_id}"
    ec2 %(describe-instances #{instance} --query #{jamespath})
  end
end
```

## 参考文献
* http://qiita.com/hash/items/40006f91d4864ceaf991
* http://qiita.com/tt2004d/items/46ea80cd7cb20212e50e
* http://stackoverflow.com/questions/625644/find-out-the-instance-id-from-within-an-ec2-machine
* http://stackoverflow.com/questions/4249488/find-region-from-within-ec2-instance
* http://stackoverflow.com/questions/3883315/query-ec2-tags-from-within-instance
Macでgitの歴史からパスワードを削除するコマンド

記事の内容はこちらを参照してください。
https://mishimay.github.io/aac4d36548c611f4ff01/
<!--

**<font color=red>Mac</font>でのコマンド例です**

パスワードを直書きしたファイルをgitで管理してしまっていて、そのパスワードをgitの歴史から抹消したいときに使用できます。
歴史上のすべてのpasswordが空文字に置き換わります。
下記コマンド例の `*.h` とか `password` とかは適宜書き換えてください。

```
git filter-branch --tree-filter "find . -name '*.h' -exec sed -i '' -e 's/password//g' {} \;" -- --all
```

- 上記例は `password` 文字列を置き換えるというものです。置き換えようとしているパスワードの文字列がパスワード以外の部分で使用されていればそれも置き換わることになるので注意してください
- **sed の -i オプションの挙動がLinuxとMacで異なる** みたいなのでMac以外で上記コマンドは使用しないでください (cf. http://qiita.com/catfist/items/1156ae0c7875f61417ee)
- 歴史上から該当パスワードを抹消するためには、上記コマンド実行後にリモートリポジトリに force push する必要があります
- **リポジトリに force push するときは細心の注意を払ってください**
  - コマンド実行後に変な部分が書き換わってないか確認
  - force push するときに他のチームメンバーが作業中ではないか確認
  - できれば以前のリポジトリをバックアップ用に保存しておく




-->
KeePassXなどから1Passwordへのインポート

Mac版[1Password](https://itunes.apple.com/jp/app/1password/id443987910?mt=12)がセールをしてた(2015/10/16)ので移行してみた。

こちらで公開されている
**Convert to 1Password Utility**
を使用します。
https://discussions.agilebits.com/discussion/30286/mrcs-convert-to-1password-utility/p1

#サポートしてるパスワード管理ソフト
- 1Password (for printing)
- Clipperz
- DataGuardian
- DataVault
- EssentialPIM
- eWallet
- Handy Safe
- IronKey Identity Manager
- Keepass 2
- KeepassX
- OS X Keychain
- LastPass
- LicenseKeeper
- mSecure
- Norton Identity Safe
- Passpack
- Password Agent
- Password Depot
- PasswordWallet
- Safe in Cloud
- SafeWallet
- SPB Wallet
- SplashID
- vCard (OS X Contacts export)

#ダウンロード
[AgileBits Utilities](https://www.dropbox.com/sh/a3skeey2zqimdlv/AAD87q6N_EJZ1YoPe5SA35a1a?dl=0)
こちらのDropboxフォルダ直下のconvert_to_1p4_XXX.zipを。
プレリリースの版なら_testingフォルダ内のものを。

#エクスポート
自分はKeePassXを使用してるので
解凍したフォルダ内のREADMEの通りにXML形式で書き出し
>Launch KeePassX, and export its database to a text file using the File > Export to > KeePassX XML File... menu. Navigate to your Desktop folder, and save the file with the name pm_export.txt to your Desktop. You may now quit KeePassX.

#コンバート
1Password形式に変換する。
解凍したフォルダ内の**AppleScript_Conversion_Helper.app**を開く。
開けない場合は右クリック(ctrl+クリック)→開く

![1psw2.png](https://qiita-image-store.s3.amazonaws.com/0/4169/836a6a03-b8b7-c98f-2625-947469884285.png)
表示ウィンドウから変換対象を選択→書き出したパスワードファイル選択
成功したらこんな感じにターミナルに表示される。
![1psw.png](https://qiita-image-store.s3.amazonaws.com/0/4169/b4efa83e-41a4-ad93-ffcc-fee40abbeb9c.png)

#インポート
1Passwordでインポート。
そして幸せへ。

#動作環境
- OS 10.10.5
- KeePassX 0.4.3
- 1Password 5.4

日本語文献が無い為記述
Nodejs4+socket.io+redisAdapterでシンプルなNode.jsサーバーを作る

## 環境概要

* NodeJS v4.2.1
* Socket.io v1.3.7

Socket.ioがv1.3.7から4に対応して動作確認が取れたので更新しました

## 作る

今回はシンプルに。そういえばSocket.ioってhttpも扱ってるからhttpサーバーを渡す必要があるんですね。

```js
var http         = require('http');
var socketIo     = require('socket.io');
var redisAdapter = require('socket.io-redis');

var server = http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Node.js server.');
});

var io = socketIo.listen(server);
io.adapter(redisAdapter({host: '127.0.0.1', port: '6379'});

server.listen(8080);
```

## セッション共有

socket.ioも便利になって、セッション共有楽になりましたよね。

```js
var cookieParser = require('cookie-parser')();
var session = require('cookie-session')({ secret: 'secret key'});

io.use(function(socket, next) {
    var req = socket.request;
    var res = {};
    cookieParser(req, res, function(err) {
        if(err) return next(err);
        session(req, res, next);
    });
});
```

## io周り

```js
io.sockets.on('connection', function(socket) {
    // 処理内容
});

// 名前空間切る場合
var ActivityIo = io.of('/activity');
ActivityIo.on('connection', function(socket) {
    // 後は一緒
});
```

## 最後に

おーわり。
何か間違えているかもなので、間違えてたら教えていただければ幸いです。

最近になってやっとNode.jsとSocket.io分かるようになってきたので嬉しい
Hubotを環境作ってIRCとSlackで動かす

Ubuntu14.04でとりあえず確認

# Node.js環境
http://qiita.com/TsutomuNakamura/items/7a8362efefde6bc3c68b

## NVMを入れる

```
$ sudo apt-get update
$ sudo apt-get install build-essential libssl-dev
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.2/install.sh | bash
$ source ~/.bashrc
```

```
$ nvm --version
```

## Node.jsを入れる

```
$ nvm ls-remote
$ nvm install v4.1.2
$ node -v
```

ついでにデフォルトにもしておく

```
$ nvm alias default 4.1.2
```

## yeomanを入れる

```
$ npm install -g yo
```

# Hubot
## hubotを入れる
http://qiita.com/bouzuya/items/11c0c6da2b3ad54b827f

```
$ npm install -g yo generator-hubot
```

## botを作る(bot名はsharl)

hubot --create sharlとすると怒られて以下のcommandが出るので打つ

```
$ npm install -g yo generator-hubot
$ mkdir -p sharl
$ cd sharl
$ yo hubot
```

作者とか適当に入れる

```
$ ./bin/hubot -a shell -n sharl
```

コンソールが開く

```
sharl> sharl ping
sharl> PONG
```

動いた！

# IRC連携
## hubot-ircを入れる
https://github.com/nandub/hubot-irc

### セットアップ

「Installation and Setup」に沿って実行

```
npm install hubot-irc --save && npm install
```

### 起動

```
HUBOT_IRC_SERVER="example.com" \
  HUBOT_IRC_ROOMS="#test" \
  HUBOT_IRC_NICK="sharl" \
  HUBOT_IRC_UNFLOOD="true" \
  bin/hubot -a irc --name sharl
```

IRC

```
00:29 miyay: @sharl ping
00:29 sharl: PONG
00:30 miyay: @sharl echo hoge
00:30 sharl: hoge
00:30 miyay: @sharl echo ほげ
00:30 sharl: ほげ
```

# Slack連携
## Slack側

1. 左上のチーム名のところを押して「Team Settings」を開く
1. 左上の「menu」を押し、「Integrations」を開く
1. Hubotを選び「view」
1. 名前を決め、「Add Hubot Integration」
1. アイコンとかチャンネルとか決めて「Add Hubot Integration」
1. 生成されるTokenをメモる
 * というか起動に必要な環境変数がそのまま表示される

## Hubot側
### hubot-slackを入れる

```
npm install hubot-slack --save
```

### 起動

```
HUBOT_SLACK_TOKEN=トークン     bin/hubot -a slack
```

シェルスクリプトとかにしとくと便利
Sensu Filter実践例


先日の[Sensu Deep Talks #2](http://sensu-talks.connpass.com/event/19515/)では「[Filter・Mutator・Aggregateの使いドコロ](http://www.slideshare.net/hico_horiuchi/filtermutatoraggregate)」を発表しました．
今回は補足として，実際に[最所研究室](https://air.eng.kagawa-u.ac.jp/)で使用しているFilterの設定を紹介します．

## アラート通知数の削減

実験等で継続的にサーバに負荷を掛けている場合，アラートが大量に通知されることがあります．
それを防ぐために，以下の2つの条件でフィルタリングしています．

  - Checkの終了ステータスが2(CRITICAL)以上の場合
  - 最初のアラート(Occurrencesが1)の場合

本番環境では使い辛いかもしれませんが，PagerDutyからの電話が鳴り続けるのは防げると思います．

```json:/etc/sensu/conf.d/filter-recurrence.json
{
  "filters": {
    "recurrence": {
      "attributes": {
        "check": {
          "status": "eval: value > 1"
        },
        "occurrences": 1
      }
    }
  }
}
```

## サーバーメンテナンス中の通知無効

研究室では金曜日の20〜21時にサーバの定期メンテナンスを行っています．
(全サーバのaptの更新と，必要に応じて再起動．)
パッケージ更新で負荷が上がったり，一度に行うのでハイパーバイザが悲鳴を上げたりします．

そこで，強引ですがメンテナンス中のアラートは無条件で通知しないことにしました．
メンテナンスの時間で，Checkの実行時刻(Executed)をフィルタリングしています．
注目して欲しいのは，`"negate": true`で条件を逆転させている点です．
これで「メンテナンスの時間以外」はフィルタリングされません．

```json:/etc/sensu/conf.d/filter-maintenance.json
{
  "filters": {
    "maintenance": {
      "attributes": {
        "check": {
          "executed": "eval: Time.at(value).wday == 5 && Time.at(value).hour == 20"
        }
      },
      "negate": true
    }
  }
}
```

## おまけ

最近，研究室で利用するチャットをSlackに乗り換えました．
それに合わせて，SensuからSlackに[Incoming Webhooks](https://api.slack.com/incoming-webhooks)を使って通知するHandlerをGo言語で書きました．
(以前は[hubot-sensu](https://github.com/hico-horiuchi/sensu-hubot)を使ってアラートをTypetalkに通知していました．)

  - [hico-horiuchi/sensu-plugins-go/handler-slack.go](https://github.com/hico-horiuchi/sensu-plugins-go/blob/master/handler/handler-slack.go)

![handler-slack.png](https://qiita-image-store.s3.amazonaws.com/0/58742/c750ea58-b164-8222-336a-5c4c605519c2.png "handler-slack.png")
フォーカスを持ち続けるInputField

以下のスクリプトを InputField に Add Component

```
using UnityEngine;
using UnityEngine.UI;

public class InputFieldFocus : MonoBehaviour {
	void Start() {
		InputField i = this.GetComponent<InputField>();
		i.ActivateInputField();	//InputFieldにフォーカスを持たせる
		i.onEndEdit.AddListener(
			delegate(string text) {
				if (!string.IsNullOrEmpty(text)) {
					Debug.Log(text);	//textの送り先
					i.text = "";
				}
				i.ActivateInputField();	//InputFieldにフォーカスを持たせる
			}
		);
		//4.6xではこの処理がないとEnterを押した後、InputFieldに改行が入ってしまう(Single Line設定でも)
		//5.2xでは要らないのでコメントアウト
//		i.onValidateInput += delegate(string _1, int _2, char c) { return c == '\n' ? '\0' : c; };
	}
}
```

この処理はGameビューに表示させるデバッグ用コンソールウィンドウ(デバッグコマンド入力ができるもの)で使うInputFieldとか、チャットウィンドウで使うInputFieldで使用。

シーン開始直後からフォーカスを持つので、すぐに文字入力できる。
Enterで入力を完了した後も、InputFieldに入力した文字をクリアして、すぐにフォーカスを持つので、続けて文字入力可能。
PC(Windows)でしか動作確認していないので、モバイルでの動作は不明。
cssでテキスト点滅 


今は懐かしい blink タグの代わり

```css 
@-webkit-keyframes blink {
  0% { opacity:0; }
  100% { opacity:1; }
}
@-moz-keyframes blink {
  0% { opacity:0; }
  100% { opacity:1; }
}
@keyframes blink {
  0% { opacity:0; }
  100% { opacity:1; }
}
```

SASSで待機時間指定出来るようにして使ってる。

```css 
@mixin blink( $wait ) {
  -webkit-animation:blink #{$wait}s ease-in-out infinite alternate;
  -moz-animation:blink #{$wait}s ease-in-out infinite alternate;
  animation:blink#{$wait}s ease-in-out infinite alternate;
}
```
PHPのモダンなテスティングフレームワークのCodeceptionを使ってみた

Codeception?

* フルスタックなテスティングフレームワーク
* 単体テスト、機能テスト、受け入れテストをサポート
* 内部はPHPUnit

あ、今回は受け入れテストのみやってみます。Seleniumと連携するまで。

```composer.json
"require-dev": {
    "codeception/codeception": "*"
  }
```

```bash
composer update
```

準備！

```bash
./vendor/bin/codecept bootstrap
```

受け入れテスト作成

```
./vendor/bin/codecept generate:cept acceptance SignIn
```

できた。　```/tests/acceptance/SignInCept.php```

Seleniumインストール(Mac)

```bash
brew install selenium-server-standalone
```

Selenium起動

```bash
selenium-server
```


```acceptance.suite.yml
class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver:
                 url: 'http://localhost/'
                 browser: firefox
```

```php:SignIn.php
$I = new AcceptanceTester($scenario);

$I->wantTo('Sign In');
$I->amOnPage('/');
$I->fillField('userid', 'admin');
$I->fillField('password', 'admin');
$I->click('ログイン');
$I->see('ログインしました。');
```

```bash
./vendor/bin/codecept run
```

これでブラウザが起動して、フォームに入力して、ログインボタンクリックしたら何が表示されるかまでテストしてくれます。

```bash
Codeception PHP Testing Framework v2.1.3
Powered by PHPUnit 4.8.13 by Sebastian Bergmann and contributors.

Acceptance Tests (1) ------------------------------------------------------------------------------------------
Sign in (SignInCept)                                                                                      Ok
---------------------------------------------------------------------------------------------------------------


Time: 8.06 seconds, Memory: 11.50Mb

OK (1 test, 1 assertions)
```

# 参考

Codeception - BDD-style PHP testing.
http://codeception.com/
SparkとJava8のファイルダウンロードサンプル

[Spark-Java](http://sparkjava.com/) のファイルダウンロードサンプル。
Servletでの処理そのまま。

起動してhttp://localhost:4567/file にアクセスするとプロジェクトのroot/public/資料.xlsxがダウンロードされる。

```Java:DownloadFileSample
package spqrk;

import static spark.Spark.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import spark.utils.IOUtils;

public class HelloWorld {

	public static void main(String[] args) {

		before("/hello", (req, res) -> {
			System.out.println("/helloの前処理");
		});

		get("/hello", (req, res) -> {
			System.out.println("/hello");
			return "Hello Spark World";
		});

		get("/file", (req, res) -> {
			System.out.println("ファイルをダウンロード");

			// ダウンロードファイルの作成
			String fileName = "資料.xlsx";

			// プロジェクトのroot/public/ フォルダが使用される。
			File file = new File("public/" + fileName);
			String savePath = file.getAbsolutePath();

			System.out.println("ダウンロードするファイル=" + savePath);

			byte[] fileContent = null;
			try (InputStream is = new FileInputStream(savePath);) {
				fileContent = IOUtils.toByteArray(is);
			} catch (FileNotFoundException e) {
				throw new RuntimeException(fileName + " not found");
			} catch (IOException e) {
				throw new RuntimeException(e);
			}

			// ファイル名の文字化け対策。
			String downName = URLEncoder.encode(fileName, "UTF-8");

			res.raw().setContentType("application/octet-stream");
			res.raw().setHeader("Content-Disposition", "attachment; filename=" + downName);
			res.raw().setContentLength(fileContent.length);

			try (OutputStream os = res.raw().getOutputStream();) {
				os.write(fileContent);
				os.flush();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}

			return "";
		});

	}
}

```
Finderの現在地をターミナルで開くボタン

#ゴール
カレントフォルダをターミナルで開くボタンを作る
![Screenshot 2015-10-16 17.50.33.png](https://qiita-image-store.s3.amazonaws.com/0/96637/315fb184-034f-e673-d495-947ed22609f8.png)



#やりかた
Automaterを開き，"Application"を選択
![Screenshot 2015-10-15 17.27.31.png](https://qiita-image-store.s3.amazonaws.com/0/96637/33f35c07-bf2a-c410-d56b-6189a20631bc.png)
"Get Selected Finder items"をワークスペースにドロップ
![Screenshot 2015-10-15 17.28.03.png](https://qiita-image-store.s3.amazonaws.com/0/96637/043e5998-7a06-796c-6c08-10edd3feb41e.png)

"Run AppleScript"を同様にドロップ
![Screenshot 2015-10-15 17.28.30.png](https://qiita-image-store.s3.amazonaws.com/0/96637/381e5876-c140-d241-f45b-497162f6929d.png)

ダミーのコードを消し，以下をペースト

```applescript:
on run {input, parameters}
	tell application "Finder"
		set myWin to window 1
		set theWin to (quoted form of POSIX path of (target of myWin as alias))
		tell application "Terminal"
			activate
			tell window 1
				do script "cd " & theWin
				-- do script "cd " & theWin & ";ls -al | more"
			end tell
		end tell
	end tell
	return input
end run
```



`⌘+s`で"ファイル名.app"を保存する．（名前は適当に）
保存した場所へFinderで行き，⌘を押しながら"ファイル名.app"をFinderのツールバーにドロップ．

#おまけ
アイコンがかっこ悪いので，好きなものに変えましょう．

1. "ファイル名.app"を選択し`⌘+i`
2. このアイコン![icn.png](https://qiita-image-store.s3.amazonaws.com/0/96637/a2514475-6803-5a88-bb36-664996aa0c33.png)
を直接オートメータさんへドロップ

![Untitled.tiff](https://qiita-image-store.s3.amazonaws.com/0/96637/982adba1-49da-6120-b552-e330d3a14c78.tiff)


#参考
http://www.macworld.com/article/1047793/folderinterm.html
Percent Support Libraryを使ってレイアウトを％指定する

**Percent Support Libraryはdeprecatedになりました。**

タブレット対応で画面サイズに併せて引き伸ばしたかったので使ってみた

# 準備
``` groovy:build.gradle
dependencies {
    compile 'com.android.support:percent:23.0.0'
}
```

# 書き方
下記のような感じで `android:layout_width` の代わりに `app:layout_widthPercent` が使える
**android:じゃなくてapp:なので間違えると死ぬ**
※ app:部分は任意の文字列が使えますがxmlns:で定義した名前空間と合ってないと死にます

```xml
<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        app:layout_widthPercent="80%"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true">
    </RelativeLayout>
</android.support.percent.PercentRelativeLayout>
```
だいたいこんな感じ

|属性名|役割|
|----|----|
|layout_widthPercent|要素の横幅を%指定する|
|layout_heightPercent|要素の高さを%指定する|
|layout_marginPercent|マージンを%指定する|
|layout_marginLeftPercent|左側のマージンを%指定する|
|layout_marginTopPercent|上側のマージンを%指定する|
|layout_marginRightPercent|右側のマージンを%指定する|
|layout_marginBottomPercent|下側のマージンを%指定する|
|layout_marginStartPercent|左(RTL環境では右)からのマージンを%指定する|
|layout_marginEndPercent|右(RTL環境では左)からのマージンを%指定する|
|layout_aspectRatio|アスペクト比を維持したまま%指定する|

詳細は[Android Developerのページ](https://developer.android.com/intl/ja/reference/android/support/percent/PercentRelativeLayout.html)を確認しよう

# 追記: xml側の％指定
```xml:dimens.xml
<dimen name="hoge">80%</dimen>
```
とかやってるとエラー吐いてビルド出来ないので

```xml:dimens.xml
<item name="hoge" type="dimen">80%</dimen>
```
とする
PHPマニュアルから関数をコピーするボタンを追加するユーザースクリプト

[PHPマニュアル]から関数を

```php
function(, )
```

形式でクリップボードにコピーします。

[Qiitaのコードにコピーボタンを追加するユーザースクリプト]
の使い回しです。

# <i class="fa fa-cogs"></i> 動作確認環境

`Windows7` + `Firefox41` + `Greasemonkey`
今回も
`Firefox`のスクラッチパッド機能で開発→`Greasemonkey`へ貼り付け
なので、`Greasemonkey`依存は無いはずです。

# <i class="fa fa-desktop"></i> デモ

![php man.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/48bd03c8-6604-3389-77f5-78949d938a83.gif)


# <i class="fa fa-code"></i> コード

[copy_function.user.js]

```js:copy_function.user.js

// ==UserScript==
// @name        copy function
// @namespace   khsk
// @description 関数説明から関数をコピーするスクリプト
// @include     http://php.net/manual/*/*
// @include     http://www.php.net/manual/*/*
// @include     http://jp.php.net/manual/*/*
// @version     1
// @grant       none
// ==/UserScript==

console.time('Copy function')
delete console.log;
var button = document.createElement('button')
button.innerHTML = 'Copy'
button.addEventListener('click', function(e){
  e.preventDefault() 
  if (!document.queryCommandSupported('copy')) {
    alert('copyに対応していません')
    return
  }
  if (typeof span === "undefined") {
    // グローバルにコピーする要素を作成する
    span = document.createElement('span')
    // 関数名の取得
    var methodName = document.getElementsByClassName('methodname')[0].textContent
    // ,数の取得
    var comma = '';
    var method = document.getElementsByClassName('methodsynopsis dc-description')[0].textContent
    var pos = method.indexOf(",")
    while ( pos != -1 ) {
      comma += ', '
      pos = method.indexOf(",", pos + 1);
    }
    span.innerHTML = methodName + '(' + comma + ')'
    span.id = 'userCopy'
    document.getElementsByTagName('body')[0].appendChild(span)
  }

  // 手動の選択状態を解除する
  window.getSelection().removeAllRanges();
  // コピー対象を選択状態にする
  // 表示されないと選択できないので一時解除
  span.style.display = '';
  var range = document.createRange()
  range.selectNode(span)
  window.getSelection().addRange(range)
  try {
    document.execCommand('copy')
  } catch (e) {
    alert('copyに失敗しました')  
  }
  // 選択を解除する
  window.getSelection().removeAllRanges();
  span.style.display = 'none';
})

document.getElementsByClassName('methodsynopsis dc-description')[0].appendChild(button)

console.timeEnd('Copy function')

```

# <i class="fa fa-tasks"></i> 課題

1. オプション引数のカンマを含めるかどうかの設定
2. 関数が複数書かれている場合の対応
3. 実行URLの調整

チェックをあまりしていないので対応できていない関数ページも多いと思います。
マニュアルのURL構成が、
`http://php.net/manual/*/funciton.*`
ではすべてカバーできないみたいなので、一旦
`http://php.net/manual/*/*`
にしています。
関数ページ以外はエラーで停止している状態だと思います…

***


直接クリップボードを操作することは難しかったので、目的のテキストを持った要素を新規に追加して、それに対してコピーしました。

[PHPマニュアル]:http://php.net/

[Qiitaのコードにコピーボタンを追加するユーザースクリプト]:http://qiita.com/khsk/items/27a80755d883521ecd73

[copy_function.user.js]:https://gist.github.com/khsk/8a67fb0fdb968d5a6114/raw/89861c58e10b7e1e8b55bf9a7cd91cc0180301c1/copy_function.user.js
jarファイルの中身を見る・一部分抽出・一部分書き込み－覚書

hoge.jarの中身を解凍せずに、中身を見たり抽出したりして、修正したあとに書き込みたい。
jar xvfで解凍するのが面倒な時に。

# やり方
- jarファイルの中身を見る
`jar tf [jarファイル名]`

- jarファイルの中身一部分を抽出
`jar -xvf [jarファイル名] [抽出するファイル名] [ディレクトリ名]`

- jarファイルの中身一部分書き込み
`jar -uf [jarファイル名] [書き込むファイル名] [ディレクトリ名]`

# 実際の例
```sh:hoge.jarの中身
$ jar tf hoge.jar
META-INF/
META-INF/MANIFEST.MF
com/hoga/foo.class
com/hoga/bar.xml
piyo.xml
```

```sh:piyo.xmlの抽出
$ jar -xvf hoge.jar piyo.xml
```

※実行したディレクトリ配下に「piyo.xml」ファイルが置かれる。

```sh:piyo.xmlファイルの書き込み
$ jar -uf hoge.jar piyo.xml
```

`com/hoga/bar.xml`を抽出したいときはディレクトリ名の指定をする。

```sh:bar.xmlの抽出
$ jar -xvf hoge.jar bar.xml com/hoga
```

※実行したディレクトリ配下に「com/hoga/bar.xml」が置かれる。
Grouped UITableViewのヘッダーの高さを0にする

# Solution

ヘッダーの高さは`heightForHeaderInSection`で指定すればいいのですが、ここで`0`を指定するとデフォルトの高さになってしまうので、代わりに`CGFloat.leastNormalMagnitude` を使います。

```swift

extension HogeViewController: UITableViewDelegate, UITableViewDataSource {
  func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    CGFloat.leastNormalMagnitude
  }
}
```

# 参考

* [How to change height of grouped UITableView header?](http://stackoverflow.com/questions/17699831/how-to-change-height-of-grouped-uitableview-header)
PHPUnit、Seleniumでエンドツーエンドテスト


以前Railsでは[こんな感じ](http://qiita.com/shunhikita/items/d02cc313496e26bb69e1)でテストしてたけどPHP案件だし、PHPでエンドツーエンドテスト書くかーってなってちょっと試してみたメモです。



Composerまではインストールしてある想定で話を進めます。

```json:composer.json
"require-dev": {
    "phpunit/phpunit": "4.8.*",
    "phpunit/phpunit-selenium": ">=1.2"
  }
```


phpunitコマンドを使うためにパスを通す。

```export PATH=$PATH:~/.composer/vendor/bin/```

パスが通っているかどうかを確認。

```phpunit --version```

テスト！

```php:login.php

class Login extends PHPUnit_Extensions_Selenium2TestCase
{

  public function setUp()
  {
    $this->setBrowser('firefox');
    $this->setBrowserUrl('http://example.com');
  }

  public function testOpenLoginForm()
  {
    $this->url('http://www.example.com/');
    $this->assertEquals('ログイン画面', $this->title());
  }

}
```

実行！

```
phpunit login.php
```

とりあえず動かすまで^^;

## 参考

https://phpunit.de/manual/3.7/ja/selenium.html
http://qiita.com/Butackle/items/61d932af17ccc1557fe8
急にVimを使うことになったとき

#はじめに
パソコンで共同作業している時に、急に友達や先輩から
「じゃあVimでこのファイル開いて」
と言われることがある。使うのが初めてor久しぶりだと、どうすればいいかわからなくなるもの。しかし、相手にわざわざ聞くのも恥ずかしい。そんな状況で役立つメモを書きました。なのでVimを使いこなせ！という主旨とは違います。
#Vimを使ってファイルを作成/編集
ターミナルを起動、作業するディレクトリへ移動する。(ディレクトリとはフォルダみたいなもの)

|コマンド名|意味|
| --- | --- |
|cd|ディレクトリの移動|
|ls|現在のディレクトリの表示|
|mkdir|ディレクトリを新しく作る|

作業したいディレクトリに移動したら

```
vi ファイル名.拡張子
```

と打つと、そのファイル名がそのディレクトリに存在しないなら新規作成、存在するなら編集となる。
#Vimの画面を開く
試しに下のようなコマンドを打ってみよう。

```
vi test.txt
```

![image](https://qiita-image-store.s3.amazonaws.com/0/95933/f94bde52-035e-2153-c98b-31d41b298e07.png)
このような画面が表示されただろうか。
#文字を書き込む
この状態で"i"を入力すると**ノーマルモード**から**入力モードになる**

![image](https://qiita-image-store.s3.amazonaws.com/0/95933/6db41acd-4b8d-32d1-3b37-4ea809c235a5.png)

-- INSERT -- と表示されただろうか、この状態が**入力モード**である。
では好きなように文字を入力しよう。

![image](https://qiita-image-store.s3.amazonaws.com/0/95933/381780e3-5117-50f9-4e17-54b0acc87028.png)

#ファイルを保存する
ファイルを保存したい時は**入力モード**から**ノーマルモード**に戻る必要がある。そのためには```escキー```を押そう。
ノーマルモードになったら

```
:w
```

コロン,w,と打ち込むと保存できる。そして

```
:q
```
を打つと終了し、ターミナルの画面に戻る。実際の画面はこんな感じ。

![image](https://qiita-image-store.s3.amazonaws.com/0/95933/29ac6e2e-9f70-ed4c-ff75-9f5fa4cbfdcc.png)

Vimの基本的なコマンドについてはこのページに一覧があるので参考までに
http://motw.mods.jp/Vim/command.html

とりあえず、これができれば最低限の編集はできるでしょう。
図形の実寸印刷（with PowerPoint）

実寸大の図形を印刷する必要があったのですが，
いろいろググってもパワポでやる方法がなかったので，
図形はなんでもパワポで描いちゃうおじさんの僕は困ってしまいました．

でも，頑張ったらなんとかなったので，シェアします．
（Qiitaのネタとしてはなんかビミョーですが...）

# 手順

1. 図形で白い四角を描く．（枠線はなしで）
2. その図形を右クリック→「配置とサイズ」を選択．高さと幅を印刷したい用紙のサイズに設定．(A4なら21.0x29.7cm)
3. その白図形の上に印刷したい図形を描き，同様にして必要なサイズに「配置とサイズ」で設定．
4. 描き終えたら白図形も含めてすべて選択し，右クリック→「図として保存」で保存する．
5. 保存した画像を「写真をフレームに合わせる」を選択して印刷．
6. 完成！

※ ただし，プリンタ側でヘンな余白が入ったりする場合があるので，
プリンタによっては印刷プロパティで余白をなくす必要があることがあります．

自分の環境では富士ゼロックスのプリンタは印刷プロパティで余白を消せたのですが，
Canonのプリンタはプロパティで設定できず，ちょっっっとだけ図が縮小されて余白をつけてくるので，印刷されたサイズを測って図の方をうまくちょっと大きくして印刷することで実寸の図形を印刷できました．
30分間React.jsチュートリアルで作ったLikeButtonコンポーネント

[30分間React入門「いいねボタン」作成チュートリアル](http://www.craftsman-software.com/blog/2015-10-16-react-js-tutorial/)で作った「いいね」ボタンのコンポーネントです。

![4.gif](https://qiita-image-store.s3.amazonaws.com/0/889/5a5fde14-ecb8-da82-0793-2e40f0824ede.gif)


```js:LikeButton
class LikeButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hovered: false,
      count: 999,
      liked: false
    }
  }

  styles() {
    return {
      container: {
        fontFamily: "helvetica, arial, 'hiragino kaku gothic pro', meiryo, 'ms pgothic', sans-serif",
        fontSize: 11
      },
      like: {
        display: "inline-block",
        background: "#3b5998",
        padding: "0px 5px",
        borderRadius: 2,
        color: "#ffffff",
        cursor: "pointer",
        float: "left",
        height: 20,
        lineHeight: "20px"
      },
      likeHover: {
        background: "#444"
      },
      counterBefore: {
        display: "block",
        float: "left",
        width: 6,
        height: 6,
        background: "#fafafa",
        marginLeft: "-12px",
        borderRight: 10,
        transform: "rotate(45deg)",
        WebkitTransform: "rotate(45deg)",
        marginTop: 6,
        borderLeft: "1px solid #aaa",
        borderBottom: "1px solid #aaa"
      },
      counter: {
        display: "block",
        background: "#fafafa",
        boxSizing: "border-box",
        border: "1px solid #aaa",
        float: "left",
        padding: "0px 8px",
        borderRadius: 2,
        marginLeft: 8,
        height: 20,
        lineHeight: "20px"
      }
    };
  }

  onMouseEnter() {
    this.setState({hovered: true});
  }

  onMouseLeave() {
    this.setState({hovered: false});
  }

  onClick() {
    this.setState({
      count: this.state.count + (this.state.liked ? -1 : 1),
      liked: !this.state.liked
    });
  }

  render() {
    const styles = this.styles();
    const likeStyle = this.state.hovered ? {...styles.like, ...styles.likeHover} : styles.like;
    return (
      <span style={styles.container}>
        <span
          style={likeStyle}
          onMouseEnter={::this.onMouseEnter}
          onMouseLeave={::this.onMouseLeave}
          onClick={::this.onClick}>{this.state.liked ? "✔ " : ""}いいね！</span>
        <span style={styles.counter}>
          <span style={styles.counterBefore}>{" "}</span>
          {this.state.count}
        </span>
      </span>
    );
  }
}


```
Away3D_Basic

away3d-core-fp11_4_1_6.swcで動作。
基本の基本。

package 
{
	import away3d.containers.View3D;
	import away3d.entities.Mesh;
	import away3d.materials.ColorMaterial;
	import away3d.primitives.PlaneGeometry;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Vector3D;
	/**
	 * ...
	 * @author umhr
	 */
	public class Away3D_Basic extends Sprite
	{
		
		private var _view:View3D;
		private var _mesh:Mesh;
		public function Away3D_Basic() 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			_view = new View3D();
			_view.antiAlias = 2;
			_view.backgroundColor = 0x000000;
			_view.width = stage.stageWidth;
			_view.height = stage.stageHeight;
			addChild(_view);
			
			_view.camera.z = -1000;
			_view.camera.y = 0;
			_view.camera.lookAt(new Vector3D());
			
			// BitmapDataでテクスチャを作る場合
			//var texture:Texture2DBase = Cast.bitmapTexture(new BitmapData(256, 256, true, 0xFFFF0000));
			//var textureMaterial:TextureMaterial = new TextureMaterial(texture);
			
			var colorMaterial:ColorMaterial = new ColorMaterial(0x00FF00, 1);
			_mesh = new Mesh(new PlaneGeometry(640, 480, 1, 1,false, true), colorMaterial);
			_mesh.x = 0;
			_mesh.y = 0;
			_mesh.z = 0;
			_view.scene.addChild(_mesh);
			
			addEventListener(Event.ENTER_FRAME, enterFrame);
			
		}
		
		private function enterFrame(e:Event):void 
		{
			_mesh.rotationY ++;
			
			_view.render();
		}
		
	}

}
VS2015でvar c = '！';が何故か「c#で文字リテラルに文字が多すぎます。」というエラーになる

VS2015にアップグレードしてコンパイルするとエラー発生。

```csharp:CharSample
var c1 = '！！';//エラー。文字が二つはエラーになるよ
var c2 = '！';//何故かエラー！文字一つなのになんで？
```
結論を言うとファイルの文字コードがShift-JISになっていました。
ファイルを開いてメニューバーのファイル→保存オプションの詳細設定から変更可能。