2

When calling the function below, I can provide values that will be used instead of the default parameters in the function (see below).

cerebro.addstrategy(GoldenCross, fast=10, slow=25)

This works great for a small number of known parameters, but I am moving up to more complex systems. Essentially, I need to pass a fast_1, fast_2, fast_3, etc.... The total amount of these parameters will change (always around 100, but it can vary). Is there a statement that I can write that will dynamically add X amount of parameters to my function call?

I have tried using a for statement in the function call, but I received a syntax error.

Deemo
  • 131
  • 1
  • 1
  • 10
  • Parameters more than 5 are not always a best coding convention. Give it a model and process inside – Tấn Nguyên Jan 22 '21 at 03:46
  • 2
    Why does your function have 100 parameters??? If you find yourself passing `x_1, x_2, x_3, ...` then you *really* probably just want to accept a *container* like a `list` – juanpa.arrivillaga Jan 22 '21 at 03:49
  • I agree with the other comments here. Passing a large number of parameters to a function is very bad form. Instead of parameters `fast_1`, `fast_2`, etc.. you should pass in `fasts`, a single list parameter containing each of the values you would have otherwise passed as individual `fast_N` parameters. – CryptoFool Jan 22 '21 at 04:00
  • Does this answer your question? [Use of \*args and \*\*kwargs](https://stackoverflow.com/questions/3394835/use-of-args-and-kwargs) – sytech Jan 22 '21 at 04:07

3 Answers3

1

how about using *? def addstrategy(GoldenCross, *fast, slow = 25): can be an example.

>>> def foo(a, *b, c = 36):
        print(a, b, c)
>>> foo(1, 2, 3, 4, 5)
1 (2, 3, 4, 5) 36

You need to initialize fast in this case, however.

HyeAnn
  • 21
  • 1
  • 4
  • I would suggest that you not promote this solution to the OPs problem, as it is very bad form to pass 100+ parameters this way. – CryptoFool Jan 22 '21 at 04:19
1

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

Merrydjff
  • 166
  • 2
  • 7
-1

Two ways: Either use a variable number of arguments using * on the parameter or treat the parameter as an iterable.

def fun1(positional, optional="value", *args):
  print(args) # args here is a tuple, since by default variable number of args using * will make that parameter a tuple.

def fun2(positional, args, optional="value"):
  print(args) # args here will be dependant on the argument you passed.

fun1("some_value", "value", 1, 2, 3, 4, 5) # args = (1, 2, 3, 4, 5)
fun2("some_value", [1, 2, 3, 4, 5]) # args = [1, 2, 3, 4, 5]
enaielei
  • 83
  • 5
  • Your first function, using a named argument followed by a variable number of positional arguments, is VERY confusing. You must always supply the `optional` parameter if you want to supply any `*args` parameters. The optional default of "value" only works in the case where you provide only a single argument to the function. - in any case, I would suggest that you not promote this solution to the OPs problem, as it is very bad form to pass 100+ parameters this wa. – CryptoFool Jan 22 '21 at 04:11
  • The thing is I got used with Python 2.7 where optional parameters should always come before the `*args` and `**kwargs`. – enaielei Jan 22 '21 at 04:13
  • I getcha. That doesn't change the fact that the API presented by that function is confusing as heck and, IMO, should be avoided. - The two arguments `optional` and `args` become co-dependent. You can only use the default value of the `optional` argument if you don't have any other positional parameters to pass. It would be better in this case to just require the `optional` parameter all the time. If you are going to often want to call the function with a single parameter, I think it would be better to make that a second function to avoid confusion. – CryptoFool Jan 22 '21 at 04:15