Python: Problems when calling outside function - python

I'm a beginner to Python, and am having problems with a function. I am making a program in which I have many parameters for the user to choose from and I need to allow them to confirm or deny their choices. Here is a simplified code section that represents my issue.
my code:
def confirm(function):
while True:
answer = raw_input('Are you sure? ')
if answer == 'yes':
break
elif answer == 'no':
return function() # if the user wants to change their name, recall function
else:
continue # to reprompt user if the answer is not "yes" or "no"
def your_name():
while True:
name = raw_input("What is your name? ")
if not name:
continue # to reprompt user if they do not enter anything
else:
confirm(your_name)
print 'Congratulations! You have a name!'
break
your_name()
When running this program, it will print the congratulatory string the same amount of times that answer received an input.
my output:
What is your name? Bastion
Are you sure? no
What is your name? Artex
Are you sure? no
What is your name? Falcor
Are you sure? yes
Congratulations! You have a name!
Congratulations! You have a name!
Congratulations! You have a name!
My intention is for the congratulatory message to be printed just one time. How can I edit my function(s) in order to achieve this?
What I've tried:
I have attempted all of these, using the exact same input values I used in my output block above.
Within the section of confirm(function) that says:
if answer == 'no':
return function()
I've tried changing it to:
if answer == 'no':
function()
In the output, this will ask for the answer raw_input 3 times, posting the congratulatory message after each input. If I write the code in this way:
if answer == 'no':
print function()
It will print the congratulatory response 3 times and print None on a separate line below for each time. I am looking for an elegant, clean format so this will not do.

So your problem is you are creating a kind of recursive function without meaning to, you don't need to pass the function to be called again as you are already inside the function. I would suggest the following:
def confirm():
while True:
answer = raw_input('Are you sure? ')
if answer == 'yes':
return True
if answer == 'no':
return False
else:
continue # to reprompt user if the answer is not "yes" or "no"
def your_name():
while True:
name = raw_input("What is your name? ")
if not name:
continue # to reprompt user if they do not enter anything
elif confirm():
print 'Congratulations! You have a name!'
break
your_name()

I think the cleanest way is to change your_name to:
def your_name(toplevel=False):
while True:
name = raw_input("What is your name? ")
if not name:
continue # to reprompt user if they do not enter anything
else:
confirm(your_name)
if toplevel: print 'Congratulations! You have a name!'
break
and the very first call from the top level to your_name(True).
There are other ways, but they require global variables (ecch:-) or even dirtier tricks to find out if the function has been called from the top level; telling it explicitly is way cleaner...

Because of the style recursion you're doing (kudos on that) you end up invoking the your_name() function once each time they fill an answer.
I'd try something more like this:
def confirm():
answer = ''
while answer == '':
answer = raw_input('Are you sure? ')
if answer == 'yes':
return True
elif answer == 'no':
return False
else:
answer = ''
def your_name():
name = ''
while name == '':
name = raw_input("What is your name? ")
if confirm():
print 'Congratulations! You have a name!'
else:
your_name()
your_name()

I think you don't have to use all those "recursive" calls, try this:
def your_name():
flag = True
while flag:
name = raw_input("What is your name? ")
if name:
while True:
answer = raw_input('Are you sure? ')
if answer == 'yes':
flag = False
break
elif answer == 'no':
break
print 'Congratulations! You have a name!'
your_name()
Using an inner loop for asking if the user is sure. With the use of a flag to determine whenever or not the main "What is your name? " question cycle is over.

You can just put the print 'Congratulations! You have a name!' inside your confirmation() function instead of your_name() so it will be something like this:
def confirm(function):
while True:
answer = raw_input('Are you sure? ')
if answer == 'yes':
print 'Congratulations! You have a name!'
break
elif answer == 'no':
return function() # if the user wants to change their name, recall function
else:
continue # to reprompt user if the answer is not "yes" or "no"
def your_name():
while True:
name = raw_input("What is your name? ")
if not name:
continue
else:
confirm(your_name)
break
your_name()
BTW, I also modify your conditional syntax in the first function so that the program won't go through two if statements.

This solution is relatively succinct. It loops requesting your name while 'name' is an empty string. When requesting confirmation, it resets name to an empty string and thus continues the loop unless the user confirms 'yes'. It then prints the user's name to confirm its assignment.
def your_name():
name = ''
while name == '':
name = raw_input("What is your name? ")
answer = raw_input('Are you sure (yes or no)? ') if name != '' else 'no'
name = '' if answer != 'yes' else name
print 'Congratulations {0}! You have a name!'.format(name)

Related

How to break a function to a specific spot after a failed test

def joe():
while True:
name = ""
answer = ""
print("What is your name? ")
name = input()
if name != "Joe":
continue
print("What is your password? (it is a fish) ")
answer = input()
if answer == "swordfish":
break
print("nice job, Joe")
joe()
If I pass the frist statement and type in "Joe" i continue with the function, and all is good. but if I fail the second test, I break the function and get retrieved back to the "what is your name?" part of the function. How can I write a test that will upon failiure retreive me back to the "what is your password"? instead of the name test?
or try this:
def joe():
name = ""
answer = ""
print("What is your name? ")
name = input()
if name == "Joe":
print("What is your password? (it is a fish) ")
answer = input()
if answer == "swordfish":
return print("nice job, Joe")
joe()
joe()
Try using the combination of a while True and `return statement my bro!
def joe():
while True:
print("What is your name? ")
name = input()
if name != "Joe":
continue
while True:
print("What is your password? (it is a fish) ")
answer = input()
if answer == "swordfish":
print("nice job, Joe")
return
joe()
Add another while loop for the password part.
def joe():
while True:
print("What is your name? ")
name = input()
if name == "Joe":
break
while True:
print("What is your password? (it is a fish) ")
answer = input()
if answer == "swordfish":
break
print("nice job, Joe")

The != statement in the while loop is returning True even when it shouldn't - Python

In the password function, I am trying to make the user enter a password and if he/she inputs the wrong password, then give them another chance to write the correct password or just simply quit.
The problem which I am facing is if I enter the wrong password, and then if i use TRY AGAIN, then even if I write the correct password(i.e, 1234), it still says INCORRECT PASSWORD!
To check what was wrong, I used print(answer, type(answer)) and print(passwd, type(passwd)) to see if they were actually the exact same or not (which they were btw). I also used print(answer != passwd) to see if this was causing the issue and it was. It is returning True even after both answer and passwd are equal. Please suggest what I should do.
passwd = '1234'
def password():
global passwd
answer = input("ENTER THE PASSWORD:\t")
print(answer, type(answer))
print(passwd, type(passwd))
while answer != passwd:
print(answer != passwd)
print('INCORRECT PASSWORD!')
print("1. TRY AGAIN.\n2. QUIT")
ans = input("Answer(1/2):\t")
while ans not in ['1', '2']:
print("Incorrect input.")
ans = input("Answer(1/2):\t")
if ans == '1':
password()
elif ans == '2':
print("Bye!")
quit()
password()
This does not mean "go back to the start of the function". It means "call the function again, as a completely new action; let it use its own completely separate set of local variables; figure out what is returned; and then continue from this point after it returns".
In other words: it means the exact same thing that it would mean if you called any other function.
When the new function call happens, it prompts for input again and you give it matching input. That means the while loop does not run, and the end of the function is reached - for that call.
Then it returns back to where it was in the old function call (just like it would if any other function had been called), with no effect on the local answer. So now answer != passwd because answer != passwd before, and neither value changed. passwd is global, but answer is local - and the local value is local to this call of the function.
You should try to rethink your logic, draw a flowchart, and re-write it without the recursive call. Make sure you understand how break and continue work, as you may find them useful.
passwd = '1234'
# I added answer = None for the first function call
answer = None
def password():
global passwd
# The global answer ensures I use whatever the latest value of answer is(defined by the return statement at teh end of function)
global answer
answer = input("ENTER THE PASSWORD:\t")
print(answer, type(answer))
print(passwd, type(passwd))
while answer != passwd:
print(answer != passwd)
print('INCORRECT PASSWORD!')
print("1. TRY AGAIN.\n2. QUIT")
ans = input("Answer(1/2):\t")
while ans not in ['1', '2']:
print("Incorrect input.")
ans = input("Answer(1/2):\t")
if ans == '1':
password()
elif ans == '2':
print("Bye!")
quit()
# This would return the answer and change the global variable
return answer
password()
Personnaly speaking, your main problem was the order of using while loops. I have managed to solve your problem with the password function by editing your code and changing the order of while loops and some other stuff:
passwd = '1234'
def password():
global passwd
while True:
answer = input("ENTER THE PASSWORD:\t")
if answer != passwd:
wrongAnswer = input("1. TRY AGAIN.\n2. QUIT\nAnswer(1/2):\t")
while wrongAnswer != "1" and wrongAnswer != "2":
print("Incorrect input.")
wrongAnswer = input("Answer(1/2):\t")
if wrongAnswer == "2":
print("Bye!")
break
else:
print("Password is correct! Goodby")
break
Example output
ENTER THE PASSWORD: 8765
1. TRY AGAIN.
2. QUIT
Answer(1/2): 1
ENTER THE PASSWORD: 8765
1. TRY AGAIN.
2. QUIT
Answer(1/2): 1
ENTER THE PASSWORD: 1234
Password is correct! Goodby
You have to include an else statement or answer == passwd
passwd = '1234'
def password():
global passwd
answer = input("ENTER THE PASSWORD:\t")
print(answer, type(answer))
print(passwd, type(passwd))
while answer != passwd:
print(answer != passwd)
print('INCORRECT PASSWORD!')
print("1. TRY AGAIN.\n2. QUIT")
ans = input("Answer(1/2):\t")
while ans not in ['1', '2']:
print("Incorrect input.")
ans = input("Answer(1/2):\t")
if ans == '1':
password()
elif ans == '2':
print("Bye!")
quit()
else:
print('correct')

Python: How do I make it so that an input has to match the input entered previously

this is my first day of coding in python so I don't know how "clean" my code is. I am trying to make a fun piece of code, that makes you add your name, and correctly re-enter it right after
name = input ("Insert name:")
print ("re-enter your name")
answer = name
if answer == name
print ("excellent")
elif
print ("You have entered the wrong name")
exit()
since you create variable answer = name, the result will always be true because the answer variable and name variable will have the same contents in memory.
Oh yes, I ran your code and there was an error. After the code if some_condition must be added a colon after it in one line, elif is like that, in using elif you must have a conditional after elif and then a colon. If you only have one conditional for the if, then use else instead of elif.
Here's your code after fixing:
name = input("Insert name:")
answer = input("re-enter your name")
if answer == name:
print ("excellent")
else:
print ("You have entered the wrong name")
exit()
CMIWW
You need to take a second input to re-enter your name. answer=name is basically assigning answer name. So you will always end up with answer==name
Also, a colon missing after if.... The elif statement is completely useless. You might want to use else there because you only want answer==name else redirect them to You have entered the wrong name
name = input ("Insert name: ")
answer = input("re-enter your name: ")
if answer == name:
print ("excellent")
else:
print ("You have entered the wrong name")
Output 1:
Insert name: John
re-enter your name: jon
You have entered the wrong name
Output 2:
Insert name: Mike
re-enter your name: Mike
excellent
name = input("Insert your nme : ")
rename_name = input("Re-enter your name : ")
if name == rename_name:
print("excellent")
else:
print("You have entered the wrong name")
It's unclear whether objective is just to verify that second entry is same as first or make sure that they match. If latter then second input must be in loop ('while first answer is not equal to second print warning and ask again, if answers match print Excellent') :
first = input("Enter your name: ")
while first != input("Enter your name again: "):
print("Names entered don't match!")
else:
print('Excellent')
Here is one of the cleanest code you would like😊😊😊 You don't have to exit from condition using any exit function. And in second line, you were just printing "re-enter your name: " not receiving any inputs.
name = input ("Insert name: ")
answer = input("re-enter your name: ")
print ("excellent" if answer == name else "You have entered the wrong name")

I want to have a yes/no loop in my code, but I'm having trouble doing it (python 3.3)

Sorry I'm just a beginner at python so this is probably a very simple question, but I have a code and I want to loop it so after the code asks the user if they want to play again and the user inputs 'yes' to restart the code and 'no' to end the code. If they input anything other than yes or no it should ask tell them to enter yes or no then ask the question again. How would I do this exactly? (I do know about while and for loops but I'm not sure how I would use them in this way)
This is a simple one:
while True:
a = input("Enter yes/no to continue")
if a=="yes":
gameplay()
continue
elif a=="no":
break
else:
print("Enter either yes/no")
Where gameplay function contains the code to be executed
I would do it the following way:
while True:
# your code
cont = raw_input("Another one? yes/no > ")
while cont.lower() not in ("yes","no"):
cont = raw_input("Another one? yes/no > ")
if cont == "no":
break
If you use Python3 change raw_input to input.
My approach to this:
# Sets to simplify if/else in determining correct answers.
yesChoice = ['yes', 'y']
noChoice = ['no', 'n']
# Prompt the user with a message and get their input.
# Convert their input to lowercase.
input = raw_input("Would you like to play again? (y/N) ").lower()
# Check if our answer is in one of two sets.
if input in yesChoice:
# call method
elif input in noChoice:
# exit game
exit 0
else:
print "Invalid input.\nExiting."
exit 1
I think this is what you are looking for
def playGame():
# your code to play
if __name__ == '__main__':
play_again = 'start_string'
while not play_again in ['yes', 'no']:
play_again = raw_input('Play Again? (type yes or no) ')
if play_again == 'yes':
playGame()
I tried this short boolean script that will maintain the loop until the if statement is satisfied:
something = False
while not something:
inout = raw_input('type "Hello" to break the loop: ')
if inout == 'Hello':
something = True
my approach is to just have a while loop
y_or_n = input("Do you want to validate another email or not? y/n: ")
while y_or_n == 'y' or email_again == 'yes':
name = input("Enter another name ")#adapt this to your needs
name = name.lower()#adapt this to your needs
#your code etc
y_or_n = input("Do you want to validate another email or not? y/n: ")

Python While Statements

I'm a bit confused on the logic of doing this.
I want the user to be able to input the number of items they have, and then ask them at the end if they are done. Right now I'm asking after every single item, and I don't like it.
How should I modify this code to get what I want?
Input:
if next1 == "2":
next2=input("How many would you like to add? ")
val = int(next2)
print("")
count = 0
while count < int(next2):
count = count + 1
next3=input(str(count) + ". Input: ")
print("")
check=input("Are you sure? (Y/N) ")
while check not in ("YyYesNnNo"):
check=input("Are you sure? (Y/N) ")
if check in ("YyYes"):
add(next3)
home()
elif check in ("NnNo"):
sort(numbers)
home()
Function:
def add(next2):
numbers.append(next2)
sort(numbers)
home()
Okay, well generally you might do something like this
def confirm_with_user():
user_data = ""
while user_data not in "YyYesNnNo":
user_data = input("Are you sure? (Y/N) ")
return user_data.lower() in "yes":
Then at the point in your code when you want to confirm with your user you just do
if confirm_with_user():
#proceed...
else:
#They don't want to proceed

Categories

Resources