formula_rule
Module for Formula Rule class
!!! classes Formula Rule
FormulaRule (RuleBase, IMultiCellBasedRule)
Implementation for the Formula rule
Source code in rules/formula_rule.py
class FormulaRule(RuleBase, IMultiCellBasedRule):
"""Implementation for the Formula rule"""
formula_output_name: str = "formula_result"
def __init__(self, name: str, input_variable_names: List[str], formula: str):
super().__init__(name, input_variable_names)
self._formula = formula
self._byte_code = None
self._setup_environment()
def validate(self, logger: ILogger) -> bool:
try:
byte_code = _compile_restricted(
f"{self.formula_output_name} = {self._formula}",
filename="<inline code>",
mode="exec",
)
local_variables = dict.fromkeys(self.input_variable_names, 1.0)
exec(byte_code, self._global_variables, local_variables)
except (SyntaxError, NameError) as exception:
logger.log_error(f"Could not create formula function: {exception}")
return False
return True
@property
def formula(self) -> str:
"""Multiplier property"""
return self._formula
def execute(self, values: Dict[str, float], logger: ILogger) -> float:
"""Calculates the formula based on the
Args:
values (DataArray): values to Formula
Returns:
float: Calculated float
"""
if not self._byte_code:
self._byte_code = _compile_restricted(
f"{self.formula_output_name} = {self._formula}",
filename="<inline code>",
mode="exec",
)
local_variables = values.copy()
try:
exec(self._byte_code, self._global_variables, local_variables)
except SyntaxError as exception:
logger.log_error(f"The formula can not be executed. {exception}")
return float(local_variables[self.formula_output_name])
def _setup_environment(self):
# use standard libraries that are considered safe
self._safe_modules_dict = {
"math": math,
"numpy": numpy,
}
# Global data available in restricted code
self._global_variables = {
"__builtins__": {**_safe_builtins, "__import__": self._safe_import},
**self._safe_modules_dict,
}
self._byte_code = None
def _safe_import(self, name, *args, **kwargs):
# Redefine import, to only import from safe modules
if name not in self._safe_modules_dict:
raise _ArgumentError(None, f"Importing {name!r} is not allowed!")
return __import__(name, *args, **kwargs)
formula: str
property
readonly
Multiplier property
execute(self, values, logger)
Calculates the formula based on the
Parameters:
Name | Type | Description | Default |
---|---|---|---|
values |
DataArray |
values to Formula |
required |
Returns:
Type | Description |
---|---|
float |
Calculated float |
Source code in rules/formula_rule.py
def execute(self, values: Dict[str, float], logger: ILogger) -> float:
"""Calculates the formula based on the
Args:
values (DataArray): values to Formula
Returns:
float: Calculated float
"""
if not self._byte_code:
self._byte_code = _compile_restricted(
f"{self.formula_output_name} = {self._formula}",
filename="<inline code>",
mode="exec",
)
local_variables = values.copy()
try:
exec(self._byte_code, self._global_variables, local_variables)
except SyntaxError as exception:
logger.log_error(f"The formula can not be executed. {exception}")
return float(local_variables[self.formula_output_name])
validate(self, logger)
Validates if the rule is valid
Returns:
Type | Description |
---|---|
bool |
wether the rule is valid |
Source code in rules/formula_rule.py
def validate(self, logger: ILogger) -> bool:
try:
byte_code = _compile_restricted(
f"{self.formula_output_name} = {self._formula}",
filename="<inline code>",
mode="exec",
)
local_variables = dict.fromkeys(self.input_variable_names, 1.0)
exec(byte_code, self._global_variables, local_variables)
except (SyntaxError, NameError) as exception:
logger.log_error(f"Could not create formula function: {exception}")
return False
return True