Plan :
Le fonctionnement est le suivant :
Le système permet d'afficher de multiples informations pendant que l'étudiant travaille :
Le système permet à l'étudiant de faire différentes actions, généralement on le laisse :
L'administrateur quand à lui peut modifier les droits et les options :
Ces droits et options sont très précis, il y en a une quarantaine. Ils permettent de modifier les actions qu'il est possible de faire ou bien le contenu de la page web.
Les droits permettent notamment :
Les premières questions du TP unix sont très faciles, elle servent à vérifier que l'étudiant est capable d'utiliser le système.
Voici quelques liens qui vous permettrons de l'utiliser sans l'installer :
Le graphe des questions peut être affiché de différentes manière. Voici ce que donne l'une d'elle.
Les exercices sont définis par les programmes Python stockés dans le répertoire Questions/unix dans le cas du questionnaire Unix. Chaque programme Python peut définir plusieurs exercices. Voici un exemple de programme Python.
# -*- coding: latin-1 -*- # Pour pouvoir mettre des accents from questions import * # Interface avec la base d'exercices from check import * # Les vérificateurs pour le shell add(name="copie de fichier", question="""Quelle commande permet de copier un ou des fichiers ?""", tests=( good("cp"), bad("copy", "C'est la commande MS-DOS pas UNIX"), bad( ("CP", "Cp"), "Sous UNIX la casse est importante"), ), ) add(name="copie de répertoire", required=["cp", "intro:final"], # Exercices à faire avant celui-ci question="""Quelle est l'option de cp pour faire une copie récursive ?""", tests=( good( ("-r", "-R", "--recursive") ), good( "-a", "Elle fait plus que la copie !"), ), )
Le nom du fichier contenant les questions est important, ce sera :
Les chaînes de caractères sont en latin1 et aussi en HTML si c'est dans des commentaires. Donc attention aux caractères <, >, &.
De plus un système de remplacement est fait donc si vous voulez afficher un % il faut le doubler.
Tous les textes visibles par l'utilisateur peuvent contenir des marqueurs de la forme '%(paramètre)s' Ces marqueurs sont remplacés lors de l'affichage par la valeur du paramètre.
Il y en a plein d'autres, mais je ne pense pas qu'ils soient utiles pour poser les questions.
FAUT-IL SUPPRIMER CETTE FONCTIONNALITE DANGEREUSE ?
Vous pouvez utilisez des triples guillemets au lieu des simples pour pouvoir mettre des retours à la ligne ou des guillemets dans la question.
C'est lui qui donne un nom à la question. Ce nom est celui qui sera affiché pour que l'étudiant puisse choisir sa question.
Il peut simplement être le texte de la question.
Il peut aussi être une fonction sans paramètres retournant un chaîne de caractères. Avant l'appel de la fonction le système définit la graine de la série aléatoire si la question est aléatoire.
Pour mettre l'image toto.png dans la question : <IMG SRC='toto.png'> Cette image sera dans le répertoire HTML du répertoire qui contient la définition des questions.
Il contient une liste de noms des questions auxquels l'étudiant doit déjà avoir répondu avant que celle-ci s'affiche.
Si ce paramètre n'est pas indiqué, alors seule la question précédente est considérée comme requise. Il n'y a donc aucun prérequis pour la première question du fichier dans ce cas.
Si un nom de questions contient le caractère ':' alors on ne le touche pas, sinon on le préfixe par le nom du fichier courant.
Si le nom est suivie par une expression régulière entre parenthèse alors la réponse de l'étudiant à cette question doit vérifier l'expression régulière. personnel:sexe([mM]) permet de n'afficher la question que si la réponse m ou M a été donnée à la question sexe du fichier personnel.py
Une liste de chaines de caractères contenant des indices pour aider l'étudiant s'il le demande. Les indices sont proposés dans l'ordre, un par un.
Ce paramètre contient un texte qui sera affiché avant la question elle-même. Cela pourra être un rappel de cours ou bien une action à faire par l'étudiant pour qu'il puisse répondre à la question.
C'est un texte qui sera affiché dans tous les cas si l'étudiant donne une mauvaise réponse. Au dessus de ce texte il sera écrit : ``peut être que ...´´
Il est conseillé d'utiliser le test comment qui n'affichera rien si un autre commentaire a déjà été affiché pour l'étudiant.
C'est un texte qui sera affiché dans tous les cas si l'étudiant donne une bonne réponse. Au dessus de ce texte il sera écrit : ``saviez vous que ...´´
Cet entier indique le nombre de lignes de la zone dans laquelle l'étudiant va répondre. Par défaut 1.
C'est la réponse par défaut proposée quand l'utilisateur arrive sur la question pour la première fois.
C'est une liste de tests. Les tests sont effectués dans l'ordre jusqu'à ce qu'un test indique que la réponse est mauvaise ou bonne (True/False). Si le test retourne None alors il peut ajouter un commentaire qui sera affiché à l'étudiant. Des commentaires successifs peuvent s'afficher.
Les fonctions de tests suivantes sont définies par défaut.
Si la réponse est exactement identique alors on considère que c'est une bonne réponse et l'on retourne le commentaire associé à la bonne réponse.
good( "a" ), good( "A", "Je préfère <tt>a</tt> comme réponse" ), good( ("c", "d") ), good( ("C", "D"), "Ok, mais je préfère les minuscules" ),
Si la réponse est exactement identique alors on considère que c'est une mauvaise réponse et l'on retourne le commentaire associé à la mauvaise réponse.
La syntaxe est la même que good
Si la réponse ne contient pas la chaine on considère que c'est une mauvaise réponse et l'on retourne le commentaire associé à la bonne réponse.
require( "a" ), require( "A", "Et alors, ou il est le <tt>A</tt>" ), require( ("c", "d") ), require( ("C", "D"), "Et C et D ? Ou sont-ils ?" ),
Si la réponse ne commence ou fini pas par la chaine on considère que c'est une mauvaise réponse et l'on retourne le commentaire associé à la bonne réponse.
require_startswith("/", "Un nom absolu commence par /"), require_endswith(".html", "Il faut indiquer que c'est du HTML"),
Si la réponse contient la chaine on considère que c'est une mauvaise réponse et l'on retourne le commentaire associé à la mauvaise réponse.
La syntaxe est la même que require
Si la réponse commence ou fini par la chaine on considère que c'est une mauvaise réponse et l'on retourne le commentaire associé à la bonne réponse.
reject_startswith("/", "Un nom relatif ne commence pas par /"), reject_endswith("/", "Le / final est inutile"),
Ce test sans paramètre refuse la réponse si ce n'est pas un entier.
Ce test a pour paramètre la longueur de la réponse attendue et un commentaire à retourner si ce n'est pas la bonne.
Ce test a pour paramètres une chaine de caractère et le nombre requis d'occurrence de cette chaine de caractère dans la réponse de l'étudiant. Le dernier paramètre est le commentaire.
Cette fonction a pour paramètre un commentaire. Dans tous les cas ce commentaire est ajouté à ce que l'étudiant va voir comme indication sur sa réponse.
Son utilisation la plus naturelle est de le mettre en dernier dans la liste des tests afin de donner un conseil général à l'étudiant quand on a pas pu lui faire un commentaire lui expliquant pourquoi sa réponse est mauvaise.
Ces tests sont utilisés pour les TP utilisant le shell et ne sont pas utiles pour les autres.
Le fonctionnement et la syntaxe sont la même que ceux sans shell_. Les différences sont :
dumb_replace = ( ("${HOME}", "$HOME"), (("~/.", "$HOME/"), "~/") )
replacement=( ("-d", "--directory", 0), ("-w", "--width", 1) )L'exemple précédent fait les subtitutions :
Ce test sans paramètre affiche simplement l'arbre syntaxique de la commande shell. Il doit être indiqué en dernier sinon il risque d'être affiché deux fois car les autres tests l'affichent quand ils interrompent la vérification .
Quand add est appelé, il stocke la valeur courante de cette variable dans la question elle même, cela évite de redonner ce paramètre à chaque add.
Cette variable contient une fonction paramétrée par la réponse de l'utilisateur et state. Elle retourne un texte qui sera affiché dans le cadre nommé Ce qui est obtenu.
Dans le cas de Python, c'est le résultat de l'évaluation du code Python.
Cette implémentation de la fonctionnalité ne me plait pas car elle n'est pas esthétique. Elle va certainement être recodée.
Cette fonctionnalité n'est pas utilisée dans le questionnaire unix c'est pour cela qu'il y a shell_display presque systématiquement à la fin de la liste des tests.
Le test minimun est le suivant :
def votre_test(reponse_etudiant): if reponse == 'x' : return False, "Mauvaise réponse car ..." if reponse == 'y' : return True, "Bonne réponse mais ..." return None, "" # On peut mettre un commentaire qui sera ajouté à la fin
Pour simplifier la vérification des questions grace à la page 'Voir les bonnes réponses' il faut que la fonction retourne la valeur de la bonne réponse comme ci dessous :
def votre_test(reponse_etudiant, get_answer=False): # Voir le fichier question.py pour savoir ce que l'on peut retourner
Dans le cas ou la question est définie par une fonction alors la graine de la série aléatoire est initialisée avant l'appel de l'affichage de la fonction et l'appel de la fonction de test.
Si votre fonction de test nécessite des paramètres, alors il faut appeler une fonction qui retourne une fonction particulière pour ces paramètres. Le plus simple est de regarder les exemples.
Le système n'a été testé que sous Linux. Quelque points de détails l'empêcheront de fonctionner sous Windows.
Le fichier configuration.py contient quelques paramètres de configuration, notemment l'adresse du serveur CAS pour l'authentification.
Le répertoire HTML contient le fichier squelette de la page HTML ainsi que le fichier CSS qui contient tous les textes de l'interface. Il y a un fichier CSS par langue.
Les Packages obligatoires :
Pas besoin de compiler c'est du Python.
Pour voir toutes les options de lancement tapez : main.py
Les options de lancements sont concaténables.
Création d'une session |
main.py NomSession create RépertoireQuestions NumeroPort Ceci crée les répertoires mais ne lance pas le serveur. |
Définition de la date de début de TP |
main.py NomSession begin_date DateDébut Les dates sont sous la forme : "8:30 15/3/2006" |
Définition de la date de fin de TP |
main.py NomSession end_date DateDébut |
Désignation de l'administrateur | main.py NomSession admin NomDuCompte |
Lancement du serveur |
main.py NomSession start Le serveur vous affiche l'URL qu'il faut utiliser pour l'atteindre. |
Détection de problèmes |
main.py NomSession problems Indique à l'auteur du questionnaire les bonnes réponses données par les étudiants durant la session qui ne sont plus acceptées par le nouveau système. |
Chaque fonctionnalité du système a son ACL. Si une ACL est préfixée par ! alors elle est enlevée même si elle est autorisée pour tout le monde (question_shuffle pour les profs par exemple). Ou interdir à un étudiant de répondre aux questions, ...
Toute les descriptions des ACL sont visibles sur la page web permettant de modifier leur valeur.
Il est compliqué de modifier les ACLs une par une pour faire ce que l'on veut, c'est pour cela qu'il est préférable d'utiliser des 'rôles'. Quand on endosse un rôle, on prend les droits correspondant sans avoir besoin de modifier ses ACL. Les ACL personnelles sont prioritaires par rapport à celle du rôle. Les rôles existants :
Le premier administrateur doit être créé avant le lancement du système.
Si le serveur est trop lent ou les étudiants trop nombreux, enlevez l'ACL par défaut 'question_pixel_map_see' qui consomme beaucoup de ressources.
Taper make pour lister les buts possibles. Voici les principaux :
make regtest effectue des tests de régression. Il faut le lancer chaque fois que vous modifiez le système. pour s'assurer qu'il fonctionne toujours correctement.
make load_simulator reprend rejoue en temps réel des sessions d'étudiants qui ont réellement travaillé. Il permet de simuler autant d'étudiant que l'on veut. Il stocke le temps moyens de réponse du serveur au cours du temps.
make simulator_plot fait un affichage graphique des statistiques générées par make load_simulator
make profiling lance le simulateur avec le profiling pour voir ou le temps CPU passe.
make plots génère l'affichage graphique du graphe des questions pour les différents questionnaires. Ainsi que de nombreux autres fichiers dans le répertoire HTML de chacune des sessions.
Une fois le TP terminé, l'auteur du questionnaire doit l'améliorer pour que les étudiants reçoive un aide quand ils donne une mauvaise réponse. Ou bien pour tenir compte des commentaire des étudiants.
Avec vos droit enseignant, vous parcourez chaque question en cliquant sur 'question suivante'. Pour chaque question vous avez l'ensemble des mauvaises réponses données par le étudiants ainsi que les commentaires. Le fond rouge pour les mauvaises réponses indique que l'étudiant n'a eu aucun commentaire concernant sa mauvaise réponse. Après avoir mis la définition de la question à jour dans le fichier Python vous pouvez faire 'Recharge ce module' pour voir combien il reste de mauvaises réponses sur fond rouge. Pas besoin de relancer le serveur.
Le système fourni énormément d'informations via les pages Web. Si néanmoins elles ne sont pas suffisantes, on peut les extraire des fichiers.
Toutes les informations sont inscrites dans Students/nom_session/Logs. Il y a un répertoire par étudiant contenant :
Les champs de l'enregistrement sont séparés par control A (^A). La suite de la ligne peut être :
Sur le système lui-même :
Pour les différents questionnaires, il faut regarder dans Questions/.../TODO
Nb Étudiants | Questionnaire | Mémoire | Max des temps moyens de réponse sur 5 minutes |
---|---|---|---|
50 | unix | ? | 0.024 secondes |
100 | unix | ? | 0.035 secondes |
200 | unix | ? | 0.14 secondes |
300 | unix | 70Mo | 1.55 secondes |
Et faire du multi tâche complique inutilement bien que cela ne devrait pas poser de problème grace à la séparation action et page.
De plus, on peut encore optimiser le code.
Changements faits lors du passage d'une version à l'autre.