"break" does not finish execution as it should

Asked

Viewed 194 times

-1

Create a program where the user can enter several numerical values and register them in a list. If the number already exists inside, it will not be added. At the end, all unique values typed will be displayed, in ascending order.

And so far so good this 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 answer 'N' the program keeps working without giving the break. However the same code in another colleague’s Pycharm works without any problem.

What can that be? One bug? It is possible to solve it?

  • 2

    ask can only be 'S' or 'N', but you use the condition while ask not in 'SN'. Something wrong is not right.

3 answers

8

No, it’s not a bug in Pycharm, much less it works on your colleague’s computer. It doesn’t work because the code is wrong.

First, indentation. Indentation defines the code blocks in Python and 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 setting of the variable on the first line and this cannot. Both must be on the same level:

lista = []
while True:
    ...

Second, the function of input at all times returns a string, then do 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 row 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 ask is not S or N, do... and soon after you check whether it is S or N. These conditions will never be met once the while ensures that ask is different of S and N. Using the continue or the break here also does not make sense, because they will act on the last loop of repetition, which is precisely the while ask not in 'SN', but that doesn’t make sense.

Fourth, your last condition elif ask != 'SN' is also wrong. If you guaranteed that ask is only the first character informed, it will never have two characters, so equality at all times will be satisfied.


Improvements:

  1. Use set in place of list; it by definition has no duplicate values;
  2. Treat the exception launched by int when the whole conversion fails;
  3. 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))

Staying:

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]

6

Certainly not because Pycharm is just a code editor. And it’s also not in Python, because two things exactly the same can only give the same result, even if it had a bug. bugs are not magicians who appear and disappear. But if it’s not all exactly the same, then it can give a different result, and you can’t blame the IDE for the problem, the problem is what’s different, your code, your configuration. Anyway, millions of people have been using Python for years, what are the chances you’d have to find one bug in a very basic code right at the beginning of your learning? It doesn’t seem more obvious that it’s a problem in your code and that you should start from that premise before thinking about bug of a consecrated tool?

I went to try to compile, it was a mistake, I fixed, I gave another, I fixed and gave another, until I gave up trying.

Anyway I saw some conceptual problems in the code and at least one logic that causes the whole problem. If you create two nested ties and in the innermost one break in it, where do you think he’s going? Towards the end of that loop. I imagine you’re thinking he’s coming out of the two loops, but that’s not the case. In addition, it is creating a third party and repeating the same things it had planned before. Not only that, a condition tests whether it is S or N, then tests them individually and then if it is neither, it makes no 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)

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

0

Actually, Pycharm only runs, through Python, what you did, so the error is in the code.

The first error that occurs is: if the user type correctly 'S' or 'N', he’ll never get into the while ask not in 'SN', yeah, that condition means: as long as "Ask" is not in 'SN'. That is to say, ask will be inside 'SN', Therefore, the condition is not true, and he does not enter the while.

The other mistake is: if ask really aren’t in 'SN', then it will not pass in the first and second conditions within the second while, for:

  • ask will not be equal to 'S'
  • ask will not be equal to 'N'

But, ask will be different from 'SN', then he’ll print the warning, and he’ll start it all over again.

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

However, after this, you should create a way to know if the "internal" response was nay (or 'N'), yeah, the break that you perform within the second while will only make the same stop, but the first while, which is the while True, will continue.

With all that in mind, I think you could do it that 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’ve helped!

Browser other questions tagged

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