Structure de contenu Progression
Définitions :
Question :
La question est un exercice unique, validé par une série de tests.
Test :
Une validation effectuée pour prouver que l’étudiant a répondu correctement à la question. Au moins un test est nécessaire par question mais la plupart devraient en comporter plusieurs.
Ébauche :
Une ébauche de réponse proposée à l’étudiant. Au moins une ébauche est requise par question; plus d’une peuvent être fournies, par exemple, pour supporter plus d’un langage de programmation.
Composition des éléments d’une question
Question
Une question est constituée d’un ou plusieurs fichiers en format YAML.
Toute Question DOIT comporter l’ attribut suivant :
Nom | Type | Description |
---|---|---|
type | str | le type de question |
Les valeurs possibles sont : | ||
«prog» : - Programmation | ||
«sys» : - Administration système |
Une Question PEUT comporter les attributs suivants :
Nom | Type | Format | Valeur par défaut | Description |
---|---|---|---|---|
titre | str | « » | Le titre de la question. | |
niveau | str | « » | Le niveau de difficulté de la question | |
objectif | str | « » | L’objectif de la question | |
description | str | « » | (réservé pour usage futur) | |
énoncé | str ou liste de dict | str markdown ou [ { titre: str, texte: str markdown }, … ] | « » | L’énoncé de la question. Il s’agit de la tâche à réaliser. Si l’énoncé est un tableau de dictionnaires, chaque élément du tableau représente une page de l’énoncé comportant un titre et un texte en markdown |
rétroactions | dictionnaire de str | markdown | {} | rétroactions générales à la question |
auteur | str | « » | Le nom du ou des auteurs de la question | |
licence | str | « » | La licence sous laquelle est publiée la question |
Rétroactions
Trois rétroactions sont prévues :
Nom | Type | Format | Défaut | Description |
---|---|---|---|---|
positive | str | markdown | « » | rétroaction fournie lorsque la solution produit une réponse correcte.1 |
négative | str | markdown | « » | rétroaction fournie lorsque la solution produit une réponse incorrecte. |
erreur | str | markdown | « » | rétroaction fournie lorsque la solution a provoqué une erreur. |
Exemple avec énoncé simple :
type: prog titre: Appeler une fonction paramétrée objectif: Mettre en pratique la notion d'appel de fonction énoncé: | La fonction `salutations` produit en sortie une salution autant de fois que la valeur reçue en paramètre. Utilisez-la pour faire produire en sortie «Bonjour le monde!» autant de fois que le nombre reçu en entrée. rétroactions: positive: "**Très bien!** Vous avez maintenant appélé une fonction paramétrée" négative: Encore un petit effort erreur: Vérifiez la syntaxe d'un appel de fonction
Exemple avec énoncé sur deux pages :
type: prog titre: Appeler une fonction paramétrée objectif: Mettre en pratique la notion d'appel de fonction énoncé: - titre: Mise en contexte texte: La fonction `salutations` produit en sortie une salution autant de fois que la valeur reçue en paramètre. - titre: À faire texte: Utilisez-la pour faire produire en sortie «Bonjour le monde!» autant de fois que le nombre reçu en entrée. rétroactions: positive: "**Très bien!** Vous avez maintenant appélé une fonction paramétrée" négative: Encore un petit effort erreur: Vérifiez la syntaxe d'un appel de fonction
Questions Prog:
Une Question spécifiquement de type «prog» DOIT comporter les attributs suivants :
Nom | Type | Description |
---|---|---|
ébauches | dictionnaire de str | les descriptifs des programmes exécutables. Doit comporter au moins un élément. |
Clé: nom du langage de programmation | ||
Valeur: l’ébauche fournie initialement à l’étudiant | ||
tests | liste de TestProgs | l’ensemble des tests de validation. Doit comporter au moins un élément. |
- Ébauche
Pour chaque langage pris en charge par la question, une ébauche de départ doit être fournie. Le programme entier réside dans ce bloc de code, c’est ce code, placé dans un fichier unique qui sera exécuté.
Les balises suivantes peuvent être utilisées pour contrôler la visibilité et la modification du code par l’étudiant. :
+VISIBLE
et-VISIBLE
- Contrôlent les parties visibles à l’étudiant.
- En l’absence de toute balise, l’ensemble du fichier est visible.
- En général, l’ébauche est visible entre une balise
+VISIBLE
et une balise-VISIBLE
. - S’il n’y a pas de balise
+VISIBLE
avant une balise-VISIBLE
, l’ébauche est visible jusqu’à la balise-VISIBLE
. - S’il n’y a pas de balise
-VISIBLE
avant une balise+VISIBLE
, l’ébauche est invisible jusqu’à la balise+VISIBLE
.
- (no term)
+TODO
et-TODO
contrôlent les parties modifiables par l’étudiant.- En l’absence de toute balise, l’ensemble du fichier est modifiable.
- En général, l’ébauche est modifiable entre une balise
+TODO
et une balise-TODO
. - S’il n’y a pas de balise
+TODO
avant une balise-TODO
, l’ébauche est modifiable jusqu’à la balise-TODO
. - S’il n’y a pas de balise
-TODO
avant une balise+TODO
, l’ébauche est non-modifiable jusqu’à la balise+TODO
.
Toutes les parties invisibles (et de ce fait immuables) seront tout de même exécutées normalement. Elles peuvent servir à mettre en place certains éléments du programme sur lesquels on ne veut pas attirer l’attention de l’étudiant. Cependant, elles ne devraient pas servir à dissimuler des réponses puisqu’il sera toujours possible pour l’étudiant débrouillard de les rendre visibles.
Questions Système (bêta)
Une question spécifiquement de type «sys» DOIT comporter les attributs suivants :
Nom | Type | Description |
---|---|---|
image | str | Le nom d’une image de conteneur (docker) à utiliser comme contexte de résolution |
Une question spécifiquement de type «sys» DOIT comporter un et un seul des deux attributs suivants :
Nom | Type | Description |
---|---|---|
tests | liste de TestSys | les tests de validation. Doit comporter au moins un élément. |
réponse | str | La réponse courte à la question. Si réponse est délimitée par des `~`, |
elle est considérée comme une expression rationnelle. Sinon, il s’agit d’une chaîne standard. | ||
Pour réussir l’exercice, une chaîne correspondant à la réponse doit être soumise. |
Une question spécifiquement de type «sys» PEUT comporter les attributs suivants :
Nom | Type | Défaut | Description |
---|---|---|---|
utilisateur | str ^[a-z][-a-z0-9_]*\$ | Selon la définition de l’image | Le nom de l’utilisateur qui démarre le conteneur |
init | str | Un script d’initialisation de l’exercice | À l’exécution du test, le script sera lancé dans le conteneur par l’interpréteur de commande par défaut |
commande | str | sh | La commande exécutée dans le terminal présenté à l’utilisateur |
- Images
Les images utilisées par les question systèmes sont des images docker qui doivent être exécutables sans paramètres et pouvoir rester en arrière-plan. Spécifiquement, l’image est démarrée par la commande
docker run -d <image>
Dans le cas des images sans mode «service» (par exemple ubuntu), il est toujours possible de les utiliser en ajoutant une clause
CMD sleep infinity
à la définition de l’image.Si une commande HEALTHCHECK existe dans l’image, le terminal est démarré pour l’étudiant dès que le statut du conteneur passe à «healthy», sinon, il le sera après une attente maximale de 5s.
Des variables d’environnement peuvent être utilisées par le conteneur si elles sont spécifiées lors de la construction de l’image par une clause
ENV
Test
Chaque test PEUT contenir les attributs suivants :
Nom | Type | Format | Défaut | Description |
---|---|---|---|---|
nom | str | « » | Nom du test | |
sortie | str | « » | les sorties textuelles attendues produites par le test | |
rétroactions | dictionnaire de str | markdown | {} | rétroactions spécifiques au test. Les rétroactions spécifiques possibles sont les mêmes que les rétroactions générales |
- TestProg
Pour une question de type «prog», un Test PEUT contenir les attributs suivants :
Nom Type Format Défaut Description entrée str « » les entrées textuelles passés directement à l’entrée standard du programme params str markdown « » les paramètres passés au programme au moment de l’exécution rétroactions dictionnaire de str {} rétroactions spécifiques au test. Les rétroactions spécifiques possibles sont les mêmes que les rétroactions générales cachée bool false Si vrai, la sortie attendue est remplacée par une chaîne vide. - TestSys (bêta)
Pour une question de type «sys», un Test DOIT contenir les attributs suivants :
Nom Type Description validation str Un script de validation du test Pour une question de type «sys», un Test PEUT contenir les attributs suivants :
Nom Type Défaut Description utilisateur str ^[a-z][-a-z0-9_]*\$ Même que QuestionSys.utilisateur L’utilisateur utilisé pour exécuter le script de validation
Exemples complets :
- Question Prog
info.yml
:type: prog titre: Appeler une fonction paramétrée objectif: Mettre en pratique la notion d'appel de fonction énoncé: | La fonction `salutations` produit en sortie une salutation autant de fois que la valeur reçue en paramètre. Utilisez-la pour faire produire en sortie «Bonjour le monde!» autant de fois que le nombre reçu en entrée. rétroactions: positive: "**Très bien!** Vous avez maintenant appélé une fonction paramétrée" négative: Encore un petit effort. Pour plus d'information sur l'appel des fonctions, voir [Appel de fonction](https://exemple.com/doc/lesfonctions.html) erreur: Vérifiez la syntaxe d'un appel de fonction ébauches: python: | #+VISIBLE nb_répétitions = int( input() ) #+TODO #-TODO #-VISIBLE java: | import java.util.Scanner; public class exec { //+VISIBLE public static void main(String[] args) { Scanner input = new Scanner( System.in ); nb_répétitions = input.nextInt(); //+TODO //-TODO } //-VISIBLE } tests: - nom: Une seule fois entrée: Bonjour le monde! params: -n 1 sortie: Bonjour le monde! - nom: Trois fois entrée: Bonjour le monde! params: -n 3 sortie: | Bonjour le monde! Bonjour le monde! Bonjour le monde! - nom: 0 fois entrée: Bonjour le monde! params: -n 0 sortie: "" rétroactions: positive: Bien joué! 0 est aussi une entrée valable. négative: N'oublie pas les cas limites, 0 est aussi une entrée valable!
Afin de limiter la taille et la complexité du fichier info.yml, il est possible d’inclure des fichiers YAML (.yml ou .yaml), texte (.txt) ou Markdown (.md) en utilisant la balise
!include
. L’exemple ci-haut peut donc être réduit à ceci :type: prog titre: Appeler une fonction paramétrée objectif: Mettre en pratique la notion d'appel de fonction énoncé: !include énoncé.md rétroactions: !include rétroactions.yml ébauches: python: !include ébauches/ébauche.py java: !include ébauches/ébauche.java tests: !include tests/tous_les_tests.yml
étant accompagné des fichiers suivants dans le même répertoire :
énoncé.md
La fonction `salutations` produit en sortie une salution autant de fois que la valeur reçue en paramètre. Utilisez-la pour faire produire en sortie «Bonjour le monde!» autant de fois que le nombre reçu en entrée.
rétroactions.yml
positive: "**Très bien!** Vous avez maintenant appélé une fonction paramétrée" négative: Encore un petit effort. Pour plus d'information sur l'appel des fonctions, voir [Appel de fonction](https://exemple.com/doc/lesfonctions.html) erreur: Vérifiez la syntaxe d'un appel de fonction
ébauches/ébauche.py
#+VISIBLE nb_répétitions = int( input() ) #+TODO #-TODO #-VISIBLE
ébauches/ébauche.java
import java.util.Scanner; public class exec { //+VISIBLE public static void main(String[] args) { Scanner input = new Scanner( System.in ); nb_répétitions = input.nextInt(); //+TODO //-TODO } //-VISIBLE }
tests/tous_les_autres_tests.yml
:- nom: Une seule fois entrée: Bonjour le monde! params: -n 1 sortie: Bonjour le monde! rétroactions: positive: "**Bravo** champion!" négative: Encore *un* effort... - nom: Trois fois entrée: Bonjour le monde! params: -n 3 sortie: | Bonjour le monde! Bonjour le monde! Bonjour le monde! - nom: 0 fois entrée: Bonjour le monde! params: -n 0 sortie: "" rétroactions: positive: Bien joué! 0 est aussi une entrée valable. négative: N'oublie pas les cas limites, 0 est aussi une entrée valable! - nom: Trop de salutations entrée: Bonjour le monde! params: -n 1000000 sortie: [un_million_de_bonjours.txt]
- Question Sys
- Exemple de réponse courte
type: sys énoncé: Quel est le numéro d'utilisateur de Krusty? utilisateur: root init: | #!/bin/bash useradd krusty -u 1234 réponse: 1234
- Exemple de validation
type: sys énoncé: Créez le répertoire config dans le répertoire utilisateur de Krusty utilisateur: root init: | #!/bin/bash useradd krusty -u 1234 -m tests: - nom: présence du répertoire config utilisateur: krusty validation: [ -d /home/krusty/config ] && echo ok sortie: ok - nom: nombre de fichiers dans le répertoire utilisateur: krusty validation: ls -a /home/krusty/ | wc -l sortie: 6
- Exemple de réponse courte
Références :
Notes de bas de page:
Certains symboles on une signification particulière en YAML ou en markdown. Le format YAML ayant préséance, pour les utiliser en markdown, utilisez les caractères les guillemets, le format yaml «bloc» ou inclure un fichier markdown :
Incorrect : positive: *Ceci est en gras* Correct : positive: "*Ceci est en gras*" négative: | *Ceci est en gras* erreur: !include rétroaction_err.md