【Python】SimplePrograms line 14 Doctest-based testing
プログラム
14行プログラムです。
def median(pool):
'''Statistical median to demonstrate doctest.
>>> median([2, 9, 9, 7, 9, 2, 4, 5, 8])
6 #change to 7 in order to pass the test
'''
copy = sorted(pool)
size = len(copy)
if size % 2 == 1:
return copy[int((size - 1) / 2)]
else:
return (copy[int(size/2 - 1)] + copy[int(size/2)]) / 2
if __name__ == '__main__':
import doctest
doctest.testmod()
実行結果
~/python $ python line14.py
**********************************************************************
File "/data/data/com.termux/files/home/python/line14.py", line 3, in __main__.median
Failed example:
median([2, 9, 9, 7, 9, 2, 4, 5, 8])
Expected:
6 #change to 7 in order to pass the test
Got:
7
**********************************************************************
1 items had failures:
1 of 1 in __main__.median
***Test Failed*** 1 failures.
~/python $
解説
前回は単体テストの機能だったんですけど、今回は「ドキュメント兼テスト」です。
こちらの方がいいかもしれない。
関数「median」についてはこちらに解説しました。
まず、こちらのオレンジで囲んだ部分は全て文字列です。
わざとエラーケースで書かれてあるのでわかりにくいのですが、普通ならおそらくこのように書きます。
def median(pool):
'''Statistical median.
データが奇数個のとき、真ん中のデータが中央値となります
>>> median([1, 2, 3, 4, 5])
3
データが偶数個のとき、真ん中の2つのデータの平均が中央値となります
>>> median([1, 2, 3, 4])
2.5
もしデータが昇順に並んでいなければ、並べ替えて中央値を決定します
>>> median([2, 9, 9, 7, 9, 2, 4, 5, 8])
7
'''
copy = sorted(pool)
size = len(copy)
if size % 2 == 1:
return copy[int((size - 1) / 2)]
else:
return (copy[int(size/2 - 1)] + copy[int(size/2)]) / 2
if __name__ == '__main__':
import doctest
doctest.testmod()
トリプルクォーター内が関数の説明です。
これを「-v」で実行すると、次のような結果が出力されます。
~/python $ python line14a.py -v
Trying:
median([1, 2, 3, 4, 5])
Expecting:
3
ok
Trying:
median([1, 2, 3, 4])
Expecting:
2.5
ok
Trying:
median([2, 9, 9, 7, 9, 2, 4, 5, 8])
Expecting:
7
ok
1 items had no tests:
__main__
1 items passed all tests:
3 tests in __main__.median
3 tests in 2 items.
3 passed and 0 failed.
Test passed.
~/python $
ようするに、文字列で
>>> median([1, 2, 3, 4, 5])
3
と書いた部分を探し出してインタプリタで実行し、結果を次の行と比較するわけです。
これは、
コードのドキュメントでもあり、
テストケースでもあり
テストの実行もできる
という優れものです。
インタプリタ言語なればこそとも言えますが、言語仕様にこういうものを取り込むというのはすごいですね。
Pythonのドキュメントには次のようにあります。
「読めるテスト」
「実行できるドキュメント」
面白い。
ソフトウェアのドキュメントというのは実にたくさんあります。こういうものを利用すれば作成するドキュメントの量も抑えることができて、強いては生産性も向上するやもしれません。
文字列をどこにおいてもいいのかどうかが気になったので試してみました。
'''
(1)データが奇数個のとき、真ん中のデータが中央値となります
>>> median([1, 2, 3, 4, 5])
3
'''
def median(pool):
'''Statistical median.
(2)データが偶数個のとき、真ん中の2つのデータの平均が中央値と なります
>>> median([1, 2, 3, 4])
2.5
'''
copy = sorted(pool)
size = len(copy)
if size % 2 == 1:
return copy[int((size - 1) / 2)]
else:
return (copy[int(size/2 - 1)] + copy[int(size/2)]) / 2
'''
(3)もしデータが昇順に並んでいなければ、並べ替えて中央値を決定します
>>> median([2, 9, 9, 7, 9, 2, 4, 5, 8])
7
'''
if __name__ == '__main__':
import doctest
doctest.testmod()
結果は・・・。
~/python $ python line14b.py -v
Trying:
median([1, 2, 3, 4, 5])
Expecting:
3
ok
Trying:
median([1, 2, 3, 4])
Expecting:
2.5
ok
2 items passed all tests:
1 tests in __main__
1 tests in __main__.median
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
~/python $
ふーん。
3つ目の(3)は試験されないんだ。
個人的には(1)の場所に書くのが好きかな。
参考
この記事が気に入ったらサポートをしてみませんか?