過去の日記


2012-12-10 [長年日記]

括弧を忘れてmethodが返ってくる罠 [Python]

やってることは嘘だけど、ざっと省略してこんなソースを書いてた。

n1=foo() #datetime型
n2=bar #datetime型
td=n1-n2 #timedelta型

if td.total_seconds>0:
    print "n1が%s秒早いです"% td.total_seconds()
else:
    print "n2が%s秒早いです"% -td.total_seconds()

これ、elseが実行されなかった。
n2のほうが小さい状況はまずありえないけど「一応書いておいた」ケース。
なのでそこを通すテストをわざわざやってみるまで間違いに気づかなかった。

if の部分、td.total_secondsの括弧を忘れていて、method型が返ってきてた。(Python2系では)0と比較することが許されて、(多分)必ず真。
テストして気がついてよかった。


2012-12-01 [長年日記]

2012年11月の読書メーター

読んだ本の数:4冊
読んだページ数:1272ページ
ナイス数:34ナイス

書物審問 (講談社ノベルス)書物審問 (講談社ノベルス)感想
犯人……あんた馬鹿だろ……
読了日:11月27日 著者:赤城 毅
疾走!千マイル急行〈下〉 (ソノラマ文庫)疾走!千マイル急行〈下〉 (ソノラマ文庫)
読了日:11月22日 著者:小川 一水
図書館戦争  図書館戦争シリーズ(1) (角川文庫)図書館戦争 図書館戦争シリーズ(1) (角川文庫)感想
p126「正論は正しい、だが正論を武器にする奴は正しくない」読んでいてニヤニヤしたり涙が浮かんだりと、外で読むには向かない本だった。郁が図書隊員を目指すきっかけになった事件のくだりですでに涙が出る。
読了日:11月18日 著者:有川 浩
疾走!千マイル急行〈上〉 (ソノラマ文庫)疾走!千マイル急行〈上〉 (ソノラマ文庫)
読了日:11月11日 著者:小川 一水

読書メーター


2012-11-26 [長年日記]

random.shuffleの話 [Python]

かなり小さい len(x) であっても、 x の順列はほとんどの乱数生成器の周期よりも大きくなるので注意してください; このことは長いシーケンスに対してはほとんどの順列は生成されないことを意味します。

9.6. random - 擬似乱数を生成する - Python 2.7ja1 documentation

どういうことだろう?

例えば乱数の周期が5しかないとする。この乱数で要素5の配列をシャッフルする。
[4, 2, 3, 5, 1]
とでた。
まあシャッフルされたっぽい。
繰り返してみる。
[2, 3, 5, 1, 4]
[5, 1, 4, 2, 3]
[4, 2, 3, 5, 1]
[1, 4, 2, 3, 5]
[5, 1, 4, 2, 3]
という感じで出てきた。
順列組み合わせは5!あるはずだが、[4, 2, 3, 5, 1, 4, 2, 3, 5] の部分列5種類しか出てこない。

こういうことが起きるって話か。


ところで「かなり小さい len(x)」っていったいどのぐらいだろう?

Python は中心となる乱数生成器として Mersenne Twister を使います。これは 53 ビットの浮動小数点を生成し、周期が 2**19937-1、本体は C で実装されていて、高速でスレッドセーフです。

9.6. random - 擬似乱数を生成する - Python 2.7ja1 documentation

周期は2**19937-1だそうだ。
桁数だけ評価する
\(\log_{10}~2^{19937}~+~1=~19937~\times~\log_{10}~2~+~1\) ですな。

import math
19937*math.log10(2)+1=6002.635023552793

まあ、6002桁ぐらい*1

順列組み合わせが6002桁ぐらいになる配列。

math.log10(math.factorial(2081)) #=> 6003.615625445271

このへんか。
2000個程度の配列から上はrandom.shuffle()は十分にランダムではない。
実際は、もっと小さな配列からrandom.shuffle()の結果に周期性が入り込んでくるはずだ。

*1 mathモジュールは19937*math.log10(2)+1でもmath.log10(2**19937)+1でも、同じ結果を返すのだけどね。:-P


2012-11-24 [長年日記]

インストールしたモジュールの場所が分からない [Python]

pip install したモジュールがどこに配置されたのか分からなかった。

import hoge
print hoge.__file__