How to handle errors if the user enters an invalid character?

Asked

Viewed 54 times

0

I wanted to do in the notes entry part, and in the final part of showing each student’s grades individually, something similar to what I did in the 'Want to continue? [S/N]', that is, only step forward, if the user enters with a valid number. because the way it is there, if an invalid note is inserted, that is, strings instead of integers, or I ask to see the notes of a student who does not exist in the list, it gives error and closes the program. then wanted to shield him from these bugs. however I tried to use the infinite loop, the loop with stop condition, but nothing works. I wait answer. and follow my code below:

nota = []
aluno = []
while True:
    pessoa = input('Nome do aluno: ').capitalize()
    while True:
        n1 = str(input('Nota 1: '))
        if n1.isnumeric == False:
            break
    while True:
        n2 = str(input('Nota 2: '))
        if n2.isnumeric == False:
            break
    aluno.append(pessoa)
    nota.append(n1)
    nota.append(n2)
    aluno.append(nota[:])
    geral.append(aluno[:])
    aluno.clear()
    nota.clear()
    while True:
        opç = str(input('Quer continuar?[S/N] ')).lower().strip()[0]
        if opç in 'sn':
            break   
    if opç == 'n':
        break
print(14 * '-=')
print(f'{"Num°":<2}{"Aluno":^10}{"média":>11}')
print(14 * '-=')
for pos,c in enumerate(geral):
    print(f'{pos:<6}{str(c[0]):<14}{sum(c[1])/2:3}')
print(14 * '-=')
while True:
    num = int(input('De qual aluno deseja saber as notas?[999 para encerrar] '))
    if num == 999:
        break    
    print(f'As notas de {geral[num][0]} foram {geral[num][1]}')
print('Volte sempre, tenha um bom dia!')```

1 answer

1

There are several problems there, the first is:

if n1.isnumeric == False

You’re not calling the method isnumeric. In fact, you’re comparing whether the method itself is false, which it never will be, so the program gets into loop in this part. To call the method, you need parentheses (n1.isnumeric()), but still the logic is flawed, because you only enter the if if it’s not numerical, which is the opposite of what you want.

Anyway, there are several characters for which isnumeric returns True but error when converting to int, see here. The best thing would be to do it soon int(entrada) and capture the ValueError to know if a number has not been entered (more or less thus).

Another detail is that input already returns a string, so do str(input()) is redundant and unnecessary. But if you want the note to be a number, just keep it as the same number.

And you don’t have to create multiple lists, and keep adding elements to them and then cleaning them. You can save everything in a dictionary, which maps each name to your respective notes:

# função que lè um número
def ler_numero(mensagem):
    while True: # enquanto não digitar um número, continua no loop
        try:
            return int(input(mensagem))
        except ValueError:
            print('Digite um número')

alunos = dict() # cria um dicionário de alunos
while True:
    nome = input('Nome do aluno: ').capitalize()
    n1 = ler_numero('Nota 1: ')
    n2 = ler_numero('Nota 2: ')
    alunos[nome] = [n1, n2] # mapeia o nome do aluno para as suas notas
    while True:
        opç = input('Quer continuar?[S/N] ').lower().strip()[0]
        if opç in 'sn':
            break   
    if opç == 'n':
        break

print(14 * '-=')
print(f'{"Num°":<2}{"Aluno":^10}{"média":>11}')
print(14 * '-=')
for pos, (nome, notas) in enumerate(alunos.items()):
    print(f'{pos:<6}{nome:<14}{sum(notas) / len(notas):5.2f}')
print(14 * '-=')
while True:
    aluno = input('De qual aluno deseja saber as notas?[999 para encerrar] ').capitalize()
    if aluno == '999':
        break
    if aluno in alunos: # verifica se o aluno existe no dicionário
        print(f'As notas de {aluno} foram {alunos[aluno]}')
    else:
        print(f'Não temos as notas de {aluno}')

print('Volte sempre, tenha um bom dia!')

Browser other questions tagged

You are not signed in. Login or sign up in order to post.