2

I'm attempting to create a small test script that appends something to a note. Contained below is the main function that I will execute in the script. The problem seems to be that I can't get the else block to run when the while block evaluates to false (that is to say, when it evaluates to anything that isn't one of those four options), the while block just continues in an infinite loop. I've also attempted to insert a break into the while loop but this terminates the script after the while loop has executed.

How do I move from the while to the else block when it evaluates to false? And why doesn't the current way I do things work as I would like it to? Thanks.

def start():
    q01 = input("What is the subject of your note?\n")
    q02 = input("Are you certain that the subject of your note is " + q01 + "?\n")
    while q02 == 'No' or 'no' or 'NO' or 'n':
       q01 = input("So, what is the subject of your note?\n")
       q02 = input("Are you certain now that the subject of your note is " + q01 + "?\n")
    else:
       q03 = Enter("Enter the content of your note")
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
seeker
  • 530
  • 1
  • 4
  • 14
  • 1
    Your use of `while`/`else` should work once the `while` condition is fixed according to the accepted answer. – mkrieger1 Jan 12 '17 at 12:27

4 Answers4

4

Your culprit is the while loop condition:

while q02 == 'No' or 'no' or 'NO' or 'n':

This is equivalent to:

while (q02 == 'No') or 'no' or 'NO' or 'n':

As 'no', 'NO' and 'n' are all non-empty strings they evaluate to True and so your condition evaluates to:

while (q02 == 'No') or True or True or True:

which is clearly always True.

To fix this you need to adjust the condition to:

while q02 == 'No' or q02 == 'no' or q02 == 'NO' or q02 == 'n':

Although to be more pythonic you could instead make this:

while q02 in ['No','no','NO','n']:
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
2

The problem is that the guard condition on the while block is always True!

>>> q02 = 'y'
>>> q02 == 'No' or 'no'
'no'

The or operator is interesting. It evaluates it's left operand and if it is "truthy" then the left operand is the result of the operation; otherwise, it evaluates it's right operand. In your case, the left operand is a boolean value (the result of q02 == 'No') and the right operand is a non-empty string. The non-empty string is "truthy" so that is the result.

IOW, q02 == 'No' or 'no' or 'NO' or 'n' evaluates to True if and only if q02 is 'No'. Otherwise it evaluates to the string 'no' which is "truthy" as far as the while loop is concerned.

>>> q02 = 'y'
>>> q02 == 'No' or 'no' or 'NO' or 'n'
'no'
>>> bool(q02 == 'No' or 'no' or 'NO' or 'n')
True
D.Shawley
  • 58,213
  • 10
  • 98
  • 113
1

Change this statement

while q02 == 'No' or 'no' or 'NO' or 'n': 

to

while q02 == 'No' or q02 == 'no' or q02 == 'NO' or q02 == 'n':

One more elegant way of doing it:

def startMe():
    q01 = input("What is the subject of your note?\n")
    q02 = input("Are you certain that the subject of your note is " + q01 + "?\n")
    negList = ['No', 'no', 'NO', 'nO', 'n', 'N']  # <<< Easily modifiable list.

    while any(q02 in s for s in negList):  
       q01 = input("So, what is the subject of your note?\n")
       q02 = input("Are you certain that the subject of your note is " + q01 + "?\n")
    break:
       q03 = input("Enter the content of your note")
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • Could you provide an explanation of why my method does not work? – seeker Jan 12 '17 at 11:32
  • `else` without `if` is destined to fail. – Saurav Sahu Jan 12 '17 at 11:34
  • Could you test this code as I still seem to be stuck in a while loop when I call the function – seeker Jan 12 '17 at 11:37
  • Your script misses an essential component of mine. I want the `q01` and `q02` input variables to loop until I've decided that yes, I am certain that the subject of the note is `[x]`. Your script only runs that `if` block once. This is why I used the `while` loop and not the `if` statement. Thank you for your help however, the negList is a nice addition. – seeker Jan 12 '17 at 12:21
  • 1
    -1. (1) `else` **can** be [combined with `while`](http://stackoverflow.com/questions/3295938/else-clause-on-python-while-statement). (2) `while q02 == 'No' or 'no' …` is **not wrong syntax**, it just doesn't do what the asker expected. – mkrieger1 Jan 12 '17 at 12:24
  • Thanks for pointing. But I still don't understand when to use `while q02 == 'No' or 'no'`. – Saurav Sahu Jan 12 '17 at 12:29
  • 1
    It makes not much sense to use it, but it's not illegal. – mkrieger1 Jan 12 '17 at 12:29
0

Your logic and code is correct except 1 syntax. Use while q02 == 'No' or q02 == 'no' or q02 == 'NO' or q02 == 'n': insted of while q02 == 'No' or 'no' or 'NO' or 'n':

You can try:

def start():
    q01 = input("What is the subject of your note?\n")
    q02 = input("Are you certain that the subject of your note is " + q01 + "?\n")
    while q02 == 'No' or q02 == 'no' or q02 == 'NO' or q02 == 'n':
       q01 = input("So, what is the subject of your note?\n")
       q02 = input("Are you certain now that the subject of your note is " + q01 + "?\n")
    else:
       q03 = input("Enter the content of your note")
start() 
Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
  • Thank you, this works but why is this the case? I did not receive any syntax errors when I did it my way, so why does this method result in activating the else block? – seeker Jan 12 '17 at 12:11