Reputation: 481
I have this code, which calls a function based on your input key. For example, if you chose pf
, it would call the pf
function, my_function(20)
.
My problem is, I know how to call a function without arguments, but I don't know how to do it with arguments. It runs all the functions right now because of the ()
, but how do I give it argmuents and still call it? Would I have to create a seperate list of arguments?
function_map = {
'pf':['finds the prime factors of a number',my_function(20)]
'cs':['solves a quadratic by completing the square',m.complete_square()]
'sr':['simplifies a radical',m.simplfy_radical(input('> '))]
}
for d in function_map.keys():
print('{} - {}'.format(d,function_map[d][0])
selection = input('Input keycode >>> ')
if selection in function_map.keys():
function_map[selection][1]()
Upvotes: 0
Views: 1031
Reputation: 17506
You want functools.partial
. partial
is so awesome that I literally have the documentation in my bookmarks.
partial
is a function that returns a function, but with some of the arguments already set:
from functools import partial
def myfunc(x, y):
print(x + y)
my_ready_func = partial(myfunc, 3)
my_ready_func(5)
my_ready_func(0)
my_ready_func(10)
8
3
13
If you need to defer the execution of the input
function until the actual execution of your function then this will not work as expected.
you might want to write a function that makes your function 'inputtable':
def inputtable(func,query="Whats the argument?"):
arg = input(query)
return func(arg)
Then you can store the inputtable function instead of your original one;
'aa':['does stuff', partial(inputtable, function, query=' > ')]
Alternatively you can write a so called decorator to make it inputtable:( I also have decorators in my bookmarks)
def inputtable(func):
def wrapper():
arg=input(' > ')
func(arg)
return wrapper
And then store it like this:
'aa':['does stuff', inputtable(function)]
Then you don't need to use partial.
Upvotes: 4
Reputation: 160397
An alternative is to use lambdas that won't evaluate (merely compile) their bodies until called:
function_map = {
'pf':['finds the prime factors of a number',lambda: my_function(20)]
'cs':['solves a quadratic by completing the square',lambda: m.complete_square()]
'sr':['simplifies a radical',lambda: m.simplfy_radical(input('> '))]
}
Upvotes: 2
Reputation: 7952
function_map[selection][1]( *args )
is how, but you first have to remove the (20)
, ()
... from the dict, as that calls the function and puts it's result in the dict, rather than storing the function itself: I then added an additional entry to the list which specifies the number of arguments.
function_map = {
'pf':['finds the prime factors of a number',my_function, 1]
'cs':['solves a quadratic by completing the square',m.complete_square, 0]
'sr':['simplifies a radical',m.simplfy_radical, 1]
}
for d in function_map.keys():
print('{} - {}'.format(d,function_map[d][0])
selection = input('Input keycode >>> ')
if selection in function_map.keys():
args = []
for _ in function_map[selection][2]:
args.append(input('Input arg>>> '))
if args:
function_map[selection][1]( *args )
else:
function_map[selection][1]()
Upvotes: 0