OmniAICreator/Qiita-1.07M huggingface dataset:
Especでファイル変更時に自動でテストを実行する方法


## 状況

PhoenixFrameworkのprojectでEspec, ExMachinaの組み合わせでテストを書き始めたが、テストを書くたびに`mix espec`を叩くのがだるい。そこで、rubyのguardみたいなことができないのか？と探してみた。

## 環境

Elixir 1.3.1
PhoenixFramework 1.1.6
Espec 0.8.22

## 解決方法

[ex_guard](https://github.com/slashmili/ex_guard)を使う

## 手順

基本的にはREADMEに書いてある通りに進める。Espec実行のために設定を少し変更した。

### ex_guardをプロジェクトに導入

test系のtoolは最新のものを使いたいので、githubを直接指定。また、開発環境で使うので`:dev`を追加している。この辺は個人の好みで設定。

```
{:ex_guard, github: "slashmili/ex_guard", only: :dev}
```

### 設定用のファイルを追加

applicationのrootに`.exguard.exs`を配置する。設定はREADMEの設定を拝借して、少しだけ書き換えた。
READMEのサンプルからの変更点は、commandを`mix espec`に変更したことと、`watch`の対象をex,exsのみにしたこと。


```
use ExGuard.Config

guard("unit-test")
|> command("mix espec")
|> watch(~r{\.(ex|exs)\z}i)
|> notification(:auto)
```

### 実行

下記コマンドで実行。後はひたすらspecを書きまくる。

```
mix guard
```

## 通知について

`ex_guard`は実行結果を通知することも可能。設定自体は下記４つがどれか使えればそれを利用する。という仕組み。

```
Terminal Title (Xterm)
TMux (Universal)
Terminal Notifier (mac only)
Notify Send (linux distros)
```

自分はOSX,tmuxを使っているので、ステータスラインにgreen, redがでることで満足していた。
がしかし、せっかくならOSXの通知で出したいなと思い、今は[terminal-notifier](https://github.com/julienXX/terminal-notifier)を導入し、別terminalを開いてそこで個別に実行させている。


## 残念なところ

### ファイルを個別に指定できない

`.exguard.exs`を見てもらうとわかるように、`command`を固定で指定しているので、常に全てのspecを実行してしまっている。理想としては、個別のファイルも指定できるとうれしい。
自分が知らないだけかもしれないので、知っている方いたらコメントをお願いしますm(__)m


## まとめ

ちょっと残念だけど、手でポチポチとコマンドを叩く手間は改善された。
[こちら](http://qiita.com/letusfly85/items/d7387e0a0453762fbd37)で紹介されていた[mix-test.watch](https://github.com/lpil/mix-test.watch)も試してみたけどうまくいかなかった。
とりあえずこの設定で運用しつつ、`mix-test.watch`もチェックしながらベストな方法を模索したい。
[WebViewシリーズ③]  WebViewは、ページ内のアンカーへリンクできない？？

#概要
iOSのWebViewは、デフォルトでページ内アンカー(#)へリンクできないようです。

```:　例
http://www.xxxx.yyyy.html?aaaa#pagetop
```

# 対応策
JavaScriptのwindow.location.hash = "アンカー名"を呼ぶ

# 参考ソースコード

```:ViewController.swift
//MARK: - UIWebViewDelegate
extension ViewController: UIWebViewDelegate {
    
    func webView(webView: UIWebView, shouldStartLoadWithRequest
        request: NSURLRequest,
        navigationType: UIWebViewNavigationType) -> Bool {
        
        if let scheme = request.URL?.scheme {
            
            if scheme.hasPrefix("http") || scheme.hasPrefix("https") {
                
                //ページ内アンカー移動
                let anchor = request.URL?.absoluteString.componentsSeparatedByString("#")
                if anchor?.count > 1 {
                    self.webView.stringByEvaluatingJavaScriptFromString("window.location.hash = \"\(anchor?.first)\"")
                }
                return true
                
            }
        }
        return false
    }
}
```

# まとめ
ページ内のアンカーへリンクするためには、JavaScriptで操作する必要があるようです。
他の方法がありましたら、ご教授頂ければ幸いです。

# こちらも合わせて読んでください♥
[[WebViewシリーズ①]　WebViewのイベントをフックする](http://qiita.com/eKushida/items/a1679e2f438d3fa83c18)
[[WebViewシリーズ②]　WebView内でJavaScriptのメソッドを操作する](http://qiita.com/eKushida/items/055dc36119757b2c304e)
[[WebViewシリーズ③]　WebViewは、ページ内のアンカーへリンクできない？？](http://qiita.com/eKushida/items/dd91615c68f3bd5abdd1)
[[WebViewシリーズ④]　WebView（アプリ内）のリンクからiTunesが表示できない](http://qiita.com/eKushida/items/f7f7195ca0f12b25bca1)

[ゆるふわにUIWebViewでJavaScriptイベントをひろってみる](http://qiita.com/nnsnodnb/items/27fd7c1ca2f8e24ec9c7)
Keras + OpenCV で画像認識

## Abstract

Keras と OpenCV を使って、画像を分類するプログラムを試作しました。バックギャモンのプレシジョンダイスの出目を判定することができます。精度もまあまあのものが出来ました。

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Backgammon dice recognition with Keras <a href="https://t.co/XO8vibXdBy">https://t.co/XO8vibXdBy</a> via <a href="https://twitter.com/YouTube">@YouTube</a></p>&mdash; Masahiro Kisono (@mkisono) <a href="https://twitter.com/mkisono/status/754288025589264385">July 16, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## Related work

去年も同じものを作りました。その時は、Caffe + OpenCV でした。

* [Backgammon dice detection with OpenCV](http://mkisono.blogspot.jp/2015/08/backgammon-dice-detection-with-opencv.html)
* [Backgammon dice recognition with Caffe](http://mkisono.blogspot.jp/2015/09/backgammon-dice-recognition-with-caffe.html)

そこそこ動いたのですが、Caffeが難しかったのと、C++でちまちま書くのが面倒になり、すぐに飽きてしまいました。
しかし、この時作った学習用データは今回も同じものを使いました。ある意味、学習用データを作る作業が一番大変なので、今回は去年の自分の肩の上に乗った仕事です。

## モデルを学習させる

[CIFAR10のサンプル](https://github.com/fchollet/keras/blob/master/examples/cifar10_cnn.py)のモデルを使いました。
画像ファイルから、トレーニングと検証用のデータを読み込ませるには、[ここ](http://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html)にあるように [ImageDataGenerator.flow_from_directory()](http://keras.io/preprocessing/image/) を使うと楽チンです。

## OpenCVの画像で predictする

出来上がったモデルを使って、画像を分類してみます。JPEGファイルを読み込んで分類するなら、先ほどのblogにあるコードが使えます。

```python
img = load_img('data/train/cats/cat.0.jpg')  # this is a PIL image
x = img_to_array(img)  # this is a Numpy array with shape (3, 150, 150)
x = x.reshape((1,) + x.shape)  # this is a Numpy array with shape (1, 3, 150, 150)
x /= 255
```
この x を引数にして [model.predict()](http://keras.io/models/sequential/) を呼べばいいです。

しかし、OpenCV形式のデータを使うにはひと手間必要でした。
OpenCVの画像データは、すでに numpy の arrayでしたが、色の順番が BGR になっているので RGB へ変換が必要です。さらに、arrayの形を合わせるためにごにょごにょします。

```python
x = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
x = x.transpose((2, 0, 1))
x = x.reshape((1,) + x.shape)
x /= 255
```

## Conclusions

Caffeに挫折した私ですが、Kerasならなんとかなりそうです。冒頭にあるYouTube動画のプログラムは 100行そこそこです。Python覚えてマジでよかったです。

## Future work

バックギャモンのチェッカー認識にもチャレンジしようと思っています。

## Acknowlegements

以下のページを参考にさせていただきました。

* [続・深層学習でアニメ顔を分類する with Keras](http://qiita.com/hogefugabar/items/afb4f6c9a93a4bbda51a)
* [Pillowで読み込んだデータをOpenCVで扱えるように変換するとブルーになる話](http://qiita.com/yusukeasari/items/3eaddfbb3a25f37d8e08)
scalaのxml機能が使えない時の対処法


scalaでxml処理をしようとしたら、\等の演算子が使えなかった。
どうやら2014年から、xmlライブラリは標準に組み込まれなくなったらしい。
コップ本はもっと古いので、そこら辺の事情が載っていなかった。

sbtを使ってビルドしているなら、build.sbtに以下のように記述すれば動くようになる。

```
libraryDependencies ++= Seq(
    "org.scala-lang.modules" %% "scala-xml" %  "1.0.5"
)
```

なお、バージョンはお好みで。
GAEデプロイ時にnot have permission エラーが発生する際の対処方法

# 結論
下記ファイルを削除して
`rm ~/.appcfg_oauth2_tokens`
or 
`rm ~/.appcfg_*`

もういちどデプロイ
※デプロイ時にOauth認証するのでブラウザ側で許可してください
`goapp deploy`
or 
`appcfg.py update`

※ブラウザのアドレスがlocalhostになった場合
1. デプロイ実行時にターミナルに表示されるURLをコピペ
2. 対象のGCPプロジェクトのアカウントでログインしているブラウザに対して1のURLをペースト
3. 許可する

# 原因
認証関連ファイル(appcfg_*)がキャッシュされているのが原因
パターンとしては下記の際に発生することが多いと思います
・複数のGCPアカウント、GCPプロジェクトを`gcloud config  configurations activate`で切り替えている
・初回のOauth認証またはデプロイ後にGCPアカウントのロール(Viewer => Editorとか)を変更した場合

GAEのデプロイ時だけじゃなくて
他のGCPサービスをgcloudコマンド経由で使用している発生することがあるかもしれない。
gcloud コマンド実行時にそれっぽいエラーが発生してい場合、試してみてもいいかも。
Processing > uartSender (v0.2) > ダミーデータ送信プログラム

```txt:動作環境
Processing 3.1.1 on Windows 8.1 pro(64bit)
Library: ControlP5
Library: Serial
```

Arduino IDEのSerial Plotterを置き換えるグラフソフトの実装において、COMポートからダミーデータを送信するエミュレータ？が欲しいので作成中。

[v0.2 @ github](https://github.com/yasokada/processing_160716_uartSender/releases)

とりあえず、sine curveを送信できるようにはなった。

- 下記、1列目はソフト起動時からの経過時間(秒)
- 2列目はsine curve (10秒周期)

```txt:結果
3,2.99
4,1.85
5,-0.00
6,-1.85
7,-2.99
8,-2.99
9,-1.85
10,0.00
11,1.85
12,2.99
13,2.99
```

##  実行環境

- シリアル送信側: processingを動かすPC (Windows 8.1pro)
- シリアル受信側: TeraTermで受信する (Windows 7 pro)

上記の2つの端末をシリアルのケーブル(クロス)で接続する。
こちらではVMイメージ2つにてnamed pipeを使っての動作をした。
受信側のTeraTermでは「設定 > 端末」にて[CR]を[CR+LF]に変更する。LFを終端として認識するため。

## code 

```java
import processing.serial.*;
import controlP5.*;

/*
 * v0.2 2016 Jul. 17
 *   - add getIntervaledValue()
 * v0.1 2016 Jul. 16
 *   - send text through COM port
 *   - add sendTestString() to send interval
 *   - add 1 second interval in draw()
 *   - add button to open COM port
 *   - add slider for COM port setting
 */

Serial myPort;

ControlP5 slider;
int sliderValue;
final int numSerial = 5;
int curSerial = -1;
int previousSecond = -1;


ControlP5 btnOpen;

void setup() {
  size(500,500);
  frameRate(10);
  slider = new ControlP5(this);
  slider.addSlider("COM")
    .setRange(-1, numSerial - 1)
    .setValue(-1)
    .setPosition(50,40)
    .setSize(200, 20)
    .setNumberOfTickMarks(numSerial + 1);

  btnOpen = new ControlP5(this);
  btnOpen.addButton("openPort")
    .setLabel("Open")
    .setPosition(275, 40)
    .setSize(100, 30);    
}

void controlEvent(ControlEvent theEvent) {
  if (theEvent.isController()) {
     if (theEvent.getName() == "COM") {
       if (curSerial != slider.getValue("COM")) {
         curSerial = (int)slider.getValue("COM");
       }
     }
  }
}

void serialEvent(Serial myPort) { 
   //String mystr = myPort.readStringUntil('\n');
   //mystr = trim(mystr);
   //println(mystr);
}

void openPort() {
   println("Open Port"); 
   if (myPort != null) {
      myPort.stop(); 
   }
   myPort = new Serial(this, Serial.list()[(int)curSerial], 9600);
   myPort.bufferUntil('\n');
 }

float getIntervaledValue(float amplitude, int elapsed_sec)
{
  final float pi = acos(-1.0);
  final float itvl_sec = 10;
  
  float ret = amplitude * sin(2 * pi * elapsed_sec / itvl_sec);
  
  return ret;
}

void sendTestString()
{
  if (myPort == null) {
    return;
  }
  
  int elapsed_sec = millis() / 1000; 
  String wrkstr;
  
  if (curSerial >= 0) {
    String ret = str(elapsed_sec);
    wrkstr = String.format("%.2f", getIntervaledValue(/*amplitude=*/3.14, elapsed_sec) );
    ret = ret + "," + wrkstr;
    ret = ret + "\r\n";
//    ret = ret + ",3.14, 2.71, 6.022, 1023\r\n";
//    println(ret);
    myPort.write(ret);
  }
}

void draw() {
  background(0);  

  // for 1 second interval
  int curSec = second();
  if (curSec == previousSecond) {
    return;
  }
  previousSecond = curSec;
 
  //
  sendTestString();
}
```

## 補足

javaは（おそらく)1週間前に始めたばかりなので、文法的によくない部分は色々ありそう。
Processing > int型をstr型に変換する > str()

```txt:動作環境
Processing 3.1.1 on Windows 8.1 pro(64bit)
```

ソフト起動時からの経過時間をCOMポート経由で送信する時に、int型をstr型に変換する必要がある。

変換はstr()を使うようだ。
http://www.musashinodenpa.com/p5/index.php?pos=291

例として、以下のようにするとソフト起動時からの経過時間と付随文字列がretに格納される。

```java
int elapsed_sec = millis() / 1000; 
String ret = str(elapsed_sec);
ret = ret + ",3.14, 2.71, 6.022, 1023\r\n";
```
技術英語 > you'll need to [weigh the significance] of each factor and make a judgement about what matters most. / in order of importance

@ Code Complete (No. 4399 / 36077)

> you'll need to <font color=red>weigh the significance</font> of each factor and make a judgement about what matters most.

http://ejje.weblio.jp/content/weigh

「各ファクターの優先度をつけて、何が一番重要かについて判断する必要がある」と訳せそう

<hr>
関連して思い出したのは

http://eow.alc.co.jp/search?q=%22of+importance%22&ref=id
> in order of importance
重要度順で［に］

<hr>
関連して思い出したのは

> Safety First and Production Second.

http://qiita.com/7of9/items/b3da40c90f7743681e49
GUIアプリを管理者権限で扱う

#環境
Ubuntu 16.04

#コマンド
GUIの場合はsudoの代わりにgksudo --syncを使う。
例えばNautilusをGUIで管理者権限で使いたい場合は
`$ gksudo --sync nautilus`
と入力しNautilusを開く

#参考にした書籍
- [Piro(結城洋志) の まんがでわかるLinux　シス管系女子（日経BP Next ICT選書）](http://amzn.to/29Lfh71)
dotenv-railsについて

# dotenv-rails
このGemを使うと、アプリケーションごとに環境変数(非公開情報)が設定できるようになり、 `secrets.yml`に公開したくない情報を設定しなくても良くなります。herokuではsecrets.ymlが必要なので、.gitignoreするわけにはいかない。

/.env
TWITTER_API_KEY="hogehoge"
TWITTER_API_SECRET="fugafuga"

・config/secrets.ymlとは環境変数を設定するファイル
環境変数"SECRET_KEY_BASE"に書こうよってなってる。

参考サイト
http://blog.10rane.com/2015/05/13/dotenv-manages-secret-of-rails4/

http://qiita.com/noraworld/items/bfa80811c9e30b4474af

gem configは下記
http://qiita.com/yumiyon/items/32c6afb5e2e5b7ff369e
SSHでリモート先のGUIのアプリケーションを使う

#環境
Ubuntu 16.04
Mac OSX El Capitan 10.11.5

#コマンド
sshコマンドにオプションを加えるとGUIのアプリケーションもリモートで扱うことができる

`$ ssh -Y -C user@アドレス`

-Y: Xの転送指定
-C: 通信内容の圧縮 (応答性が良くなる)

SSH接続を行った後、起動したいアプリ名を入力

↓MacでUbuntuのLibreOfficeを実行した場合
<img width="1920" alt="Screenshot 2016-07-17 05.38.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/42913/bd249572-b913-a17b-9fa7-9c6a5122f2f6.png">

#参考にした書籍
- [Piro(結城洋志) の まんがでわかるLinux　シス管系女子（日経BP Next ICT選書）](http://amzn.to/29Lfh71)
Railsの.gitignoreについて

# .gitignoreとは
.gitignore とは、gitで無視するファイルを指定するファイルです。

# 参考サイト
・ .gitignore
http://www.omakase.org/misc/gitignore.html

・ Railsの.gitignore
http://source.hatenadiary.jp/entry/2014/02/09/084318
ubuntuのssh設定

#環境
Ubuntu16.04
Mac OSX El capitan 10.11.5

#sshdのサービスを開始
パッケージの管理を行うためのaptitudeをインストール
`$ sudo apt-get install aptitude`

aptitudeを使ってsshを導入
`$ sudo aptitude install ssh`


/etc/ssh/sshd_configを編集し、PermitRootLoginの行を
`PermitRootLogin no`
に書き換える

`$ sudo /etc/init.d/ssh restart`
でsshdのサービスを再起動させる

#SSH接続
あとは別のクライアントPCから通常通りSSH接続するだけ
`$ ssh user@ipアドレス`
bundle updateについて　※自分用メモ

参考サイト
http://techracho.bpsinc.jp/hachi8833/2014_02_07/15390

# うかつにbundle updateは行わない
開発初期のローカルアプリならともかく、実際に動いているシステムのメンテ中にうかつにbundle updateを実行すると死を招きます。そしてGemfile.lockがリポジトリに登録されておらず、前回デプロイ時のバックアップもなければ、動いていた状態を再現できなくなって詰んで終わります。

# bundle updateを行うときは、bundle update gem名のようにgem名を指定して実行する
Gemfile.lockはリポジトリに登録しましょう。そしてbundle updateは基本的に実行せず、特定のgemのみを最新にする目的でbundle update gem名のようにgem名を指定して実行するぐらいにとどめましょう。

# bundle updateについて
bundle updateを実行すると現状のGemfile.lockの内容は無視され、上で言う「Gemfile.lockがない場合」と同じことが行われます。当然ながら、Gemfile.lockは、現時点の最新バージョンと依存関係を持つgemによってごっそり更新されてしまいます。
Ubuntuのホーム直下のディレクトリ名を英語にする

#環境
Ubuntu 16.04

#対処法
日本語環境のUbuntuにするとディレクトリ名が「デスクトップ」とか「ドキュメント」とか日本語名になっててCUI操作する際に非常に面倒

コンソールで以下のコマンドを叩く
`$ LANG=C xdg-user-dirs-gtk-update`

ダイアログ中の「Update Name」を押すと英語にリネームされる
同一ネットワーク上に存在するIPアドレスを調べる

#環境
Mac OSX El Capitan

#arp-scanを使う方法
`$ arp-scan -I インターフェイス名 -l`
インターフェイス名はMacでifconfigした際の自分のipアドレスが書かれている奴です
例えば自分の場合
`$ arp-scan -I en0 -l`
みたいな感じになる

#arp
`$ arp -a`
を入力する


#補足
他にも色々あるっぽいですが、コマンドによってヒットするipの件数が違ったりするっぽい(謎)
arpで出ないときはarp-scanを使う等いろいろしてみましょう
sudoを付けずにVimでルート権限のファイルを編集してしまった時

顔面蒼白ですよね。
安心して以下を実行します。

#対処法
コマンドモードで以下のコマンドを叩く
`:w !sudo tee %`
パスワードを聞かれるので入力し、`:q!`でVimを閉じれば完了
ちゃんと編集内容が保存されます。
Raspberry Pi のCUIを使ってのWi-Fi設定(DHCP)

#環境
Raspberry Pi 2 Model B Raspbian

#USBドングル
Raspberry Pi 3ではWi-fiによる通信を行うためのチップが最初から内蔵されていますが、
それ以外の機種でWi-Fi通信を行うためには別売りのUSBドングルを挿す必要があります

Amazon等で色々売ってますが、安いものは発熱する機種があるので個人的には以下のUSBドングルがおすすめです
- [PLANEX 無線LAN子機 (USBアダプター型) 11n/g/b 150Mbps MacOS X10.10対応 GW-USNANO2A (FFP)](http://amzn.to/29KK8An)

#SSIDとパスワードの登録
接続したいWi-FiのSSIDとパスワードを設定します。

ターミナルで以下のコマンドを入力すると(Wi-FI_SSIDとPasswordは適宜替えて下さい)
`$ wpa_passphrase "Wi-Fi_SSID" "Password"`

以下のような結果が出力されます
`network={
        ssid="Wi-Fi_SSID"
        #psk="Password"
        psk=6781b0948749e59fe6d3cf2a72456a9b048ce2683c0d4737bd8e56dbe967386a
}`

これを
`/etc/wpa_supplicant/wpa_supplicant.conf`のファイルの最後にペーストして保存します。
pskの項目はPasswordが生のまま記述してあるので消しておきます

#SSH接続
reboot後、設定が反映されているので、`ifconfig`コマンドでDHCPによって割り当てられたipアドレスを確認します
例えば`inet addr:192.168.76.73`のような具合です。

後は、別のPCからターミナルで
`ssh pi@192.168.76.73`と入力してみてログインIDをパスワードを入力するとSSHによる接続ができ、完了です.

※DHCPによるIPアドレスは自動で割り振られたものなので状況によって変化します
SpringBootで実行可能jarをリモートから起動する



#実行コマンド
```
ssh user@remotehost "sudo nohup java -jar myaply-0.0.1-SNAPSHOT.jar > log.txt 2> errors.txt < /dev/null &"
``` 


#必要な準備
sudoはリモートで実行できないため、sshのユーザーについて、
ttyの

#参照
http://qiita.com/yuku_t/items/0f15d487ed6232d21410
コマンド全体をルート権限で実行する

#環境
Raspberry Pi2 Model B Raspbian

#sudoで実行した際の部分的な権限エラー
コマンドラインでWi-Fiの設定をする際などに、リダイレクト(>>)を使って設定ファイルに書き込むと便利だが
`$ sudo wpa_passphrase "Wi-Fi_Name" "Password" >> wpa_supplicant.conf`
のようにsudoを使ってルート権限で書き込もうとしても、`>> wpa_supplicant.conf`のリダイレクトを行うコマンドが一般ユーザーでの実行になってしまうためエラーが出てしまう。

#対処
`$ sudo bash -c '全体のコマンド'`
とすることで、コマンド全体をルート権限で実行することができる。

今回の場合だと、
`$ sudo bash -c 'wpa_passphrase "Wi-Fi_Name" "Password" >> wpa_supplicant.conf'`
となる
SpringBootでTomcat connector in failed stateエラーが発生



#原因
tomcatがすでに起動しているため

#対応
Jenkinsを停止する。
または別ポートを利用する。


#背景
SpringBootを起動していたわけではないが、Jenkinsが起動していたためエラーとなった。
JenkinsもデフォルトではtomcatがAPサーバとして利用されている。



#ポート番号を変えても起動できない場合
ウェルノウンポートである1024以下はroot権限でないとlistenすることができない。
Blender マテリアルの設定


**Cycle Renderに設定**
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/f005d1bf-59e5-4552-ee27-9f21401c1759.png)

Cycle Renderの公式ドキュメント
https://www.blender.org/manual/render/cycles/index.html


**Node Editorの表示**
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/5c52a810-8695-8ae8-f326-2031464dabe4.png)

画面の分割はこちらを参照：[Blender レイアウトの変更](http://qiita.com/gansaibow/items/960f44d68dffd811713b)

**EditorでMaterialの状態を確認する**
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/ee857947-5ae1-928d-5d4e-5b50a8be107c.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/111261/07603188-d32f-3442-9e0b-c3cf69b409be.png)

**ノードの追加**
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/ad73b08b-1670-328a-7938-aa6abd6024ed.png)
Team Foundation Severの作業項目をカスタマイズする

# 概要
Team Foundation Serverの作業項目を自分の担当プロジェクトに合わせてカスタマイズするためにやったことを防備録として残します。
具体的には作業項目のアクティビティに項目を追加しました。

# 環境
- Team Foundation Sever 2012
- Visual Studio 2012

あ、クライアントはWindowsです。

# 手順
Visual Studioの[チーム エクスプローラー]->[設定]->[チーム プロジェクト コレクション]->[プロセス テンプレート マネージャー]からカスタマイズするプロセステンプレートをダウンロードする。


テキストエディタでカスタマイズしたファイルを開く。
(作業項目のアクティビティをカスタマイズするため、WorkItem Tracking\TypeDefinitions\Task.xmlを開く。)

```xml:Task.xml
<FIELD name="Activity" refname="Microsoft.VSTS.Common.Activity" type="String" reportable="dimension">
  <HELPTEXT>Type of work involved</HELPTEXT>
  <SUGGESTEDVALUES>
    <LISTITEM value="Development" />
    <LISTITEM value="Testing" />
    <LISTITEM value="Requirements" />
    <LISTITEM value="Design" />
    <LISTITEM value="Deployment" />
    <LISTITEM value="Documentation" />
  </SUGGESTEDVALUES>
</FIELD>
```
新しい項目を追加する。

```xml:Task.xml
<FIELD name="Activity" refname="Microsoft.VSTS.Common.Activity" type="String" reportable="dimension">
  <HELPTEXT>Type of work involved</HELPTEXT>
  <SUGGESTEDVALUES>
    <LISTITEM value="Development" />
    <LISTITEM value="Merge" /> <!-- 新しく追加 -->
    <LISTITEM value="Testing" />
    <LISTITEM value="Requirements" />
    <LISTITEM value="Design" />
    <LISTITEM value="Deployment" />
    <LISTITEM value=Release" /> <!-- 新しく追加 -->
    <LISTITEM value="Documentation" />
  </SUGGESTEDVALUES>
</FIELD>
```
プロセス テンプレート マネージャーでプロセステンプレートをアップロードする。

新しくチームプロジェクトを作る場合はこれで作業終了。
アップロードしたプロジェクトテンプレートを使ってチームプロジェクトを作成すれば良い。

#### チームプロジェクトを作成済みの場合
コマンドプロンプトを起動し、以下のコマンドを実行する。
>witadmin importwitd /collection:[チームコレクションのURL] /p:[コレクション名] /f:[修正したファイル名]

いきなりコマンドを実行するのがこわい場合は/vオプションをつけると適用可能か確認することができる。
Macで複数のターミナルを移動する際のショートカット変更

複数のTerminalを用いて作業することが多いため、ショートカットキーを簡単なものに変更する。
###Before
⇧⌘→ 次のタブを表示
⇧⌘← 前のタブを表示

###After
⌘→ 次のタブを表示
⌘← 前のタブを表示
![スクリーンショット 2016-07-17 2.16.15.png](https://qiita-image-store.s3.amazonaws.com/0/94861/7a9b0c4d-eeb6-e7b3-9aac-897813562f80.png)

画像中の「次のタブを表示」は手動で書かなければならず、タイプミスすると変更が適用されない。
Yosemite以前は「次のタブを選択」だったらしく、設定変更時にミスって詰みかけた。
psコマンドからプロセスIDを取得する


#ローカルの場合
```
ps -ef | grep name | grep -v grep | awk '{ print $2 }'
```


#リモートの場合
```
awkのパラメータをエスケープする必要がある
ssh user@remotehost "ps -ef | grep name | grep -v grep | awk '{ print \$2 }'"
```


#参考
http://qiita.com/aibou/items/159a18ca70ac87b40bad
Blender レイアウトの変更

# 画面の分割

![image](https://qiita-image-store.s3.amazonaws.com/0/111261/ad28aa5c-aab1-047b-da22-823adeedafe7.png)


![image](https://qiita-image-store.s3.amazonaws.com/0/111261/b39367ac-6326-dac6-0977-459edc26f932.png)


![image](https://qiita-image-store.s3.amazonaws.com/0/111261/77af67d0-146b-b103-1619-c3a0d0cb2634.png)

# 画面の統合

![image](https://qiita-image-store.s3.amazonaws.com/0/111261/c8b44b4c-55ce-5985-51a7-38725ce3c3c3.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/111261/4cc101d3-342d-7858-1ed9-73501cfb0f59.png)

# ウィンドウに分離する
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/51e2f839-252a-49bc-57e4-f2fd154bc96a.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/111261/56041889-4bfd-c5c4-0f28-627e9fece7c9.png)
HandBrakeのインストール

#### 環境
OS: LinuxMint18 

#### インストール
```
$ sudo add-apt-repository ppa:stebbins/handbrake-releases
$ sudo apt-get update
$ sudo apt-get install handbrake-gtk

おまけ
$ sudo apt-get install handbrake-cli
```

#### 削除する場合

```
sudo apt-get remove handbrake-gtk handbrake-cli
```
いまどきのSwing用レイアウト部品

#TMGridBagLayoutについて

## はじめに

Java 8でJava FXが標準ライブラリ扱いとなりましたが、今でもSwingを使う人はたくさんいます。私もJava FXの基本的なGUI部品(TreeView等)がまだ扱いづらいと感じていて、未だに積極的に使おうという気分になれません。今でも、簡単なGUI部品ならSwingで済ませてしまいます。

Swingでは画面にGUI部品を配置するにはレイアウトマネージャ(java.awt.LayoutManager2の実装クラス)を使うわけですが、自分が満足に使えるものがJava標準ライブラリにはありません。GridBagLayoutもちょっと今ひとつです。

というわけで、レイアウトマネージャを作りました。

## TMGridBagLayoutのご紹介

自作レイアウトマネージャは、GridBagLayoutとGridBagConstraintsを拡張したようなものです。TMGridBagLayout と TMGridBagConstraints をGistにあげました。サンプルもあります。Java 8以降で動作します（Stream APIを使っているので…）。

* [Enhanced GridBagLayout Components](https://gist.github.com/sipadan2003/f07408d4e3e63d00d284d8b7a1d78c5b)

そこにあるサンプルを起動すると、次のようなウィンドウが表示されます。
![TMGridBagLayoutSample.gif](https://qiita-image-store.s3.amazonaws.com/0/33023/5ab3b3bd-5c3d-7232-5178-f32d3511a8ce.gif)

そのウィンドウの幅を伸長すると、次のようになります。JLabelやJButtonのサイズは常に不変ですが、JTextFieldだけはウィンドウ幅に合わせて幅が自動的に伸縮されます。
![TMGridBagLayoutSample2.gif](https://qiita-image-store.s3.amazonaws.com/0/33023/9c3ce42b-5979-5b4e-d5dc-3f180a034068.gif)

## TMGridBagLayoutの使い方

java.awt.GridBagLayoutとjav.awt.GridBagConstraintsと同じ要領で、TMGridBagLayoutとTMGridBagConstraintsを組み合わせて使います。

まず、画面をグリッドに分割して考えます。上のサンプルでは、下図のように縦3×横3のグリッドにGUI部品を配置しています。なお、丸数字の1は、ウィンドウの幅に合わせて伸縮する横グリッドの番号です。他のグリッドは伸縮しません。
![TMGridBagLayoutSample3.gif](https://qiita-image-store.s3.amazonaws.com/0/33023/7e436d3a-a0f4-d50f-f3f8-217676b7390a.gif)

このような方法でGUI部品を配置するには、次のようにTMGridBagLayoutを用意します。第1引数と第2引数ではグリッドは3×3であることを指定しています。第3引数では横1番目のグリッドの幅を伸縮可能であることを指定し、第4引数では縦はどのグリッドも伸縮しないよう-1を指定しています。

```java
TMGridBagLayout layout = new TMGridBagLayout(3, 3, 1, -1);
```

そして、パネルにGUI部品を追加するときに、TMGridBagConstraintsを次のようにして使います。

```java
add(new JLabel("Item1: "), new TMGridBagConstraints(0, 0, 1, 1));
add(new JTextField()     , new TMGridBagConstraints(1, 0, 2, 1));
add(new JLabel("Item2: "), new TMGridBagConstraints(0, 1, 1, 1));
add(new JTextField()     , new TMGridBagConstraints(1, 1, 2, 1));
add(new JButton("Button"), new TMGridBagConstraints(2, 2, 1, 1));
```

たとえば、2つ目のJTextFieldの追加では、「new TMGridBagConstraints(1, 1, 2, 1)」としていますが、これは横1番め、縦1番目のグリッドに、幅2、高さ1で配備するように指示しているわけです。

説明は以上ですが、ぜひ、使っていただき、便利さを理解していただけたらと思います。ソースは自由に改変・配布してもOKです。
docker on ec2

# docker on ec2


気になってたけど、全然やれてなかったdocker
少し動かすだけだとそこまで時間かからなかったので
もうすこしはやくさわっておけばよかったとおもった。
少しでも誰かの役に立てばうれしい。

参考:https://docs.docker.com/engine/installation/linux/rhel/
1.確認

```sudo su -
uname -r```

2.yum update

```yum update```

3.yumリポジトリ情報の作成

```tee /etc/yum.repos.d/docker.repo <<-EOF
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF```

4.dockerのinstall
```yum install docker-engine```

5.dockerServiceの起動
```service docker start```

6.Testイメージ?の起動
```docker run hello-world```


7.ubuntuのImageからhello world
参考：https://docs.docker.com/engine/tutorials/dockerizing/

```docker run ubuntu /bin/echo 'Hello world'```

★このとき、コンテナはどうなっているのだろう（実行して落ちてる?実行後も動いてる）？
以下らしい。コマンドを実行したら停止
```So what happened to the container after that? 
Well, Docker containers only run as long as the command you specify is active. 
Therefore, in the above example, the container stops once the command is executed.```


8.インタラクティブ(対話的)に実行
```docker run -t -i ubuntu /bin/bash```

9.httpdをコンテナにいれて起動してつないで見る
これが一番最初にやりたかったこと。

hello worldでやったようにCentOSを起動
※systemdを静かに避け、centos6を入れる
```docker run -t -i centos:centos6 /bin/bash```
普通にyumでhttpdをinstallする
```yum install httpd -y```



```chkconfig httpd on```
```/etc/init.d/httpd start```
```netstat -an | grep httpd```
```ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0```



```ps -aux | grep http```
```echo "docker test" >> /var/www/html/index.html```

10.HostOS側での操作

```docker commit reverent_bardeen centoshttpd```
```docker run -i -t -p 50050:80 centoshttpd /bin/bash```

11.コンテナでの操作
```chkconfig httpd on```
```/etc/init.d/httpd start```

```curl http://localhost```
```docker test```
```exit```

```curl http://localhost:50050
curl: (7) Failed connect to localhost:50050; Connection refused```

※Exitで抜けたら上手く行かなかった

```docker run -i -t -p 50050:80 centoshttpd /bin/bash```

```chkconfig httpd on```

```/etc/init.d/httpd start```

```curl http://localhost:50050
docker test```

```curl http://localhost:50050/index.html
docker test```

Ctrl+P,Qでコンテナから抜ける

12.ELB配下において設定
50050でコンテナの80にPortForwardするので
hostOS側の50050をhealthcheckPortにして組み込む

13.接続確認OK
Vagrant1.8.4でVirtualBox5.1を利用する

VirtualBox5.1がリリースされました。

[Oracle VM VirtualBox 5.1.0 is now available!](https://blogs.oracle.com/virtualization/entry/oracle_vm_virtualbox_5_14)

しかし現状、Vagrant1.8.4ではVirtualBox5.1は動きません。

※ 追記 : 既にVagrant1.8.5がrelease済みで、VirtualBox5.1に対応済みなので、そちらを使いましょう。
…と思ったら、バグがあってまともに動かないようなので、現状は1.8.6待ちか1.8.4でこの対処を行うかのどちらかのようですね。[^1]

[^1]: [Vagrantのインストール](http://qiita.com/shimitei/items/31b65fd63a6e369568de#_reference-167bec3a2c7882ed6740)

```
$ vagrant up
==>  Provider 'virtualbox' not found. We'll automatically install it now...
     The installation process will start below. Human interaction may be
     required at some points. If you're uncomfortable with automatically
     installing this provider, you can safely Ctrl-C this process and install
     it manually.
==>  Downloading VirtualBox 5.0.10...
     This may not be the latest version of VirtualBox, but it is a version
     that is known to work well. Over time, we'll update the version that
     is installed.
==>  Installing VirtualBox. This will take a few minutes...
     You may be asked for your administrator password during this time.
     If you're uncomfortable entering your password here, please install
     VirtualBox manually.
```

この後、VirtualBox5.0系をダウンロードしようとします。
また、`vagrant status`などのコマンドを実行しても、Providerがないとしてエラーになります。

```
$ vagrant status
There are errors in the configuration of this machine. Please fix
the following errors and try again:

AWS Provider:
* An access key ID must be specified via "access_key_id"
* A secret access key is required via "secret_access_key"
* vagrant_aws.config.ami_required
```

ここにissueが挙がっていますが、現時点ではコードの書き換えを行う必要がありそうです。

https://github.com/mitchellh/vagrant/issues/7411

以下はMacの場合:

```/opt/vagrant/embedded/gems/gems/vagrant-1.8.4/plugins/providers/virtualbox/driver/meta.rb
            "4.3" => Version_4_3,
            "5.0" => Version_5_0,
            "5.1" => Version_5_1,  # 64行目 この行を足す
          }
```

```/opt/vagrant/embedded/gems/gems/vagrant-1.8.4/plugins/providers/virtualbox/plugin.rb
      autoload :Version_5_0, File.expand_path("../driver/version_5_0", __FILE__)
      autoload :Version_5_1, File.expand_path("../driver/version_5_1", __FILE__) # 59行目 この行を足す
    end
```

```
sudo cp -p /opt/vagrant/embedded/gems/gems/vagrant-1.8.4/plugins/providers/virtualbox/driver/version_5_0.rb \
/opt/vagrant/embedded/gems/gems/vagrant-1.8.4/plugins/providers/virtualbox/driver/version_5_1.rb
```

```/opt/vagrant/embedded/gems/gems/vagrant-1.8.4/plugins/providers/virtualbox/driver/version_5_1.rb
      # Driver for VirtualBox 5.0.x
      class Version_5_1 < Base # 11行目 Version_5_0 -> Version_5_1へ書き換え
        def initialize(uuid)
```

また、Windowsの場合にも `/opt/vagrant` の部分を `C:\HashiCorp\Vagrant` に読み替えて、同様に対応することが可能です。

そのうち対応されるはずなので、待てる方は待ちましょう。
"ansibleでzabbixにホストを自動登録"

zabbixにansibleからホストを登録してグラフまで出すroleを作った


### 使い方とかもろもろ
```
$ ansible-galaxy install connvoi.add_hosts_to_zabbix
```
  
[ansible-galaxy](https://galaxy.ansible.com/connvoi/add_hosts_to_zabbix/)に登録したので、これでrolesに書けば使えるようになります。  
  
  
zabbixへのホスト登録とテンプレートの紐付け、  
ポート番号のインターフェースの追加、  
各ホストごとのスクリーンの作成  
とかをいい感じでやってくれるものです。  
  
### zabbixのセットアップ
zabbixをセットアップする機会があって、せっかくなので自動化というか  
セットアップをansibleを使ってだれでもできるようにしてみた。  
  
やっぱり、ポートの追加とかグラフの追加とかポチポチするのいやじゃないですか?  
ansibleにzabbix用のモジュールがあったので、role化しました。  
  
これやると、各ホストに対して指定したグラフのスクリーンが作られるんで、  
グラフとかインターフェース追加とかサーバの数だけぽちぽちしたり、  
xml作ってインポートとかはしなくてもよくなりました。  
  
登録が1回でできるってのと、  
やり直したい時とかコマンド１回で全部もとに戻るってのがいいなと。  
hostgroupがhost数だけ増えちゃうとか、  
若干微妙なところもあるんだけど、それはそのうちになおすかもしれない。
Vagrant  (provider Virtualbox) で network の promiscuous を設定する。

VirtualBox 5.0.24 & Vagrant 1.8.3 現在くらいのお話です。

Vagrantで普通にNetworkの設定をすると、
VirtualBoxではpromiscuousのモードが拒否になっていて、VMで仮想MacAddressを使ったりするとアクセスできないことがあります。
そこで、Vagrantfileでpromiscuousモードを設定してしまおうという話です。

どんなオプションで設定できるのかはVirtualBoxの[公式ドキュメント](https://www.virtualbox.org/manual/ch08.html)を見ると

`--nicpromisc<1-N> deny|allow-vms|allow-all`

とあります。

これをVagrantfileに書けば良いのですが、NIC番号<1-N>が必要になります。

NIC番号ってどれでしたっけ？となるので、当該NIC番号がどれかを判断することがひつようになります。

まず、Vagrantが接続するために1番目のNICを使います。
2番目以降にコンフィグで設定したものが追加されていきます。
例えば

```
Vagrant.configure(2) do |config|
  config.vm.define "default" do |box|
   box.vm.network "private_network", ip: "192.168.56.10"
   box.vm.network "private_network", ip: "192.168.57.10"
   end
end
```

こんなVagrantfileですと、2,3番目のNICが作成されます。
で、これらに先ほどのVirtualBoxへの設定を行うのですが、それを追加すると

```
Vagrant.configure(2) do |config|
  config.vm.define "default" do |box|
    box.vm.network "private_network", ip: "192.168.56.10"
    box.vm.network "private_network", ip: "192.168.57.10"
    box.vm.provider :VirtualBox do |vb|
      vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all",
                                     "--nicpromisc3", "allow-all"]
    end
  end
end
```

こんな感じになるわけです。
NICを増やすとまた1行増やす……
それはないわーとなりますね。

そこでとりあえず追加するNIC全部にprimiscuous allow-allを設定したい！みたいなときは

```
Vagrant.configure(2) do |config|
  config.vm.define "default" do |box|
    box.vm.network "private_network", ip: "192.168.56.10"
    box.vm.network "private_network", ip: "192.168.57.10"
    (1..box.vm.networks.count {|nw| !nw.include? :forwarded_port}).each do |i|
      box.vm.provider :VirtualBox do |vb|
        vb.customize ["modifyvm", :id, "--nicpromisc#{i+1}", "allow-all"]
      end
    end
  end
end
```
みたいなことをするのです。

`config.vm.network`には今のところNICを作らない設定は`forwarded_port`くらいっぽいので、大体このやり方でうまくいくかと思います。
NICが作られる順番は上から順なので、`forwarded_port`の設定を必ず最後にやる、みたいなことを決めていれば、`private_network`だけ設定したいときは

```
    (1..box.vm.networks.count).zip(box.vm.networks).each do |i,nw|
      if nw and nw.include? :private_network then
        box.vm.provider :VirtualBox do |vb|
          vb.customize ["modifyvm", :id, "--nicpromisc#{i+1}", "allow-all"]
        end
      end
    end
```
みたいな書き方をしてみるとか、
特定のIPアドレスのものだけをというときは、IPアドレスを変数にしてしまって、
条件として指定するとかできますね。


こんなの普通はハマらないんですけど、たまたまVMでルータを動かしてVRRPを利用したら仮想IPアドレスが仮想MacAddress持ってる状況で、仮想IPアドレスへ通信できないという事態に遭遇したので忘備録として残しておきます。
LinuxのHAで使われる仮想IPアドレスによる冗長化する場合はkeepalivedを使うとおもいますが、これ完全なVRRPじゃなくて、仮想MacAddressを持たないのでprimiscuousモードが拒否でもハマらないのです。(LinuxはNICが2つのMacAddressを持てない仕様なんでしたっけ？)
BSD系だと仮想MacAddress使えるんですよね……
PHP本体の開発での参考サイト

PHP開発での参考サイトについてピックアップしてみました。見逃してるな、というものがあったらお知らせください。

## 基本
  - http://php.net/sites.php
    - bugsなどはここから

## RFC

  - php.net
    - https://wiki.php.net/rfc

<br/>

  - PHP RFC Watch
    - [![https://php-rfc-watch.beberlei.de/](https://qiita-image-store.s3.amazonaws.com/0/7949/06396282-d671-02f7-0f3c-ce4eaf5fd248.png)](https://php-rfc-watch.beberlei.de/)
    - https://php-rfc-watch.beberlei.de/
    - 投票状況のタイムライン

<br/>

  - Why can't we have nice things
    - [![whycantwe.png](https://qiita-image-store.s3.amazonaws.com/0/7949/5ddb1239-25cc-a4b9-9e36-b6f2f6761320.png)](https://why-cant-we-have-nice-things.mwl.be/)
    - https://why-cant-we-have-nice-things.mwl.be/
    - 投票の統計

## ML
  - http://news.php.net/
    - 一番参照されるのはinternalsかな
      - http://news.php.net/php.internals 

<br/>

  - internals関連
    - [![externals.png](https://qiita-image-store.s3.amazonaws.com/0/7949/efa622fb-a2e8-73bb-227d-326fb227aea4.png)](http://externals.io/)
    - http://externals.io/
    - 過去ログ参照

<br/>

  - 日本PHPユーザ会
    - [![phpgrjp.png](https://qiita-image-store.s3.amazonaws.com/0/7949/1b329a5d-9c32-5396-0520-3b878efb8dd9.png)](http://ml.php.gr.jp/)
    - http://ml.php.gr.jp/
    - mbstringなどの開発をまず日本語でしたい場合はphp-devで

## コード検索
  - ![opengrok.png](https://qiita-image-store.s3.amazonaws.com/0/7949/57792439-0816-a07b-1775-bb0a351584a0.png)
  - https://php-lxr.adamharvey.name/source/
   - lxr.php.net は、うぅ泣 ( https://bugs.php.net/bug.php?id=72396 )

## GithubでのPR
  - https://github.com/php/php-src/pulls

## 言語仕様
  - https://github.com/php/php-langspec

## ヴァージョン間の挙動、opcode確認
  - https://3v4l.org/

## 翻訳
  - Status of the translated PHP Manual
    - ![translatestatus.png](https://qiita-image-store.s3.amazonaws.com/0/7949/618cb96b-5b01-df5d-081d-99267a239290.png)

    - http://phpdoc.m-takagi.org/revcheck.html
    - 翻訳参加については、[高木さんのスライド](http://www.slideshare.net/m.takagi/php-53571819) 参照

## pecl
  - pecl開発MLの過去ログ
    - http://marc.info/?l=pecl-dev

## internals での読み物
  - https://github.com/ziadoz/awesome-php#php-internals-reading

## もうネットでは参照できなくなったもの
  - 小泉守義のPHPソースコードウォッチ
    - https://www.codeblog.org/blog/moriyoshi/

## たまにPHP開発の話がでてくるpodcast(ビデオ会議)
  - https://www.phproundtable.com/

## twitter
  - ハッシュタグはたぶん`#internals`がよく使われてるかと
    - https://twitter.com/search?q=%23php%20%23internals&src=typd
  - リストはお好みのをお探し下さい
goimportsのスキャン対象から特定ディレクトリを除外する

goimportsが[高速になりました](https://groups.google.com/forum/#!msg/golang-nuts/in9IVmPc_fQ/BO4wzOylCAAJ)！

goimportsとは、.goファイルのimport文を自動的に追加・削除してくれる、Goによる開発には欠かせないツールです。しかし、Goのパッケージの仕様上、パッケージ名の探索のためにGOROOT/GOPATH配下の全てのディレクトリを探索する必要があり、GOPATH配下に大量のディレクトリが存在する場合、遅くなることでも知られています[1](https://github.com/fatih/vim-go/issues/207) [2](https://groups.google.com/forum/#!topic/golang-dev/NxbGjAvnVVY)。

そこでbradfitzがgoimportsにパフォーマンス改善を[加えた](https://github.com/golang/tools/commit/e047ae774b027ae958a270598c5ac2591e457afc)のですが、その中の一つに、[設定ファイルで特定ディレクトリを除外する](https://github.com/golang/tools/commit/ffe4e61c6496f07d2bdbb590286f0b13bd51a158)という新機能を見つけたので紹介します。

## やり方

`$GOPATH/src/.goimportsignore` ファイルを作成し、除外したいディレクトリを(設定ファイルからの相対パスで)記述すると、goimportsはそのディレクトリを無視してくれます。スマートです。
これでテストのためにパッケージ配下に大量のディレクトリを作っていても安心ですね。
pgfutter 利用で CSV/Json ファイルを PostgreSQL へ読み込み

こんにちは。
[pgfutter](https://github.com/lukasmartinelli/pgfutter) を使って、CSV/Json ファイルを PostgreSQL へ読み込ませてみました。

```console
$ cat data.json | pgfutter --jsonb json
```


デフォルトパラメータは下記の値となります。テーブル名はデフォルトでファイル名が使われます。

```console
$ pgfutter --port 5432 --host localhost --user postgres --pass "" --dbname postgres --schema import json --table table_name table_name.json
```

気がついた点は、

* 標準入力から入力の場合、```stdin```というテーブルに取り込まれる（冒頭例）。
* json/jsonb データの場合、フィールド名```data``` に取り込まれる。
* devel 版では jsonb にも対応
Hadoopを構築するまで


自分用のmemoです

# 環境
- CentOS 7.2
- VirtualBox 5.0.2
- Hadoop 2.7.2
- Hive 2.1.0

# Hadoop構築

## Javaインストール

```
$ yum -y update
$ yum -y groupinstall 'Development tools'
$ wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.rpm
$ rpm -ivh jdk-8u66-linux-x64.rpm
$ export JAVA_HOME=/usr/java/jdk1.8.0_66
$ source .bashrc
```

## Hadoopインストール

```
$ wget http://ftp.riken.jp/net/apache/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz 
$ tar -xzvf hadoop-2.7.2.tar.gz 
$ mv hadoop-2.7.2 /usr/
$ export HADOOP_HOME=/usr/hadoop-2.7.2
$ export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$JAVA_HOME/bin:$PATH
$ source .bashrc
```

## 設定ファイル編集

- etc/hadoop/core-site.xml:

```
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>
```

- etc/hadoop/hdfs-site.xml:

```
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>
```

- etc/hadoop/mapred-site.xml:

```
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>
```

- etc/hadoop/yarn-site.xml:

```
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
</configuration>
```

## 起動

```
$ hadoop namenode -format
$ start-dfs.sh
$ start-yarn.sh
```

## 起動確認

```
$ jps

28962 NodeManager
28868 ResourceManager
28713 SecondaryNameNode
28554 DataNode
29245 Jps
28431 NameNode
```

# Hive構築

## インストール

```
$ wget http://ftp.riken.jp/net/apache/hive/hive-2.1.0/apache-hive-2.1.0-bin.tar.gz
$ tar -xzvf apache-hive-2.1.0-bin.tar.gz
$ mv apache-hive-2.1.0-bin /usr/hive-2.1.0
$ export HIVE_HOME=/usr/hive-2.1.0
$ export PATH=$PATH:$HIVE_HOME/bin
$ souce .bashrc
```

ここでhive実行後エラー、、、
よくわからないが、以下を試したらOKだった

```
$ mv metastore_db metastore_db.tmp
$ schematool -initSchema -dbType derby
$ hive
```
Safari の ES5 strict mode で Object.defineProperty() の奇妙な現象

## キミョい現象
iOS 9.3.2 の Safari では，ES5 の strict modeの場合，特定の条件下で `Object.defineProperty()` をコールすると，JavaScript が実行されず何もエラーや exception も吐かないという奇妙な現象に出会しました．

その特定の条件とは，わりと限定的ですが，`Object.defineProperty()` で設定する property に setter として名前付き関数を設定し，その関数名と引数名を同じにした場合です．

なお strict mode を解除すると，Safari でも期待通りの結果になります．Chrome や Firefox，そして Node.js では strict mode でもこの現象は発生しません．

## 実証コード
[gist でも公開しています](https://gist.github.com/udnp/c5e8896d7532bd88aa2932fd780c451d)が，次のようなコードで確認できます．
このコードは，setter/getter を`Object.defineProperty()` で設定する方法を解説した次のサイトにある参考情報を元にしています．
https://robertnyman.com/javascript/javascript-getters-setters.html#object-defineproperty

```js
'use strict';

var lost = {
  loc : "Island"
};	

Object.defineProperty(lost, "location", {
  get : function location() {
    return this.loc;
  },
  set : function location(location) {
    this.loc = location;
  }
});

// call getter
console.log(lost.location);
// => Island

// call setter
lost.location = "Another island";
console.log(lost.location);
// => Another island
```
このコードを実行すると iOS 9.3.2 の Safari では，この strict mode のスコープにある JavaScript の実行がエラーを吐いて停止したような状況になりますが，try-catch ではエラーや exception をひろえません．

なので調査はここまでに留めています．

## Safari の strict mode に対する生温い不信感
Safari の strict mode でのキミョい挙動は [別の件](http://qiita.com/pnlybubbles/items/7bb65b033048a3fcc181) でも報告されていて，今回の現象と合わせて，Safari の strict mode に生温い不信感をもちました．

そして，原因不明のバグに悩まされた場合は strict mode を疑ってみることも覚えました．

## 参考
* [[Proof Code] Safari ES5 strict mode issue for Object.defineProperty() with a named setter function](https://gist.github.com/udnp/c5e8896d7532bd88aa2932fd780c451d)
* [Testing getters and setters, and Object.defineProperty](https://robertnyman.com/javascript/javascript-getters-setters.html)
* [[Qiita] SafariにおけるgetOwnPropertyNamesの"use strict"下での挙動](http://qiita.com/pnlybubbles/items/7bb65b033048a3fcc181)
SpringBootをサービスとして実行する方法



nohupを利用すればよい

#起動
```
nohup java -jar myapplication.jar > log.txt 2> errors.txt < /dev/null &
PID=$!
echo $PID > pid.txt
```



#停止
```
PID=$(cat pid.txt)
kill $PID
```


#参照
http://stackoverflow.com/questions/11203483/run-a-java-application-as-a-service-on-linux/21283530#21283530
Calendarクラスで月末を取得する方法の速さ比較

JavaでCalendarクラスを使って月末を取得する2つの方法について速さを比較してみました。

実行環境は以下の通りです。

+ DELL VOSTRO 1540
+ Windows 10 Pro 32bit
+ Intel Celelron 2.00 GHZ
+ メモリ 2.0GB
+ HDは約300GB

月末を取得する方法は以下の2つです。

+ getActualMaximumメソッドを使用
+ 翌日初日-1を設定

#ソースと実行結果

上記をそれぞれ30000回実行して時間を比較しました。以下、ソースと結果です。

```Java:ソース
package test;

import java.util.Calendar;
import java.util.function.IntSupplier;

public class Test {

    // --計測用--
    private void printProcessingTime(IntSupplier f) {
        int count = 30000;
        long start, end;
        start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            f.getAsInt();
        }
        end = System.currentTimeMillis();
        System.out.printf("出力確認:%s, 計測 %3d: ", f.getAsInt(), end - start);
        System.out.println();
    }

    // --計測--
    public static void main(String[] args) {
        new Test().test();
    }

    private void test() {
        // test1
        System.out.println("test1");
        printProcessingTime(() -> {
            Calendar c = Calendar.getInstance();
            c.clear();
            c.set(2016, 1, 1);
            return c.getActualMaximum(Calendar.DATE);
        });

        // test2
        System.out.println("test1");
        printProcessingTime(() -> {
            Calendar c = Calendar.getInstance();
            c.clear();
            c.set(2016, 2, 1);
            c.add(Calendar.DATE, -1);
            return c.get(Calendar.DATE);
        });
    }
}
```

以下、実行結果です。

```DOS:結果
test1
出力確認:29, 計測 286: 
test1
出力確認:29, 計測 112: 
```

getActualMaximumメソッドの方が遅いという結果が出ました。

#修正履歴

20161009

+ 文言修正。
+ ソースを修正し、java.util.functionを使用。
+ 出力結果も再実施。
Dockerでよく使うコマンドメモ

# Dockerでよく使うコマンドメモ
すぐ忘れてしまうのでメモ

## Dockerイメージ取得
リポジトリからDockerイメージを取得する。デフォルトのリポジトリはDocker Hub

```shell-session
$ docker pull イメージ名
```

## Dockerイメージ削除
取得したイメージ、作成したイメージを削除

```shell-session
$ docker rmi イメージ名
```

## Dockerイメージ一覧
取得済みDockerイメージの一覧を表示

```shell-session
$ docker images
```

## コンテナ作成
取得したDockerイメージからコンテナを作成する

```shell-session
$ docker run [オプション] イメージ名 
```

## 起動コンテナ一覧
起動中のコンテナの一覧を表示。停止中のコンテナも一覧に表示する場合は-aオプションを使用

```shell-session
$ docker ps
```

## コンテナ起動
作成したコンテナを起動

```shell-session
$ docker start コンテナ名
```

## コンテナ停止
起動済みコンテナの停止

```shell-session
$ docker stop コンテナ名
```
Raspberry Pi1 のリビジョンを見分ける方法

#Raspberry Pi1のリビジョンについて
Raspberry Pi1 Model Bにはリビジョンが2種類存在する。
初代ラズパイを使って電子工作などをする際、リビジョンの違いで使用するGPIOのポートが若干異なったりするので注意が必要。


#ボードを見て判断する場合
ラズベリーのマークの下の文字をチェックする

Rev.1の場合は「(C)2011」となっている
<img width="202" alt="Screenshot 2016-07-16 22.14.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/42913/2cc186e9-baf2-45e4-efa4-c7169a3d1537.png">

Rev.2の場合は「(c)2011.12」と「12」まで含めて記入されている
<img width="202" alt="Screenshot 2016-07-16 22.14.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/42913/7d0f90d5-3e83-0d09-2a75-6e901db3f732.png">


#ターミナルのコマンド操作で判断する場合
`$cat /proc/cpuinfo` を入力する
Revisionの項目が
0002 であれば Rev.1
000f であれば Rev.2
となる。

#GPIOポートの違い
・Model B Rev.1
![gpio-pinout.jpg](https://qiita-image-store.s3.amazonaws.com/0/42913/d7d53c6b-44b7-48d0-414e-9dc331f8f3f5.jpeg)

・Model A または Model B Rev.2
![gpio-pinout-rev2.jpg](https://qiita-image-store.s3.amazonaws.com/0/42913/c459519a-350f-37a8-0d6f-a8e498cec825.jpeg)

・Model B++ (Model B Rev.2に13ピン追加された)
![gpio-pinout-bplus.jpg](https://qiita-image-store.s3.amazonaws.com/0/42913/92021e08-ed5b-d171-2303-914396dfe754.jpeg)

#参考書籍
- [Raspberry Pi［実用］入門――手のひらサイズのARM/Linuxコンピュータを満喫！ Software Design plus](http://amzn.to/29KTNCO)
BlueZのAPI

BlueZのAPIについて調べてみた。

なんでこうなっているのか、よくわかりませんが、なるべくならD-BusのAPIを使うのが良さそうです。

APIの切り口として以下があるみたいです。
* lib
* src/shared
* attrib
* btio
* D-Bus
* Android Bluetooth HAL


# lib
* 場所:lib
* bluezの内部API
* bluezのプロトコルスタックの中で使用する共通処理を行う関数のあつまり

# src/shared
* 場所:src/shared
* Bluezの内部API
* ATT, GATT, GAP, HCI など色々


# btio
* 場所:btio
* socket APIのwrapper
* attribはbtioのAPIを使っている。
* pygattlibが使っている

# attrib
* 場所:attrib
* gattの読み書きをするAPI
* gatttoolが使っている。
* attribはbtioのAPIを使っている。
* discovery/scanはできない

# D-Bus
* LinuxのIPC
* APIのヘッダファイルはないので、docにあるドキュメントとsrc/のソースコードとサンプルのソースコードを読む。
* サンプルのbluetoothctlはD-BusのAPIのみを使っている

# Android Bluetooth HAL
* 場所:android
* Android Bluetooth HAL互換のAPI
* BTとBLEに対応、l2cap, rfcommのsocketもある。 
* 最近、メンテする人がいなくAndroid 5.0までしか対応していない。
ログイン時にtmuxセッションを選択する

# 動機
Windowsからrloginで画面分割して同じサーバで作業するときに、楽にtmuxのセッションを選択したい。bashで

# 要件
* ログイン時に、セッション一覧を選択できる
* セッションがない場合、新しくセッションを作成する
* セッションがある場合でも新しくセッションを作成する
* セッションを作成するときには名前を付ける

# 成果物
```code:create_tmux_session.sh
create_new_session(){
  echo "session name>"
  read session_name
  tmux new-session -s $session_name
}

select_tmux_session(){
if [ -z $TMUX ]
then
  IFS_BACKUP=$IFS
  IFS=$'\n'
  ID=$(tmux ls)
  if [ -z "$ID" ]
  then
    create_new_session
    exit 0
  fi
  select item in $ID
  do
    case "$REPLY" in
      n )
        create_new_session
        break;;
      * ) echo "you select $item ($REPLY)"
        tmux attach -t $(echo $item | awk -F: '{print $1}')
        IFS=$IFS_BACKUP
        break;;
    esac
  done
fi
}
```
素直に書いた。これを.bashrcに書いておくだけ

# 結果
便利
カーソルサイズをトグルするAppleScript


動作するけど汚い…

```AppleScript
tell application "System Preferences"
	set current pane to pane "com.apple.preference.universalaccess"
	
	tell application "System Events"
		repeat until application process "System Preferences" is not (exists)
		end repeat
		delay 0.5
		tell first window of process "System Preferences"
			tell table 1 of scroll area 1
				set selected of row 2 to true
			end tell
			repeat until slider "カーソルのサイズ：" exists
			end repeat
			
			set theSlider to slider "カーソルのサイズ："
			set stash to value of theSlider
			if value of theSlider is 1.0 then
				set value of theSlider to 4
			else
				set value of theSlider to 1.0
			end if
			stash
		end tell
	end tell
	quit
end tell
```

---

20160716時点でうまく動かない…repeat入っているので使用には注意。

カーソルサイズを最小＝最大でトグル。
Maestroなどでショートカットキーを当てて使用

```Applescript
tell application "System Preferences"	
	set current pane to pane "com.apple.preference.universalaccess"
end tell
tell application "System Events"
	tell first window of process "System Preferences"
		repeat until slider "カーソルのサイズ：" exists
		end repeat
		tell table 1 of scroll area 1
			set selected of row 2 to true
		end tell
		set theSlider to slider "カーソルのサイズ：" 		
		set stash to value of theSlider
		if value of theSlider is 1.0 then
			set value of theSlider to 4
		else
			set value of theSlider to 1.0
		end if
		stash
	end tell
end tell
tell application "System Preferences" to quit
```

##問題点
アクセシビリティパネルで「キャプション」を選択している（していた）と、ディスプレイへ自動で移動できない。

##コードをお借りした＆参考にしたページ

『画面のグレー/カラーのスイッチ』
http://goozenlab.com/blog/2013/02/grayscale-switch/

『mouse - How can I easily toggle the cursor size back and forth between normal and largest? - Ask Different』
http://apple.stackexchange.com/questions/88267/how-can-i-easily-toggle-the-cursor-size-back-and-forth-between-normal-and-larges
Raspberry PiのOSをSDカードに焼く

#環境
RaspberryPi 1 Model B
Mac OSX El Capitan 10.11.5 (US環境)
TDK SDHCカード 8GB Class10
書き込むOS: 2016-05-10-raspbian-jessie.img

#SDカードをフォーマット
SDカードをMacに挿す
Disk Utilityを開いて左のInternalの中からフォーマットしたいSDカードを選択
※間違えて他のものを選ばないように！

ちなみにSDカードが階層になってると思うけど、上の▽がついてる方をを選びましょう
<img width="186" alt="Screenshot 2016-07-16 21.13.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/42913/5f3adb5d-0829-59c2-4591-a03f2377d6c2.png">


Eraseタブを押して、FormatをMS-DOS(FAT)にしてEraseを押すとフォーマットが始まる

#OSをダウンロード
今回はRaspbianを使用したいと思うので↓から「RASPBIAN JESSIE Full desktop image based on Debian Jessie」をダウンロード
https://www.raspberrypi.org/downloads/raspbian/

他に好きなOSがあったら別のところからダウンロードすればいいです
(Raspberry Pi 1は対応していないOSがあるので注意)

#SDカードををアンマウント
Terminalを開く
`$diskutil list`
で現在Macで認識しているデバイスが表示される

<img width="564" alt="Screenshot 2016-07-16 21.22.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/42913/da566a99-5957-2341-a0aa-485dbf20bc66.png">

8GBのSDカードを使ってるので、SIZEが8.0GBの/dev/disk2がSDカードのパスだとわかる

OSを焼くにはSDのマウントを解除しないといけないので、以下のコマンドで/dev/disk2をアンマウント
`$diskutil unmountDisk /dev/disk2`

#SDにOSを書き込む
`$sudo dd if=OSイメージファイルのパス of=SDカードのパス bs=1m`
で書き込める

今回の場合、
`$sudo dd if=/Users/mrsisyamo/Downloads/2016-05-10-raspbian-jessie.img of=/dev/rdisk2 bs=1m`
となる。
`/dev/disk2`ではなく `/dev/rdisk2`と`r`を付けているのは、高速で書き込みを行えるようにするため
bsは1回毎に書き込む際のブロックサイズ数を指定しており、`bs=1m`にしておくのが丁度いいらしい

10分前後待つと書き込みが完了する

#SDカードの相性について
SDにうまく書き込めたとしてもOSが正常に起動しない場合がある。
http://elinux.org/RPi_SD_cards
ここのサイトにラズパイとSDカードの相性が載っているので確認すると良い。
ただ、okと書いてあっても使えなかったり、nokと書いてあっても使える場合があるので、SDカードを購入する際の参考程度に事前に見ておこう。

#参考書籍
- [Raspberry Pi［実用］入門――手のひらサイズのARM/Linuxコンピュータを満喫！ Software Design plus](http://amzn.to/29KTNCO)
- [Raspberry Pi電子工作レシピ](http://amzn.to/29KSWlJ)
FacebookでシェアするURLを動的にする方法

シングルページアプリケーション(SPA)でページ状態に合わせてFacebookでシェアしたいURLを切り替えたい（動的にしたい）時がたまにありますよね。

そんな時はFacebook公式APIの「FB.XFBML.parse()」を使うと便利ですよ。

事前にFacebookのシェアボタンとメッセンジャーで送信ボタンをHTMLで準備します。

```html
<!-- シェアボタン -->
<span class="facebook-share-button fb-share-button"
 data-size="large"
 data-layout="button"
 data-mobile-iframe="true"
 ref="unique-parameter-value">
</span>
<!-- メッセンジャーで送信ボタン -->
<span class="facebook-share-button fb-send"
 data-size="large"
 data-mobile-iframe="true"
 ref="unique-parameter-value">
</span>
```

次にjavascriptでFacebookの初期化と任意のタイミングでボタンの表示をします。

```js
// Facebookの初期化
$(function() {
    var d = document;
    var s = 'script';
    var id = 'facebook-jssdk';
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6";
    fjs.parentNode.insertBefore(js, fjs);
});

// FBの初期化(Facebook sdk.jsの完了)が未だなら待つ。
function callAfterFacebookInitialization(callback){
  if(typeof FB !== "undefined"){
    callback();
  } else {
    setTimeout(function(){
        callAfterFacebookInitialization(callback);
    }, 100);
  }
}

var shareUrl = "http://qiita.com/";
var targetClass = ".facebook-share-button";

// twttrが使えるようになったらシェアボタンを作る。
callAfterFacebookInitialization(function(){
  $(targetClass).attr("data-href", shareUrl).data("href", shareUrl);
  FB.XFBML.parse();
});
```

FB.XFBML.parseで再描画が行われるので、その前にfacebook-share-buttonの必要な属性を上書きします。

すっきり。

Twitterで同じ事をする場合は以下URLを参照してください。
http://qiita.com/tkosuga@github/items/78266333790ed9479c8a

参考：https://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse/