How to set and call a function with different combinations of parameters
I have a python program (or function) and I want to call it with different values for its parameters.
Suppose the function is:
myfunc(x = 0,y = 0,z =0, w=0, ...):
I use a command line like this to set parameters:
run x=2#3#4--y=1#2--z=5
It shows values for x,y, and z (The number of parameters isn't fixed, many could have default values and I want to set arbitrary set of them). I want to call the function with all combinations such as x=2, y=1, z=5
. For this example there are 6 combinations.
I tried to write it with a loop but i think it must be written recursively, because in loop I don't know when to set and unset variables for a next run.
all_vars = var.split("--")
cont = True
while cont:
ii = 0
for _var in all_vars:
_var_name,_var_item_list = _var.split("=")
_var_item_list = _var_item_list.split("#")
cont = False
for var_item in _var_item_list:
if not _var_name in args or args[_var_name] != var_item
args[_var_name] = var_item
_output_name += "_" + _var_name + "_" + str(var_item)
cont = True
ii += 1
break
else:
continue
if cont and ii == len(all_vars):
ctx.invoke(run, **args) # calling the function
3 answers
-
answered 2022-05-04 10:40
Xiidref
You can do it this way and without library :
var = "x=2#3#4--y=1#2--z=5" var = {var_bloc[:var_bloc.index("=")]: var_bloc[var_bloc.index("=")+1:].split("#") for var_bloc in var.split("--")} #Here var will be {"x":['2', '3', '4'], "y": ['1', '2'], "z": ['5']} def enumerate_possibility(params): if len(params) == 1: for k, possible_values in params.items(): for val in possible_values: yield {k:val} else: key, possible_values = list(params.items())[0] for val in possible_values: for item in enumerate_possibility({k:v for k, v in params.items() if k != key}): yield {key:val, **item} for possible_param in enumerate_possibility(var): myfunc(**possible_param)
-
answered 2022-05-04 10:52
assume_irrational_is_rational
I think you can do this in below manner
import itertools import inspect def fun(x,y,z, d=3): print(x,y,z) return x+y+z params = inspect.signature(fun).parameters # paramters of your function a = "x=2#3#4--y=1#2--z=5".split("--") var_names = [x.split("=")[0] for x in a] values = [map(int, x.split("=")[1].split("#")) for x in a] tot_comb = [dict(zip(var_names, comb)) for comb in itertools.product(*values)] for comb in tot_comb: print(fun(**comb))
I have included inspect module for the use case if you want to check if your funtion is callable with given keyword arguments or not
-
answered 2022-05-04 10:59
FedericoCozziVM
I usually do this in tests scenarios, but using pytest:
@pytest.mark.parametrize('bar', ['a', 'b', 'c']) @pytest.mark.parametrize('_x', [1, 2, 3]) def test_foo(bar:str, _x: int): print(bar, _x)
this code will execute the function test with all the arguments combinations:
============================= test session starts ============================== collecting ... collected 9 items test_static_models.py::test_foo[1-a] test_static_models.py::test_foo[1-b] test_static_models.py::test_foo[1-c] test_static_models.py::test_foo[2-a] test_static_models.py::test_foo[2-b] test_static_models.py::test_foo[2-c] test_static_models.py::test_foo[3-a] test_static_models.py::test_foo[3-b] test_static_models.py::test_foo[3-c]
do you know?
how many words do you know