Backtracking in a while loop (python 3.x) - python

I'm reasonably new to Python. I wanted to know if I could use an input and ask a question like 'are you sure?', and if the answer is no to go back to the original input. I've got this so far:
variable = input("Make a choice between a, b, c or d. ")
while variable not in ("a","b","c","d"):
variable = input("Make a correct choice. ")
if variable == "a":
do things
if variable == "b":
do other things
etc etc
I want to ask, after they have typed in their choice, are you sure about your choice? If they say yes, that's fine, carry on, but if they say 'no' I want to be able to go to the same input without typing the whole thing out again. Is there any way to do that?

You could embed the bit that you want to repeat in a while True block that you break out of? For example:
while True
answer = input("What is the correct answer, a, b, or c? ")
check = input("Are you sure (y/n)? ")
if check=="y" or check=="Y":
break

Take the code you already have and wrap it in another while loop:
# loop forever until they confirm their choice
while True:
variable = input("Make a choice between a, b, c or d. ")
while variable not in ("a","b","c","d"):
variable = input("Make a correct choice. ")
confirm = input("You entered %s. Is this correct?" % variable)
if confirm == "yes":
break

ok=False
while not OK:
variable = input("Make a choice between a, b, c or d. ")
while variable not in ("a","b","c","d"):
variable = input("Make a correct choice. ")
ishesure=input("You chose {}, Are you sure? (Y or N)".format(variable))
if ishesure=="Y":
ok=True
Should work. You surround everything by a while loop that will loop until the customer enters "Y" to your second question, that is asked once he entered a valid value for variable

Something like this will work (though it's not the cleanest thing right now).
def prompt_for_something():
variable = input("Make a choice between a, b, c or d. ")
while variable not in ("a","b","c","d"):
variable = input("Make a correct choice. ")
confirm = input("Are you sure?")
if confirm == "No": return False
return variable
option = prompt_for_something()
while option == False:
option = prompt_for_something()
if option == "a":
do something

It is not easy to have editable console output. If it is just for you, you can press the 'up' arrow key to go back to your last input, but if you want to embed it into the code it may be easier to use a proper GUI (i.e. tkinter) than what you are doing.

Related

How do I clear a variable that I have referenced outside of my if statement?

while Guessp1 != Player1_secretword:
Guessp1 = input("player 1, guess your secret word: ")
nogp1 += 1
if Guessp1 != Player1_secretword:
hint1 = input("would you like a hint? (Y/N): ")
if hint1 in ["yes", "y", "Y"]:
hintcharecter = Player1_secretword[0]
print("hint: " + hintcharecter)
noghp1 += 1
else:
print("ok continue")
I want to clear the variable hint1 however when i try the "local variable "hint1" referenced outside the assesment" error, how do i fix this?.
I think we need to restructure some things here.
Add x = True statement before the loop. (Or whichever variable you prefer.)
Change the "while" condition to be "while x == True".
Move the "if" condition for hint1 to be a subset of the first if condition, instead of just following it. (In other words, the hint if condition should only appear if the user got the guess wrong in the first place.)
Add an else statement to the Guessp1 if condition. "else: x = False"
This should break the while loop only if the correct word has been guessed. There may be some additional issues to contend with, depending on the rest of your code, but I think this should get you started.
Good luck!

Making a simple menu within a loop to call upon functions, stuck on why it won't work

For a school project me and my group partner made a code, I tested each function in a separate test file to see if they worked and it all looks good, but the menu just isn't working as intended. My brain can't seem to figure out where I went wrong, I would love a second opinion on this.. thank you so much <3 Here is my code!
def mainmenu():
print("Hello! Welcome to The Sprint Project Company! Please choose from 1-5: ")
print("1. Simple IPO Program")
print("2. IFs and Loop sample")
print("3. Strings and dates")
print("4. Data files and Default Values")
print("5. Quit")
while True:
choice = input("Enter choice (1-5): ")
if choice == 1:
ipo()
elif choice == 2:
ifloop()
elif choice == 3:
stringsdates()
elif choice == 4:
datafiles()
else:
break
mainmenu()
Whenever I run this it just automatically ends. I even tested by putting a print section under the else but it just skips straight to ending the code. Thank you so much for looking at my question <3
There are two points on your code.
First, the function "input()" returns a string, hence you are comparing a STRING with an INTEGER, then it evalueates to False.
It is like you are comparing 1 with '1', and they are not the same.
Second, your function mainmenu() must be put inside the loop.
Make this two changes and it will work.
while True:
mainmenu() # Add the function here.
choice = int(input("Enter choice (1-5): ")) # Change here
if choice == 1:

Checking input against a list in python - why does one way work while the other doesn't?

Started learning python a few days ago and was doing a task with simple yes/no inputs and doing different things with the while loop depending no whether the user wants to continue using the program or not.
The whole program is fairly small so hope it's alright to post the entirety of its code here. This is what worked for me:
import random
print("=====================================")
print("I Add Numbers and Tell You the Sum v2")
print("=====================================")
while True:
rand1 = random.randint(1, 100)
rand2 = random.randint(1, 100)
result = rand1 + rand2
print(f"I'm adding {rand1} and {rand2}. If you add them together,the result would be {result}")
print()
again_input = input("Would you like to try again? (Y/N) ")
again = again_input.lower().strip()
validyes = ["yes", "y"]
validno = ["no", "n"]
if again in validyes:
print("Sure thing!")
print()
elif again in validno:
print("Okay. See you!")
break
else:
print("That's not a valid response. The program will now exit.")
break
While the relevant code that didn't work as expected was this, to do with checking the user input against the valid list:
valid = ["yes", "y", "no", "n"]
if valid == "yes" or "y":
print("Sure thing")
elif valid == "no" or "n":
print("Okay bye")
break
else:
print("That's not a valid response. The program will now exit")
break
The former would run just fine, while the latter will print "Sure thing" regardless of what the user inputs. Why is that the case?
On that front, I'm happy to hear any other tips you guys might have with regards to making the rest of the code better. Eager to hear from and take part in this community!
You have to show what all the string what they are comparing to
if again == "yes" or again == "y":
print("Sure thing")
elif again == "no" or again == "n":
print("Okay bye")
break
else:
print("That's not a valid response. The program will now exit")
break
Also a tip is to use "\n" for a new line. The \n will not be shown
Old:
print(f"I'm adding {rand1} and {rand2}. If you add them together,the result would be {result}")
print()
New:
print(f"I'm adding {rand1} and {rand2}. If you add them together,the result would be {result}\n")
Last is that for the lower and strip function u can use it in the same line were u get your input
Old:
again_input = input("Would you like to try again? (Y/N) ")
again = again_input.lower().strip()
New:
again = input("Would you like to try again? (Y/N) ").lower().strip()
In the second case you're using the OR operand wrong and that's why it is always printing Sure thing. Here you can take a look and understand it better.
To make the code better, i would suggest keeping the valid list with all valid inputs, and checking for yes or no using the if again in valid method, but playing with what is and isn't valid inputs.
This is how or works
operation: x or y result: if x is false, then y, else x
Explanation:
valid == "yes" will be false for obvious reason because you are comparing a list to a string. When the first condition is false operator or goes to evaluate next condition which is just "y" and will always be true(you can confirm it using bool("y")) so that's why it's always printing "Sure thing".
You use this:
if valid == "yes" or "y":
print("Sure thing")
elif valid == "no" or "n":
print("Okay bye")
break
So in the first condition you check if (valid == "yes") or ("y"), but not if valid == ("yes" or "y"). Non-empty string is always True, when you use it as bool, so the first condition is always True. If you want to do somwthing like this, you can use tuples (it's like lists, but you cant edit it): if valid in ("yes", "y")
valid is a list, so valid will never equal to "yes", so it just goes to "y", which will always equal true. You need to check if "yes" or "y" is in valid:
if "yes" in valid or "y" in valid:
print("Sure thing")
elif "no" in valid or "n" in valid:
print("Okay bye")
break
Of course, with this code it will always print "Sure thing" because valid includes all the options.

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.
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 :)
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.
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()

Python code error, code not working properly

After 4th line, even if u type something else other than yes, it still prints okay?
x = input("Enter any number of your choice: ")
print("the number you picked is", x)
yes = x
input(" right? : ")
if yes:
print("ok")
else:
print("you liar")
Unless you don't enter anything when you prompt for this:
x = input("Enter any number of your choice: ")
if yes: # it's always going to be true
Also this is not doing anything:
input(" right? : ")
you need to assign it to a variable
I think what you want is this:
sure = input(" right? : ")
if sure == 'yes':
You may want to use isnumeric() in case you want to check for a number.
Some documentation on isnumeric() is located at http://www.tutorialspoint.com/python/string_isnumeric.htm
At the moment, you are basically just checking the existence of the variable yes.
BTW: The output for checking up on the number can be rewritten to a formatted statement as follows:
print("The number you picked is {:d} right?".format(x))
Checking, if the user answers with a "yes", can be done easily as well:
yes = input("The number you picked is {:d} right?".format(x))
if (yes == "yes"):
print("ok")
else:
print("you liar")
In case of python2.x you should use raw_input() instead of input(), which is fine for python3.
You want to check what the user is saying for the "Right?" prompt:
x = input("Enter any number of your choice: ")
print("the number you picked is", x)
yes = input(" right? : ") # capture the user input
if yes == "yes": # check if the user said yes
print("ok")
else:
print("you liar")

Categories

Resources