Calling a function with unknown number of parameters Python

Viewed 1032

I am trying to read in a Fuzzy plain text rule and pass the parameters to a SciKit-Fuzzy function call to create fuzzy rules. For example, if I read in this text rule:

IF service IS poor OR food IS rancid THEN tip IS cheap

Then the function call will be:

ctrl.Rule(service ['poor'] | food ['rancid '], tip ['cheap'])

If text rule is:

IF service IS good THEN tip IS average; 

Then the function call will be:

ctrl.Rule(service ['good '] , tip ['average'])

Since each rule can have unlimited number of input variables, e.g. the user can also say:

IF service IS good AND food IS good AND mood IS happy THEN tip IS high

which contains 3 inputs variables service['good'],food['good'],and mood['happy'], and 1 output variable tip['high']. I can't think of a way to automatically read in the text rule and convert it to a function call, do you have any idea or suggestion to achieve this goal? Any help will be appreciated. Thanks.

2 Answers

In python, we can pass an unknown amount of arguments into the function using asterisk notation.

Let's try to create a function sum_up() with an unknown number of arguments.

def sum_up(*args):
    s = 0
    for i in args:
        s += i
    return s

As you see, an argument with an asterisk before will collect all arguments given to this function inside a tuple called args.

We can call this function that way:

sum_up(5, 4, 6)  # Gives 15

But if we want to sum up elements of a list and we need to pass it into the function as arguments...

We can try the following:

l = [5, 4, 6]
sum_up(l)

This won't give an effect we need: args of sum_up will look like ([5, 4, 6],). To do what we want, we need to put an asterisk before the argument we're passing:

sum_up(*l)  # Becomes sum_up(5, 4, 6)

All you need to do is collect all arguments you want to pass in a list and then put an asterisk before this list passed as an argument inside a call:

args = [service ['good '] , tip ['average']]
ctrl.Rule(*args)

You could try something like this:

string_input = "IF service IS poor OR food IS rancid THEN tip IS cheap"
string_input = string_input.replace(" THEN ", '"], ').replace(' IS ', '["').strip("IF ").replace(" OR ", '"] | ') +'"]'
eval('ctrl.Rule({})'.format(string_input))

But be warned you need to be very very careful with eval. It is a security risk because user can execute code this way!!! Before using this you might to do research on how to prevent this security issue.

Related