Python - While Loops Not Appearing in Console When the code is run - python

I'm currently trying to make a scoring system where a user can enter an event as a team and I used while loops and defs to make this possible but I'm having trouble using them.
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 "+ 2]["Team Miller"].append(team_player)
print(teamS["Team 2"])
print("\nThank You for Joining Team Miller\n")
team_choice = True
elif team_choice == "3":
menu()
team_choice = True
else:
print("Enter a value between 1-3")
team_choice = False
When I try to run this code it imidiently asks me for what to team to join even though it didn't even ask of the name of the user before. How do I fix this? My ideal output would be to ask for the name of the user first then let them pick what team they want to join

The loops within the function seem unnecessary since you're only prompting for one player.
from typing import Dict, List, NamedTuple
class Team(NamedTuple):
name: str
players: List[str]
def team_menu(team_dict: Dict[str, Team]) -> None:
player = input("What is your name: ")
print(
"""
Available Teams
1) Team Ahab
2) Team Ishmael
3) Go back to Main Menu
"""
)
choice = ""
while choice not in ["1", "2", "3"]:
choice = input("Enter your choice here:")
if choice == "3":
return # back to main menu
team_dict[choice].players.append(player)
print(f"Thank you for joining {team_dict[choice].name}")
team_dict = {
"1": Team("Team Ahab", []),
"2": Team("Team Ishmael", []),
}
team_menu(team_dict)
# menu()

You need to change 7th line:
while team_player == "":
You are using complex two-state branching based on team_player and team_choice values, it could be facilitated with one current state of team menu aka state machine:
from collections import namedtuple
def team_menu():
# Code smells, it could be passed here by param, i.e. team_menu(teamS)
global teamS
states = namedtuple("States", ("CHOOSE_PLAYER", "CHOOSE_TEAM", "END"))
# Starts from player.
state = states.CHOOSE_PLAYER
while state != states.END:
if state == states.CHOOSE_PLAYER:
team_player = input("What is your name:")
# If player name selected then continue with team.
if team_player:
state = states.CHOOSE_TEAM
elif state == states.CHOOSE_TEAM:
print(
"""
Available Teams
1) Team Ahab
2) Team Ishmael
3) Go back to Main Menu
"""
)
team_choice = input("Enter your choice here:")
# all valid choices on team menu
team_choice_option = ["1", "2", "3"]
# If team selected, add this player and continue with another player.
if team_choice in team_choice_option:
state = states.CHOOSE_PLAYER
if team_choice == "1":
teamS["Team 1"]["Team Ahab"].append(team_player)
print(teamS["Team 1"])
print("Thank You for Joining Team Ahab")
elif team_choice == "2":
teamS["Team 2"]["Team Miller"].append(team_player)
print(teamS["Team 2"])
print("Thank You for Joining Team Miller")
elif team_choice == "3":
# You don't need to call menu() but if you do, then
# be prepared to get sometimes "RecursionError: maximum
# recursion depth exceeded".
state = states.END
else:
print("Enter a value between 1-3")
# There is the end of team_menu() it could return `teamS` here
# to main `menu()` to avoid using global.
return None

Related

I cant pick a choice after looping

def print_menu():
print('1. American')
print('2. Asian')
print('3. Indian')
print('4. Mexican')
print('5. French')
print('6. Italian')
print('7. Seafood')
print('8. Pizza')
print_menu()
menu = input('\nChoose where you want to eat from-->')
if menu == "1":
def american_menu():
print('1. Dempsey Burger Pub')
print('2. Redrock Canyon Grill-Wichita')
print("3. Cheddar's Scratch Kitchen")
print("4. Neighbors| Restaurant & Bar")
print("5. The Kitchen")
print("6. Firebirds Wood Fired Grill")
print("7. Chicken and Pickle")
american_menu()
american = input("\nChoose which American Restaurant--> ")
if american == "1":
print("\nCall Dempsey Burger Pub")
while True:
go_back = input("Will you like to try another menu option?: ")
if go_back == "Yes":
print_menu()
else:
print("We'll continue with your current choice")
break
so i tried looping it so it goes back to choose again from the Cuisines and moving on to where you want to eat but so far, it just asks the go_back, after i say yes...it keeps repeating the go_back again
any help will be appreciated. Thanks. i want it to loop back to the choices, pick the choice and sub-choice i selected rather than it just picking the choice and not do anything. Thanks again
NB:this is an assignment and i am stuck plus i had a list of the choices but couldnt post it due to the site.
Write a while loop for print_menu and change continue with break
def print_menu():
while True:
#Use 2 while loops if you want. But the loop you are using is not needed
while True:
go_back = input("Will you like to try another menu option?: ")
if go_back == "Yes":
print_menu()
break
else:
print("We'll continue with your current choice")
break
Second Option:
def print_menu():
while True:
#Just use "while" here instead of the second one
go_back = input("Will you like to try another menu option?: ")
if go_back == "Yes":
print_menu()
else:
print("We'll continue with your current choice")
You don't need to use a while True loop at all. It might cause problems with infinite looping. You can avoid it by calling a new function check_if_wants_to_order_again after a user has chosen his menu in print_menu().
def print_menu():
print('1. American')
print('2. Asian')
print('3. Indian')
print('4. Mexican')
print('5. French')
print('6. Italian')
print('7. Seafood')
print('8. Pizza')
menu = input('\nChoose where you want to eat from-->')
if menu == "1":
american_menu()
check_if_wants_to_order_again()
def american_menu():
print('1. Dempsey Burger Pub')
print('2. Redrock Canyon Grill-Wichita')
print("3. Cheddar's Scratch Kitchen")
print("4. Neighbors| Restaurant & Bar")
print("5. The Kitchen")
print("6. Firebirds Wood Fired Grill")
print("7. Chicken and Pickle")
american = input("\nChoose which American Restaurant--> ")
if american == "1":
print("\nCall Dempsey Burger Pub")
def check_if_wants_to_order_again():
go_back = input("Will you like to try another menu option? Enter \"Yes\" or \"No\":")
if go_back == "Yes":
print_menu()
else:
print("We'll continue with your current choice")
print_menu()
When you continue your loop, you're calling print_menu() again, but you aren't doing any of the other things that need to follow print_menu() in order to prompt the user to make another choice.
Give this a shot:
# Define the menus as dictionaries.
# The key is the number that the user will pick,
# the value is the selected item.
# Main menu -- pick a cuisine.
main_menu = {
"1": "American",
"2": "Asian",
"3": "Indian",
"4": "Mexican",
"5": "French",
"6": "Italian",
"7": "Seafood",
"8": "Pizza",
}
# American restaurant menu.
american_menu = {
"1": "Dempsey Burger Pub",
"2": "Redrock Canyon Grill-Wichita",
"3": "Cheddar's Scratch Kitchen",
"4": "Neighbors| Restaurant & Bar",
"5": "The Kitchen",
"6": "Firebirds Wood Fired Grill",
"7": "Chicken and Pickle",
}
# This dict maps each cuisine name to the appropriate submenu.
cuisine_menus = {
"American": american_menu,
# "Asian": asian_menu,
# "French": french_menu,
# ...
}
# This dict maps each restaurant name to its contact info.
contact_info = {
"Dempsey Burger Pub": (
"(316) 425-3831",
"https://www.dempseysburgerpub.com/"
),
"Redrock Canyon Grill-Wichita": (
"(316) 636-1844",
"https://www.redrockcanyongrill.com/"
),
# ...
}
def print_menu(menu):
"""Print a menu, e.g. '1. American'..."""
for k, v in menu.items():
print(f"{k}. {v}")
def contact_restaurant(restaurant):
"""Contact a restaurant. Raises KeyError if we don't have contact info."""
phone, website = contact_info[restaurant]
print(restaurant)
print(f"Phone: {phone}")
print(f"Website: {website}")
# maybe do something with website to open a browser? idk
# Interactive loop. Go through the menus in turn,
# and repeat when done or when they enter something invalid.
# Break the loop once they finish picking a restaurant.
while True:
# Main menu (pick a cuisine)
print_menu(main_menu)
pick = input('\nChoose where you want to eat from-->')
# Error checking for invalid picks.
if pick not in main_menu:
print("Please select one of the listed options.")
continue
cuisine = main_menu[pick]
if cuisine not in cuisine_menus:
# This happens if they picked something that was in main_menu
# but not in cuisine_menus yet because we haven't written that part.
print("Oops! Haven't implemented that one yet.")
print(f"Try {', '.join(cuisine_menus)}")
continue
# Now we have a valid main menu pick that we can continue with.
cuisine_menu = cuisine_menus[cuisine]
# Print the menu and ask them to pick an item from that.
print_menu(cuisine_menu)
pick = input(f"\nChoose which {cuisine} Restaurant--> ")
if pick not in cuisine_menu:
print("Sorry, not an option. Let's start over.")
continue
restaurant = cuisine_menu[pick]
if restaurant not in contact_info:
print(f"Oops, we don't have contact info for {restaurant}.")
print("Let's start over...")
continue
print(f"\nCall {restaurant}")
# Prompt them to start over. If they don't, break the loop.
pick = input("Will you like to try another menu option?: ")
if pick != "Yes":
print("We'll continue with your current choice")
break
# Now the user has picked a restaurant to contact,
# so go ahead and contact them.
contact_restaurant(restaurant)
Note that all of the interaction happens inside the while True loop. Any time there's a continue within that loop, it goes back to the print_menu(main_menu) at the start, and then continues from there.

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.

Python - Never Ending Multiple While Loops Interferring with Other Definitions

I'm currently making a scoring system where a user can join the event as a team or by themselves and in order to do this I was using while loops as a form of simple validation. I used while loop to prevent user entering the event without their name. The problem I am having is that I have different definitions if they want to join the event as a team or by themselves and the while loops inside this defintions keeps interferring with each other and by interfering I mean that even after I asked the user for their name the other defintion comes up and asks for the user for their name again
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
\n3) 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:")
teamS["Crew "+team_choice]["Team "+team_choice]
print(teamS["Crew "+team_choice])
print("Thank you for Joining Team "+ team_choice)
Here's my second def that keeps interfering its while loops with the first one
def individual():
global solo_player
solo_name=""
while solo_name == "":
solo_name = input("What is your name:")
print(""" \nIndividual Menu and Available Spots\n
1) Player 1
2) Player 2""")
solo_menu_options = ["1","2"]
while solo_menu not in solo_menu_options:
solo_menu = input("Please enter your choice here:")
solo_player["Contestant "+solo_menu]["Player "+solo_menu].append(solo_name)
print(solo_player["Contestant "+solo_menu])
print("Thank you for taking the spot of Player "+solo_menu)
My ideal output would be that the definition would just stop as soon I entered all the necessary user inputs

Breaking out of loop - 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.

Allowing users to create multiple list in Python

I want to user to input information and print out the total list. However, when the user input another list it only prints out the first list. How can I make the program print the users total input. Here's my code.
listing = []
class Car:
def __init__(self, ownerName=None, model=None, make=None, price=None):
self.ownerName = ownerName
self.model = model
self.make = make
self.price = price
def input(self):
print "Please update car info \n"
while True:
i = 0
listing.append(Car(raw_input("Owner Name"), raw_input("Model?"), raw_input("Make?"), raw_input("Price?")))
print "Updated"
print listing[i].ownerName, listing[i].model, listing[i].make, listing[i].price
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() == "y":
i += 1
continue
else:
break
# search a car and print its information. Exit when user input is 'exit'
def menu():
x = Car()
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) search a car and print info\n" \
"\"exit\" Exit")
if choice == "1":
x.input()
elif choice == "2":
print "Price"
elif choice == "3":
print "Search and Print info"
menu()
#mhawke's answer should fix your problem. However, I do not like the idea of creating objects of a class from one of its functions. Check the edited code below.
listing = []
class Car:
def __init__(self, ownerName=None, model=None, make=None, price=None):
self.ownerName = ownerName
self.model = model
self.make = make
self.price = price
def input_car():
print "Please update car info \n"
i = 0
while True:
listing.append(Car(raw_input("Owner Name"), raw_input("Model?"), raw_input("Make?"), raw_input("Price?")))
print "Updated"
print listing[i].ownerName, listing[i].model, listing[i].make, listing[i].price
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() == "y":
i += 1
continue
else:
break
# search a car and print its information. Exit when user input is 'exit'
def menu():
#x = Car()
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) search a car and print info\n" \
"\"exit\" Exit")
if choice == "1":
input_car()
elif choice == "2":
print "Price"
elif choice == "3":
print "Search and Print info"
menu()
I cleaned up the code a little bit. I should work now. Option 3 gives you a complete listing of all cars so far, so youhave an example to build on.
listing = []
class Car:
def __init__(self, ownerName=None, model=None, make=None, price=None):
self.ownerName = ownerName
self.model = model
self.make = make
self.price = price
#to have a useful method for our example I overwrite the __str__ method from object
def __str__(self):
return ",".join([self.ownerName, self.model, self.make, self.price])
#input does not handle aspects of car, therefore it should be not a method of car
def input():
print "Please update car info \n"
while True:
# there is no need for 'i' so I removed it
car = Car(raw_input("Owner Name"),
raw_input("Model?"),
raw_input("Make?"),
raw_input("Price?"))
listing.append(car)
print "Updated"
print car #possible since __str__ is overwritten
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() == "n":
break
def menu():
keep_running = True
#added a while loop so the user stays in the program until he types 'exit'
#changed option '3' to have a working example to build on
while keep_running:
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) list all cars\n" \
"\"exit\" Exit")
if choice == "1":
input()
elif choice == "2":
print "Price"
elif choice == "3":
print "\n".join(map(str, listing))
elif choice == "exit":
keep_running = False
menu()
That's because you reset i on each iteration of your while loop.
Move the line:
i = 0
to the line before the while True:
That should fix the immediate problem, however, your code uses an unusual design. You should not create a Car object in order to create further instances of Cars which are then inserted into a global list.
At a minimum you could make input() a static method and have it return a list of Car instances to the caller. Then you can do away with the global listing variable. Also, you don't actually need to keep a counter in i you can just use -1 as the subscript to access the last item in the list:
#staticmethod
def input(listing=None):
if listing is None:
listing = []
print "Please update car info \n"
while True:
listing.append(Car(raw_input("Owner Name"), raw_input("Model?"), raw_input("Make?"), raw_input("Price?")))
print "Updated"
print('{0.ownerName} {0.model} {0.make} {0.price}'.format(listing[-1]))
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() != "y":
break
return listing
Using a static method is good here because input() is related to Car objects so it makes sense to package that function with the class.
Now you can call input() without creating an instance of a Car. In your menu() function remove the x = Car() and change x.input() to listing = Car.input(). Or, if you want to append to an existing "listing" list, call Car.input(listing) which will append new input to listing. You can then print the returned list to see all user input:
def menu():
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) search a car and print info\n" \
"\"exit\" Exit")
if choice == "1":
listing = Car.input()
# print out all user entered cars
for car in listing:
print('{0.ownerName} {0.model} {0.make} {0.price}'.format(car))
elif choice == "2":
print "Price"
elif choice == "3":
print "Search and Print info"

Categories