简体   繁体   中英

Python: while (True != True) loop

I started learning to code this week so I'm playing around with small programs that I'm creating to try to get a better understanding of how it work.

One of the programs I made is a Pig Latin translator that loops until the user exits. The program works but the logic isn't making any sense to me.

pyg = "ay" #Pig Latin words end with ay.

def translate(): #Creating a function.
    original = input("Enter a word: ").lower() #Ask for input then convert to lower.
    if len(original) > 0 and original.isalpha() : #isalpha() verifies only abc's and more than one letter.
        first = original[0] #Assigns the first letter of the string to first.
        latin = original[1:] + first + pyg #Adds original starting at 2nd letter with first and pyg.
        print(latin)
    else:
        print("You did not enter a valid word, please try again.")
        translate() #If you did not enter valid word, then call function again until you do.

translate() #Don't forget to actually call the function after you define it.

#Set run to False.
#Can be set to True if while (run != True) is set to while (run == True).
run = False

#Defining cont(). Ask for imput and error handling.
def cont():
    loop = input("Would you like to convert another word? (y/n): ").lower()
    if loop == "y" :
        run = True
    elif loop == "n" :
        run = False
        print("Thank you for using this program, have a nice day!")
        exit()
    else :
        print("You did not enter a valid response, please try again.")
        cont()

cont()

#Infinite loop as long as run is not equal to True.
while (run != True) :
    translate()
    cont()

My question is, why does this program work? I set run to False and I set the loop to run as long as run != True. No problem there, however when I defined cont(), I set run to take on the value True if the user inputs "y". True != True should be False (if I understand correctly) and the loop should end, but instead it is working as I wanted it to.

Is this a coding mistake that I've made or am I just thinking about this the wrong way? Thank you in advance.

Edit: Thank you very much to everyone that answered. I hadn't learned about local and global variables yet.

The run inside the cont function is a local variable. Changing its value has no effect on the global variable that the while loop refers to.

To expand on what others have already stated, run on these lines

if loop == "y" :
    run = True
elif loop == "n" :
    run = False

are not referring to the same run defined by

#Can be set to True if while (run != True) is set to while (run == True).
run = False

run in the cont function is a local variable to your function, not the globaly defined run .

There are a couple (at least) ways to fix this. The preferred (imo) way to do it is have cont return a new value to be assigned to run . That would look like

#Defining cont(). Ask for imput and error handling.
def cont(_run):
    loop = input("Would you like to convert another word? (y/n): ").lower()
    if loop == "y" :
        return _run
    elif loop == "n" :
        return not _run
    else :
        print("You did not enter a valid response, please try again.")
        return cont(_run)

...

#Infinite loop as long as run is not equal to True.
while (run != True) :
    translate()
    run = cont(run)

The other (less preferred) way would be to use the global run variable inside of your cont function. This is achieved using the global keyword.

That would look like this:

#Defining cont(). Ask for imput and error handling.
def cont():
    global run
    loop = input("Would you like to convert another word? (y/n): ").lower()
    if loop == "y" :
        run = True
    elif loop == "n" :
        run = False
        print("Thank you for using this program, have a nice day!")
        exit()
    else :
        print("You did not enter a valid response, please try again.")
        cont()

** Couple side notes
In my first example I return _run when the value is y and not _run when the value is n . This allows you to change you initial run value to be True, and change the while condition without having to change the cont function itself.

You don't need to actually change the run value at all if you use the global and the user enters n since you exit before the function returns.

You might be better off changing your if conditional checks to

if loop in ("yes", "y"):
if loop in ("no", "n"):

since lots of people don't read full instructions :)

I think this is probably because of the scope of your run variable; because you're not returning run from your cont function. I believe what your != True check sees is always going to be False outside of that function, though obviously you can successfully end the program within the function.

The problem is that the run variable defined in cont() is not the same as the run variable defined in the global scope. (If you aren't sure what I mean by that you might want to look at https://docs.python.org/3.4/tutorial/classes.html#python-scopes-and-namespaces . Perhaps a better approach for your code would be to have cont() return True or False . It is also more intuitive and readable to use True for when you want to continue. Here's how I would rewrite it.

pyg = "ay" #Pig Latin words end with ay.

def translate(): #Creating a function.
    original = input("Enter a word: ").lower() #Ask for input then convert to lower.
    if len(original) > 0 and original.isalpha() : #isalpha() verifies only abc's and more than one letter.
        first = original[0] #Assigns the first letter of the string to first.
        latin = original[1:] + first + pyg #Adds original starting at 2nd letter with first and pyg.
        print(latin)
    else:
        print("You did not enter a valid word, please try again.")
        translate() #If you did not enter valid word, then call function again until you do.

#Defining cont(). Ask for imput and error handling.
def cont():
    while True:
        loop = input("Would you like to convert another word? (y/n): ").lower()
        if loop == "y":
            return True
        elif loop == "n": 
            print("Thank you for using this program, have a nice day!")
            return False
        else :
            print("You did not enter a valid response, please try again.")

translate()
while cont():
    translate()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM