sohatach's blog

http://github.com/soha

pandas.read_fwf()の使い方

www.oreilly.co.jp
Think Stats 第2版を読んでいます。

冒頭でサンプルデータを読み込んでいる

import nsfg
df = nsfg.ReadFemPreg()

の中で実行されている
pandas.read_fwf()
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_fwf.html
の意味が公式ドキュメントを見てもさっぱり分からなかったので実際に動作確認した結果をメモ。

pandas.read_fwf()
をどんな時に使うかというと、
テキストを区切り文字(カンマやタブなど)で分割するのではなく、固定長で分割し読み込みたい時。
ということのようです。
なおカンマ区切りであれば、read_csv()、タブ区切りであれば、read_table()が使えます。

サンプル

以下のようなinput.txtがあるとする。
特に区切り文字を使用せず、文字の長さで分割してみる。

001 abc A
0002 abcd B
00003 abcde C

import pandas as pd
import numpy as np

#入力ファイル名
filename = 'input.txt'

#ファイルの区切り位置の定義
colspecs = [(0,5),(5,12),(13,14)]

#ファイルを区切った際のカラム名
names = ['key','name','flg']

df = pd.read_fwf('input.txt',colspecs=colspecs,names=names,converters={'key':np.str})

実行結果

index key name flg
0 001 00003 A
1 0002 abcde B
2 00003 abcde C

colspecs = [(0,5),(5,12),(13,14)]
の位置で分割した形でDataFrameが取得できます。

OpenAMをソースからビルドする。

OpenAMとは

Wikipediaによれば、
「OpenAMは、オープンソースのアクセス管理、エンタイトルメント、フェデレーション·サーバーのプラットフォームである。」
とのこと。
よくわかりにくいですが、簡単に言うとWebアプリでシングルサインオンを実現するためのサーバです。

OpenAMの情報は以下のサイトが詳しいです。
http://openstandia.jp/oss_info/openam/

0. 前提条件

Java 8u40 64bit
Maven 3.3.1
Subversion 1.7.19

がインストールされていること。
今回OSは、MacOS 10.10を使用しました。

※今回MacにインストールされていたSubversion 1.7系を使用しましたが、
1.8系がインストールされている場合、pom.xmlに1.8用のsvnkitを指定しないとビルドエラーになるかもしれません。
Linuxでビルドしたところそのようになりました。
https://code.google.com/p/maven-svn-revision-number-plugin/issues/detail?id=18

1. ソースコードのダウンロード

svn checkout時にアカウントが求められるようですので、作成しておきます。(無料です)
https://backstage.forgerock.com/#!/account/registe

続いてソースのチェックアウト
http://wikis.forgerock.org/confluence/display/openam/Guide+to+OpenAM+Subversion
こちらにtrunkをチェックアウトする手順が書かれていますが、
trunkは、随時修正が入って変わってしまいそうな気がするので、今回は12.0.0-1のタグを使用します。
以下のコマンドにてチェックアウトできます。

svn checkout https://svn.forgerock.org/openam/tags/12.0.0-1 openam-12.0.0-1

2. ビルド

http://wikis.forgerock.org/confluence/display/openam/Build+OpenAM+from+Source
こちらに記載のある通り、チェックアウトしたディレクトリの直下にあるopenamディレクトリに移動したのち以下のコマンドでビルドできるようです。

mvn -DskipTests=true clean install

(テストは通らないようなのでスキップさせる必要があります)

[INFO] Installing /Users/user1/repo/openam-12.0.0-1/openam/openam-sts/openam-soap-sts/target/openam-soap-sts-12.0.0-1.war to /Users/user1/.m2/repository/org/forgerock/openam/openam-soap-sts/12.0.0-1/openam-soap-sts-12.0.0-1.war


[INFO] OpenAM SOAP STS ................................... SUCCESS [21.434s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15:41.487s
[INFO] Finished at: Sun Apr 05 19:25:19 JST 2015
[INFO] Final Memory: 263M/1597M
[INFO] ------------------------------------------------------------------------

上記のログに出ているように
/Users/user1/.m2/repository/org/forgerock/openam/openam-soap-sts/12.0.0-1/openam-soap-sts-12.0.0-1.war
にwarファイルがインストールされました。

Travis CIで継続インテグレーション、Coverallsでテストカバレッジ確認

Travis CIという継続インテグレーション(自動ビルドや自動テストを継続的に行う)サービスを使ってみました。
https://travis-ci.org/

1. 動作確認対象レポジトリの用意

Travis CI上でビルドやテストを実行するには、自身のGitHubのアカウントの対象となるレポジトリが必要になりますが、
今回は動作確認を目的としているので、以下のレポジトリをfolkし使用させていただきました。

https://github.com/skinny-framework/skinny-framework-example

以下のように本家のGitHubのサイトからforlし、自身のGitHubのアカウントのレポジトリとします。

f:id:sohatach:20150215233026p:plain

2. Travis CI上でのGitHubレポジトリの有効化

この状態でTravis CIにログイン(ログインには、GitHubアカウントが必要)すると
アカウント設定の画面にて、自身のレポジトリ一覧が表示されますので、
skinny-framework-exampleレポジトリのTravic CIとの連携をONにします。

f:id:sohatach:20150215233127p:plain

OFFの状態からONにしました。

これでTravis CIを使う準備はできましたが、デフォルト設定では、レポジトリに対し
なんらかのcommitのpushをフックしてビルドが起動するようですので、
まずはなんでもいいのでcommitを作りpushします。

3. Travis CIの設定ファイル

ここcommitを作る前にTravis CIの設定ファイルを確認します。
プロジェクト直下の.travis.xmlというファイルが該当します。
動作確認した状態では以下のようなものになっていました。

language: scala
scala: 2.11.5
sudo: false
jdk: oraclejdk8
script: "./travis.sh"
after_success: sbt coveralls
env:
  global:
    secure: ほげほげ

ここで特筆すべきは、scriptの項目がTravis CIでテストを実行させるコマンドになります。
travis.shの中身を見ると以下のようになっていました。

#!/bin/bash
./skinny db:migrate test && ./skinny test:coverage

ここは使用するフレームワークなどにより記載内容は異なるものになると思います。

after_successについては、テスト実行時に実行される処理です。
ここでは、sbtのcoverallsプラグインを使用して、coverallsにテスト結果を送信しています。
env.global.secureは、coverallsで使用するレポジトリを特定するためのものです。
coverallsから発行されるREPO_TOKENをそのまま記載しGitHubに載せるのは望ましくないとのことから
このように暗号化して記載することが推奨されているようです。

参考
・Go + Travis CI + Coveralls でCI環境を作る
http://qiita.com/dmnlk/items/3fb4e0abb98e39fee275
「Tokenを暗号化してセキュアにする」のところ。
4. フック用新規commitの作成(Coverallsのsecure設定)

新規commitは、ダミーファイルを作るなりどんな変更でもいいのですが、
さきの.travis.xmlのenv.global.secureは、レポジトリ毎に有効な値のため、
folkした今回のレポジトリでは、オリジナルの値は使えません。
そのため今回のレポジトリ用の値を取得します。

まずはCoverallsのサイトにアクセスし、REPO TOKENの値をメモします。
ここでは、Travis CIと同様にまずは、レポジトリを有効にします。

f:id:sohatach:20150215233144p:plain

(REPO TOKENの値は、ログインしていればCoverallsのレポジトリ画面右側に表示されてるようです)
この値をもとにenv.global.secureの値を生成します。
実行にはRubyの動作環境が必要です。

>gem install travis
travisパッケージをインストールし、以下のコマンドを実行します。

>travis encrypt COVERALLS_TOKEN=メモしたREPO_TOKENの値
画面上にsecureの値が表示されるため、これを.travis.xmlに上書きコピーします。

>git add .travis.xml

>git commit
適当にコミットログを記載し、commitします。

>git push
clone元へのpushなので、デフォルトで引数不要です。
このあたりは単純にGitHubの話ですね。

5. Travis CI,Coverallsサイト上での結果確認

Travis CI上で処理が実施されているはずなので、サイトにアクセスしてみます。
今回のケースでは以下のURLとなります。(見るだけであればログインせずとも誰でも可能なようです)
https://travis-ci.org/soha/skinny-framework-example

f:id:sohatach:20150215233245p:plain
f:id:sohatach:20150215233304p:plain

ずらずらと処理が実行されています。


Travis内で実行されている主な処理は以下の通りです。

$ git clone --depth=50 --branch=master git://github.com/soha/skinny-framework-example.git soha/skinny-framework-example

GitHubより該当ソースをcloneしています。(Travis内のワークディレクトリに)

$ export COVERALLS_TOKEN=[secure]

Coverallsの認証設定をしています。

$ jdk_switcher use oraclejdk8
$ export JVM_OPTS=@/etc/sbt/jvmopts
$ export SBT_OPTS=@/etc/sbt/sbtopts
$ java -version
$ javac -version

.travis.xmlの設定に従いJava環境まわりの設定をしています。

$ ./travis.sh

テストscriptの実行

$ sbt coveralls

Coverallsへのテスト結果反映


今回のCoverallsのサイトのURLは、以下の通りです。
こちらもログインせずとも参照はできるようです。
https://coveralls.io/r/soha/skinny-framework-example

f:id:sohatach:20150215233556p:plain

BeagleBone Blackで温度測定

ただ温度を測定するだけではおもしろくないので、
BeagleBone Blackで部屋の温度を測定し、時系列でログに残し、
外気温や電気代(冷暖房費)との関係を調べてみたいと思っています。

進めるにあたりこちらのページを参考にさせていただいています。
・BBBとBoneScriptとGroveモジュールで温度を表示しよう
http://marutsuparts.blog74.fc2.com/blog-entry-1057.html


BeagleBone自体の入門としては、こちらの記事をまず読むことをおすすめします。
・BeagleBone Black の購入とセットアップをしよう
http://marutsuparts.blog74.fc2.com/blog-entry-1050.html

・BeagleBone Black で お手軽に開発をしよう
http://marutsuparts.blog74.fc2.com/blog-entry-1051.html


BeagleBoneでは、JavaScriptにて端末を操作することができます。
またまだβ版とはいえ、「Cloud9 IDE」というWebアプリでの開発ツールが提供されているのが斬新でした。
f:id:sohatach:20150211182641p:plain


ブログサイトの問題か、上記ページのサンプルコードが非常に読みづらかったため、
必要な箇所のみ以下に転記させていただきます。
ledblink.jsのコード

var b = require('bonescript');

leds_out = function(status){
    b.digitalWrite('USR0', status);
    b.digitalWrite('USR1', status);
    b.digitalWrite('USR2', status);
    b.digitalWrite('USR3', status);
}

var state = b.HIGH;

blink = function(){
    if (state == b.HIGH){
        state = b.LOW;
    } else{
        state = b.HIGH;
    }
    leds_out(state);
}

// setup b.pinMode('USR0', b.OUTPUT); b.pinMode('USR1', b.OUTPUT); b.pinMode('USR2', b.OUTPUT); b.pinMode('USR3', b.OUTPUT);

setInterval(blink, 1000);

BeagleBone本体の4つのLEDが1秒ごとにチカチカするのが確認できました。


続いて本題のこちら
・BBBとBoneScriptとGroveモジュールで温度を表示しよう
http://marutsuparts.blog74.fc2.com/blog-entry-1057.html

こちらもサイトのソースコードが見づらいため
以下に転記させていただきます。
また私の環境ではなぜか、ファイル名を指定の「grove_temp_sensor_test.js 」にしたところ
うまく動かなかったため、「temp.js」としました。

var b = require('bonescript');

var getTemperature = function(){
    var AN0 = "P9_39";
    var B = 3975;
    var R0 = 10000;
    var Rs = 10000;
    var Vref = 1.8;
    var Ts = 25 + 273.15;
    
    var a_val = b.analogRead(AN0);
    var V = a_val * 1.8; // 0 to 1 : 0 to 1.8(V)
    var R = R0 * V / (Vref - V);
    var T = 1 / ( 1 / Ts - Math.log(R / Rs) / B ) - 273.15;
    
    console.log("V = " + V);
    console.log("R = " + R);
    console.log("Temperature: " + T);
}

var timer = setInterval(getTemperature, 1000);

実際の画面はこちら、
f:id:sohatach:20150211182740p:plain
画面下部にTemperatureとして温度が取得できているのがわかります。
このサンプルのケースでは、setIntervalにより1秒毎に更新されます。

今はコンソールに出力するだけですが、定期的にログファイルに残すことで、目的とすることが実現できそうです。

IntelliJ IDEAでのEmacsキーバインドの設定の仕方

IntelliJ IDEA 14では、最初からEmacsキーバインドの設定を持っています。
Preferences -> Appearance & Behavior -> Keymap
この中のKeymapsという項目に「Emacs」というものがあり、エディタをEmacsキーバインドに設定できます。

しかしこのキーバインド、初期状態のままでは、私には少し使いづらいかったので
以下の点をカスタマイズしました。

f:id:sohatach:20150211170045p:plain
Save to Kill Ring

こちらに「command + w」を追加しました。
f:id:sohatach:20150211170118p:plain
(なぜかもともとの設定の「option + w」では、Σ記号が入力され、Save to Kill Ringの動きとならないようでした。)

「option + w」が使えないのは、どうやらMac特有の問題のようです。
参考
Mac OS XIntelliJ IDEA の Emacs キーマップで Option+W とかが効かないアレを解消する
http://qiita.com/komiya_atsushi/items/476ad61c546655082d7a

SoftBankの4G LTE(XPERIA Z3)のSIMをAterm MR03LNで使う。

XPERIA Z3が欲しいがために契約したSoftBankの4G LTEの回線が余っていたので、
Aterm MR03LN(NECのルータ)で使えないか試してみました。

Aterm MR03LNでは、通常APNの設定をすれば多くのSIMで使用できますが、
SoftBankの4GLTE回線では、契約ごとにユーザ名とパスワードが変わるなど設定にひと手間掛かるようです。
この契約毎のユーザ名とパスワードを確認できる大変便利なAndroidアプリSbmApnGetterというものがあったので
こちらを使用させていただきました。

SbmApnGetter
http://littleapps.hateblo.jp/entry/2014/01/26/234149

使い方は、SIMを挿した状態でXPERIA Z3でこのアプリを起動することで
電話番号やIMSIなども設定してくれたため、そのままGenerateボタンを実行するだけでユーザ名とパスワードが生成されました。
(厳密にはユーザ名やパスワードを抜き出すのではなく、電話番号やIMEIなどから生成しているようです。)

Aterm MR03LNの方の設定
3G/LTE用のAPNの設定として以下のものを追加しました。
APNは「fourgsmartphone」、ユーザ名、パスワードはSbmApnGetterで入手したものを入力。
また、暗号化方式はCHAP、接続方式は、IPv4を指定しました。

参考
http://www.aterm.jp/function/mr03ln/guide/lte_3g.html

上記にてLTE/3Gに繋がりました。
My SoftBankで確認する限り追加の費用などは掛かっていないようですが、
想定外の使い方になると思いますので、高額請求が来る可能性などもあり得ます。
お試しする際は、自己責任にてわかる方のみお願いします。

numpyのargsortの動き

Pythonによるデータ分析入門――NumPy、pandasを使ったデータ処理
Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理
を読んでいて、よくわからなかった箇所があったのでメモ。
numpyのargsort()の動きについてです。


http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html

>>> x = np.array([3, 1, 2])
>>> np.argsort(x)
array([1, 2, 0])

ドキュメントによれば、argsort()は、ソート結果の配列のインデックスを返すとのことのようですが、
これの意味が当初よくわからなかったので実際に動かして確認してみました。

もとの配列は、[3, 1, 2]となっており、それぞれのインデックスは、
左から0(対応する値は3), 1(対応する値は1), 2(対応する値は2)となります。
対応がわかりやすいように値の後ろに括弧でインデックス値を入れると3(0),1(1),2(2)となります。
argsort()により、並び替えた結果の配列のインデックスを返すとなるので、
並び替えた結果の「値の配列」は、[1(1), 2(2), 3(0)]となるべきはずで、
元の配列でのインデックス値で表現すると結果は、
1(対応する値は1), 2(対応する値は2), 0(対応する値は3)
となります。


実際に値を増やして動かしたところ想定通りの結果となっているため上記認識の理解で良さそうです。

>>> import numpy as np
>>> x = np.array([3, 2, 1, 4])
>>> np.argsort(x)
array([2, 1, 0, 3])
>>>

元の配列は、
3(0), 2(1), 1(2), 4(3)
値を並び替えると
1(2), 2(1), 3(0), 4(3)
となり、インデックス値で表現すると
[2, 1, 0, 3]となります。