Reputation: 1620
Suppose I have the following vars:
x
y
and functions:
def runx(x):
print(x)
def runy(y):
print (y)
def runxy(x, y):
print(x + y)
def nonexy():
print('none')
What's the Pythonic way to choose a function based on the next requirements:
-If value
is only greater than y
run the func runy
-If value
is only greater than x
run the func runx
-If value
is greater than both x
and y
run the func runxy
-If value
is not greather than x
and y
runt the func nonexy
value
, x
, y
could be any number
Example:
x = 4
y = 6
value = 5
Here value
is only greater than x
, so run runx(x)
Upvotes: 0
Views: 132
Reputation: 1531
We define a dictionary, which maps a boolean-pair to a lambda expression.
The boolean-pair is a two-tuple, representing the function-selecting criteria.
The lambda expression wraps a function. It takes x y, and calls the function
with the parameters it needs.
Now, we can define a function which combines the tools we defined above.
mapping = {
(True, True): lambda x,y: runxy(x,y),
(True, False): lambda x,y: runx(x),
(False, True): lambda x,y: runy(y),
(False, False): lambda x,y: nonexy()
}
def f(x, y, value):
mapping[value > x, value > y](x,y)
Note that it is enough to define mapping
only once, regardless how many times we want to run the task. This is why we put it outside f
. (No need to define it each time the task is run.)
Upvotes: 1
Reputation: 2562
If all the functions take x,y as parameters, you could use:
(nonexy,runx,runy,runxy)[1*(x<=value<=y)+2*(y<=value<=x)+3*(x<value>y)](x,y)
Upvotes: 1
Reputation: 6386
Even more overkill than other answers, but might be interesting for someone:
def fn_picker(value, x, y):
functions = { # lambdas to make it shorter
0: lambda kwargs: 'none',
1: lambda kwargs: kwargs['x'],
2: lambda kwargs: kwargs['y'],
3: lambda kwargs: kwargs['x'] + kwargs['y']
}
key = sum([(value > x), (value > y)*2]) # True is 1, False is 0
fn = functions[key]
return fn(locals())
print(fn_picker(5, 4, 6))
Upvotes: 2
Reputation: 1519
if value > y and value <= x:
runy(y)
elif value <= y and value > x:
runx(x)
elif value > x and value > y:
runxy(x, y)
else:
nonexy()
There's no real good way to handle this kind of pattern but to just write out the if/else block.
Upvotes: 3
Reputation: 61935
One approach that is often forgotten is the use of logic tables. Now, while I'm not arguing that this is the best approach here, I consider it interesting so here goes - take or leave what you will.
value > y value <= y
---------- ----------
value > x | runxy runx
value <= x | runy nonex
Then we can codify it as so, utilizing the fact that functions are first-class values:
arr = [[runxy, runx], [runy, nonex]]
And access it as so:
col = 0 if value > y else 1
row = 0 if value > x else 1
fn = arr[row][col]
Then just edit the current design such all the functions should take x and y parameters (or use wrapping lambdas in the above table) and..
fn(x, y)
Upvotes: 6
Reputation: 3277
if value > y :
if value > x :
runxy(x, y)
else :
runy(y)
else :
if value > x :
runx(x)
else :
nonexy()
Am I missing something?
Upvotes: 7