Olá, Harone. Como vai?
Parabéns pela resolução do exercício! O seu código está muito bem estruturado e sua preocupação em evitar o uso de índices manuais ([i]) é uma excelente prática em Python. Utilizar funções como o zip() torna o código muito mais "pythônico", limpo e fácil de ler.
O seu tratamento de exceções com o bloco try-except-else também ficou ótimo, garantindo que o programa não quebre caso uma alternativa inválida seja inserida.
Para agregar ainda mais valor ao seu aprendizado e comentar a sua observação sobre evitar os índices ([i]), vamos analisar por que a sua abordagem com o zip() foi a melhor escolha e trazer pequenos refinamentos sobre o fluxo de execução das exceções.
Por que fugir do [i] com o zip() é uma boa prática?
Quando usamos loops baseados em índices (como for i in range(len(lista))), estamos forçando o Python a fazer uma busca manual na memória a cada iteração para encontrar o elemento naquela posição.
A função zip() cria um iterador de alta performance que combina os elementos das duas listas de forma pareada na memória de uma só vez. Veja como a sua lógica interna funcionou perfeitamente:
teste do aluno: ['A', 'A', 'E', 'C', 'A']
| | | | |
(zip junta os elementos por coluna)
| | | | |
gabarito oficial:['D', 'A', 'B', 'C', 'A']
Um ponto de atenção sobre o escopo do try-except
Analisando a estrutura do seu código, você colocou o laço for teste in testes principal dentro do bloco try. Essa lógica funciona, mas ela tem um comportamento específico no tratamento de erros:
Se a lista testes contiver as respostas de vários alunos e o segundo aluno digitar uma nota inválida (como 'E'), o comando raise ValueError será disparado. Como o bloco try envolve o laço principal, o Python vai interromper o loop dos alunos imediatamente, pular para o except e a função não retornará a pontuação de nenhum aluno (nem mesmo dos que estavam corretos antes do erro).
Se a intenção for apenas invalidar a nota do aluno que errou e continuar corrigindo o teste dos outros, o bloco try-except deve ser colocado dentro do primeiro laço. Veja esta variação refinada:
gabarito = ['D', 'A', 'B', 'C', 'A']
def corretor(testes):
respostas_validas = ['A', 'B', 'C', 'D']
pontuacao = []
for teste in testes:
nota = 0
try:
for resposta, resposta_correta in zip(teste, gabarito):
if resposta not in respostas_validas:
raise ValueError(f"A alternativa {resposta} não é válida")
if resposta == resposta_correta:
nota += 1
# Só adiciona a nota se o teste inteiro for válido
pontuacao.append(nota)
except ValueError as e:
print(f"Erro ao corrigir este teste: {e}")
pontuacao.append("Invalido") # Registra que este teste teve erro, mas não para o sistema
return pontuacao
O que mudou aqui:
except ValueError: É uma boa prática capturar a exceção específica (ValueError) em vez da genérica (Exception), evitando mascarar outros erros inesperados do sistema.- Continuidade: Se um aluno errar a preenchimento, o sistema avisa o erro, mas continua a correção dos demais estudantes da lista.
Sua mentalidade de buscar códigos limpos e sem indexadores manuais está super alinhada com as melhores práticas de Engenharia de Software com Python. Continue com esse foco!
Espero que possa ter lhe ajudado!