What is a good pattern for validating multiple complex conditions?

Question:

I’m working on a piece of code that needs to validate whether two users are “matched” under several different criteria. If it helps, think of this as a dating app, where we are trying to match people based on age, sexual preference, ethnicity preference, etc. Here’s an example with 3 conditions, each of which is a function.

def is_match(row):
    return True 
        and ethnicity(user_a, user_b) 
        and sexual_orientation(user_a, user_b) 
        and age(user_a, user_b) 

Now, let’s say I want to add another condition for proximity, I would just add it to the function:

def is_match(row):
    return True 
        and ethnicity(user_a, user_b) 
        and sexual_orientation(user_a, user_b) 
        and age(user_a, user_b) 
        and proximity(user_a, user_b)

Of course, this is feasible for a small application, but I can imagine a point where other co-workers may want to check out the code and pass their own conditions to it, and this doesn’t seem abstract enough. I know there must be a pattern here to follow. Should I pass in each function as an array? How would you recommend doing this? I’m working in Python, but you can use any language you want to demonstrate the patterns.

Asked By: Evan Zamir

||

Answers:

def is_match(list_of_functions, user_a, user_b):
   return all([cur_fun(user_a, user_b) for cur_fun in list_of_functions])

Edit:

The following variant is more efficient, since it short-circuits the moment it hits a non-True value, rather than necessarily evaluating all of the functions:

def is_match(list_of_functions, user_a, user_b):
   for cur_fun in list_of_functions
       if not cur_fun(user_a, user_b):
            return False
   return True
Answered By: Boa

Checkout the Specification Pattern. This is exactly what you need. Its written in C# but can be easily converted

Answered By: Sievajet

I think sets are good for such tasks, because it’s rather comparsion than validation. I will give You example:

user_a = {
    'ethnicity': 1,
    'sexual_orientation': 'straight',
    'age': 37,
}

user_b = {
    'ethnicity': 2,
    'sexual_orientation': 'straight',
    'age': 34,
}

differences = set(user_a.items()) ^ set(user_b.items()) # s.symmetric_difference(t)
commons = set(user_a.items()) & set(user_b.items()) # s.intersection(t)

print({'differences': differences, 'commons': commons})

output:

{'differences': {('ethnicity', 2), ('ethnicity', 1), ('age', 37), ('age', 34)}, 'commons': {('sexual_orientation', 'straight')}}

So You could just load data of two users to dicts and compare.

Answered By: Nuncjo

hello guys i want to match 3 people instead of 2 , means the user+2 people instead of 1 and gather the 3 of them in a group chat is it that easy to code or not ? because im still a newbie at coding …

Answered By: Ayoub Baali
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.