C言語のswitch文みたいな条件分岐をやってみる @Python3 その4

続きです)

 最後にテストをやってオシマイとする。多分大丈夫だと思うけど…(;^ω^)…まあやってみれば分かるさ。
 今回はこんな感じのスクリプトでテストしてみた。今回はコマンドライン引数で分岐条件をとる。
#!/usr/bin/python3
# -*- coding: utf-8 -*-


import mockswitch2 as msw
import sys

def func_a(): # 引数も返り値もなし
print("Whither Canada?")

def func_b(): # 引数はとらないが値を返す
print("killer joke")
return "ROTFLMAO"

def func_c(a, b): # 引数をとるが返り値なし
print("{}'s {}".format(a, b))

def func_d(a): # 引数をとり、値も返す
print('dead-parrot:', a)
return "{} is SPAM".format(a)

def func_default1():
print("default1 done.")

def func_default2(d):
print("default2:", d)
return d * 3

if __name__ == '__main__':
rndm = sys.argv[1]

test1 = msw.Switch(case = [(0, func_a, None, msw.BREAK), # 引数caseはシーケンスを格納したシーケンスでヨロ
(1, func_b, None, None), # 律儀に全部書いてあるが、省略可(ただしBREAKするときは省略不可)
(2, func_c, ['Philosopher', 'Football']), # 実行時に渡す引数もシーケンスでヨロ
('d', func_d, ["Hell's Grannies"]),
],
) # 引数defaultが要らないときは省略可

test2 = msw.Switch(case = [(0, func_a, None, msw.BREAK),
(1, func_b),
(2, func_c, ['Philosopher', 'Football']),
('d', func_d, ["Hell's Grannies"]),
],
default = (func_default2, ['SPAM'])) # 引数defaultもシーケンスでヨロ

# 重複テスト
test3 = msw.Switch(case = [(0, func_a, None, msw.BREAK),
(1, func_b),
(1, func_c, ['Philosopher', 'Football']), # 重複は改名される
('1_0', func_d, ["Hell's Grannies"]), # 不幸にして改名したのと同じラベルが…
(1, func_b),
('1_0', func_d, ["Twentieth-Century Vole"]),
],
default = [func_default2, ['SPAM']])

for test in [test1, test2, test3]:
print("---")
for k, v in test.branches.__dict__.items():
print(k, '->', v.nextcase, ', arg:', v.args, ', exe:', v.executable)

print("\nresult:")
result = test(rndm)
print("\nreturn values:", result)

 ひとまず、各Switchのbranchesの中身を印字させてみた。
$ python3 ./switchtest2.py 0
---
d -> default , arg: ["Hell's Grannies"] , exe:
1 -> 2 , arg: None , exe:
0 -> None , arg: None , exe:
default -> None , arg: None , exe:
2 -> d , arg: ['Philosopher', 'Football'] , exe:

result:
Whither Canada?

return values: [None]
---
d -> default , arg: ["Hell's Grannies"] , exe:
1 -> 2 , arg: None , exe:
0 -> None , arg: None , exe:
default -> None , arg: ['SPAM'] , exe:
2 -> d , arg: ['Philosopher', 'Football'] , exe:

result:
Whither Canada?

return values: [None]
---
1_0 -> _1_0 , arg: ['Philosopher', 'Football'] , exe:
1 -> 1_0 , arg: None , exe:
0 -> None , arg: None , exe:
1_0_0 -> default , arg: ['Twentieth-Century Vole'] , exe:
default -> None , arg: ['SPAM'] , exe:
1_1 -> 1_0_0 , arg: None , exe:
_1_0 -> 1_1 , arg: ["Hell's Grannies"] , exe:

result:
Whither Canada?

return values: [None]
 辞書をそのまま印字してるので順番がばらばらでいささか分かりづらいけど、0→None(BREAK)、1→2→'d'→default の流れはバッチリできてる様子。

 最後の 'test3' はわざとラベルを重複させ、さらに重複によって内部で改名されたラベルと同じのをわざわざ入れてやったが、0→None(BREAK)、1→'1_0'→'_1_0'→'1_1'→'1_0_0'→default と、ちゃ~んと流れができている。(・∀・)イイネ!!

 以後うっとおしいのでスクリプトの、branchesの中身を晒す部分(for k, v in test.branches.__dict__.items(): のブロック)をコメントアウトして実行する。
 今度はコマンドライン引数を '1' にしてみる。
$ python3 ./switchtest2.py 1
---

result:
killer joke
Philosopher's Football
dead-parrot: Hell's Grannies
default1 done.

return values: ['ROTFLMAO', None, "Hell's Grannies is SPAM", None]
---

result:
killer joke
Philosopher's Football
dead-parrot: Hell's Grannies
default2: SPAM

return values: ['ROTFLMAO', None, "Hell's Grannies is SPAM", 'SPAMSPAMSPAM']
---

result:
killer joke
Philosopher's Football
dead-parrot: Hell's Grannies
killer joke
dead-parrot: Twentieth-Century Vole
default2: SPAM

return values: ['ROTFLMAO', None, "Hell's Grannies is SPAM", 'ROTFLMAO', 'Twentieth-Century Vole is SPAM', 'SPAMSPAMSPAM']
 よっしゃよっしゃ、思惑通り。いいじゃんか。(・∀・)
 最後に駄目押し。
$ python3 ./switchtest2.py 1_0
---

result:
default1 done.

return values: [None]
---

result:
default2: SPAM

return values: ['SPAMSPAMSPAM']
---

result:
Philosopher's Football
dead-parrot: Hell's Grannies
killer joke
dead-parrot: Twentieth-Century Vole
default2: SPAM

return values: [None, "Hell's Grannies is SPAM", 'ROTFLMAO', 'Twentieth-Century Vole is SPAM', 'SPAMSPAMSPAM']
 'test3' には '1_0' があるが、他には無い。従って 'test3' 以外は default のみが実行されている。もちろん引数defaultが無ければ何も実行されずに終わる。
 ちなみに、コマンドライン引数を '1_1' にすると、全てが default のみ実行される。'test3' の中身には改名された '1_1' があるのだが、最初のラベルに含まれないので実行されない。

 テストも色々なパターンが考えられるがキリが無いのでオシマイとさせていただく。多分大体大丈夫だと思う。

---

 バグの種は尽きない。実際このエントリーを書きながらテストしてて、不具合が見つかり何箇所も慌てて訂正した (;´Д`)
 最初は蛇足と思ったがちゃんとテストをやってよかったわ。大分マシになった。でもきっと気付かない穴がまだあるんだろうなあ...(´・ω・`)

 とは言え、引数をとれるようにして、値も返せるので大分実用的になったんでないかい。
 他にも色々アイデアは盛り込みたかったけど、収拾がつかなくなるので一旦〆ます。…いや、でも手を入れたいところがまだまだある…けど〆ないと先に進めぬ。許せ、自分。

---

 是非こいつで遊んでいただいて、感想・ツッコミなどいただければ嬉しいです。

 したっけ~♪ ヽ(´ー`)ノ

"C言語のswitch文みたいな条件分岐をやってみる @Python3 その4"へのコメントを書く

お名前:
ホームページアドレス:
コメント: