Fhernd icon

rule.py

Fhernd | PRO | 02/21/26 10:45:22 PM UTC | 0 ⭐ | 12333 👁️ | Never ⏰ | []
Python |

1.89 KB

|

Source Code

|

0 👍

/

0 👎

import functools
import operator
import inspect
from typing import Callable, Any, Dict, List
 
 
class Rule:
    def __init__(self, func: Callable[[Dict[str, Any]], bool], name: str = None):
        self.func = func
        self.name = name or func.__name__
 
    def __call__(self, context: Dict[str, Any]) -> bool:
        return self.func(context)
 
    def __and__(self, other: "Rule") -> "Rule":
        return Rule(lambda ctx: self(ctx) and other(ctx),
                    name=f"({self.name} AND {other.name})")
 
    def __or__(self, other: "Rule") -> "Rule":
        return Rule(lambda ctx: self(ctx) or other(ctx),
                    name=f"({self.name} OR {other.name})")
 
    def __invert__(self) -> "Rule":
        return Rule(lambda ctx: not self(ctx),
                    name=f"(NOT {self.name})")
 
 
class RuleEngine:
    def __init__(self):
        self.rules: List[Rule] = []
 
    def register(self, rule: Rule):
        self.rules.append(rule)
 
    def evaluate(self, context: Dict[str, Any]) -> Dict[str, bool]:
        results = {}
        for rule in self.rules:
            try:
                results[rule.name] = rule(context)
            except Exception as e:
                results[rule.name] = False
        return results
 
 
def auto_rule(fn):
    sig = inspect.signature(fn)
    def wrapper(ctx):
        bound = {k: ctx.get(k) for k in sig.parameters}
        return fn(**bound)
    return Rule(wrapper, name=fn.__name__)
 
 
@auto_rule
def is_adult(age):
    return age >= 18
 
 
@auto_rule
def high_income(income):
    return income > 5000
 
 
@auto_rule
def country_allowed(country):
    return country in {"CL", "MX", "CO"}
 
 
engine = RuleEngine()
engine.register(is_adult & high_income | country_allowed)
engine.register(~high_income & is_adult)
 
context = {"age": 25, "income": 3000, "country": "CL"}
print(engine.evaluate(context))

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎