Un feedback immediato e personalizzato è stato al centro dell’esperienza di apprendimento su DataCamp sin dal lancio dei primi corsi. Se gli studenti inviano del codice con un errore, viene indicato dove hanno sbagliato e come possono correggerlo. Puoi provarlo nel nostro corso gratuito Introduction to R. Lo screenshot qui sotto è tratto dal nostro corso Intermediate R.

Per controllare gli invii e generare feedback, ogni esercizio su DataCamp include un cosiddetto Submission Correctness Test, o SCT.
Lo SCT è uno script di test personalizzati che valuta il codice inviato dagli studenti e l’output e le variabili che hanno creato con il loro codice. Per ogni linguaggio che insegniamo su DataCamp, abbiamo realizzato un pacchetto open source corrispondente per verificare facilmente tutti questi elementi di una consegna. Per gli esercizi in R, questo pacchetto si chiama testwhat. Nel corso degli anni, abbiamo aggiunto molte funzioni per:
- controllare l’assegnazione delle variabili
- controllare le chiamate di funzione e i risultati delle chiamate
- controllare if, for e while
- controllare la definizione di funzioni
- controllare che i pacchetti corretti siano caricati
- controllare l’output generato dallo studente
- controllare le chiamate di grafica di ggplot e ggvis
- ...
Quando queste funzioni di controllo individuano un errore, generano automaticamente un messaggio di feedback significativo che indica agli studenti dove hanno sbagliato. Puoi anche specificare messaggi di feedback personalizzati che sovrascrivono quelli generati automaticamente.
Storicamente, testwhat era strettamente collegato al nostro backend proprietario che esegue il codice R sui server di DataCamp. Anche se testwhat è sempre stato open source, senza questo backend personalizzato non funzionava bene e poteva essere usato solo nel contesto di DataCamp. Oggi, però, testwhat può essere usato in modo indipendente e supporta anche altri casi d’uso. Puoi sfruttare tutto ciò che testwhat offre per testare le consegne degli studenti, anche quando il tuo formato didattico è molto diverso da quello di DataCamp. Puoi installare il pacchetto da GitHub:
library(remotes) # devtools works fine too
install_github('datacamp/testwhat')
Come rapida demo, supponiamo che tu chieda agli studenti di creare una variabile x uguale a 5. Una versione in stringa della soluzione ideale sarebbe qualcosa del genere:
solution_code <- 'x <- 5'
Ora immagina che lo studente abbia inviato uno script in cui x è impostata in modo errato come un vettore di due valori, che può essere scritto così:
student_code <- 'x <- c(4, 5)'
testwhat include una funzione chiamata setup_state() che esegue una consegna dello studente e uno script di soluzione in ambienti separati e cattura l’output e gli errori generati dal codice dello studente. Tutte queste informazioni sono memorizzate nel cosiddetto stato dell’esercizio, accessibile con ex():
library(testwhat)
setup_state(stu_code = student_code,
sol_code = solution_code)
ex()
## <RootState>
Questo stato dell’esercizio può essere passato all’ampia gamma di funzioni di controllo offerte da testwhat usando la sintassi a pipe di magrittr. Per verificare che lo studente abbia definito una variabile x, puoi usare check_object():
ex() %>% check_object('x')
## <ObjectState>
Questo codice funziona, perché lo studente ha effettivamente definito una variabile x. Per proseguire e controllare se lo studente ha definito la variabile x in modo corretto, puoi usare 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.
Questo genera un errore. check_equal() rileva che il valore di x nell’ambiente dello studente (un vettore) non corrisponde al valore di x nell’ambiente della soluzione (un singolo numero). Nota come il messaggio di errore includa un testo comprensibile che descrive l’errore.
L’esempio sopra era interattivo: imposti uno stato e poi continui digitando catene di funzioni di controllo. A un livello più alto, puoi usare run_until_fail() per incapsulare il codice di controllo. Questo eseguirà la tua batteria di test finché non fallisce:
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."
Questo approccio di base, che prevede la costruzione di uno stato dell’esercizio con una consegna dello studente e una soluzione e poi l’uso di run_until_fail() per eseguire una batteria di test, può essere facilmente inserito in un flusso di autovalutazione adatto alle tue esigenze. Supponi che i tuoi studenti abbiano inviato i loro compiti sotto forma di uno script R che hai scaricato sul tuo computer nella cartella submissions (abbiamo precompilato la cartella con alcuni dati casuali). Abbiamo un gruppo di script R nella cartella submissions. Ogni script R contiene una consegna di uno studente:
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"
Ora possiamo scorrere tutte queste consegne e generare un data.frame che indica per ogni studente se la consegna è corretta o meno:
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
Questa piccola demo è ancora un po’ grezza, ma spero renda l’idea: con un po’ di lavoro in R per costruire gli input appropriati per setup_state(), puoi mettere al lavoro tutte le funzioni di controllo di testwhat. I test che specifichi in run_until_fail() verificheranno sia il lavoro degli studenti sia genereranno un feedback significativo per indirizzarli sugli errori che stanno commettendo.
Per saperne di più su testwhat, visita il repo su GitHub o la documentazione del pacchetto, generata con pkgdown. Include sia vignette che illustrano come usare determinate funzioni di controllo, sia la reference delle funzioni che descrive tutti gli argomenti che puoi specificare. Non esitare ad aprire issue su GitHub o a contattarci a content-engineering@datacamp.com, ci fa piacere ricevere feedback! Buon insegnamento!
Questo blog è stato generato con RMarkdown. Puoi trovare il sorgente qui.

