Home > Blockchain >  How to set and call a function with different combinations of parameters
How to set and call a function with different combinations of parameters

Time:05-04

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

CodePudding user response:

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] 

CodePudding user response:

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

CodePudding user response:

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)
  • Related