added generic rule generation
This commit is contained in:
78
core/functionality.py
Normal file
78
core/functionality.py
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
import sys
|
||||
import inspect
|
||||
|
||||
from typing import Union
|
||||
from random import SystemRandom
|
||||
|
||||
from core.meow import BasePattern, BaseRecipe, BaseRule
|
||||
from core.correctness.validation import check_input, valid_dict, valid_list
|
||||
from core.correctness.vars import CHAR_LOWERCASE, CHAR_UPPERCASE
|
||||
from patterns import *
|
||||
from recipes import *
|
||||
from rules import *
|
||||
|
||||
def check_pattern_dict(patterns, min_length=1):
|
||||
valid_dict(patterns, str, BasePattern, strict=False, min_length=min_length)
|
||||
for k, v in patterns.items():
|
||||
if k != v.name:
|
||||
raise KeyError(f"Key '{k}' indexes unexpected Pattern '{v.name}' "
|
||||
"Pattern dictionaries must be keyed with the name of the "
|
||||
"Pattern.")
|
||||
|
||||
def check_recipe_dict(recipes, min_length=1):
|
||||
valid_dict(recipes, str, BaseRecipe, strict=False, min_length=min_length)
|
||||
for k, v in recipes.items():
|
||||
if k != v.name:
|
||||
raise KeyError(f"Key '{k}' indexes unexpected Recipe '{v.name}' "
|
||||
"Recipe dictionaries must be keyed with the name of the "
|
||||
"Recipe.")
|
||||
|
||||
def generate_id(prefix:str="", length:int=16, existing_ids:list[str]=[],
|
||||
charset:str=CHAR_UPPERCASE+CHAR_LOWERCASE, attempts:int=24):
|
||||
random_length = max(length - len(prefix), 0)
|
||||
for _ in range(attempts):
|
||||
id = prefix + ''.join(SystemRandom().choice(charset)
|
||||
for _ in range(random_length))
|
||||
if id not in existing_ids:
|
||||
return id
|
||||
raise ValueError(f"Could not generate ID unique from '{existing_ids}' "
|
||||
f"using values '{charset}' and length of '{length}'.")
|
||||
|
||||
def create_rules(patterns:Union[dict[str,BasePattern],list[BasePattern]],
|
||||
recipes:Union[dict[str,BaseRecipe],list[BaseRecipe]],
|
||||
new_rules:list[BaseRule]=[])->dict[str,BaseRule]:
|
||||
check_input(patterns, dict, alt_types=[list])
|
||||
check_input(recipes, dict, alt_types=[list])
|
||||
valid_list(new_rules, BaseRule, min_length=0)
|
||||
|
||||
if isinstance(patterns, list):
|
||||
valid_list(patterns, BasePattern, min_length=0)
|
||||
patterns = {pattern.name:pattern for pattern in patterns}
|
||||
else:
|
||||
check_pattern_dict(patterns, min_length=0)
|
||||
|
||||
if isinstance(recipes, list):
|
||||
valid_list(recipes, BaseRecipe, min_length=0)
|
||||
recipes = {recipe.name:recipe for recipe in recipes}
|
||||
else:
|
||||
check_recipe_dict(recipes, min_length=0)
|
||||
|
||||
rules = {}
|
||||
|
||||
all_rules ={(r.pattern_type, r.recipe_type):r for r in [r[1] \
|
||||
for r in inspect.getmembers(sys.modules["rules"], inspect.isclass) \
|
||||
if (issubclass(r[1], BaseRule))]}
|
||||
|
||||
for pattern in patterns.values():
|
||||
if pattern.recipe in recipes:
|
||||
key = (type(pattern).__name__,
|
||||
type(recipes[pattern.recipe]).__name__)
|
||||
if (key) in all_rules:
|
||||
rule = all_rules[key](
|
||||
generate_id(prefix="Rule_"),
|
||||
pattern,
|
||||
recipes[pattern.recipe]
|
||||
)
|
||||
rules[rule.name] = rule
|
||||
return rules
|
Reference in New Issue
Block a user