Im trying to create a menu. The idea is to make the script loop back to the main menu when the number two is selected. It loops back but when i select number 1 it just keeps looping. How do i fix this.
import os
import sys
def mainmenu():
print """
this is a test menu
"""
mainmenu()
choice = raw_input("DMF>>")
if choice == '1':
def men1():
print """
this is the second menu
"""
men1()
def back():
men1_actions['mainmenu']()
men1_actions = {
'mainmenu': mainmenu,
'2': back,
}
while True:
choice2 = raw_input("DMF>>")
if choice2 == '2':
back()
I'm not sure with what you are pertaining to exactly but you can first define the functions and then just call on one raw_input to indicate whether the input is 1 or 2.
def mainmenu():
print """this is a test menu"""
def men1():
print """this is the second menu"""
while True:
choice = raw_input("DMF>>")
if choice == '1':
mainmenu()
elif choice == '2':
men1()
else:
print """Please choose between 1 or 2"""
Related
I'm quite new to Python and I am trying to make a little adventure game, just to develop my skills. So, for my game, I want there to be a few options, and the player will pick one and it will return a different result. However, the options will not always be the same, so I decided to make a function, so the options and results could differ. Here is the code for my function:
def action(act1, act2, act3, act4):
loop = True
while loop:
print(menu)
player_action = input("Where would you like to go? ")
if player_action == '1':
act1
return
elif player_action == '2':
act2
return
elif player_action == '3':
act3
return
elif player_action == '4':
act4
return
else:
print("Please type \'1\', \'2\', \'3\', or \'4\'")
The parameters are functions for what I want to print out.
My problem is, when I call this function and run the code, Python executes each function in every if and elif statement. For example, when I call this:
def home_act1():
print("Welcome to the wilderness!")
def home_act2():
print("Welcome to the town!")
def home_act3():
print("Welcome to the store!")
def home_act4():
print("You left the adventure.")
exit()
action(home_act1(), home_act2(), home_act3(), home_act4())
I run the program and it does this:
Welcome to the wilderness!
Welcome to the town!
Welcome to the store!
You left the adventure.
Process finished with exit code 0
It seems to just be running all four of my parameters, it worked before I made it a function but something isn't working right.
Thanks to any help!
In this line:
action(home_act1(), home_act2(), home_act3(), home_act4())
you are actually calling each function and passing the result (None in each case, since that is the default.
Try passing just the functions (home_act instead of home_act()), then in the loop body actually call act().
The reason you have all 4 outputs and then the code exiting is because you call all four home_act functions immediately by doing action(home_act1(), home_act2(), home_act3(), home_act4()), which executes one after another and exits the program due to the exit() in home_act4().
Another thing that is problematic is that you return after each action within the while-loop, which means the code would have stopped once the user has done one single action.
Fixing these problems results in the following code:
def action():
loop = True
while loop:
#print(menu)
player_action = input("Where would you like to go? ")
if player_action == '1':
home_act1() # call the respective action function here
elif player_action == '2':
home_act2()
elif player_action == '3':
home_act3()
elif player_action == '4':
home_act4()
else:
print("Please type \'1\', \'2\', \'3\', or \'4\'")
def home_act1():
print("Welcome to the wilderness!")
def home_act2():
print("Welcome to the town!")
def home_act3():
print("Welcome to the store!")
def home_act4():
print("You left the adventure.")
exit()
action()
Good luck with further coding :)
def home_act1():
print("Welcome to the wilderness!")
def home_act2():
print("Welcome to the town!")
def home_act3():
print("Welcome to the store!")
def home_act4():
print("You left the adventure.")
exit()
def action():
loop = True
while loop:
# print(menu)
player_action = input("Where would you like to go? ")
if player_action == '1':
return home_act1() #or you can remove the return and carry on in the function
elif player_action == '2':
return home_act2()
elif player_action == '3':
return home_act3()
elif player_action == '4':
return home_act4()
else:
print("Please type \'1\', \'2\', \'3\', or \'4\'")
action()
You can return a function call:
def functionToCall():
print('Ok function called')
def function():
return functionToCall()
function()
I am new to python and learning quickly. Thank you all for the help.
I am attempting to create a text menu that will always run in the background of a storytelling text rpg. I have searched and cannot find an explanation of how to create an "always on" menu or how one would work.
I would like the player to be able to hit "m" at any time in the game and have the menu prompt show up.
So far, I have created a "userinput" function as well as a "menu" function that will be deployed each time the game prompts the user/player for input.
def menu():
print('Press "1" for map >>> "2" for stats >>> "3" for exit')
choice = input()
if choice == '1':
print('map needs to be made and shown')
elif choice == '2':
print('stats need to be made and assinged to choice 2 in def menu')
elif choice == '3':
print('You are exiting the menu. Press "M" at any time to return to the menu')
return
else:
print('I did not recognize your command')
menu()
def userinput():
print('Press 1 to attack an enemy >>> 2 to search a room >>> 3 to exit game')
print('Press "M" for menu at any time')
inputvalue = input()
if inputvalue == 'm':
menu()
elif inputvalue == '1':
print('attack function here')
elif inputvalue == '2':
print('search function here')
elif inputvalue == '3':
exit
else:
userinput()
This does not appear to be an ideal solution because the user cannot choose to view a map or exit the game at any time they want.
Is there a way to have a menu always running in the background?
I thought of using a while loop that would never close and all of the game would be held within that while loop but that doesn't seem economical by any means.
Any thoughts or help would be appreciated.
I took a stab at it. This is perhaps not the best structure for doing what you're looking for but I don't want my reply to get too complicated.
The "standard" approach for anything with a UI is to separate the model, the view and the control. Check out MVC architecture online. While it adds complexity at the start it makes life much simpler in the long run for anything with a non trivial UI.
Other points of note are:
you're not stripping whitespace from your input (potentially problematic "3 " won't do what you want)
you're input is case sensitive (you ask for "M" but check for "m") .. maybe use choice = choice.strip.lower()??
there's a difference between the way raw_input and input work between Python 2 and Python 3 which means your code doesn't work in python 2. What's the difference between raw_input() and input() in python3.x? I've changed my example to use raw_input. You may want to use this work around http://code.activestate.com/recipes/577836-raw_input-for-all-versions-of-python/ near the top of your code for portability.
Some code
# flag we set when we're done
finished = False
def finish():
# ask the user for confirmation?
global finished
finished = True
return
def handle_menu_input(choice):
handled = True
if choice == '1':
print('map needs to be made and shown')
elif choice == '2':
print('stats need to be made and assinged to choice 2 in def menu')
else:
handled = False
return handled
def menu():
finished_menu = False
while not finished_menu:
print('Press "1" for map >>> "2" for stats >>> "3" for exit')
choice = raw_input() # NOTE: changes behaviour in Python 3!
if handle_menu_input(choice):
# done
pass
elif choice == '3':
print('You are exiting the menu. Press "M" at any time to return to the menu')
finished_menu = True
else:
print('I did not recognize your command')
menu()
return
def userinput():
print('Press 1 to attack an enemy >>> 2 to search a room >>> 3 to exit game')
print('Press "M" for menu at any time')
choice = raw_input() # NOTE: changes behaviour in Python 3!
if choice == 'm':
menu()
elif choice == '1':
print('attack function here')
elif choice == '2':
print('search function here')
elif choice == '3':
finish()
# elif handle_menu_input(choice):
# # delegate menu functions?? ..
# # do this if you want to see maps anytime without going through the menu?
# # otherwise comment this elif block out.
# # (Problem is 1, 2 etc are overloaded)
# pass
else:
print('I did not recognize your command')
return
def main():
# main loop
while not finished:
userinput()
return
if __name__ == "__main__":
main()
A beginner's problem, here it goes:
I'm writing a program which keeps records of a game of darts. The user types in the players and their respective scores. It's possible to do a query about a player's scores and ask the program for the best overall score between all the players. I have the following functions:
add_score
return_players_score
return_best_score
exit_program
main
In main(), we begin by creating a new empty dictionary (say, players = {}). Then we ask the user to input a number that takes him/her to the function of choice (1: add_score etc.).
Now, once we're in add_score and have added a key:value pair (player:score), we need to go back to inputting the number taking to the function of choice. I implemented it simply by writing main() to the end of add_score.
That, however, takes us to the beginning, where there's players = {} and thus whatever data we input in add_score gets wiped out. This then affects other functions and the program remains useless as long as it forgets everything right away. How to solve this?
I'd paste the actual code but it's not in English and it's an assignment anyway...
Thanks.
Rather than calling main() from each of your other functions, you should just return (or run off the end of the function, which is equivalent to return None). Since you need the main function to run things repeatedly, you should use a loop.
def main():
players = {}
while True: # loop forever (until a break)
choice = input("what do you want to do (1-4)")
if choice == "1":
add_score(players)
elif choice == "2":
return_players_score(players)
#...
elif choice == "4":
break # break out of the loop to quit
else:
print("I didn't understand that.")
If you have a loop that does something like the following..
example:
while True:
players = {}
some code adding to players
This loop will always reset players to {}
However, if you do:
players = {}
while something:
some code adding to players
then players is not being reset at the start of each iteration through the loop
But your question is not clear
If you have something like this:
def add_score(dicccionary):
#do something with diccionary
main()
def main():
dicccionary = {}
while something:
option = input("option")
if option == 1:
addscore(dicccionary)
else:
#otherfunction
main()
your reset problem can be solve like:
dicccionary = {} #global variable
def add_score():
#do something with diccionary
main()
def main():
option = input("option")
if option == 1:
addscore()
else:
#otherfunction
main()
By the way, you shouldn't make it this way, try something as:
dicccionary = {} #global variable
def add_score():
#do something with diccionary
def main():
while somecondition:
option = input("option")
if option == 1:
addscore()
else:
#otherfunction
main()
If I was doing it for real then I would go for something like:
import sys
class ScoreKeeper(object):
def init(self):
self.scores = {}
def add_score(self, player, score):
self.scores[player] = score
def _print_player_score(self, player, score):
print 'player:', player, 'score:', score
def print_scores(self):
for player, score in self.scores.items():
self._print_player_score(player, score)
def best_score(self):
best, player = 0, "no player"
for player, score in self.scores.items():
if score > best:
best, player = score, player
self._print_player_score(player, best)
if __name__ == '__main__':
scorer = ScoreKeeper()
quit = lambda: sys.exit()
choices = quit, scorer.add_score, scorer.print_scores, scorer.best_score
def help():
print 'Enter choice:'
for index, c in enumerate(choices):
print '%d) %s' % (index, c.__name__)
def get_integer(prompt):
res = raw_input(prompt)
try:
return int(res)
except:
print 'an integer is required'
return get_integer(prompt)
def get_choice():
choice = get_integer('choice? ')
if not 0 <= choice < len(choices):
help()
return get_input()
return choice
help()
choice = get_choice()
while(choice):
args = []
if choices[choice] == scorer.add_score:
args.append(raw_input('player name? '))
args.append(get_integer('score? '))
choices[choice](*args)
choice = get_choice()
quit()
I am trying to create menu where user can choose which part of the program he/she wants to run. When I am importing function computer automatically runs it rather to wait for user input. What shall I do to run function only when called? My code:
import hangman
menu = raw_input("""Welcome to Menu, please choose from the following options:
1. Hangman game
2.
3.
4. Exit
""")
if menu == 1:
hangman()
elif menu == 2:
"Something"
elif menu == 3:
"Something"
elif menu == 4:
print "Goodbye"
else:
print "Sorry, invalid input"
The code for hangman.py looks like that:
import random
words = ["monitor", "mouse", "cpu", "keyboard", "printer",]
attempts = [] # Stores user input
randomWord = random.choice(words) # Computer randomly chooses the word
noChar = len(randomWord) # Reads number of characters in the word
print randomWord , noChar
print "Hello, Welcome to the game of Hangman. You have to guess the given word. The first word has", noChar, " letters."
def game():
guess = raw_input ("Please choose letter")
attempts.append(guess) # Adds user input to the list
print (attempts)
if guess in randomWord:
print "You have guessed the letter"
else:
print "Please try again"
while True:
game()
chance = raw_input ("Have a guess")
if chance == randomWord:
print "Congratulations, you have won!"
break
Without seeing hangman.py, I would assume that it directly contains the code for running the hangman game, not wrapped in a function. If that's the case, you created a module, no function (yet).
Wrap that code in
def run_hangman():
# Your existing code, indented by 4 spaces
# ...
import it like this:
from hangman import run_hangman
and finally call the function like this:
run_hangman()
So here is the start menu:
import hangman
option = raw_input('1) Start Normal\n2) Quick Start\n3) Default') # '\n' is a new line
if option == '1':
hangman.main()
elif option == '2':
hangman.run_hangman('SKIP')
elif option == '3':
handman.run_hangman('Default User')
Inside your hangman code you want to have it modulated. You should have somthing like this:
def main():
stuff = raw_input('Starting new game. Please enter stuff to do things')
run_hangman(stuff)
def run_hangman(options):
if options == 'SKIP':
important_values = 5
vales_set_by_user = 'Player 1'
else:
values_set_by_user = options
rest_of_code()
How should I write this so I could constantly move between "menus".
#!/bin/env python
import os
class Menu:
def __init__(self):
self.menu = '1'
def Main(self):
os.system('clear')
print "main menu"
test = raw_input()
if test == '2':
self.menu = '2'
def Sub(self):
os.system('clear')
print "sub menu"
test = raw_input()
if test == '1':
self.menu = '1'
menu = Menu()
while menu.menu == '1':
menu.Main()
while menu.menu == '2':
menu.Sub()
At the moment I can swap once. ie I start with menu.Main(), enter '2' and menu.Sub() is shown. But then when I enter '1' the program quits. why does it not go back to showing menu menu.Main() ? Any thoughts welcome!
EDIT:
just needed to put them in a main while loop
The first while loop runs, and when you enter '2', finishes. Therefore, the second while loop will begin to loop.
In the second while loop, you enter '1', which causes the second while loop to finish (because menu.menu is now == '1'). Thus, the program finishes.
Instead, you'll probably want one value for menu (that is neither '1' nor '2') to act as the exit state. For example, 'E'. Then, you can replace your two while loops with the following:
while menu.menu != 'E':
menu.Do()
The "Do" method will handle the menu state if it's 1 or 2.
class Menu:
def __init__(self):
self.menu = '1'
def Do(self):
if self.menu == '1':
self.Main()
elif self.menu == '2':
self.Sub()
def Main(self):
os.system('clear')
print "main menu"
test = raw_input()
if test == '2':
self.menu = '2'
def Sub(self):
os.system('clear')
print "sub menu"
test = raw_input()
if test == '1':
self.menu = '1'
You will still need to make it so that you can actually get to the 'E' case. I'll leave that as a task for you to finish.
First of all, please keep the coding conventions when naming your classes and functions.
modules in python start with lowercase and usually do not include more a than a word, if it does it is separated by underscore. (e.g. datetime)
Classes in python start with uppercase and CamelCased for more than one word. (e.g. MainClass)
functions in python start with lowercase and separated with underscore (e.g. keep_trying)
I have been trying to read your code and misunderstood the code because of your style of naming. It is a bad practise for peer-reviewing, also bad practise for yourself as you will have hard time to understand the other codes.
--
To your question, if you follow the workflow you'll see that when you call menu you cannot call sub as your if statement only checks that if it is 1, not 2.
Here is a better way:
#!/bin/env python
import os
class Menu:
def __init__(self):
self.get_input()
def get_input(self):
input = raw_input()
if input == '1':
self.main()
elif input == '2':
self.sub()
def main(self):
os.system('clear')
print "main menu"
self.get_input()
def sub(self):
os.system('clear')
print "sub menu"
self.get_input()
menu = Menu()