こんにちは。
水色コーダーのヤスローと申します。
みなさんAtCoderでコンテスト参加時に毎回テストケースを手動で実行してないですか?
今回、エディタでコードを保存するだけでテストケースを自動で実行できるツールを作りました。
自動実行環境用コードセット
より詳細には、フォルダ内の「最も新しいpythonファイル」を探索し、一定間隔で実行し続けるプログラムです。
以下が想定する実行環境です。AutoTester
ディレクトリ内のファイルを作っていきます。
.
└── AtCoder/
├── AutoTester/
│ ├── AutoTester.bat
│ └── AutoTester.py
└── ABC/
├── abc385/
│ ├── a.py
│ ├── b.py
│ ├── c.py
│ └── input.txt
└── abc386/
├── a.py
├── b.py
└── input.txt
下のpythonファイル(AutoTester.py
)とバッチファイル(AutoTester.bat
)を作成して、バッチファイルを実行すれば動作します。
#親ディレクトリの親ディレクトリ内で最新の .py ファイルを見つけ、そのファイルを実行する。
import subprocess
import time
import os
import glob
def run_func_with_input():
# Get the most recent .py file in the parent of the parent directory
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
list_of_files = glob.glob(os.path.join(parent_dir, '**', '*.py'), recursive=True)
# Remove the current file from the list
list_of_files.remove(os.path.abspath(__file__))
# Get the latest file
latest_file = max(list_of_files, key=os.path.getmtime)
input_data = ""
input_file_path = os.path.join(os.path.dirname(latest_file), 'input.txt')
if not os.path.exists(input_file_path):
# Create input.txt with initial value "1 2 3"
with open(input_file_path, 'w') as input_file:
input_file.write("1 2 3")
# Open the input.txt file in the default text editor
os.startfile(input_file_path)
with open(input_file_path, 'r') as input_file:
# Check if input.txt exists in the latest file's directory
input_data = input_file.read()
# Check if the latest file was modified within the last 3 seconds
if time.time() - os.path.getmtime(latest_file) > 3 \
and time.time() - os.path.getmtime(input_file_path) > 3 : #ここデバッグ用
print(".", end="")
return
print(f"Input:\n{input_data}")
print(f"\n実行開始({"\\".join(latest_file.split(os.path.sep)[-2:])})")
start_time = time.time()
# Run the latest .py file
result = subprocess.run(['python', latest_file], input=input_data, text=True)
end_time = time.time()
execution_time = end_time - start_time
print(f"実行完了({execution_time * 1000:.2f}ms)")
if __name__ == "__main__":
run_func_with_input()
@echo off
set script_name=%~n0.py
:loop
python %script_name%
timeout /t 1 /nobreak >nul
goto loop
「AutoTester.bat」は「自分と同じ名前の .py ファイル」を連続実行するプログラムなので、ファイル名を変更するときは両方とも拡張子より前が同じ名前になるようにしてください。
(例えば「AutoTester.py」を「hoge.py」に変える場合は、「AutoTester.bat」も「hoge.bat」に変更してください。)
コンテスト用コード生成セット
もう一つ、毎回コンテスト用のコードを生成するのダルいなと思っていたので、URLをコピペするだけでpyコードを自動で生成するやつも作りました。
例えば、
https://atcoder.jp/contests/abc379
-
https://atcoder.jp/contests/abc379/tasks/abc379_e
のような入力に対して、ABC/abc379/a.py ~ g.py を作成します。
ABCコンテストや、ARCコンテストはコンテスト形式ごとにまとめるようにしてあります。
さっきのディレクトリの直上に置いちゃってください。
.
└── AtCoder/
├── AtCoderコード生成.bat
├── AtCoderコード生成.py
├── AutoTester/
│ ├── AutoTester.bat
│ └── AutoTester.py
└── ABC/
├── abc385/
│ ├── a.py
│ ├── b.py
│ ├── c.py
│ └── input.txt
└── abc386/
├── a.py
├── b.py
└── input.txt
#AtCoderのURLを貼り付けることで、空の .py ファイルをA.py~G.pyまで作成する
import os
def create_files_from_url(url):
# Create a directory based onthe contest name
contest_name = url.split('/')[-1]
print(contest_name)
#個別の課題ページを入力した場合の処理
contest_name = contest_name.split('_')[0]
print(contest_name)
typical_contests = ['abc', 'arc', 'agc']
for typical_contest in typical_contests:
if contest_name.startswith(typical_contest):
contest_name = os.path.join(typical_contest.upper(), contest_name)
break
if not os.path.exists(contest_name):
os.makedirs(contest_name)
# Create empty files A.py to G.py
for letter in 'ABCDEFG':
file_path = os.path.join(contest_name, f'{letter}.py')
if not os.path.exists(file_path):
with open(file_path, 'w') as file:
pass
print(f'Created {file_path}')
# Example usage
url = input("Enter the AtCoder contest URL\n (ex.https://atcoder.jp/contests/abc777)\n: ")
create_files_from_url(url)
@echo off
set script_name=%~n0.py
:loop
python %script_name%
goto loop
いざ実行
ずっと表示し続けると見づらいですから、最新のpythonファイルの更新が3秒以前の場合は「.」を出力するようにしていますので、ピリオドしか出力されなくても怒らないでください。
以下のコードを作って保存してみます。
A = list(map(int, input().split()))
print(sum(A))
仕様として何回か(3回程度)連続して実行されるようになっています。
また、pythonファイルを作った場所にinput.txtがない場合は「1 2 3」と適当な内容を入れて作成し、テキストを開くようにしてあります。
蛇足
自分はコンテスト参加時、問題ページとVisualStudio、今回紹介したコードテスターとinput.txtのテキストエディタを開いています。みなさんはどうでしょうか。
あと「そもそもアレを使えばこの記事のコードいらないよ!」とかあったら教えてください。
競プロ仲間も募集中です。
では。