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.
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
Checkout the Specification Pattern. This is exactly what you need. Its written in C# but can be easily converted
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.
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 …
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.
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
Checkout the Specification Pattern. This is exactly what you need. Its written in C# but can be easily converted
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.
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 …