Feedback imediato e personalizado sempre foi central na experiência de aprendizado da DataCamp desde os primeiros cursos. Se os alunos enviam um código com erro, eles recebem orientações sobre onde erraram e como corrigir. Você pode testar isso no nosso curso gratuito Introduction to R. A captura de tela abaixo é do nosso curso Intermediate R.

Para avaliar envios e gerar feedback, todo exercício na DataCamp conta com um Submission Correctness Test, o SCT.
O SCT é um script com testes personalizados que avalia o código enviado pelos alunos e os outputs e variáveis que eles criaram. Para cada linguagem ensinada na DataCamp, criamos um pacote open source correspondente para verificar facilmente todos esses elementos de um envio. No caso de exercícios em R, esse pacote se chama testwhat. Ao longo dos anos, adicionamos diversas funções para:
- verificar atribuição de variáveis
- verificar chamadas de função e os resultados dessas chamadas
- verificar if statements, for loops e while loops
- verificar definição de funções
- checar se os pacotes corretos foram carregados
- verificar o output gerado pelo aluno
- verificar chamadas de plotagem do ggplot e ggvis
- ...
Quando essas funções de verificação encontram um erro, elas geram automaticamente uma mensagem de feedback útil que aponta o problema ao aluno. Você também pode definir mensagens personalizadas que substituem as mensagens geradas automaticamente.
Historicamente, o testwhat era fortemente ligado ao nosso backend proprietário que executa código R nos servidores da DataCamp. Apesar de sempre ter sido open source, ele não funcionava bem sem esse backend e só podia ser usado no contexto da DataCamp. Hoje, porém, o testwhat pode ser usado de forma independente e atende a outros casos de uso. Você pode aproveitar tudo o que o testwhat oferece para testar envios de alunos, mesmo que o seu formato de ensino seja bem diferente do da DataCamp. Instale o pacote a partir do GitHub:
library(remotes) # devtools também funciona
install_github('datacamp/testwhat')
Como um demo rápido, imagine que você pede aos alunos para criar uma variável x igual a 5. Uma versão em string da solução ideal seria algo assim:
solution_code <- 'x <- 5'
Agora suponha que o aluno enviou um script em que x foi definido incorretamente como um vetor com dois valores, algo como:
student_code <- 'x <- c(4, 5)'
O testwhat oferece uma função chamada setup_state() que executa o envio do aluno e o script de solução em ambientes separados e captura o output e os erros gerados pelo código do aluno. Todas essas informações ficam armazenadas no chamado estado do exercício, acessível com ex():
library(testwhat)
setup_state(stu_code = student_code,
sol_code = solution_code)
ex()
## <RootState>
Esse estado do exercício pode ser passado para a ampla variedade de funções de verificação do testwhat usando a sintaxe de pipes do magrittr. Para checar se o aluno definiu uma variável x, use check_object():
ex() %>% check_object('x')
## <ObjectState>
Esse código roda sem problemas, porque o aluno realmente definiu a variável x. Para continuar e verificar se a variável x foi definida corretamente, use 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.
Isso gera um erro. O check_equal() detecta que o valor de x no ambiente do aluno (um vetor) não corresponde ao valor de x no ambiente da solução (um número único). Note como a mensagem de erro é legível e descreve o problema.
O exemplo acima foi interativo: você configurou um estado e depois foi digitando cadeias de funções de verificação. Em um nível mais alto, você pode usar run_until_fail() para englobar o código de checagem. Ele executa sua bateria de testes até ocorrer uma falha:
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."
Essa abordagem básica — montar um estado de exercício com o envio do aluno e a solução e depois usar run_until_fail() para executar uma bateria de testes — pode ser facilmente incorporada a um fluxo de autograding que funcione para você. Suponha que seus alunos tenham enviado as atividades como scripts R que você baixou para a pasta submissions no seu computador (preenchemos a pasta com alguns dados aleatórios). Temos vários scripts R na pasta submissions. Cada script contém o envio de um aluno:
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"
Agora podemos percorrer todos esses envios e gerar um data.frame indicando se o envio de cada aluno está correto ou não:
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
Esse pequeno demo ainda é simples, mas a ideia é essa: com um pouco de R para montar as entradas certas para o setup_state(), você consegue colocar todas as funções de verificação do testwhat para trabalhar. Os testes que você definir no run_until_fail() vão tanto validar o trabalho dos alunos quanto gerar feedback útil para indicar onde estão errando.
Para saber mais sobre o testwhat, visite o repositório no GitHub ou a documentação do pacote, gerada com pkgdown. Lá você encontra tanto vignettes com orientações de uso de funções específicas quanto a referência completa com todos os argumentos disponíveis. Fique à vontade para abrir issues no GitHub ou falar com a gente em content-engineering@datacamp.com. Adoramos feedback! Boas aulas!
Este blog foi gerado com RMarkdown. Você pode acessar o código-fonte aqui.
