How do I call functions from a dictionary in Python? - python

Easy one for you guys. Why can't I get cmd to run a function from a dictionary? (I didn't want to paste all the code, but everything called has a class or function somewhere else. I have functions called "help()" and "exit() and such in a commands.py file and it's already been imported.)
The error I'm getting is: "line 87, in runCMD Commands[cmd](Player, args) KeyError: 0"
Commands = { #In-game commands
'help': help,
'stats': stats,
'exit': exit
}
def isValidCMD(cmd):
if cmd in Commands:
return True
return False
def runCMD(cmd, Player, args):
Commands[cmd](Player, args)
def main(Player): #Main function
Player.dead = False
while(Player.dead == False):
cmd = input(">> ")
if isValidCMD(cmd):
runCMD(0, 1, Player)
else:
print("Please enter a valid command.")
charactercreation()
main(Player)

You should be calling
runCMD(cmd, 1, Player) # or runCMD(cmd, Player, 1) <= looks like they are in the wrong order
anyway, they first parameter of runCMD needs to be one of the keys in Commands
Possibly you mean to pass an arbitrary number of parameters in args. then you need to place a * in there
def runCMD(cmd, Player, *args):
Commands[cmd](Player, *args)
def main(Player): #Main function
Player.dead = False
while(Player.dead == False):
cmd = input(">> ")
if isValidCMD(cmd):
runCMD(cmd, Player, 0, 1)
else:
print("Please enter a valid command.")

Related

call a 'def' with an 'input' in Python

I'm working on a project, and I got a bit stuck. I want the user the of the program to be able to call a function. But it must be easy for the user to call it. For example
def definition():
print("This is a function")
command = input("> ")
if command == definition:
definition()
else:
print("")
in this function I want the user not to write the () in the input. But I want the user just to be able to write 'definition' to call the function. Does anyone have any clue how to do this?
You are missing the quotes from around definition, therefore trying to compare an undeclared variable with an inputted string which will always equate to false.
Try:
def definition():
print("This is a function")
command = input("> ")
if command == 'definition':
definition()
else:
print("")
You are mixing up the function name (callable object in you code) and the name from your input.
For your problem I would use a dictionary of function names for the keys and function references for the value
def function1():
print ('calling function1')
def function2():
print ('calling function2')
def function3():
print ('calling function3')
functions = {}
functions['function1'] = function1
functions['function2'] = function2
functions['function3'] = function3
name = input('Enter the function name:\n')
if name in functions:
functions[name]()
else:
print ('Invalid function name. Use one of: ')
for key in functions.keys():
print (' - ' + key)
Just one command "definition"
def definition():
print("This is a function")
command = input("> ")
if command == "definition":
definition()
else:
print("Wrong command !")
More commands and functions
def definition():
print("This is definition function")
def modify():
print("This is modify function")
func = {"definition":definition, "modify":modify}
command = input("> ").strip().lower()
if command in func:
func[command]()
else:
print("Wrong command !")
You will have to implicitly define the conditions with if statement..
For ease of user you can do like this:
def definition():
#your function here
if __name__=='__main__':
print ("Choose your option:\n1. Definition")
choice = int(input("Enter choice: "))
if choice == 1:
definition ()
Try this
whitelist_funcs = ['definition', 'something else']
command = input("> ")
if command in whitelist_funcs:
exec(f"{command}()")
else:
print("")

Python - Input Menu Function

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()

How to set variable to string input python 3.5?

I'm trying to set a variable to a string input that the user inputs. I've done something similar similar before, by setting a variable to an integer input that the user inputs and tried copying that and just changing it from int() to str() but it didn't work. Here's what I have thus far:
import time
def main():
print(". . .")
time.sleep(1)
playerMenu()
Result(playerChoice)
return
def play():
playerChoice = str(playerMenu())
return playerChoice
def playerMenu():
print("So what will it be...")
meuuSelect = str("Red or Blue?")
return menuSelect
def Result():
if playerChoice == Red:
print("You Fascist pig >:c")
elif playerChoice == Blue:
print("QUICK, BEFORE YOU PASS OUT, WHAT DOES IT TASTE LIKE?!?")
return
main()
When I run it, it tells me that playerChoice is not defined. I don't understand why it's telling me this since I clearly set playerChoice = to whatever the user's string input was
Your functions return values (good) but you're not doing anything with them (bad). You should store the values in a variable and pass them to whoever needs to work with them:
def main():
print(". . .")
time.sleep(1)
choice = playerMenu()
Result(choice)
# no need for "return" at the end of a function if you don't return anything
def playerMenu():
print("So what will it be...")
menuSelect = input("Red or Blue?") # input() gets user input
return menuSelect
def Result(choice):
if choice == "Red": # Need to compare to a string
print("You Fascist pig >:c")
elif choice == "Blue":
print("QUICK, BEFORE YOU PASS OUT, WHAT DOES IT TASTE LIKE?!?")
main()

Doing a sort of a loop while avoiding a certain prerequisite (beginner/python)

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()

Infinite while loop reset when a function is run

I was just wondering if I could remove some redundancy for a help function in a text-game. What I have right now is at the start of every function hint = 0, and hint is increased one every time an invalid answer is entered.
Here is what I have at the moment (inside every function):
hint = 0
valid = False
while valid == False:
print "Would you like to begin?"
begin = raw_input("> ")
if "yes" in begin:
valid = True
print "Great!\n"
start.start()
elif "no" in begin:
quit.quit()
else:
error.error(1)
hint += 1
if hint > 4:
print "\nYou may choose from \"yes\" and \"no\"."
The following code use decorator to separate hint logic and command logic. Every command is handled by a function which can be decorated by Hint object.
When the function return False, the count in Hint object will increase and when it's larger than the limit, it will print out a hint message.
When the function return a tuple it will be called by the main loop.
class Hint(object):
def __init__(self, n, msg):
self.n = n
self.msg = msg
def __call__(self, f):
def wrap(*args, **kw):
count = 1
while True:
ret = f(*args, **kw)
if ret == False:
count += 1
if count > self.n:
print self.msg
count = 0
else:
break
return ret
return wrap
def start_at(place):
print "start at %d" % place
return "start"
#Hint(3, "You may choose from 1, 2, 3.")
def start():
print "What place will you start?"
cmd = raw_input("> ")
try:
place = int(cmd)
if place not in (1,2,3):
return False
else:
return start_at, (place,)
except ValueError:
return False
def quit():
print "I will quit"
return "quit"
#Hint(4, "You may choose from yes and no.")
def begin():
print "Would you like to begin?"
cmd = raw_input("> ")
if "yes" in cmd:
print "Great!\n"
return start, ()
elif "no" in cmd:
print "Bad!\n"
return quit, ()
else:
return False
call_func, args = begin, ()
while True:
ret = call_func(*args)
if isinstance(ret, tuple):
call_func, args = ret
else:
break
Here is some test:
Would you like to begin?
> abc
Would you like to begin?
> def
Would you like to begin?
> 123
Would you like to begin?
> 345
You may choose from yes and no.
Would you like to begin?
> yes
Great!
What place will you start?
> 5
What place will you start?
> fg
What place will you start?
> sd
You may choose from 1, 2, 3.
What place will you start?
> 2
start at 2
from itertools import count
for hint in count()
print "Would you like to begin?"
begin = raw_input("> ")
if "yes" in begin:
print "Great!\n"
start.start()
break
elif "no" in begin:
quit.quit()
else:
error.error(1)
if hint > 4:
print "\nYou may choose from \"yes\" and \"no\"."
Now the next problem is what does start.start() do? It looks/feels like you might be using function calls like a GOTO

Categories

Resources