Source code for ewoksfluo.math.expression

import re
from typing import Dict, Any, Tuple, Callable

import numpy


[docs] def expression_variables( expression: str, get_data: Callable[[str], Tuple[str, Any]], start_var: str = "<", end_var: str = ">", ) -> Tuple[str, Dict[str, Any], Dict[str, str]]: """Return the variables and associated expression to be evaluated. :param expression: for example `"<name A> * <name B>"` :param get_data: takes a variable name as input and returns its full name and value :param start_var: marks the start of a variable name :param end_var: marks the end of a variable name :returns: expression, variables and name map. For example expression `"data0 * data1"`, variables `{"data0":..., "data1":...}` and name map `{"data0":"name A", "data1":"name B"}`. """ pattern = rf"{re.escape(start_var)}([^{re.escape(end_var)}]+){re.escape(end_var)}" variables = {} name_map = {} for i, variable_name in enumerate(re.findall(pattern, expression)): new_name = f"data{i}" name_map[new_name], variables[new_name] = get_data(variable_name) expression = expression.replace( f"{start_var}{variable_name}{end_var}", new_name ) return expression, variables, name_map
[docs] def eval_expression(expression: str, variables: Dict[str, Any]) -> Any: """Evaluate an arithmetic expression with python and numpy arithmetic. :param expression: arithmetic expression where datasets are define as `data1` where `data1` must be a key in `variables`. :param variables: variables to be used in the expression """ globals = {"__builtins__": {"len": len, "sum": sum}, "np": numpy, "numpy": numpy} return eval(expression, globals, variables)