Code does not work as expected

Asked

Viewed 127 times

1

My code should read name and weight using an auxiliary list and throwing the data to a main list. In the end, it generates a result of the highest and lowest weight with the name of the people who have these weights.

The problem is that it is replacing the variable menor by a greater weight, which should go to the if assigning the variable maior weight and not in if below. Also, after the third result he no longer uses the if's, which is very strange.

I commented on some lines I was using to thresh. Follows the code:

cadastro = []
dados = list()

while True:

    dados.append(input('Digite o nome: '))
    dados.append(input('Digite o peso: '))
    # print(dados[1])

    if len(cadastro) == 0:
        maior = menor = dados[1]

    else:

        if dados[1] > maior:
            maior = dados[1]
            # print(f'Função maior funcionando. {maior} {menor}')

        elif dados[1] < menor:
            menor = dados[1]
            # print(f'Função menor funcionando. {menor} {maior}')

    cadastro.append(dados.copy())
    dados.clear()
    resp = ' '

    while resp not in 'SN':
        resp = input('Você quer continuar? [S/N] ').strip().upper()[0]

    if resp == 'N':
        break

print(f'Ao todo você cadastrou {len(cadastro)} pessoas.')
print(f'O maior peso cadastrado foi {maior} de: ', end='')

for (nome, peso) in cadastro:
    if peso == maior:
        print(f'{nome}', end=' ')

print(f'O menor peso cadastrado foi {menor} de: ', end='')

for (nome, peso) in cadastro:
    if peso == menor:
        print(f'{nome}', end=' ')

3 answers

2

You didn’t report the data you used to test, but the problem probably occurs because the weight should be a number, but in the code you manipulate it as a string (since input returns a string).

The problem with comparing strings is that even if they only have digits, they are compared lexicographically. That means the string '2' is considered "larger" than the string '10':

print('2' > '10') # imprime "True"

This is the relevant part of documentation that explains this behavior:

Lexicographical Ordering for strings uses the Unicode code point number to order individual characters

That is, the lexicographical order takes into account the Unicode code points of each character (to better understand what a code point, suggest we start around here). But basically, each character has an associated numeric code (think of Unicode as an extension of ascii table - and make it clear that this is a simplification well coarse), and when comparing strings, the value of that code (which is the code point) is used to determine what is "higher" or "lower".

In the case, the code point of character '2' is greater than the character of '1', so the string '2' is considered "larger" than the string '10'. Works the same way as a comparison between strings 'b' and 'ac'. Like the b is "bigger" than the a (the code point of character b is greater than the character of a), then lexicographically 'b' > 'ac' - that is, in a string ordering, the 'b' would come after 'ac', as well as the '2' would come after '10':

lista = [ '2', '10' ]
print(sorted(lista)) # ['10', '2']

lista = [ 'b', 'ac' ]
print(sorted(lista)) # ['ac', 'b']

See here this code running

Finally, when comparing weights in this way, such as strings, the situation you described may occur: a weight with a smaller numerical value (for example, 2) is considered larger than other (such as the 10) because the data is as strings, and not as numbers.


If you want to take into account the numeric values (and not the code points of the string characters) to make the comparisons (and I believe this is what you want, since we are talking about weights), you must convert the weight to number, using int() (if it can only have integers) or float() (if you can have decimal places). You can also capture the ValueError, which occurs if you do not enter a number, and ask it to type again. It would look like this:

while True:
    try:
        peso = int(input('Digite o peso: '))
        break
    except ValueError:
        print('Peso deve ser um número')

Including, in the documentation has an example just like this.

That is, until a number is typed, keep asking you to type again. Thus you ensure that the weight will be a number and that comparisons are made correctly, taking into account the numerical value.


Another detail is that you may not need to store everything in a list, if the goal is only to get the highest and lowest value. One option would be to keep a register counter and update the highest and lowest values directly, without having to store in a list:

cont = 0
while True:
    nome = input('Digite o nome: ')
    while True:
        try:
            peso = int(input('Digite o peso: '))
            break
        except ValueError:
            print('Peso deve ser um número')

    if cont == 0:
        maior_peso = menor_peso = peso
        nome_maior = nome_menor = nome
    else:
        if peso > maior_peso:
            maior_peso = peso
            nome_maior = nome
        elif peso < menor_peso:
            menor_peso = peso
            nome_menor = nome

    cont += 1
    resp = ' '
    while resp not in 'SN':
        resp = input('Você quer continuar? [S/N] ').strip().upper()[0]
    if resp == 'N':
        break

print(f'Ao todo você cadastrou {cont} pessoas.')
print(f'O maior peso cadastrado foi {maior_peso} de: {nome_maior}')
print(f'O menor peso cadastrado foi {menor_peso} de: {nome_menor}')

OBS: The difference to your code is that it only prints one of the names in the event of a tie. Already the loop You print all the names if you have more than one person with the minimum or maximum weight. In this case, I even understand why I have to keep everything on a list.


If you want to save the entries in a list, you don’t need two lists like you did (and insert them in a list and then remove them, it’s a complication for no reason). Simply add the register inside the loop, thus:

cadastros = [] # Obs: usar [] e list() dá no mesmo, ambos criam uma lista vazia
while True:
    nome = input('Digite o nome: ')
    while True:
        try:
            peso = int(input('Digite o peso: '))
            break
        except ValueError:
            print('Peso deve ser um número')

    if len(cadastros) == 0:
        maior_peso = menor_peso = peso
    else:
        if peso > maior_peso:
            maior_peso = peso
        elif peso < menor_peso:
            menor_peso = peso

    cadastros.append((nome, peso))
    resp = ' '
    while resp not in 'SN':
        resp = input('Você quer continuar? [S/N] ').strip().upper()[0]
    if resp == 'N':
        break

print(f'Ao todo você cadastrou {len(cadastros)} pessoas.')

print(f'O maior peso cadastrado foi {maior_peso} de: ', end='')    
for (nome, peso) in cadastros:
    if peso == maior_peso:
        print(f'{nome}', end=' ')

print(f'O menor peso cadastrado foi {menor_peso} de: ', end='')    
for (nome, peso) in cadastros:
    if peso == menor_peso:
        print(f'{nome}', end=' ')

Although the final part is somewhat repetitive, it would simplify creating a function:

def encontrar_nomes_por_peso(cadastros, peso_busca, descricao):
    print(f'O {descricao} peso cadastrado foi {peso_busca} de: ', end='')

    for (nome, peso) in cadastros:
        if peso == peso_busca:
            print(f'{nome}', end=' ')
    print()

encontrar_nomes_por_peso(cadastros, maior_peso, 'maior')
encontrar_nomes_por_peso(cadastros, menor_peso, 'menor')

2


The only mistake I saw in the code was to treat the weight input as String.

Demonstrated on the line append(int(input('Enter the weight: ')))

cadastro = []
dados = list()

while True:

    dados.append(input('Digite o nome: '))
    **dados.append(int(input('Digite o peso: ')))**
    # print(dados[1])

    if len(cadastro) == 0:
        maior = menor = dados[1]

    else:

        if dados[1] > maior:
            maior = dados[1]
        # print(f'Função maior funcionando. {maior} {menor}')

        elif dados[1] < menor:
            menor = dados[1]
            # print(f'Função menor funcionando. {menor} {maior}')

    cadastro.append(dados.copy())
    dados.clear()
    resp = ' '

    while resp not in 'SN':
        resp = input('Você quer continuar? [S/N] ').strip().upper()[0]

    if resp == 'N':
        break

print(f'Ao todo você cadastrou {len(cadastro)} pessoas.')
print(f'O maior peso cadastrado foi {maior} de: ', end='')

for (nome, peso) in cadastro:
    if peso == maior:
        print(f'{nome}', end=' ')

print(f'O menor peso cadastrado foi {menor} de: ', end='')

for (nome, peso) in cadastro:
    if peso == menor:
        print(f'{nome}', end=' ')

0

dude , I used dictionary list..

cadastro = []
while True:
    nome = input('Digite o nome: ')
    peso = int(input('Digite o peso: ')) 
    cadastro.append({'nome':nome,'peso':peso})
    resp = input('Você quer continuar? [S/N] ')
    if resp.upper() == 'N':
        break

print(f'In all you have registered {Len(registration)} people.') lista_pesos = [x['peso'] for x in cadastro] list_pesos.Sort() peso_maior = lista_pesos[-1] peso_menor = lista_pesos[0]

maior = [ x for x in cadastro if x['peso']== peso_maior][0] minor = [ x for x in cadastro if x['peso']== peso_menor][0]

print(f'The largest registered weight was {greater["name"]} with {greater["weight"]}' ) print(f'The lowest recorded weight was {lowest["name"]} with {lowest["weight"]}', )

Browser other questions tagged

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