Skip to content

Instantly share code, notes, and snippets.

@omaraboumrad omaraboumrad/rules.py
Last active Jan 3, 2016

Embed
What would you like to do?
import operator
import collections
class Rule(object):
def __init__(self, logic, left=None, right=None, op=None, inv=False):
self.logic = logic
self.left = left
self.right = right
self.op = op
self.inv = inv
def __call__(self, *given):
if self.logic is not None:
return self._run(*given)
elif None not in (self.left, self.right, self.op):
return self.op(
self.left(*given) ,
self.right(*given)) ^ self.inv
def _run(self, *given):
return self.logic(*given) ^ self.inv
def __or__(self, other):
return Rule(logic=None, left=self, right=other, op=operator.or_)
def __and__(self, other):
return Rule(logic=None, left=self, right=other, op=operator.and_)
def __invert__(self):
return Rule(logic=self.logic, left=self.left, right=self.right,
op=self.op, inv=True)
# Rules
is_an_adult = Rule(lambda x: x.age > 18)
has_any_degree = Rule(lambda x: len(x.degrees) > 0)
still_in_school = Rule(lambda x: len(x.degrees) == 0)
lives_in_lebanon = Rule(lambda x: x.country == 'Lebanon')
lives_in_egypt = Rule(lambda x: x.country == 'Egypt')
lives_in_france = Rule(lambda x: x.country == 'France')
has_BS = Rule(lambda x: 'BS' in x.degrees)
has_MS = Rule(lambda x: 'MS' in x.degrees)
has_BE = Rule(lambda x: 'BE' in x.degrees)
# Rule Composition
is_loser = is_an_adult & still_in_school
is_doomed = is_an_adult & has_any_degree & lives_in_lebanon
is_middle_eastern = lives_in_lebanon | lives_in_egypt
fits_position_requirements = has_BE | (has_BS & has_MS)
is_school_boy = ~is_an_adult & still_in_school
is_possible_candidate = fits_position_requirements & ~is_doomed
# Sample Data
Person = collections.namedtuple('Person', ['name','age','country','degrees'])
joe = Person(name='joe', age=17, country='France', degrees=['BE'])
omar = Person(name='omar', age=34, country='Lebanon', degrees=['BS'])
sam = Person(name='sam', age=24, country='Finland', degrees=['BS', 'MS'])
jaafar = Person(name='dave', age=23, country='Egypt', degrees=[])
dany = Person(name='dany', age=12, country='France', degrees=[])
# Checks
assert lives_in_france(joe)
assert is_loser(jaafar)
assert is_middle_eastern(jaafar)
assert is_doomed(omar)
assert fits_position_requirements(joe)
assert fits_position_requirements(sam)
assert not fits_position_requirements(omar)
assert is_school_boy(dany)
assert not is_possible_candidate(omar)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.