Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Estendendo a Questão 5

Estava fazendo a questão 5 e decidi me desafiar um pouco mais colocando algumas coisas a mais, como por exemplo qual foi a questão marcada errada e qual aluno que marcou(a questão só pede a alternativa originalmente), por em quanto só consegui fazer até o primeiro erro. Queria mesmo que ele retornasse todos as marcadas erradas para que assim o professor pudesse dizer aos alunos quais questões eles marcaram erradas.

def avaliador(l1: list) -> list:
    gabarito = ['D', 'A', 'B', 'C', 'A']
    opcoes_validas = list(set(gabarito))
    notas = []
    
    try:
        '''
        Estava utilizando .index para localizar qual aluno era mas se por acaso o aluno 2 tivesse colado do aluno 1, o indice retornado com o .index iria repetir a do aluno 1, pq ele pega o primeiro valor a aparecer.
        for i in range(len(l1)): #aqui pegamos as listas de alternativas do aluno i.
            for x in l1[i]: #aqui pegamos as alternativas uma por uma que o aluno i escolheu.
                if x not in opcoes_validas: #aqui verifico se a opçao que o aluno escolheu não pertence a lista que criei com as alternativas possiveis.
                    raise ValueError(f"A alternativa {x} da questão {l1[i].index(x)+1}, do aluno {i+1} não é uma opção de alternativa válida.")
        '''
        for i, respostas in enumerate(l1): 
            for x, alternativas in enumerate(respostas):
                if alternativas not in opcoes_validas:
                    raise ValueError(f"A alternativa {alternativas} da questão {x+1}, do aluno {i+1} não é uma opção de alternativa válida.")
    except Exception as e:
        print(f'Erro: {e}')
    else:
        for i in range(len(l1)):
            notas.append([1 if x == y else 0 for x,y in zip(l1[i],gabarito)])
            notas[i] = sum(notas[i])
        return notas
2 respostas
solução!

Só mostra o primeiro erro Isso acontece porque você está usando raise, e quando isso é chamado, o programa para imediatamente. Então, se o primeiro aluno marcar uma alternativa inválida, o resto nem é verificado. em vez de dar erro com raise, você pode guardar os erros em uma lista e só mostrar tudo no final.

Exemplo:

erros = []
for i, respostas in enumerate(l1):
    for j, alternativa in enumerate(respostas):
        if alternativa not in ['A', 'B', 'C', 'D']:
            erros.append(f"Aluno {i+1}, questão {j+1}: alternativa inválida '{alternativa}'")

if erros:
    for erro in erros:
        print(erro)
    return  # Encerra aqui se tiver erro

.index() dá o aluno errado Você percebeu bem: quando dois alunos respondem igual, o .index() retorna sempre o primeiro. Então você acaba dizendo que foi o aluno 1 que errou, mesmo que tenha sido outro. você pude usar enumerate() pra saber exatamente qual aluno e qual resposta você está analisando.

Exemplo:

for i, respostas in enumerate(l1):
    print(f"Aluno {i+1}: {respostas}")

Assim você pega o número do aluno (i+1) certinho.

Agora, como mostrar os erros de cada aluno Você pode comparar cada resposta do aluno com o gabarito. Quando a resposta estiver errada, você guarda uma mensagem dizendo:

Qual aluno errou, Em qual questão, O que ele marcou E qual era a resposta correta

exemplo:

gabarito = ['D', 'A', 'B', 'C', 'A']
for i, respostas in enumerate(l1):
    for j, alternativa in enumerate(respostas):
        if alternativa != gabarito[j]:
            print(f"Aluno {i+1} errou a questão {j+1}: marcou '{alternativa}', correto era '{gabarito[j]}'")

Entendo, fiquei muito preso ao usar o try e o excepct que nem me toquei q poderia usar essa mensagem salva em uma lista.