Accelerating Accurate Assignment Authoring Using Solution-Generated Autograders
Este artigo apresenta a "correção automática gerada por soluções", um método que aproveita soluções fornecidas para criar corretores automáticos precisos e escaláveis sem a enumeração manual de casos de teste, demonstrado através do sistema Questioner, que suportou com sucesso um grande curso de CS1 com quase 800 questões de programação ao longo de quatro anos.
Artigo original sob licença CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/). Esta é uma explicação gerada por IA do artigo abaixo. Não foi escrita nem endossada pelos autores. Para precisão técnica, consulte o artigo original. Ler aviso legal completo
Imagine que você é um professor tentando ensinar uma turma de milhares de alunos a assar o bolo de chocolate perfeito. Antigamente, para avaliar o bolo de cada aluno, você teria que provar cada um deles pessoalmente. Mas com milhares de alunos, isso é impossível. Então, você constrói um robô chef para provar os bolos por você. Este robô é um "autocorretor". Normalmente, para ensinar este robô o que um "bom" bolo parece, você teria que escrever uma lista enorme e tediosa de regras: "Se o bolo estiver muito seco, reprove. Se estiver muito doce, reprove. Se a cobertura for azul, reprove." Você tem que adivinhar cada possível erro que um aluno possa cometer e escrever uma regra para ele. Se você esquecer apenas uma, o robô pode deixar passar um bolo ruim ou, pior, rejeitar um bolo perfeito porque você esqueceu de dizer a ele que a cobertura azul é aceitável para um bolo de "mirtilo". Esse processo de escrever as regras é lento, entediante e frequentemente resulta em um robô que não é muito inteligente.
Este artigo é sobre uma nova maneira de construir esse robô chef. Em vez de escrever uma longa lista de regras, o professor simplesmente mostra ao robô o bolo perfeito que ele mesmo assou. O robô então usa esse bolo perfeito para descobrir por conta própria o que um "bom" bolo parece. Ele faz isso tentando assar o bolo de um milhão de maneiras ligeiramente "erradas" para ver se consegue distinguir entre um erro real e um bolo perfeito. Este método é chamado de "autocorreção gerada pela solução". Ele transforma o trabalho entediante de escrever regras em um jogo divertido de "encontre as diferenças", tornando muito mais rápido criar enormes bibliotecas de problemas de prática para alunos que estão aprendendo a programar.
O Problema: A Armadilha da "Escrita de Regras"
Quando os alunos aprendem a programar, eles precisam praticar a resolução de centenas de diferentes quebra-cabeças. Para que isso funcione, os professores precisam de uma maneira de verificar o código dos alunos instantaneamente. É aqui que entram os corretores automáticos. Tradicionalmente, criar um corretor automático é como construir um segurança que só conhece formas específicas de identificar intrusos. O professor tem que escrever manualmente uma lista de casos de teste: "Se o código retornar 5 quando a entrada for 2, está correto. Se retornar 6, está incorreto."
Essa abordagem tem três grandes problemas. Primeiro, é incrivelmente tedioso. Você tem que adivinhar todas as formas possíveis de um aluno errar, o que é como tentar listar todas as formas possíveis de alguém tropeçar em um corredor. Segundo, é difícil saber se sua lista é boa o suficiente. Você esqueceu algum erro complexo? Se não souber, seu corretor pode ser impreciso, deixando passar códigos ruins ou reprovando códigos bons. Terceiro, essas listas de testes costumam ser confusas para os alunos. Se um teste falha, o aluno pode não saber se o erro está no seu código ou se a lista de testes do professor foi apenas mal escrita.
A Solução: A Estratégia do "Bolo Perfeito"
Os autores, Geoffrey Challen e Ben Nordick, propõem uma reviravolta inteligente. Em vez de escrever uma lista de regras, o professor apenas fornece a solução — o código perfeito que resolve o problema. Eles chamam sua ferramenta de Questioner.
Veja como o Questioner funciona, usando uma analogia lúdica: Imagine que o professor entrega ao robô um bolo perfeito, dourado e fofinho (a solução de referência). O robô não apenas olha para ele; ele começa a tentar "quebrá-lo". Ele usa uma ferramenta especial de "mutação" para cometer erros pequenos e bobos no bolo perfeito. Talvez ele troque o açúcar pelo sal, ou mude a temperatura do forno em um grau, ou esqueça de misturar os ovos. Estes são os "mutantes".
O robô então pergunta a si mesmo: "Consigo notar a diferença entre meu bolo quebrado e o bolo perfeito?" Ele gera milhares de ingredientes aleatórios (entradas) para testar os bolos. Se o robô conseguir notar a diferença entre o bolo perfeito e o bolo quebrado usando esses ingredientes aleatórios, ele sabe que possui um bom teste. Se ele não conseguir notar, ele continua gerando mais ingredientes aleatórios até conseguir.
Esta é a magia: o robô usa a solução perfeita para ensinar a si mesmo o que não aceitar. Ele não precisa que o professor escreva uma lista de "nãos". Ele descobre os limites da correção tentando quebrar a solução perfeita e observando o que acontece.
O Que Eles Descobriram
A equipe construiu o Questioner para Java e Kotlin e o utilizou por quatro anos em um curso massivo de introdução à ciência da computação na Universidade de Illinois. Eles criaram quase 800 questões de programação que foram usadas por milhares de alunos para avaliar milhões de envios.
Aqui estão as principais conclusões de sua experiência:
- Velocidade e Diversão: Escrever questões com o Questioner era muito mais rápido e prazeroso do que escrever suítes de teste tradicionais. Um instrutor foi capaz de escrever aproximadamente uma nova questão por dia útil durante três anos seguidos, construindo um banco de 771 questões.
- Precisão: Como o robô testa contra a solução perfeita real, ele é muito bom em distinguir o certo do errado. Em seus testes, eles nunca precisaram descartar uma questão porque o corretor automático estava impreciso.
- Feedback Rico: O sistema não diz apenas "Certo" ou "Errado". Ele também pode verificar a qualidade do código. Por exemplo, ele pode dizer se o código do aluno é muito complicado (usando etapas demais) em comparação com a solução simples e elegante. Ele pode até verificar se o aluno usou uma técnica específica, como recursão, caso esse fosse o objetivo da lição.
- Lidando com as Coisas Difíceis: Às vezes, ingredientes aleatórios não são suficientes. Por exemplo, se um problema exige um número específico como "88" para funcionar, o robô pode nunca adivinhá-lo por acaso. Nesses casos, o professor pode dar ao robô uma pequena lista de "ingredientes especiais" para tentar. Mas, mesmo assim, o robô ainda usa a solução perfeita para realizar a correção, de modo que o professor não precisa escrever uma suíte de testes completa.
Por Que Isso Importa
Este artigo sugere que não precisamos ser "enumeradores de casos de teste" para construir bons corretores automáticos. Ao permitir que a própria solução gere os testes, podemos construir enormes bancos de problemas de prática muito mais rapidamente. Isso significa que mais alunos podem receber feedback imediato e preciso sobre sua codificação, ajudando-os a aprender sem ficarem presos em erros confusos.
Os autores também observam que isso não é apenas para Java; eles já estão construindo uma versão para Python chamada Snapact, e estão até explorando como usar IA para ajudar a escrever as soluções perfeis iniciais. Embora admitam que nenhum sistema é perfeito (um aluno ainda poderia tentar burlar o sistema com um hack de "força bruta"), seu método torna muito mais difícil burlar o sistema e muito mais fácil para os professores criarem materiais de aprendizagem de alta qualidade.
Em resumo, em vez de escrever um milhão de regras para pegar cada erro, o professor apenas mostra ao robô a resposta correta, e deixa o robô descobrir o resto. É uma maneira mais rápida, inteligente e menos frustrante de ensinar a próxima geração de programadores.
Afogado em artigos na sua área?
Receba digests diários dos artigos mais recentes que correspondam às suas palavras-chave de pesquisa — com resumos técnicos, no seu idioma.