HackInScience est un logiciel de publication et de correction automatique d'exercices, son instance hackinscience.org est une collection d'exercices Python.
HackInScience est né en 2014 : j'enseignais alors le Python en université (promos d'environ 70 élèves), et avec les collègues on s'est dit qu'il serait bon de passer plus de temps à aider les élèves qu'a les corriger, que la correction c'était automatisable, mais que passer du temps avec eux, ça ne l'était pas.
Deux "on jette tout et on recommence" plus tard, et deux confinements plus tard, on en est là :
Tout le code est open-source, c'est un simple Django pour présenter les exercices, des websockets pour recevoir sans attendre la correction du bot, et un Celery pour "load-balancer" les rendus aux serveurs de correction. Je n'enseigne plus en université mais le site étant toujours en ligne, et les confinements aidant, il a trouvé son public : 1500 exercices sont réussis par semaine en ce moment.
J’essaye de passer deux semaines par an à plein temps sur le projet, en 2019 j’ai travaillé l’internationalisation (être traducteur de la doc de Python et ne pas traduire ses propres projets n’était pas bien sérieux…), et en 2020 la notion de classement et d’équipes.
Du point de vue d'un élève
L'interface est minimaliste (d'abord parce que je suis plutôt nul en front :p) :
À gauche l'énoncé, au milieu l'utilisateur rédige son code, et à droite la réponse du bot. C'est simple et il n'y a pas de place pour de la pub ;)
Du point de vue admin
C'est toute suite plus compliqué et mon but n'étant pas de rédiger la documentation ici je vais passer vite sur les détails les moins intéressants.
Pour l'installation d'une instance HackInScience je pense qu'un bon point de départ serait de s'inspirer de notre playbook Ansible, mais pour un test local un python manage.py runserver
suffit.
La création d'exercices se passe dans un django-admin classique :
Mais pour plus de confort j'ai pris l'habitude d'éditer les exercices localement (emacs étant un peu plus confortable que ACE Editor pour éditer du Python), de les versionner, et de tester mes modifications avant de les publier, pour ça j'utilise fetch.py
et push.py
dans le dossier scripts/
.
La partie intéressante de la création d'un exercice, c'est son bot de correction : c'est aussi un script Python qui est appelé dans une sandbox à côté du rendu. La rédaction de ce script est totalement libre, la seule règle c'est : s'il print (sur stderr ou stdout) l'exercice est faux, sinon il est considéré juste.
Pour me faciliter le travail j'ai crée correction-helper qui lui même utilise friendly-traceback, à l'usage, rédiger un bot de correction ressemble à :
for message in test_messages:
expected = bencode(message)
with student_code():
got = student_encode(message)
if expected != got:
message = _("Wrong answer while testing `{thing}`").format(thing=f"bencode({message!r})")
if type(got) != bytes:
message += "\n\n" + f"Expected a `bytes` instance, got a `{type(got)}`."
fail(message, _("Got:"), code(got), _("Expected:"), code(expected))
Alors corriger du Python depuis du Python c'est assez simple, je peux soit utiliser subprocess.run
pour exécuter le code de l'élève, soit importer ses fonctions et les tester, ça ressemble beaucoup à de la rédaction de tests unitaires, sauf qu'au lieu de se contenter d'un assert
on rédige une description explicite de l'erreur, et parfois des conseils pour l'éviter.
Mais corriger du bash, du C, ou n'importe quoi d'autre doit être tout à fait possible aussi : rien n'empêche de rédiger une moulinette qui compile le code de l'élève puis le teste à coup de subprocess.run
aussi.