Skip to content

Instantly share code, notes, and snippets.

@MaxHalford
Created December 6, 2020 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaxHalford/4c4f2d5dcc1eb26e32c1e84a64236bf9 to your computer and use it in GitHub Desktop.
Save MaxHalford/4c4f2d5dcc1eb26e32c1e84a64236bf9 to your computer and use it in GitHub Desktop.
Rule-based system
import abc
class Rule(abc.ABC):
def __init__(self, var_name):
self.var_name = var_name
@abc.abstractmethod
def __repr__(self):
"""String representation of the Python expression."""
@abc.abstractmethod
def __call__(self, obj):
"""Evaluates an object's properties."""
class HigherThan(Rule):
def __init__(self, var_name, low):
super().__init__(var_name)
self.low = low
def __repr__(self):
return f'{self.var_name} > {self.low}'
def __call__(self, obj):
return getattr(obj, self.var_name) > self.low
class LowerThan(Rule):
def __init__(self, var_name, high):
super().__init__(var_name)
self.high = high
def __repr__(self):
return f'{self.var_name} < {self.high}'
def __call__(self, obj):
return getattr(obj, self.var_name) < self.high
class Between(Rule):
def __init__(self, var_name, low, high):
super().__init__(var_name)
self.low = low
self.high = high
def __repr__(self):
return f'{self.low} < {self.var_name} < {self.high}'
def __call__(self, obj):
return self.low < getattr(obj, self.var_name) < self.high
class And(Rule):
def __init__(self, *rules):
self.rules = rules
def __repr__(self):
return ' & '.join(map(str, self.rules))
def __call__(self, obj):
return all(rule(obj) for rule in self.rules)
@classmethod
def from_str(cls, s):
rules = []
for rule in s.split(' & '):
if rule.count('<') == 2:
low, name, high = rule.split(' < ')
rules.append(Between(name, float(low), float(high)))
elif '>' in rule:
name, low = rule.split(' > ')
rules.append(HigherThan(name, float(low)))
elif '<' in rule:
name, high = rule.split(' < ')
rules.append(LowerThan(name, float(high)))
return cls(*rules)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment