Breaking out of loop - Python - python

I've tried googling and searching on SO, but I cant figure out why my break on the second to last line is not heading out of the while loop. Better yet, I cant figure out why the loop is not continuing either. My intention is to give the user the possibiltiy to head to the main menu after the last choice (basically the while loop for menuchoice (which is one loop above what I have pasted here).
Any suggestions? Thank you in advance. It feels like I'm missing something essential.
#this is going to show how many exercise weapons you need for next magic level
if menuchoice == "4":
#these functions returns the amount of magic wands/rods that is needed to be spent for next magic level
print("Select vocation")
print("Press P for Royal Paladin")
#ask user to input vocation:
while True:
vocationchoice = input()
if vocationchoice == "P" or vocationchoice == "p":
#ask user to input magic level for paladin
num1 = float (input("Enter your magic level: "))
#ask for own training dummy
print("Do you have your own exercise dummy? Type Y for yes and N for no.")
while True:
trainingdummy = input()
if trainingdummy == "y" or trainingdummy == "Y":
#list the different exercise weapons
print("Select exercise weapon:")
print("1. Training rod")
#loop, where we ask user to input what exercise weapon they want to calculate
while True:
while True:
weaponchoice = input()
if weaponchoice == "q":
sys.exit() #quit the program
if weaponchoice == "1" or weaponchoice == "2" or weaponchoice == "3" or weaponchoice == "f":
break #break out of the input loop
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")
if trainingdummy == "n" or trainingdummy == "N":
#list the different exercise weapons
print("Select exercise weapon:")
print("1. Training rod")
#loop where ask user to input what exercise weapon they want to calculate
while True:
weaponchoice = input()
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpal(num1))) + ".")
elif weaponchoice == "f":
break
print("\nGo to main menu? Press F.")

This will help you I think. Break only breaks from current loop. If you want to go up on levels you need to break from each loop separately.
A suggestion is to turn a loop into a function and use return which will effectively exit any loop. A little bit of code refactor will be needed though.
If not the case can you maybe provide some more info and possibly the full code (there is a higher loop that we dont see here?)

First, you should print things in the input() command as it will be cleared in intend: input("Text to display").
Second, if you want to exit to the main menu, you need to break every nested loop. Here you only break the most inner loop.
As in Python there is no goto instruction nor named loops, you can use a flag. A flag is set to true when the used presses 'F' and this flag is then used at the beginning of every outer nested loop to break them. It can look like this:
while True: # This is your menu loop
menuFlag = False # Declare and set the flag to False here
menu = input("Choose the menu: ")
# ...
while True: # Choose character loop
if menuFlag: break # Do not forget to break all outer loops
character = input("Choose a character: ")
# ...
while True: # Any other loop (choose weapon, ...)
weapon = input("Choose weapon: ")
# Here you want to return to the menu if f is pressed
# Set the flag to True in this condition
if weapon == "f":
menuFlag = True
break
In your game this ressembles to:
goToMainMenu = False
while True:
if goToMainMenu: break
vocationchoice = input("Select vocation.\nPress P for Royal Paladin: ")
if vocationchoice == "P" or vocationchoice == "p":
#ask user to input magic level for paladin
num1 = float (input("Enter your magic level: "))
#ask for own training dummy
while True:
if goToMainMenu: break
trainingdummy = input("Do you have your own exercise dummy?\nType Y for yes and N for no: ")
if trainingdummy == "y" or trainingdummy == "Y":
#loop, where we ask user to input what exercise weapon they want to calculate
while True:
while True:
weaponchoice = input("Select exercise weapon:\n1. Training rod: ")
if weaponchoice == "q":
sys.exit() #quit the program
if weaponchoice == "1" or weaponchoice == "2" or weaponchoice == "3" or weaponchoice == "f":
break #break out of the input loop
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")
if trainingdummy == "n" or trainingdummy == "N":
#list the different exercise weapon
#loop where ask user to input what exercise weapon they want to calculate
while True:
weaponchoice = input("Select exercise weapon (press F for main menu):\n1. Training rod: ")
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")
elif weaponchoice == "f" or weaponchoice == "F":
goToMainMenu = True
break

Add a break for weaponchoice == "1" to get out of the loop.

Related

Python - Never Ending While Loops caused by a Definition

I'm currently making a main menu for my scoring system that will take the user to different parts of code by using while loops as a simple form of validation but it causes a never ending while loops because some of my definition also have while loops as well. Here's what I've done
def menu():
print("""\n Main Menu \n
1) Join the Event as a Team
2) Join the Event by Yourself
3) Score Screen""")
menuchoice_option = ["1","2","3"]
menuchoice = ""
while menuchoice not in menuchoice_option:
menuchoice = input("Please enter your choice here:")
if menuchoice == "1":
team_menu()
menuchoice = True
elif menuchoice == "2":
individual()
menuchoice = True
elif menuchoice == "3":
#scorescreen()
menuchoice = True
else:
menuchoice = False
print("Please enter a value between 1-3")
menuchoice = input("Please enter your choice here:")
Here's my other functions that the menu def causes to do an infinite whille loops
def team_menu():
global teamS
team_player = ""
while team_player != "":
team_player = input("What is your name:")
print("""\n Available Teams \n
1) Team Ahab
2) Team Ishmael
\n 3) Go back to Main Menu\n""")
team_choice = ""
team_choice_option = ["1","2","3"] # all valid choices on team menu
while team_choice not in team_choice_option:
team_choice = input("Enter your choice here:")
if team_choice == "1":
teamS["Team 1"]["Team Ahab"].append(team_player)
print(teamS["Team 1"])
print("Thank You for Joining Team Ahab")
team_choice = True
elif team_choice == "2":
teamS["Team "+ team_choice]["Teeam Ishmael"].append(team_player)
print(teamS["Team 2"])
print("\nThank You for Joining Team Miller\n")
team_choice = False
elif team_choice == "3":
menu()
team_choice = True
else:
print("Enter a value between 1-3")
team_choice = False
My ideal output would be for it stop causing infinite while loops from different defs in my code. I'm a beginner so please execuse me
Old:
Well... True will never be one of your menuchoice_option, they are 1,2,3.
Make menuchoice="1" (instead of True), for example, if the user select "1".
Edit:
Try to simplify your code: ideally, data should be atomic, and code should work around the data to extract and act as best/smart as possible. And use a better indentation (helps seeing the blocks).
Something like the following would be much, much better to maintain/develop:
def menu():
options = {
1: "Join the Event as a Team",
2: "Join the Event by Yourself",
3: "Score Screen"
}
funcs = {
1: team_menu,
2: individual,
3: scorescreen
}
print("\n Main Menu \n")
for k,v in options.items():
print(f"{k}) {v}")
choice = None
while choice not in options:
# notice that if a value invalid for "int()" casting,
# the code will blow. Wrap this with try/except to avoid it.
choice = int(input("Please enter your choice here:"))
# By now, you know a valid option was chosen.
# Let's use to select the corresponding function from "funcs" dict
funcs[choice]()
I did not test it. But looks like working.
How about using some recursion for the menu, I share my idea:
options = """
Main Menu
1) Join the Event as a Team
2) Join the Event by Yourself
3) Score Screen
4) Exit
>>> """
def menu(menuchoice):
if menuchoice == "1":
team_menu()
elif menuchoice == "2":
individual()
elif menuchoice == "3":
#scorescreen()
pass
elif menuchoice == "4":
exit()
else:
print("Please enter a value between 1-5")
decision = str(input(">>> "))
menu(decision)
if __name__ == "__main__":
decision = str(input(options))
menu(decision)
I hope I give you an idea.

When I have a function with the continue statement in it it errors out even when its only used within a while loop

all_options = ["rock", "paper", "scissors"]
outcomes = {"rockP": ["paper", "computer"], "rockS": ["scissor", "player"], "paperR": ["rock", "player"], "paperS": ["scissor", "computer"], "scissorsR": ["rock", "computer"], "scissorsP": ["paper", "player"]}
input_loop = True
def play_again():
again = input("Would you like to play again?(Yes or No): ")
if again.lower() == "yes":
continue
elif again.lower() == "no":
exit()
else:
print("Invalid input. Exiting")
exit()
while True:
while input_loop == True:
choice = input("Please input Rock, Paper, or Scissors: ")
if choice.lower() in all_options: #Making sure that the input is lowercase so it doesn't error
choice = choice.lower()
input_loop = False
break
else:
print("\n That is not a valid input \n")
computer_choice = random.choice(all_options)
if choice == computer_choice:
print("Draw!")
play_again()
computer_choice = computer_choice.upper()
current_outcome = choice + computer_choice
current_outcome_list = outcomes.get(current_outcome)
current_outcome_list.insert(0, choice)
player, winner, outcome = current_outcome_list
winning_message = print(f"{winner} has won, \nplayer chose: {player}, \ncomputer chose: {computer}.")
print(winning_message)
play_again()
How can I use that function with the continue statement? Or any other method to avoid me repeating that chunk of code. I am new to python and I need to add enough words to allow me to post this. Thank you for everybody who is going to help me :)
Error message:
C:\desktop 2\files\Python projects\rock paper scissiors\Method2>gamelooped.py
File "C:\desktop 2\files\Python projects\rock paper scissiors\Method2\gamelooped.py", line 9
continue
^
SyntaxError: 'continue' not properly in loop
It sounds like you may not be familiar with the purpose of the continue keyword. It can only be used in loops. When you reach a continue statement in a for or while loop, none of the remaining statements in the loop are executed, and the loop continues from the beginning of the next iteration (if there is another iteration to be had).
You can't continue in a function unless you're in a loop that's in a function. What is it that you intended for that continue statement to do? It might be that you just need to return.

Unable to get desired outcome of a while True loop

Until this semester I didn't even know a while True was a thing. I have to write a while True loop to loop until the user enters 'n' to break. My problem is restarting the loop if the user enters anything other than 'y' or 'n'. Currently, I can loop with any character besides 'n'. I need a way to catch the if say 'q' was entered, "please enter 'y' or 'n'" and prompt the user again. I have considered doing another while loop within the loop but I feel like there is a more optimal way to achieve this.
def main():
userinput = "y"
display_title()
while True:
userinput.lower() == "y"
choice = ""
display_menu()
choice = str(input("Select a conversion (a/b): "))
while choice == "a" or "b":
if choice == "a":
print()
feet = int(input("Enter feet: "))
meters = conversions.to_meters(feet)
print(str(round(meters, 2)) + " meters")
print()
break
elif choice == "b":
print()
meters = int(input("Enter Meters: "))
feet = conversions.to_feet(meters)
print(str(round(feet, 2)) + " feet")
print()
break
elif choice != "a" or "b":
print("Please enter a valid option a or b")
choice = str(input("Select a conversion (a/b): "))
userinput = input("Would you like to perform another conversion? (y/n): ")
if userinput == "n":
print()
print("Thanks, Bye!")
break
You don't need another while loop. You could just need to put the input check to the beginning of the loop and add a check for any other character than 'y' and 'n', e.g.:
def main():
userinput = "y"
display_title()
while True:
if userinput == "n":
print()
print("Thanks, Bye!")
break
elif userinput != "y":
userinput = input("Please select yes (y) or no (n)").lower()
continue
### If you get this far, userinput must equal 'y'
choice = ""
display_menu()
choice = str(input("Select a conversion (a/b): "))
while choice == "a" or "b":
if choice == "a":
print()
feet = int(input("Enter feet: "))
meters = conversions.to_meters(feet)
print(str(round(meters, 2)) + " meters")
print()
break
elif choice == "b":
print()
meters = int(input("Enter Meters: "))
feet = conversions.to_feet(meters)
print(str(round(feet, 2)) + " feet")
print()
break
elif choice != "a" or "b":
print("Please enter a valid option a or b")
choice = str(input("Select a conversion (a/b): "))
userinput = input("Would you like to perform another conversion? (y/n): ").lower()
continue
Be aware, the way you implemented the inner loop asking for the conversion type doesn't allow you to exit the xcript if you suddenly decide abort the procedure e.g. a Keyboard interrupt.
[Edit]
I've not looked at your inner loop. As someone else has suggested,
while choice == "a" or "b"
will always evaluate to True. Why? beacuse internally python will split this expression:
(choice == "a") or "b"
It doesn't matter if choice == "a", as "b" is a non-empty string and thus evaluates to True.
If you were to rewrite yout inner loop as follws:
while choice: # Will evaluate to True as long as choice isn't an empty string.
if choice == "a":
print()
feet = int(input("Enter feet: "))
meters = conversions.to_meters(feet)
print(str(round(meters, 2)) + " meters")
print()
break
elif choice == "b":
print()
meters = int(input("Enter Meters: "))
feet = conversions.to_feet(meters)
print(str(round(feet, 2)) + " feet")
print()
break
else:
print("Please enter a valid option a or b")
choice = input("Select a conversion (a/b): ")
you'll be able to give the user an option to exit the inner loop by inputing nothing and you'll remove an uneccessary double-check if the choice equals a or b.
Tip: If you want to check if one variable matches one of some different options in a while statement, you could use the following:
while var in [opt1, opt2 ...]:
...

'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" :

how to use an if else statement in another while loop

I am new to coding. I want to try writing a simple rock paper scissors game. But I can't figure out how to end the game.
In the end of this program if the user input is wrong I want to go to the end variable again. I tried with the commented lines but its not working.
player1 = input("What is player 1's name ? ")
player2 = input("What is player 2's name ? ")
player1 = player1.title()
player2 = player2.title()
while True:
print(player1 + " What do you choose ? rock / paper / scissors : ")
a = input()
print(player2 + " What do you choose ? rock / paper / scissors : ")
b = input()
if a == "rock" and b == "scissors" :
print(player1, "won !!!")
elif a == "scissors" and b == "rock":
print(player2, "won !!!")
elif a == "paper" and b == "rock":
print(player1, "won !!!")
elif a == "rock" and b == "paper":
print(player2, "won !!!")
elif a == "scissors" and b == "paper":
print(player1, "won !!!")
elif a == "paper" and b == "scissors":
print(player2, "won !!!")
elif a == b:
print("Its a tie :-(")
elif a or b != "rock" or "paper" or "scissors":
print("Wrong input, Try again")
end = input("Do you want to play again ? yes/no ") == "yes"
if input == "yes":
continue
else:
print('''
GAME OVER''')
break
# elif input != "yes" or "no":
# print("Wrong input, Try again. yes or no ?")
I expect it to end game if the input is "no" and restart the game if input is "yes" if the input is not correct I want the prompt to appear again.
Your code has a few issues which need some addressing, and a few places where it can be streamlined. I have made a few changes to your program as well as added a few comments explaining the changes.
player1 = input("What is player 1's name ? ").title() #This uses chaining to streamline code
player2 = input("What is player 2's name ? ").title() #Same as above
while True:
a = input(player1 + " What do you choose ? rock / paper / scissors : ") #no need to use a separate print statement
b = input(player2 + " What do you choose ? rock / paper / scissors : ")
valid_entries = ["rock", "paper", "scissors"] #To check for valid inputs
if (a not in valid_entries) or (b not in valid_entries):
print("Wrong input, try again")
continue
a_number = valid_entries.index(a) #Converting it to numbers for easier comparison
b_number = valid_entries.index(b)
if(a_number == b_number):
print("Its a tie :-(")
else:
a_wins = ((a_number > b_number or (b_number == 2 and a_number == 0)) and not (a_number == 2 and b_number == 0)) #uses some number comparisons to see who wins instead of multiple if/elif checks
if(a_wins):
print(player1, "won !!!")
else:
print(player2, "won !!!")
end = input("Do you want to play again ? yes/no ")
while (end !="yes") and (end != "no"):
print("invalid input, try again")
end = input("Do you want to play again ? yes/no ")
if end == "yes":
continue
else:
print("GAME OVER")
break
These changes also make the check by using another while loop to see if the input to restart the game was valid or not
*Note that I have not tested these changes and some edits may need to be be made
Just check the value of end
if end is True:
continue
else:
break
Since, you have set the value of end as a boolean by comparing the input() to "yes", it will say whether the user wants to end the game?
Also, you are not initializing the input variable, and the last elif condition will always be true as mentioned in the comment.
Well you can simplify your code using a list and then simplify your if tests. You can check the order of the options and based on it make a decision. You can also make the tests standard to minimize the number of if statements. This my suggestion to improve your code. I hope it helps:
# get playe names
player1 = input("What is player 1's name ? ")
player2 = input("What is player 2's name ? ")
player1 = player1.title()
player2 = player2.title()
# init vars
options = ["rock", "paper", "scissors"]
players = [player1, player2]
# start game
while True:
a = input(player1 + " What do you choose ? rock / paper / scissors : ")
b = input(player2 + " What do you choose ? rock / paper / scissors : ")
# check if inputs are correct
while (a not in options or b not in options):
print("Wrong input, Try again")
a = input(player1 + " What do you choose ? rock / paper / scissors : ")
b = input(player2 + " What do you choose ? rock / paper / scissors : ")
# check who won
if abs(options.index(a) - options.index(b)) == 1:
print(players[1*int(options.index(a) > options.index(b))], "won !!!")
elif abs(options.index(b) - options.index(a)) > 1:
print(players[1*int(options.index(a) > options.index(b))], "won !!!")
elif a == b:
print("Its a tie :-(")
# continue or drop game
end = input("Do you want to play again ? yes/no ")
if end == "yes":
continue
else:
print('''
GAME OVER''')
break

Categories