Je fais Atcoder (programmation de compétition) comme passe-temps, mais cela a été lent récemment. J'ai pensé que ce serait bien d'automatiser le travail de test pendant le concours, J'ai créé un outil d'automatisation de test avec python.
Voici quelques-uns des outils les plus polyvalents que ceux que j'ai présentés dans cet article.
Veuillez également comparer ce qui précède lors de son utilisation.
Code source https://github.com/tks3210/autoJudge
Environnement d'exploitation
>python autojudge.py [contest_name] [quest] Si vous spécifiez le nom du concours (abc143) et le nom de la question (abc143_a) comme indiqué dans ↑, Il se construit automatiquement, obtient des échantillons de données d'entrée / sortie et les teste. J'ai également essayé de créer une atmosphère avec la famille d'origine. Les trois cas de test ci-dessus sont https://atcoder.jp/contests/abc143/tasks/abc143_a Il est automatiquement obtenu à partir de l'exemple d'entrée et de l'exemple de sortie de.
Je ne peux pas déranger le serveur d'Atcoder avec mes propres tests, donc L'accès est une fois pour chaque problème. (Le cas de test acquis est enregistré localement afin qu'il soit référencé dans les tests suivants et suivants.)
Lorsque vous écrivez le mauvais code, cela vous dira que c'est faux.
** En cas de WA (mauvaise réponse) ** ** En cas de TLE (temps de calcul dépassé) ** Dans le paramètre actuel, s'il dépasse ** 2 secondes ** jusqu'à ce que le résultat soit sorti, il est traité comme TLE. Même si vous exécutez une boucle infinie, elle sera coupée dans environ 3 secondes et le prochain test sera effectué. ** En cas de CE (erreur de compilation) ** Peu importe s'il ne se compile pas en premier lieu, il se termine donc sans test.
Si vous exécutez ce test pendant le concours, vous ne pourrez pas accéder à la page de questions sans vous connecter. En définissant le nom d'utilisateur / mot de passe, etc. avec l'option -i, l'authentification automatique et l'exécution du test pendant le concours sont activées.
>python autojudge.py abc143 abc143_d -i
Atcoder Username:tks_fj * Nom d'utilisateur du compte Atcoder
Atcoder Password:******** Mot de passe du compte Atcoder
Src Directory(Ex. ./aaa/abc140/abc140.cpp => input "./aaa"):../../02_contest
Judging abc143/abc143_d...
testcase 1: AC
testcase 2: AC
testcase 3: AC
result: AC
** Ces informations de paramétrage sont stockées dans le fichier de paramétrage local (setting.conf), ce travail ne peut donc être effectué qu'une seule fois. ** ** (Ce travail peut également être effectué en réécrivant directement le fichier de paramètres.)
Vous pouvez également ajouter de nouveaux cas de test de manière interactive Afin de prendre en charge l'entrée et la sortie de plusieurs lignes, "quitter" + Entrée est utilisé pour quitter.
(contribution:20 7 Sortie:Ajouter 6)
>python autojudge.py abc143 abc143_a -a
type test input(exit by "quit")
20 7
quit
type test output(exit by "quit")
6
quit
Si vous le testez à nouveau, il sera ajouté à testcase4.
>python autojudge.py abc143 abc143_a
Judging abc143/abc143_a...
testcase 1: AC
testcase 2: AC
testcase 3: AC
testcase 4: AC
result: AC
** Pour les paramètres initiaux, reportez-vous à Auto Judge: Initial Settings ou au chapitre suivant. ** **
Je présenterai également la conception et la mise en œuvre à l'intérieur, qui sert également de mémorandum.
Les artefacts suivants sont gérés dans un référentiel appelé ** autoJudge **.
On suppose que ** autoJudge ** sera cloné dans le répertoire où est stocké le code source (.cpp) à tester. Il est recommandé d'utiliser la structure de répertoires et la convention de dénomination suivantes. (Mais cela fonctionne même si ce n'est pas le cas ↓ (voir 4. Option -p supplémentaire))
.
├── autoJudge * Le livrable créé cette fois
│ ├── setting.conf * Fichier de configuration
│ ├── autojudge.py * Corps du programme
│ ├── testcase * Liste des cas de test(Généré pendant le test)
│ │ ├── abc142@abc142_a.txt
│ │ └── abc143@abc143_a.txt
│ └── design.pu * Diagramme de classe
├── abc142 * Nom du concours
│ ├── abc142_a.cpp * Nom du problème.cpp
│ ├── abc142_b.cpp
│ ├── abc142_c.cpp
│ ├── abc142_d.cpp
│ ├── abc142_e.cpp
│ └── abc142_f.cpp
├── abc143
:
Il s'agit d'un fichier de paramètres utilisé pour l'authentification et la recherche de l'emplacement de la source.
setting.conf
username:tks_fj
password:*******
srcpath:../
Il peut être défini avec l'option -i introduite dans ** 2.3 Authentification automatique **, mais bien sûr, il est possible de réécrire directement.
Le programme comprend les deux classes suivantes.
autojudge.py
def RegisterUser(self):
"""paramètres utilisateur(Première fois)"""
print("Atcoder Username:", end="")
username = input().rstrip('\r\n')
print("Atcoder Password:", end="")
password = input().rstrip('\r\n')
print("Src Directory(Ex. ./aaa/abc140/abc140.cpp => input \"./aaa\"):", end="")
srcpath = input().rstrip('\r\n')
with open(CONF_FILE, "w") as f:
f.write("username:" + username + "\n")
f.write("password:" + password + "\n")
f.write("srcpath:" + srcpath + "\n")
autojudge.py
def GetTestCases(self, test_name, islogin = False):
"""Obtient un cas de test à partir du nom du problème spécifié et renvoie une liste"""
self.__UpdateConf()
file_name = self.contest + "@" + test_name + ".txt"
testinfo = [{"contest":self.contest, "testname":test_name}]
#Ne grattez pas l'acquisition des mêmes informations pour réduire la charge du serveur
if file_name in os.listdir(TESTCASES_PATH):
testcases = self.__ReadFile(file_name)
else:
testcases = self.__ScrapePage(test_name, islogin)
self.__WriteFile(file_name, testcases)
return testinfo + testcases
autojudge.py
def AddTestCases(self, test_name):
"""Ajoutez votre propre scénario de test au scénario de test acquis"""
self.__UpdateConf()
testcase = {}
print("type test input(exit by \"quit\")")
testcase["input"] = ""
while(1):
line = input()
if (line == "quit"):
break;
testcase["input"] += line + "\n"
print("type test output(exit by \"quit\")")
testcase["output"] = ""
while(1):
line = input()
if (line == "quit"):
break;
testcase["output"] += line + "\n"
file_name = self.contest + "@" + test_name + ".txt"
if file_name in os.listdir(TESTCASES_PATH):
testcases = self.__ReadFile(file_name)
testcases.append(testcase)
self.__WriteFile(file_name, testcases)
autojudge.py
def Execute(self, srcpath = ""):
"""Lancer le test"""
print(YELLOW + "Judging " + self.testinfo["contest"] + "/" + self.testinfo["testname"] + "..." + COLORRESET)
if (srcpath == ""):
srcpath = self.__GetPath()
self.__Build(srcpath)
if (self.result["build"] == 0):
self.__Run()
self.__Result()
abc143@abc143_a.txt
[test case 0]
---input---
12 4
---output---
4
---fin---
[test case 1]
---input---
20 15
---output---
0
---fin---
Les modules suivants sont requis. Vous pouvez le mettre immédiatement avec pip, pip3, conda, etc.
pip3 install requests
pip3 install bs4, lxml
>python autojudge.py --help
usage: autojudge.py [-h] [-p PATH] [-a] [-i] contest_name question
positional arguments:
contest_name set contest name(ex. abc143)
question set question name(ex. abc143_a)
optional arguments:
-h, --help show this help message and exit
-p PATH, --path PATH set path of source code
-a, --addtest add testcase
-i, --init set configuration
Lorsque la structure de répertoire du code source n'est pas "3.1 Structure de répertoire" (Par exemple, dans les cas suivants)
.
├── 02_contest
│ ├── abc143
│ │ ├── abc143_a.cpp
│ │ ├── abc143_b.cpp
│ │ └── abc143_c.cpp
├── 04_autotest
│ ├── autoJudge
│ │ ├── README.md
│ │ ├── autoJudge.py
│ │ ├── autojudge.pu
│ │ ├── setting.conf
│ │ └── testcase
Vous pouvez spécifier l'emplacement du code source directement avec l'option -p.
>python autojudge.py abc143 abc143_a -p ../../02_contest/abc143/abc143_a.cpp
Judging abc143/abc143_a...
testcase 1: AC
testcase 2: AC
testcase 3: AC
testcase 4: AC
result: AC