"break" does not end execution as it should

1
  

Create a program where the user can type multiple numeric values and sign them into a list. If the number already exists inside, it will not be added. At the end, all the unique values entered will appear in ascending order.

And so far so good, that was my solution:

lista= []
     while True:
         ad = (int(input('Digite um valor: ')))
         if ad not in lista:
             lista.append(ad)
             print('Adicionado com sucesso!')
         else:
             print('Valor duplicado. Adição negada.')
         ask = str(input('Deseja continuar?[S/N] ')).strip().upper()[0]
         while ask not in 'SN':
             if ask == 'S':
                 continue
             elif ask == 'N':
                 break
             elif ask != 'SN':
                 print('Resposta inválida, por favor escolha entre [S/N]')
                 while ask not in 'SN':
                    ask = str(input('Deseja continuar?[S/N] ')).strip().upper()[0]
print('-=' * 30)
lista.sort()
print(f'Voce digitou os números: {lista}')

When asked if I want to continue and I say 'N', the program will still work without giving break . However the same code in another colleague's PyCharm works with no problem at all.

What can this be? A bug ? Is it possible to resolve it?

    
asked by anonymous 20.12.2018 / 18:42

3 answers

6

No, it's not bug in PyCharm, much less it works on your colleague's computer. It does not work because the code is wrong.

First, indentation. The indentation defines the blocks of code in Python and it is fundamental that it is correct. Unlike most languages, the code will not work with the wrong indentation. Your first loop is indented relative to the definition of the variable in the first row and this can not. Both should be on the same level:

lista = []
while True:
    ...

Second, the function input always returns a string , so str(input(...)) is redundant and completely unnecessary. You remove the spaces from the read value, convert to uppercase and take the first character:

lista= []
while True:
    ad = (int(input('Digite um valor: ')))
    if ad not in lista:
        lista.append(ad)
        print('Adicionado com sucesso!')
    else:
        print('Valor duplicado. Adição negada.')
    ask = input('Deseja continuar?[S/N] ').strip().upper()[0]

Third, you expect the user to type only S or N, but in the line below you do:

lista= []
while True:
    ad = (int(input('Digite um valor: ')))
    if ad not in lista:
        lista.append(ad)
        print('Adicionado com sucesso!')
    else:
        print('Valor duplicado. Adição negada.')
    ask = input('Deseja continuar?[S/N] ').strip().upper()[0]
    while ask not in 'SN':
        ...

While% wont be S or N, do ... and soon after you check whether it is S or N. These conditions will never be satisfied since ask ensures that while is different from S and N. Using ask or continue here also does not make sense because they will act on the last loop of repetition, which is just break but that does not make sense.

Fourth, your last condition while ask not in 'SN' is also wrong. If you ensure that elif ask != 'SN' is only the first character entered , it will never have two characters, so equality will always be satisfied.

Improvements:

  • Use ask instead of set ; it by definition has no duplicate values;
  • Treat the exception thrown by list when conversion to integer fails;
  • You can stop reading when the user reports something other than a number;
  • For example:

    numeros = set()
    
    while True:
        try:
            numero = int(input('Número? '))
            numeros.add(numero)
        except ValueError:
            break
    
    print('Ordem crescente: ', sorted(numeros))
    

    Getting:

    Número? 5
    Número? 3
    Número? 4
    Número? 8
    Número? 1
    Número? 9
    Número?
    Ordem crescente:  [1, 3, 4, 5, 8, 9]
    
        
    20.12.2018 / 19:13
    5

    Certainly not because PyCharm is just a code editor. And neither is it in Python, because two things exactly the same can only give the same result, even if it has a bug . bugs are not magic that appear and disappear. But if everything is not exactly the same, it can give different result, and you can not blame the IDE for the problem, the problem lies in what is different, that is, its code, its configuration. Anyway, millions of people have used Python for years, what are the chances that you would have to find a bug in a very basic code right at the beginning of your learning? Does not it seem more obvious that it is a problem in your code and should you start from this premise before you think of a bug of a consecrated tool?

    I tried to compile, it was a mistake, I would repair it, I would give it another, I would repair it and give it another, until I gave up trying.

    Anyway I've seen some conceptual issues in the code and at least one of logic that causes the whole problem. If you create two nested loops and the innermost one gives break to it, where do you think it goes? Toward the end of this bond. I suppose you think he's out of two ties, but that's not the case. In addition, he is creating another third and repeating the same things he had already programmed earlier. Not only this, a condition tests whether it is S or N, then tests them individually and then if it is neither, this does not make sense.

    So it's simpler, more organized and works:

    def entrada(lista):
        while True:
            ad = (int(input('Digite um valor: ')))
            if ad not in lista:
                lista.append(ad)
                print('Adicionado com sucesso!')
            else:
                print('Valor duplicado. Adição negada.')
            while True:
                ask = str(input('Deseja continuar?[S/N] ')).strip().upper()[0]
                if ask == 'S':
                    break
                elif ask == 'N':
                    return
    lista = []
    entrada(lista)
    print(lista)
    

    See running on ideone . And no Coding Ground . Also I put GitHub for future reference .

        
    20.12.2018 / 19:10
    0

    In fact, PyCharm only executes, through Python, what you did, so the error is in the code.

    The first error that occurs is: if the user correctly types 'S' or 'N' , he will never enter while ask not in 'SN' , because this condition means: while "ask" is not in 'SN '. That is, ask will be inside 'SN' , so the condition is not true, and it does not enter while .

    The other error is: if ask is not really in 'SN' , then it will not pass in the first and second conditions within the second while , because:

    • ask will not equal 'S'
    • ask will also not equal 'N'

    But, ask will be different from 'SN' , so it will print the warning, and start all over again.

    So, you first have to test whether ask is equal to 'S' , or equal 'N' , before running while . And, if you enter while , you ask the question again, assigning the new answer to ask .

    However, after this, you should create a way to tell if the "internal" response was not (or 'N' ), since the break you execute within the second while will only stop, but the first while , which is while True , will continue.

    Having all this in mind, I think you could do it this way:

    lista= []
    while True:
        ad = (int(input('Digite um valor: ')))
        if ad not in lista:
            lista.append(ad)
            print('Adicionado com sucesso!')
        else:
            print('Valor duplicado. Adição negada.')
        ask = str(input('Deseja continuar?[S/N] ')).strip().upper()[0]
        if ask == 'N':
            break
        resposta = None
        while ask not in 'SN':
            ask = str(input('Deseja continuar?[S/N] ')).strip().upper()[0]
            if ask == 'S':
                break
            elif ask == 'N':
                resposta = ask
                break
        if resposta == 'N':
            break
    print('-=' * 30)
    lista.sort()
    print(f'Voce digitou os números: {lista}')
    

    I hope I have helped!

        
    20.12.2018 / 19:28