Last active
November 10, 2017 20:17
-
-
Save rgutierrez1014/b073152a7dce5a36ddc304879fccdc7b to your computer and use it in GitHub Desktop.
An example of my condition evaluation algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# utility function | |
def cast_to_strings(varlist): | |
"""Cast all values in a list to string""" | |
new_list = [] | |
for v in varlist: | |
if type(v) in (int, long): | |
new_list.append(str(v)) | |
else: | |
new_list.append(v) | |
return new_list | |
def evaluate_conditions(conditional, **kwargs): | |
""" | |
Evaluate a list of conditions | |
""" | |
eval_type = conditional.get('type', 'all') | |
if eval_type not in ('all', 'any', 'none'): | |
raise TypeError("eval_type must be 'all', 'any', or 'none'") | |
conditions = conditional.get('conditions') | |
if not conditions: | |
raise TypeError('A list of conditions is required if a conditional is enabled') | |
results = [] | |
for c in conditions: | |
results.append(evaluate_condition(c)) | |
if eval_type == 'all': | |
return all(results) | |
elif eval_type == 'any': | |
return any(results) | |
elif eval_type == 'none': | |
return not any(results) | |
def evaluate_condition(condition): | |
""" | |
Evaluate a single condition, returning True or False. | |
""" | |
operator = condition.get('operation') | |
if not operator: | |
raise TypeError('Operator required to evaluate a condition') | |
values = condition.get('values') | |
if not values: | |
raise TypeError('Values must be present to evaluate a condition') | |
# FIXME this is a bit janky but I'm leaving it for now | |
values = cast_to_strings(values) | |
val_to_check = condition.get('val_to_check') | |
if not val_to_check: | |
raise TypeError('Please supply a value to check for the condition') | |
if operator == 'equals': | |
return val_to_check in values | |
elif operator == 'not': | |
return val_to_check not in values | |
else: | |
raise TypeError("Unknown condition operator '%s'. Please use 'equals' or 'not'." % operator) | |
conditional_dict = { | |
'type': 'all', | |
'conditions': [ | |
{ | |
'val_to_check': 'foo', | |
'operation': 'not', | |
'values': ['bar', 'baz', 'buzz'], | |
}, | |
{ | |
'val_to_check': 'the cake', | |
'operation': 'equals', | |
'values': ['a lie', 'too many carbs'], | |
} | |
] | |
} | |
# Should return False since the second condition returns False | |
# all(True, False) => False | |
assert evaluate_conditions(conditional_dict) == False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Referenced by my blog post on Medium: https://medium.com/@rgutierrez1014/creating-a-condition-evaluation-algorithm-6bb24e9fc424
This has been simplified from the original implementation due to some proprietary bits