Asking for a specific input without using break - python

I'm creating a dice poker game and am trying to ask if the user would like to play before continuing with the game and then asking if the player would like to play again after each game.
I am unsure how to allow for incorrect inputs other than Y and N in order to tell the user to enter a correct answer and then loop the input until either is input. I am not allowed to use a break.
play = True
s = input("Would you like to play dice poker [y|n]? ")
if s == "y":
play = True
elif s == "n":
play = False
else:
print("Please enter y or n")
while play:
From here onward is the code for my game
This below section is repeated at the end of each game
again=str(input('Play again [y|n]? '))
if again == "n":
play = False
if again == "y":
play = True
else:
print('Please enter y or n')

wrap your input in a function that evaluates the user input, if it's not valid, call it recursively as necessary. Example:
def keep_playing():
valid = 'ny'
again=str(input('Play again [y|n]? '))
a = again.lower().strip() # allow for upper-case input or even whole words like 'Yes' or 'no'
a = a[0] if a else ''
if a and a in valid:
# take advantage of the truthiness of the index:
# 0 is Falsy, 1 is Truthy
return valid.index(a)
# Otherwise, inform the player of their mistake
print(f'{again} is not a valid response. Please enter either [y|n].')
# Prompt again, recursively
return keep_playing()
while keep_playing():
print('\tstill playing...')

Related

How to break multiple loops in an if-statement within an if-statement in Python 3

How do I make a loop in an if-statement within an if-statement? I'm busy with How to learn Python 3 the hard way, and so far I know I can do the following:
while True:
print("choose 1st branch")
choice = input()
if choice == '1':
print('1, now choose second branch')
while True:
choice = input("")
if choice == "2":
print("2")
while True:
choice = input("")
if choice == "3":
print('3')#
else: #needs to ask for input for choice 3 again
print("try again")
else:print("try again")#needs to ask for input for choice 2 again
ive edited a simpler code example of what im trying to accomplish
Instead of creating a loop everywhere you want to check if the user input is a valid choice, you can extract that "checking if user input is within a valid choices" into a function. Said function will be something like
def get_user_choice(prompt, choices=None):
while True:
choice = input(prompt)
if choices is None:
# Return the entered choice without checking if it is
# valid or not.
return choice
if choice in choices:
return choice
print("unknown choice, try again")
With this new function, we check the validity of the choices first, then after we received the correct input, we then process with the logic for each of the choices.
occu = "ranger"
prompt = "-->"
def get_user_choice(prompt, choices=None):
while True:
choice = input(prompt)
if choices is None:
# Return the entered choice without checking if it is
# valid or not.
return choice
if choice in choices:
return choice
print("unknown choice, try again")
def room1():
print("you walk into an bare room")
door = False
gemstone = False
hole = False
monster = False
rat = False
trap = False
occu = "ranger"
while True:
print("you see a door infront of you")
print("do you go left, right or forward?")
choice = get_user_choice(prompt, ("left", "right", "forward"))
if choice == "left" and hole == False:
print("\nDo you \ndodge \nor \nattack?")
choice = get_user_choice(prompt, ("dodge", "attack"))
if choice == "dodge" and occu == "ranger":
trap = True
rat = True
print("\nhole \nroom")
choice = get_user_choice(prompt, ("hole", "room"))
if choice == "hole" and rat == True:
print("you walk up to the hole, you see a faint glitter")
print("do you reach your hand in?")
print("\nyes \nno")
choice = get_user_choice(prompt, ("yes", "no"))
if choice == "yes":
print("you reach into the whole and pull out a gemstone")
print("you put the gemstone in your inventory")
print("and go back to the room\n")
hole = True
gemstone = True
choice = True
elif choice == "no":
print(" you go back to the centre of the room")
Notice that other input also get modified to use this function to check if the choice user selected is valid or not.
The problem is that you are reusing the variable choice, and assigning it to be a boolean value and later on be the input. Try using another variable as well for either the boolean or the input, i.e. proceed.
proceed = False # CREATE VARIABLE PROCEED
while proceed == False: # LOOP WHILE PROCEED IS FALSE
print("do you reach your hand in?")
print("\nyes \nno")
choice = input(prompt)
if choice == "yes":
print("you reach into the whole and pull out a gemstone")
print("you put the gemstone in your inventory")
print("and go back to the room\n")
hole = True
gemstone = True
proceed = True # CHANGE PROCEED, NOT CHOICE
elif choice == "no":
print("You go back to the center of the room")
# Perhaps assign proceed to be True here as well?
else:
print("unknown choice, try again")
occu = 'ranger'
prompt = "-->"
def room1():
print("you walk into an bare room"
door = False
gemstone = False
hole = False
monster = False
rat = False
trap = False
occu = 'ranger'
while True:
print("you see a door infront of you")
print("do you go left, right or foward?")
if input(prompt) == 'left' and hole == False:
print('\nDo you \ndodge \nor \nattack?')
if input(prompt) == 'dodge' and occu == 'ranger':
trap = True
rat = True
print("\nhole \nroom")
if input(prompt) == 'hole' and rat == True:
print("you walk up to the hole, you see a faint glitter")
while True:
print("do you reach your hand in?")
print("\nyes \nno")
choice = input(prompt)
if choice not in ['yes', 'no']:
print("unknown choice, try again")
continue # <-- Starts loop over.
elif choice == "yes":
print("you reach into the whole and pull out a gemstone")
print("you put the gemstone in your inventory")
print("and go back to the room\n")
hole = True
gemstone = True
else:
print(" you go back to the centre of the room")
break # <-- Breaks out of loop.

How to execute this code without letting it become a never-ending loop?

I just tried to write the code below that takes only a whole number between 1 to 10 and prints some statements of the input value does not fulfill the required conditions.
gamelist = list(range(0,11))
def display_game(gamelist):
print('Here is your list of options:')
print(gamelist)
def user_choice():
choice = 'x'
acceptable_range = range(0,11)
within_range = False
while choice.isdigit() == False or within_range == False:
choice = input('Please enter a digit from the above options:')
if not choice.isdigit():
print("Oops! That's not a digit. Please try again.")
if choice.isdigit():
if int(choice) in acceptable_range:
within_range == True
else:
within_range == False
print('The entered number is out of acceptable range!')
return int(choice)
display_game(gamelist)
user_choice()
And after running this code, even after entering the correct value it keeps on asking for the input.I am not understanding what's gone wrong exactly and where.
Arguments are generally passed to give the function access to the data is has no access to but is required to work upon the task it is assigned to do.
A good example would be if you call a function from inside other function and want to use data of local variable of your former function into latter, you would have to pass it as argument/arguments .
This is a very vague example just to give you some basic hint , basically there are many factors you would consider before deciding whether or not you need arguments in your function!!
== is for comparison, = is for assigment:
gamelist = list(range(0, 11))
def display_game(gamelist):
print("Here is your list of options:")
print(gamelist)
def user_choice():
choice = "x"
acceptable_range = range(0, 11)
within_range = False
while choice.isdigit() == False or within_range == False:
choice = input("Please enter a digit from the above options:")
if not choice.isdigit():
print("Oops! That's not a digit. Please try again.")
if choice.isdigit():
if int(choice) in acceptable_range:
# within_range == True # this doesn't assign, but compares
within_range = True # this assigns
else:
# within_range == False # And the same here
within_range = False
print("The entered number is out of acceptable range!")
return int(choice)
display_game(gamelist)
user_choice()
This prevents the endless loop. Comparing to booleans is not really necessary. Keeping the same idea this version is a bit more readable:
def user_choice():
choice = "x"
acceptable_range = range(0, 11)
while not choice.isdigit() or not within_range:
choice = input("Please enter a digit from the above options:")
if not choice.isdigit():
print("Oops! That's not a digit. Please try again.")
else:
within_range = int(choice) in acceptable_range
if not within_range:
print("The entered number is out of acceptable range!")
return int(choice)
Or even a version where choice is never a string. But maybe you haven't gotten to Exceptions yet :-). (this will change the message for '-1', though.)
def user_choice():
choice = None
acceptable_range = range(0, 11)
while choice not in acceptable_range:
try:
choice = int(input("Please enter a digit from the above options:"))
except ValueError:
print("Oops! That's not a digit. Please try again.")
if choice not in acceptable_range:
print("The entered number is out of acceptable range!")
return choice

'while' loop not behaving as expected

Background:
I have made a program that takes a text input, applies encryption (a simple cipher) and saves the output to a list - if desired. Messages can also be decrypted.
The program is navigated through an options menu:
1. Encrypt a message
2. View encrypted messages
3. Decrypt a message
To allow all sections of the program to access the same list (variable) of saved messages, I have written it within a class. Within the class exist def's that call on this list.
Only the 'encrypt a message' bit has been written so far.
Problem:
The user decision flow is made with two Y/N choices.
However, the choices do not work - even if the user types in 'N' - my program thinks they have typed 'Y' in both cases.
def encrypt():
def save_cip():#This function allows the user to save the ciphered message to the ciphered_messages if they choose
choosing = True
while choosing:
save_choice = input("Would you like to save your Ciphered message? (Y/N)\n")
if save_choice == "Y" or "y":
print("You chose yes")
cct.ciphered_messages.append(' '.join(["Message", str(len(cct.ciphered_messages)), ":", cipher]))
choosing = False
elif save_choice == "N" or "n":
print("You chose no")
choosing = False
continue
else:
print("That was not a valid entry, please enter Y or N only")
continue
I think the problem lay within the scope, and that somehow the same variable is not being referenced when setting and reading Y or N. I have been going up and down the same code for about 3 hours and still nothing, declaring all variables in many different places with no luck, so any advice greatly appreciated.
Full executable code:
class cct:
print("Welcome to the CaeserCipher tool v1.0")
menu_state = "main" #This is used to record what state the program is in
unciphered_messages = [] #Decrypted messages are saved here
ciphered_messages = [] #Encrypted messages are saved here
def menu(): #This is the main menu interface
while cct.menu_state == "main": #This while
cct.menu_state = input("What would you like to do? \n 1: Encrypt a Message \n 2: View Encrypted Messages \n 3: Decrypt a message\n")
if cct.menu_state == "1":
cct.encrypt()
elif cct.menu_state == "2":
cct.view()
elif cct.menu_state == "3":
cct.decrypt()
elif cct.menu_state == "main":
print("\n\nWelcome back to the menu!\n\n")
else:
print("You did not enter a valid choice. Please enter a number between 1 and 3.\n")
cct.menu_state = "make_choice"
continue
def encrypt():
def save_cip():#This function allows the user to save the ciphered message to the ciphered_messages if they choose
choosing = True
while choosing:
save_choice = input("Would you like to save your Ciphered message? (Y/N)\n")
if save_choice == "Y" or "y":
print("You chose yes")
cct.ciphered_messages.append(' '.join(["Message", str(len(cct.ciphered_messages)), ":", cipher]))
choosing = False
elif save_choice == "N" or "n":
print("You chose no")
choosing = False
continue
else:
print("That was not a valid entry, please enter Y or N only")
continue
#This while loop continually takes messages, gives the option of saving, and asks if you want to cipher another
while cct.menu_state == "1":
text = input("Enter your message: ") #Enter the message you wish to cipher
cipher = '' #Create a string for the cipher
for char in text: #This for sub-loop will increment each character by 1. e.g. A -> B, T -> U, Z -> A
if not char.isalpha():
continue
char = char.upper()
code = ord(char) + 1
if code > ord('Z'):
code = ord('A')
cipher += chr(code)
print(' '.join(["Your ciphered message is:", cipher]))
save_cip()
print(cct.ciphered_messages)
#This sub-while loop is reponsible for checking if you want to cipher another message
#and making sure the user has made a valid choice
choosing_another = True
while choosing_another == True:
choice_variable = input(' '.join(["You have", str(len(cct.ciphered_messages)), "saved messages \n", "Would you like to Cipher another? (Y/N)\n"]))
if choice_variable == "Y" or "y":
print("You chose yes")
choosing_another = False
elif choice_variable == "N" or "n":
print("You chose no")
cct.menu_state = "main"
choosing_another = False
else:
choice_variable = input("That was not a valid entry, please enter Y or N only: \n")
continue
return
def view():
#TO BE CODED
return
def decrypt():
#TO BE CODED
return
cct.menu()
This is always true:
if save_choice == "Y" or "y":
bacause its interpreted as :
if (condition) or (condition):
the 1st condition is (save_choice == "Y")
the 2nd condition is just ( "y" ) which python interprets as 'True'
So the whole condition is always True.
U probably mean:
if save_choice == "Y" or save_choice == "y":
Or better :
if save_choice.lower() == "y":
Not a python programmer, but i don't think python allows a "implied" subject for the or operator
--> IF save_choice == "Y" OR save_choice == "y" :

Can I create a function to break a while loops in python?

I am writing a program with python to simulate flipping a coin or rolling dice. The coin and dice use while loops to give the user the option to roll or flip again, an example is:
def d4():
d4ing = True
while d4ing:
print(random.randint(1,4))
done = input("""would you like to roll again? Type y to roll again,
type d to roll a dice, or type anything else to exit:""")
if done == "y":
continue
elif done == "d":
break
else:
print("thank you for using my coin/dice simulator")
sys.exit("goodbye")
The problem I am having is that I would like to take every line starting from done and make it into it's own function that I can just insert into every function rather than typing the whole thing out again and again, like this.
def d4ing():
d4ing = True
while d4ing:
print(random.randint(1,4))
rerolling()
def rerolling():
done = input("""would you like to roll again? Type y to roll again, type d to roll a dice, or type anything else to exit:""")
if done == "y":
continue
elif done == "d":
break else:
print("thank you for using my coin/dice simulator")
sys.exit("goodbye")
The error message I am getting:
SyntaxError: 'continue' not properly in loop
A break or a continue must be in a loop in its current scope. You cannot break a loop in the above scope from inside a function. Here is a general example of what raises the SyntaxError: 'break' outside loop error. The same holds for continue.
def break_up():
break # This is a syntax error
while True:
break_up()
Although, this is not a problem, since you can make the function return a value and conditionally break in the upper scope.
In your specific example though, you can also return whether or not you want to reroll by assigning the return value to d4ing.
def d4():
d4ing = True
while d4ing:
print(random.randint(1,4))
d4ing = rerolling()
def rerolling():
done = input("Would you like to roll again?")
if done == "y":
return True
elif done == "d":
return False
else:
print("thank you for using my coin/dice simulator")
sys.exit("goodbye")

Looping error (homework)

I'm having an issue with (apparently) a loop not working as intended. Assuming that everything else works as intended, my second while loop is (according to the grader) calling raw_input more times than necessary.
The code plays a word game. You can play a hand, replay a hand, or exit. Second loop determines if you play the hand or the computer.
All the called functions work correctly, but the loop, as I said is calling raw_input too many times.
Sorry if there are lots of other issues, I'm relatively new to coding.
userInput = ''
playInput = ''
hasPlayed = False
# while still playing, e exits
while userInput != 'e':
userInput = raw_input("Enter n to deal a new hand, r to replay the last hand, or e to end game: ").lower()
if userInput not in 'nre':
print("Invalid command.")
elif userInput == 'r' and hasPlayed == False:
print("You have not played a hand yet. Please play a new hand first!")
print
else:
while True:
#
print
playInput = raw_input("Enter u to have yourself play, c to have the computer play: ").lower()
if playInput == 'u':
print
hand = dealHand(HAND_SIZE)
playHand(hand, wordList, HAND_SIZE)
hasPlayed = True
elif playInput == 'c':
print
hand = dealHand(HAND_SIZE)
compPlayHand(hand, wordList, HAND_SIZE)
hasPlayed = True
else:
print("Invalid command.")
print
Your loop is working perfectly fine; it is looping forever just like you told it to:
while True:
What is missing then, is a way to exit that loop. Either test for a different condition:
playing = True
while playing:
# game
#
# stop playing with
playing = False
or explicitly break out of the loop with the break keyword:
while True:
# game
#
# stop playing with
break

Categories