直交表とpair wise法

直交表とかpair wise(all pair)法とか、テストケースの抽出に利用する技法について少し調べてみた。

  • 直交表

ある2列の組み合わせで見ると、同じ組がそれぞれ同じ数だけある。
2なら、すべて2組ずつ。

  • all-pair

ある2列の組み合わせで、全ての組み合わせが最低1つはある。
組み合わせを生成するツールとしてpict,pictMaster,Jennyなどがある。

用語

因子 :列のこと
水準 :パラメータ(列の取る値)

hashの実装について

Beautiful Codeという本にhashの実装についての章があったので、少し調べてみた。

参考にしたソース、資料

本ではPythonのhash実装を説明していたが、そこでポイントされていたのが下記の資料。

  • 資料

http://svn.python.org/view/python/trunk/Objects/dictnotes.txt?view=markup

  • ソース

http://svn.python.org/view/python/trunk/Objects/dictobject.c?view=markup

小技

hashのindexを取得する時、配列のサイズで剰余演算を行うが、配列のサイズを2の階乗にしておくと、ビット演算で高速に剰余を取得できる。
上記のdictobject.cの lookdict_string メソッド内で、

i = hash & mask

のような感じの箇所。maskはあらかじめ 配列のサイズ - 1 に設定されている。

open addressでのアドレス取得

ソースの先頭付近のコメントで解説されている。
上と同じlookdict_string メソッド内で、変動値を入れながら、

nextIndex = (currentIndex * 定数値 + ループごとの変動値 + 1) mod entrySize

のようなロジックで次のインデックスを取得している。
ループごとの変動値の初期化にもhash値を使っている所も工夫されている。
コメント部分にも書いてあるが、

 j = ((5*j) + 1) mod 2**i

を繰り返すと、jが重複せずindexを一巡する。

DocumentBuilderで日本語のパスを渡すとエラーになる不具合

下記のようなファイルをxpathで読もうとします。


  
    id01
    car1
  
  
    id02
    car2
  

読み込むソースは下記です。

import javax.xml.parsers.*
import javax.xml.xpath.*
import org.w3c.dom.*

// documentの作成
def path = "C:\\englishpass\\car.txt"
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance()
f.setNamespaceAware(true)
DocumentBuilder b= f.newDocumentBuilder()
Document doc = b.parse(path)

// xpathの作成
XPathFactory xf = XPathFactory.newInstance()
XPath xpath = xf.newXPath()
XPathExpression exp = xpath.compile("/cars/car/name/text()")

// 読み込み
Object ret = exp.evaluate(doc, XPathConstants.NODESET)
NodeList nodes = (NodeList) ret
nodes.each{
println it.getNodeValue()
}

パスがasciiのみの場合は正常に結果が取得されます。

car1
car2

DocumentBuilderのparseメソッドに渡すパスに日本語が含まれている場合、エラーが発生しました。

def path = "C:\\日本語のパス\\car.txt

xercesのパーサが日本語に対応していないのが原因らしいです。
なので、パス文字列でなく入力ストリームをparseメソッドに渡す方法に変更。

def path = "C:\\日本語のパス\\car.txt"
// FileInputStreamのインスタンスを作成
def f = new FileInputStream(path)
DocumentBuilderFactory f= DocumentBuilderFactory.newInstance()
f.setNamespaceAware(true)
DocumentBuilder b= f.newDocumentBuilder()
// parseメソッドにFileInputStreamを渡す
Document doc = b.parse(f)

これで日本語のパスを含むファイルを解析できました。
もしくはparse(new File(path))でもOKなようです。
中身が日本語の場合大丈夫なのかというと、UTF-8の場合はそのまま使えました。
Shift_JISの場合はXMLファイルの頭に

<?xml version="1.0" encoding="Shift_JIS" ?>

のような指定をしておけばプログラム的には何もしなくても読めました。
文字コードを明示的に指定する場合は、InputSourceを利用できます。

import org.xml.sax.InputSource

def f = new FileInputStream(path)
def s = new InputSource(f)
s.setEncoding("Shift_JIS")
// ...
Document doc = b.parse(s)

この場合、XMLファイル先頭の文字コード指定は不要となります。

見積もりのリンク

規模見積もりやファンクションポイントなどのリンク
http://itpro.nikkeibp.co.jp/article/COLUMN/20070221/262654/?ST=mngskill
http://www.1offshoring.com/modules/wordpress/index.php?p=29
http://allabout.co.jp/career/swengineer/subject/msubsub_est.htm
http://allabout.co.jp/career/swengineer/closeup/CU20030727A/
http://cafe.eyln.com/cgi-bin/wiki/wiki.cgi?page=FP%CB%A1%A4%CB%A4%C4%A4%A4%A4%C6#p33
http://www.thinkit.co.jp/cert/trend/16/2/2.htm

jvmの起動時にロケール指定

jvmの起動パラメータに下記の指定でロケールが変更できる。

-Duser.language=en -Duser.country=US

ちなみにEclipseではアプリケーションとしての起動パラメータに -nl があり、-nl en_USなどと指定するとそのロケールで動作している模様。

Groovyのeachの動作

配列のように順次取り出せる構造になっている対象に対するeachは各要素でブロックを実行し、そうでない場合は自分自身で一回だけブロックを実行している模様。

def a = new Expando()
a.id="id_a"
[a].each{
println it
}
/*
結果:
{id=id_a}
*/


a.each{
println it
}
/*
結果:
{id=id_a}
*/
["abc"].each{
println it
}
/*
結果:
"abc"
*/


"abc".each{
println it
}
/*
結果:
a
b
c
*/

使っているEclipeプラグインのまとめ

  • Editor Enhancements

主にemacsのような矩形選択、編集ができる。その他emacs風の編集が少しできる。

  • プロパティエディタ

これがないとめんどくさいです。

ファイル単位でのチェックスタイルの有効無効の切り替えは、右クリックメニューから行うことができる。

テスティングフレームワークカバレッジ
eclemmaはJUnitだけでなく好きなテスティングフレームワークと組み合わせて使えるようなので。

subversionのクライアント

テストファーストな開発でTestCase実行の時にカバレッジの確認も行うと、通ったはずと思い込んでた箇所が通っていなかったとか分かるので、ソースに色をつけてくれるeclEmmaはなかなかよかったです。