昨日、ふと思い立って AtCoder の Beginner Contest 075 に参加したらボロボロだった。
打ったコードの内容はともかくとして、提出前の動作確認が非常に面倒だった。
自分は C++ で参加していたので、コンパイル後に毎回実行して、毎回同じデータを入力して、毎回出力を確かめて……という作業が、なんというか、煩雑。なので、自動化してみよう。
やりたいことは、動作確認データの標準入力の自動化と、その後の標準出力の結果判定。そして複数例の動作確認を一度に。これをできればコマンド一発で判定して欲しい。
というわけで Python を使ってやってみた。 practice contest ページの練習用問題 #A の解答プログラムが既にコンパイル済みで、入出力の確認をする、という想定。入力例と出力例はスクリプト本体に文字列として埋め込む。間違った場合のみ、プログラムからの出力をそのままコンソールへ出力する。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
Example = (
# 入力例1
("""1
2 3
test""",
# 出力例1
"""6 test"""),
# 入力例2
("""72
128 256
myonmyon""",
# 出力例2
"""456 myonmyon"""),
)
Program = "./a.out" # コンパイル後の実行ファイル名
def SampleAnswerDiff(sample, answer) :
p = subprocess.Popen(Program, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.write(sample.encode ('utf8'))
p.stdin.close()
result = p.stdout.read().rstrip()
if result != answer.encode('utf8'):
return "NG...\n" + result.decode('utf8')
return "OK!"
if __name__ == "__main__":
for s, a in Example:
print (SampleAnswerDiff(s, a))
Mac OS 10.11.6, Python 3.6.1 で動作確認済み。
できれば入力例も出力例も、ウェブページからコピペしたものをそのまま使えるようにしたい。文字列化のためのクォートを前後にそれぞれ挿入するのが、ちょっと泥臭く感じる。ここのコピペで些細な事故が起こってしまった場合、原因に気付かないままプログラムを修正し続けてしまって精神力持って行かれそう。そんな事故の可能性があるような実装はできれば避けたい。
どうせ Python を使うならコンパイルも含めてテストと同時にやってしまった方が良いのかもしれない。でも個人の趣味としては、コンパイル時の問題と実行時の問題は分けて扱いたい。何より、コンパイル時のエラーはコンパイラ様が色もインデントもキレイに整理して表示して下さっているので、その恩恵に与りたい。
というかわざわざ Python を使わなくても、シェルスクリプトの方がこういう作業には向いているんじゃないかな。詳しくないけどなんとなくそう思った。
詳しい人がいらっしゃいましたら、お教え頂けるとありがたいです。