Un retour immédiat et personnalisé est au cœur de l’expérience d’apprentissage sur DataCamp depuis nos tout premiers cours. Si des apprenants soumettent du code contenant une erreur, ils sont informés de l’endroit où elle se situe et de la manière de la corriger. Vous pouvez l’essayer dans notre cours gratuit Introduction to R. La capture d’écran ci-dessous provient de notre cours Intermediate R.

Pour vérifier les soumissions et générer des retours, chaque exercice sur DataCamp comporte un « Submission Correctness Test » ou SCT.
Le SCT est un script de tests personnalisés qui évalue le code soumis par les apprenants ainsi que la sortie et les variables générées par ce code. Pour chaque langage enseigné sur DataCamp, nous avons développé un package open source correspondant afin de vérifier facilement tous ces éléments d’une soumission. Pour les exercices R, ce package s’appelle testwhat. Au fil des années, nous avons ajouté de nombreuses fonctions pour :
- vérifier l’affectation de variables
- vérifier les appels de fonctions et leurs résultats
- vérifier les instructions if, les boucles for et while
- vérifier la définition de fonctions
- vérifier si les bons packages sont chargés
- vérifier la sortie générée par l’apprenant
- vérifier les appels de tracés ggplot et ggvis
- ...
Lorsque ces fonctions de vérification détectent une erreur, elles génèrent automatiquement un message de feedback pertinent qui oriente l’apprenant vers sa faute. Vous pouvez aussi définir des messages personnalisés pour remplacer ceux générés automatiquement.
Historiquement, testwhat était étroitement lié à notre backend propriétaire qui exécute du code R sur les serveurs de DataCamp. Même si testwhat a toujours été open source, il ne fonctionnait pas bien sans ce backend, et son usage restait limité au contexte DataCamp. Aujourd’hui, toutefois, testwhat peut être utilisé de manière autonome et couvre d’autres cas d’usage. Vous pouvez tirer parti de tout ce que testwhat propose pour évaluer des soumissions, même si votre format d’enseignement est très différent de celui de DataCamp. Installez le package depuis GitHub :
library(remotes) # devtools works fine too
install_github('datacamp/testwhat')
Pour une courte démonstration, supposons que vous demandiez aux apprenants de créer une variable x égale à 5. Une version chaîne de caractères de la solution idéale ressemblerait à ceci :
solution_code <- 'x <- 5'
Supposons maintenant que l’apprenant soumette un script où x est, à tort, un vecteur de deux valeurs, ce qui peut s’écrire ainsi :
student_code <- 'x <- c(4, 5)'
testwhat propose une fonction appelée setup_state() qui exécute la soumission de l’apprenant et le script de solution dans des environnements séparés et capture les sorties et erreurs générées par le code de l’apprenant. Toutes ces informations sont stockées dans l’état d’exercice, accessible via ex() :
library(testwhat)
setup_state(stu_code = student_code,
sol_code = solution_code)
ex()
## <RootState>
Cet état d’exercice peut être transmis à la large gamme de fonctions de vérification de testwhat en utilisant la syntaxe de pipe de magrittr. Pour vérifier si l’apprenant a défini une variable x, utilisez check_object() :
ex() %>% check_object('x')
## <ObjectState>
Ce code s’exécute correctement, car l’apprenant a effectivement défini une variable x. Pour aller plus loin et vérifier si la variable x a été définie correctement, utilisez check_equal() :
ex() %>% check_object('x') %>% check_equal()
## Error in check_that(is_equal(student_obj, solution_obj, eq_condition), : The contents of the variable `x` aren't correct. It has length 2, while it should have length 1.
Cela produit une erreur. check_equal() détecte que la valeur de x dans l’environnement de l’apprenant (un vecteur) ne correspond pas à la valeur de x dans l’environnement de solution (un nombre unique). Notez que le message d’erreur est lisible et décrit clairement la faute.
L’exemple ci-dessus était interactif : vous configurez un état, puis vous enchaînez les fonctions de vérification. À un niveau plus élevé, vous pouvez encapsuler le code de vérification avec run_until_fail(). Cela exécutera votre batterie de tests jusqu’à échec :
library(testwhat)
setup_state(stu_code = 'x <- 4',
sol_code = 'x <- 5')
res <- run_until_fail({
ex() %>% check_object('x') %>% check_equal()
})
res$correct
## [1] FALSE
res$message
## [1] "The contents of the variable `x` aren't correct."
Cette approche de base, qui consiste à construire un état d’exercice avec une soumission et une solution puis à utiliser run_until_fail() pour exécuter une batterie de tests, s’intègre facilement dans un flux d’autocorrection adapté à vos besoins. Supposons que vos apprenants aient remis leurs devoirs sous forme de scripts R que vous avez téléchargés sur votre ordinateur dans le dossier submissions (nous avons prérempli le dossier avec quelques données). Nous avons plusieurs scripts R dans le dossier submissions. Chaque script R correspond à une soumission :
dir('submissions')
## [1] "student_a.R" "student_b.R" "student_c.R" "student_d.R" "student_e.R"
## [6] "student_f.R" "student_g.R" "student_h.R" "student_i.R" "student_j.R"
readLines('submissions/student_a.R')
## [1] "x <- 4"
readLines('submissions/student_b.R')
## [1] "x <- 5"
Nous pouvons maintenant parcourir toutes ces soumissions et générer un data.frame indiquant, pour chaque apprenant, si la soumission est correcte ou non :
library(testwhat)
folder_name <- 'submissions'
all_files <- file.path(folder_name, dir(folder_name))
student_results <- sapply(all_files, function(file) {
student_code <- readLines(file)
setup_state(sol_code = 'x <- 5',
stu_code = student_code)
res <- run_until_fail({
ex() %>% check_object('x') %>% check_equal()
})
res$correct
})
results_df <- data.frame(name = all_files, correct = student_results,
row.names = NULL, stringsAsFactors = FALSE)
results_df
## name correct
## 1 submissions/student_a.R FALSE
## 2 submissions/student_b.R TRUE
## 3 submissions/student_c.R TRUE
## 4 submissions/student_d.R TRUE
## 5 submissions/student_e.R FALSE
## 6 submissions/student_f.R TRUE
## 7 submissions/student_g.R FALSE
## 8 submissions/student_h.R FALSE
## 9 submissions/student_i.R TRUE
## 10 submissions/student_j.R TRUE
Cette petite démonstration reste sommaire, mais l’idée est là : avec un peu de R pour construire les bons paramètres d’entrée de setup_state(), vous pouvez exploiter toute la panoplie de fonctions de vérification de testwhat. Les tests définis dans run_until_fail() valideront le travail des apprenants et généreront des retours utiles pour les guider vers leurs erreurs.
Pour en savoir plus sur testwhat, consultez le repo GitHub ou la documentation du package, générée avec pkgdown. Vous y trouverez des vignettes expliquant l’usage de certaines fonctions de vérification ainsi qu’une référence détaillant tous les arguments possibles. N’hésitez pas à ouvrir des issues sur GitHub ou à nous écrire à content-engineering@datacamp.com, vos retours nous sont précieux ! Bonne transmission !
Ce billet a été généré avec RMarkdown. Vous pouvez retrouver la source ici.