Calling Dynamic Function with Dynamic Number of Parameters

Calling dynamic function with dynamic number of parameters

Use the apply method of a function:-

function mainfunc (func){
window[func].apply(null, Array.prototype.slice.call(arguments, 1));
}

Edit: It occurs to me that this would be much more useful with a slight tweak:-

function mainfunc (func){
this[func].apply(this, Array.prototype.slice.call(arguments, 1));
}

This will work outside of the browser (this defaults to the global space). The use of call on mainfunc would also work:-

function target(a) {
alert(a)
}

var o = {
suffix: " World",
target: function(s) { alert(s + this.suffix); }
};

mainfunc("target", "Hello");

mainfunc.call(o, "target", "Hello");

How to provide dynamic number of arguments to a function inside a function in R?

If the change the apply to do.call, it would work as expected. Note that apply with MARGIN = 2, loop over the columns of 'df' individually, whereas the 'f1' needs the values of all those available columns (or else use the default values) to calculate the ((a + b) * c)

f2 <- function(...){
arglist = list(...)
df = expand.grid(arglist)
do.call(f1, df)
}

and the f1

f1 <- function(a=1,b=1,c=2){
(a+b)*c

}

-testing

> f2(a = 10)
[1] 22
> f2(c = 10)
[1] 20
> f2(a = 5, c= c(5, 10))
[1] 30 60

Calling function with variable arguments dynamically

I'm self answering, because this will be a solution for other people. If you want to call functions with variable arguments dynamically without writing direct machine code just use avcall library from FFCALL. Quick reference guide of avcall library can be found here. It's a crossplatform library that makes this possible. For example to call function named func1 with return type void which takes three arguments and all of them are of type int just do this:

#include <avcall.h>

int a = 1, b = 2, c = 3;

av_alist alist;
av_start_void(alist,&func1);
av_int(alist,a);
av_int(alist,b);
av_int(alist,c);
av_call(alist);

You can of course use this for functions which returns value or takes arguments of different type, for more just look at avcall library manual page. :)

Javascript: how to dynamically call a method and dynamically set parameters for it

For call function by string name:

window[obj.method](...obj.params)

Example:

let obj = {
method: 'foo1',
params: ['one', 'two']
}

function foo1(p1, p2) {
console.log(p1, p2)
}

window[obj.method](...obj.params) // result: one two

Python dynamic function parameters

I understood your question of two ways:

  1. You want to call your function passing to it different parameters (that are optional), you can accomplish it like this:
def add(first, second=0, third=3):
return (first+second+third)

number_list = list(range(1, 200)) # Generates a list of numbers
result = [] # Here will be stored the results

for number in number_list:
# For every number inside number_list the function add will
# be called, sending the corresponding number from the list.
returned_result = add(1,second=number)
result.insert(int(len(result)), returned_result)

print(result) # Can check the result printing it

  1. You want your function handles any number of optional parameters, as you don't know any way to determine how many they are, you can send a list or parameters, like this:
def add(first,*argv):
for number in argv:
first += number
return first

number_list = (list(range(1, 200))) # Generates a list of numbers
result = add(1,*number_list) # Store the result

print(result) # Can check the result printing it

Here you can find more information about *args

Calling function with dynamic args

(Posting this separately since it's fundamentally different to my other answer.)

If you need to pass a lot of values to some callbacks, without requiring other callbacks to declare a lot of unused parameters, a neat solution is to encapsulate all of those values in a single object. You can use collections.namedtuple to define a value type with named attributes, and then the callback can take one parameter and decide which attributes to use.

from collections import namedtuple
SomeFunctionResult = namedtuple('SomeFunctionResult', 'foo bar baz qux quz')

def some_function(callback):
result = SomeFunctionResult('foo', 'bar', 'baz', 'qux', 'quz')
callback(result)

Example:

>>> some_function(lambda r: print(r.foo, r.bar))
foo bar
>>> some_function(lambda r: print(r.baz, r.qux, r.quz))
baz qux quz

The downside is that this makes some_function less usable with existing functions which might expect to receive foo directly, rather than an object with a foo attribute. In that case, you have to write some_function(lambda r: blah(r.foo)) which is not as neat as some_function(blah).

how to dynamically create a function with changing number of parameter pairs

The following shows how to dynamically create the desired function. Note that I simplified the dynamic function's code to minimize redundant calculations.

from textwrap import dedent

def test(num_terms):

def smart_func(num_terms): # nested to mimic OP's usage
template = dedent('''
def func(t, freq, offset, a0, b0, {params}):
ang = 2.*np.pi*freq*t
sin_ang = np.sin(ang)
cos_ang = np.cos(ang)
return (a0 + b0
{terms}
+ offset)
''')
indent = ' ' * 12
params, terms = [], []
for i in range(1, num_terms):
params.append('a{i}, b{i}'.format(i=i))
terms.append((indent + '+ a{i}*sin_ang\n' +
indent + '+ b{i}*cos_ang').format(i=i))

src_code = template.format(params=', '.join(params), terms=' \n'.join(terms))

print('Dynamically created function of {} terms:'.format(num_terms))
print(src_code)

exec(src_code, globals(), locals()) # compile into function object
# exec src_code in globals(), locals() # older Python 2 syntax

return locals()['func'] # return compiled function

return smart_func(num_terms) # return result of calling nested function

print(test(3))

Output:

Dynamically created function of 3 terms:

def func(t, freq, offset, a0, b0, a1, b1, a2, b2):
ang = 2.*np.pi*freq*t
sin_ang = np.sin(ang)
cos_ang = np.cos(ang)
return (a0 + b0
+ a1*sin_ang
+ b1*cos_ang
+ a2*sin_ang
+ b2*cos_ang
+ offset)

<function func at 0x0232A228>


Related Topics



Leave a reply



Submit