2

I have tree types of sub-functions:

  • one without any parameters (arguments),
  • second with one parameter
  • third with multiple parameters (tuple)

I am trying to pass that functions and its arguments to another function which sum results of all sub-functions and return the sum value. Parameters in that function should be: names of each sub-function as position arguments (*args) and arguments of each subfunction as key-value arguments (*kvargs).

Example:

 def no_arg()
 def one_arg(a)
 def multiple_args(a, b, c, e, f)

 # execution of function_results_sum:
 function_results_sum(
     no_arg, one_arg, multiple_args,
     one_arg=23,
     multiple_args=(1, 2, 3, 4, 5))

What i have done so far:

def no_arg():
    return 5

def ident(x):
    return x

def mult(x, y):
    return x * y    

def function_results_sum(*args, **kwargs):
        return no_arg() + ident(kwargs[ident.__name__]) + mult(*kwargs[mult.__name__])   

The code above is passing arguments to each sub-function, but sub-function names are hardcoded. I would like to modify the current code to be able to get function names from *args. Below I wrote a pseudocode expressing more less what i am trying to achieve:

def function_results_sum(*args, **kwargs):
    for functionName in args:
        result = sum(funcionName(kwargs))
    return result

I have already spent all day struggling with that problem, so please don't write me that "using google doesn't hurt" ;)

2
  • Will it always be three functions, one of each of those types? Note, the signature you desire might get tricky, if you aren't on Python 3.6, otherwise, the order of the kwargs is not guaranteed. Commented Nov 3, 2017 at 19:02
  • I am using Python 3.6. The order is always the same. Commented Nov 3, 2017 at 19:12

3 Answers 3

6

Something like this would work:

def no_arg():
    return 5

def one_arg(x):
    return x

def multiple_args(x, y):
    return x * y

def function_results_sum(*args, **kwargs):
    result = 0
    for func in args:
            result += func(*kwargs[func.__name__])
    return result

Output:

function_results_sum(
    no_arg, one_arg, multiple_args,
    no_arg=(),
    one_arg=(23, ),
    multiple_args=(1,5))

33

The only difference between what you are asking is that you have to put args in a tuple to then unpack as args to pass in later.

If you dont want to have to supply anything for no argument functions, you can double check if the func name is in kwargs:

def function_results_sum(*args, **kwargs):
    result = 0
    for func in args:
        if func.__name__ i kwargs:
            result += func(*kwargs[func.__name__])
        else:
            result += func()
    return result
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! Its exactly what i needed!
0

Post of R Nar is exactly what I tried to achieve. I added additional if statement to verify if kwarg is an integer or a tuple. Thanks that it is not neccessary to put all **kwargs in a tuple. Thank you guys for help!

def function_results_sum(*args, **kwargs):
    result = 0
    for func in args:
        if func.__name__ in kwargs:
            if type(kwargs[func.__name__]) == int:
                result += func(kwargs[func.__name__])
            elif type(kwargs[func.__name__]) == tuple:
                result += func(*kwargs[func.__name__])
        else:
            result += func()
    return result

result = function_results_sum(no_arg, ident, mult, ident=2, mult=(3, 4))
print(result)

Comments

-1

by goolging 'python determine number of args for passed function' I found How can I find the number of arguments of a Python function?

I'm pretty sure you don't want the **kwars key, value syntax so I use a func_list regular arg and *args

from inspect import signature


def function_results_sum(func_list, *args):

    arg_gen = (e for e in args)

    return sum([func(*(next(arg_gen)
                       for _ in range(len(signature(func).parameters))))
               for func in func_list])

function_results_sum([no_arg, ident, mult], 7,8,9)
84  

the input can be made flatter by parsing *args for Functions and (presumed) arguments (anything not Type Function)

from inspect import signature
import types


def function_results_sum(*args):

    func_gen = (e for e in args if isinstance(e, types.FunctionType))

    arg_gen = (e for e in args if not isinstance(e, types.FunctionType))

    return sum(func(*(next(arg_gen)
                       for _ in range(len(signature(func).parameters))))
               for func in func_gen)

function_results_sum(no_arg, ident, mult, 10,6,90)
555

order of functions and order of args are important, but separately, can be interleaved:

function_results_sum(no_arg, 10, ident, 6, 90, mult)
Out[399]: 555

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.