Terada's Blog

フリーランスでソフトウェア開発してます。プログラミング、競プロ、スタートアップなどについて

python/競プロでローカルでテストしてから提出する場合のテンプレを作りました。


どうもーー


久しぶりに更新します。
ここ3ヶ月間ぐらい色々ありました。


ハッカソンに参加して、小さいですけども優勝することもできました。
そちらについても気が向いたら書こうと思います。



今日は、競プロの環境についてちょっと書いておきたいなと思います。

もう今日プロに参加しはじめて半年以上たちます。

4月5月6月は事情により参加できなかったのですが、最近少し参加しています。
レート推移はこんな感じ。

f:id:mktrdbg:20190804164546p:plain
レート推移


今日は、アルゴリズムがどうこうよりも、競プロのテンプレ的なメモです。

いつもみなさんはテストケースなどはどのように試していますか?
試していない猛者はおいておくとして、僕はvimでコードを書いているので、ローカルでpythonを実行して、入力を貼り付けしてテストしていました。

しかし、これだいぶ効率悪いなと今更ながらに気づき、改めることとなりました。

要件としては、
1. 入力を一回貼り付けたらそれですむようにしたい
2. 外部ファイルにするのが面倒なので、ソースコード内にinputを置いておきたい
3. 提出時はスルーされるように
の3点を満たすように考えました。

色々と説明する前に、一旦完成形を載せます。

import os

def main(N, A):
    # 処理を書く
    return N 


if __name__ == '__main__':
    if 'LOCAL' in os.environ:
        # ローカル実行時のみ通る処理
        # テストしたい入力を入れておく
        input_values = [
                """3
7 6 8
3
                """.strip(),
                """3
12 15 18
6
                """.strip()
                ]
        for input_value in input_values:
            input_value = input_value.split('\n')
            N = int(input_value[0])
            A = list(map(int, input_value[1].split()))
            ans = main(N, A)
            expected_value = int(input_value[2])
            assert ans == expected_value, 'failed: ans: {ans}, exp: {exp}'.format(ans=ans, exp=expected_value)
    else:
        # 実際に提出したときの処理
        N = 'some_input'
        A = 'some_input'
        print(main(N, A))


ポイントとしては、環境変数を利用して、ローカル実行時と、提出時の処理を変えています。
LOCALという環境変数があれば、ローカル実行となります。
これは

LOCAL='なんらかの値 ' python my_code.py

のように実行すると、LOCALというキーで環境変数が設定されるので、最初のif文の中の処理を実行できます。
提出時はLOCALには値がセットされていないので、elseの中の処理が実行されます。

input_valuesに入力値を貼り付けた後、リスト化、数値化などの処理は問題によりけりですが、基本的にはリストの中に入力をstringとして突っ込んで、1つ1つ取り出して上手くやるという感じです。
今回は実際にAtCoderの入力をそのまま貼り付けています
空白とか無駄なものがついてくるので、一応今回はstrip()しています。

最後に、assertを利用してやることで、失敗ケースで止めるようにしました。
その際、""" """内に入力した入力値の1行下に、正解の値を入れるのが良いと思います。
お好みで。


以上、ローカルでpythonで競プロに参加する場合のちょっとしたテンプレでした。

かんたんな問題では利用する必要はあまりありませんが、何回もテストしてから提出するぐらいの問題であれば使えるのかなと思います。