Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching on function parameters in Python

Suppose I have a function named generator that returns a 4-tuple with randomly selected values in certain pre-specified ranges. Let's say the tuple is of the form (age, sex, location, marital_status):

age is in range(5, 85)
sex is a member of the set {"m", "f"}
location is a member of the set of all the cities in California
marital_status is a member of {"married", "single", "separated"}

On the other hand, let's say I have defined 20 different functions with definitions like this:

def p1 (age, sex, location, marital_status)
def p2 (age, sex, location, marital_status)   
.
.

where p1 is supposed to receive parameters with values of the following form:

`age` must be in the range 20 to 45
`sex` must be male
`location` could be any city in Southern California
`marital_status` could be either single or married

and imagine a different set of values for p2 all the way to p20.

What is a pragmatic way to determine which set of generated values match which function?

In this case all the definitions where exactly the same, but I can imagine instances where there might be slight differences in the definitions, for example p18 could be def p1 (age, location) with specific limitations on the range of possibilities for age and location.

P.S. The patters are not necessarily mutually exclusive, meaning a set of generated values might as well match more than one function.

like image 765
Morteza R Avatar asked Jul 23 '15 05:07

Morteza R


People also ask

How do you perform pattern matching in Python?

regex = r"([a-zA-Z]+) (\d+)" if re.search(regex, "Jan 2"): match = re.search(regex, "Jan 2") # This will print [0, 5), since it matches at the beginning and end of the # string print("Match at index %s, %s" % (match. start(), match. end())) # The groups contain the matched values. In particular: # match.

What is meant by pattern matching in Python?

Pattern matching involves providing a pattern and an associated action to be taken if the data fits the pattern. At its simplest, pattern matching works like the switch statement in C/ C++/ JavaScript or Java. Matching a subject value against one or more cases.

What is pattern matching explain with example?

Pattern matching is the process of checking whether a specific sequence of characters/tokens/data exists among the given data. Regular programming languages make use of regular expressions (regex) for pattern matching.


1 Answers

As a Pythonic way in Python 3.X (but not 2.X), you can attach annotation information (arbitrary user-defined data about a function’s arguments and result) to a function object. Here you can use this feature in a decorator to wrap your function to check the range of your arguments.

For example you can use the following range test function :

def rangetest(func):
    def onCall(**kargs):
        argchecks = func.__annotations__

        if all(val in range(*argchecks.get(arg)) for arg,val in kargs.items()):
            return func(**kargs)
        else :
              print ("invalid arg range")
    return onCall


@rangetest
def func(a:(1, 5), b:(4,7), c:(0, 10)):
    print(a + b + c)

Demo :

func(a=2, b=6, c=8)
16
func(a=2, b=6, c=15)
invalid arg range

There is some point here. The first is that, since the annotation information is within a dictionary (python returns it as a dictionary) and dictionaries don't have a specific order, you need to use keyword arguments in your function to be able to get its relative range in annotation information dictionary.

Also here I just used numeric range but you can use some custom ranges like list of words like what you show in your question.But inside the all you need to check its type then based on its type use a proper operation :

all(kwargs.get(arg) in range(*arg_range) if is instance (arg_range,tuple) else kwargs.get(arg) in arg_range for arg,arg_range in argchecks.items())
like image 126
Mazdak Avatar answered Sep 20 '22 15:09

Mazdak