2018年1月2日火曜日

Python3でプログラムの実行時間を計測する方法

Python3でプログラムの実行時間を計測する方法を紹介します。

以下は、timeモジュールを利用した計測方法です。
import time

start = time.time()
time.sleep(3)
finish = time.time()
print(finish - start)
以下は実行結果です。
3.0009043216705322

time.time()で、タイムスタンプを取得できます(単位は秒)。
計測したい処理の開始前と開始後にtime.time()を実行し、その差を計算すれば、それが実行時間となります。

先ほどのサンプルコードでは、3秒間スリープさせているので、実行時間は、ほぼ3秒になります。

Pythonのfor文

Pythonのfor文の使い方を紹介します。

まず最初に、rangeを使う方法です。
for i in range(3):
    print(i)
実行結果は以下です。
0
1
2
このように、rangeでXを指定すると、0から(X-1)までループします。

次に、もう一つのrangeの使い方。
for i in range(2, 6):
    print(i)
実行結果は以下です。
2
3
4
5
rangeで2つの値(X,Y)を指定すると、Xから(Y-1)までループします。

続いて、リストを使ってループさせる方法。
vals = [1, 5, 7, 9, 11]
for v in vals:
    print(v)
実行結果は以下です。
1
5
7
9
11

リストを指定すると、リストの最初から最後までループします。

Pythonで引数を受け取る方法

Pythonで引数を受け取る方法を紹介します。

Pythonで引数を受け取るには、sysモジュールをimportします。
import sys

def usage_and_exit():
    print("""
USAGE: python test.py [filename]
    """)
    sys.exit(-1)

args = sys.argv
if len(args) != 2:
    usage_and_exit()

filename = args[1]

sys.argvが引数のリストです。
argvの最初の要素(上記プログラムだとargs[0])には、実行中のスクリプトが格納されています。なので、通常、スクリプトの引数は2つ目の要素から格納されることになります。

上記のサンプルコードでは、引数のリストのサイズをチェックして、サイズが2じゃなかったら(引数が1個指定されていない場合)、usageを表示して、プログラムを終了するようにしています。

プログラムの終了は、sys.exitで可能です。

以下は引数を処理するサンプルコードになります。

import sys

# 引数の配列を取得
args = sys.argv

for i, arg in enumerate(args):
    if arg == "-a":
        argA = args[i+1]
    elif arg == "-b":
        argB = args[i+1]
   

sys.argv で、引数の配列を取得できます。そのあと、forループで引数を処理しています。上のサンプルコードの名前が hoge.py だとすると、以下のように実行する想定です。

$ python hoge.py -a 50 -b 100

これで、変数argAに50が、変数argBに100が代入されます。

グラフのデータを作成するプログラム「Rudy」

グラフのデータを作成するプログラム「Rudy」を紹介します。

Stanford大学のStefan E. Karischさんが作成したプログラムで、Stanford大学のウェブサイトからダウンロードできます。gb_lib.crudy.cをダウンロードすればOKです。

readmeに書いてあるように、以下でコンパイルできます。
$ gcc gb_lib.c rudy.c -lm -o rudy

rudyは色々なグラフのデータを作成できます。

以下は、ノード数5の完全グラフを作成する例です (完全グラフとは、全てのノード(vertex)が、全てのノードとつながっている(辺を持つ)グラフのこと)。
$ ./rudy -clique 5
5 10
1 5 4
1 4 3
1 3 2
1 2 1
2 5 3
2 4 2
2 3 1
3 5 2
3 4 1
4 5 1
一行目はノード数とエッジ数です。二行目以降は、[ノードID ノードID エッジの重み]です。ノードIDは1始まりです(0始まりではない)。エッジの重みの最大値は、(ノード数 - 1)で決まります。

以下は、ノード数5の平面グラフを作成する例です (平面グラフとは、辺(エッジ)同士が交差しないグラフのこと)。
$ ./rudy -planar 5 40 3.1415
5 4
1 4 1
1 3 1
2 5 1
3 4 1
40というのは、グラフの密度です。0~100で指定できます。密度が大きいほど、エッジの数が増えます。3.1415というのは、乱数のシード(seed)です。たぶん、適当に指定しても大丈夫です(笑

以下はランダムグラフを作成する例です。
$ ./rudy -rnd_graph 5 60 42221
5 5
1 3 1
1 2 1
2 4 1
3 5 1
4 5 1
引数の意味は、平面グラフのときと同じです(ノード数、密度、シード)。

JavaScriptで10進数と16進数を変換する方法

JavaScriptで10進数と16進数を変換する方法を紹介します。 まず、16進数を、10進数に変換する方法です。 以下のサンプルコードでは、16進数の"DB"や"0A"を、10進数に変換しています。 var a = pa...