def eval_input(self, s): namespace = {} exec(PREEXEC, {}, namespace) def plot(f=None, **kwargs): """Plot functions. Not the same as SymPy's plot. This plot function is specific to Gamma. It has the following syntax:: plot([x^2, x^3, ...]) or:: plot(y=x,y1=x^2,r=sin(theta),r1=cos(theta)) ``plot`` accepts either a list of single-variable expressions to plot or keyword arguments indicating expressions to plot. If keyword arguments are used, the plot will be polar if the keyword argument starts with ``r`` and will be an xy graph otherwise. Note that Gamma will cut off plot values above and below a certain value, and that it will **not** warn the user if so. """ pass namespace.update({ 'plot': plot, # prevent textplot from printing stuff 'help': lambda f: f }) evaluator = Eval(namespace) # change to True to spare the user from exceptions: if not len(s): return None transformations = [] transformations.append(synonyms) transformations.extend(standard_transformations) transformations.extend((convert_xor, custom_implicit_transformation)) parsed = stringify_expr(s, {}, namespace, transformations) logging.info(f"Parsed as: {parsed}") try: evaluated = eval_expr(parsed, {}, namespace) except SyntaxError as e: logging.exception(e) raise except Exception as e: raise ValueError(str(e)) input_repr = repr(evaluated) namespace['input_evaluated'] = evaluated return parsed, arguments(parsed, evaluator), evaluator, evaluated
def variableGet(self, expression): local_dict = {} global_dict = {} transformations = standard_transformations code = sympy_parser.stringify_expr(expression, local_dict, global_dict, transformations) code = sub(' ', '', code) pattern = compile(r'(?<=Symbol\(\').*?(?=\'\))') variableList = pattern.findall(code) pattern = compile(r'(?<=Function\(\').*?(?=\'\))') functionList = pattern.findall(code) return [variableList, functionList]
def eval_input(self, s): namespace = {} exec PREEXEC in {}, namespace def plot(f=None, **kwargs): """Plot functions. Not the same as SymPy's plot. This plot function is specific to Gamma. It has the following syntax:: plot([x^2, x^3, ...]) or:: plot(y=x,y1=x^2,r=sin(theta),r1=cos(theta)) ``plot`` accepts either a list of single-variable expressions to plot or keyword arguments indicating expressions to plot. If keyword arguments are used, the plot will be polar if the keyword argument starts with ``r`` and will be an xy graph otherwise. Note that Gamma will cut off plot values above and below a certain value, and that it will **not** warn the user if so. """ pass namespace.update({ 'plot': plot, # prevent textplot from printing stuff 'help': lambda f: f }) evaluator = Eval(namespace) # change to True to spare the user from exceptions: if not len(s): return None transformations = [] transformations.append(synonyms) transformations.extend(standard_transformations) transformations.extend((convert_xor, custom_implicit_transformation)) parsed = stringify_expr(s, {}, namespace, transformations) try: evaluated = eval_expr(parsed, {}, namespace) except SyntaxError: raise except Exception as e: raise ValueError(str(e)) input_repr = repr(evaluated) namespace['input_evaluated'] = evaluated return parsed, arguments(parsed, evaluator), evaluator, evaluated
def job(equations): response = "" i = 1 for equation in equations: if not equation.strip(): continue response += f"\r{i}. " try: parsed = stringify_expr(equation, {}, namespace, transforms) evaluated = eval_expr(parsed, {}, namespace) response += repr(evaluated) except Exception as e: response += f"{e.__class__.__name__} occured." i += 1 return response
def parse_expr(expression_str, *, local_dict=None, hints=None): """A copy of sympy.sympy_parser.parse_expr(...) which prevents all evaluation. Arbitrary untrusted input should be cleaned using "cleanup_string" before calling this method. This is almost a direct copy of the SymPy code, but it also converts inline relations like "==" or ">=" to the Relation class to prevent evaluation and uses a more aggresive set of transformations and better prevents any evaluation. It also ignores the 'global_dict', 'transformations' and 'evaluate' arguments of the original function. Hints can be provided to choose between ambiguous parsings, like 'i' being either a letter or sqrt(-1). These should be values from _PARSE_HINTS. """ if not isinstance(expression_str, str): return None elif expression_str == "" or len(expression_str) == 0: return None # Ensure the local dictionary is valid: if local_dict is None or not isinstance(local_dict, dict): local_dict = {} # If there are parse hints, add them to the local dictionary: if hints is not None and isinstance(hints, (list, tuple)): for hint in hints: if hint in _PARSE_HINTS: local_dict.update(_PARSE_HINTS[hint]) # FIXME: Avoid parsing issues with notation for Python longs. # E.g. the string '2L' should not be interpreted as "two stored as a long". # For now, just add a space to force desired behaviour: expression_str = re.sub(r'([0-9])([lL])', r'\g<1> \g<2>', expression_str) try: code = sympy_parser.stringify_expr(expression_str, local_dict, _GLOBAL_DICT, _TRANSFORMS) ef_code = evaluateFalse(code) code_compiled = compile(ef_code, '<string>', 'eval') return sympy_parser.eval_expr(code_compiled, local_dict, _GLOBAL_DICT) except (tokenize.TokenError, SyntaxError, TypeError, AttributeError, sympy.SympifyError) as e: print(("ERROR: {0} - {1}".format(type(e).__name__, str(e))).strip(":- ")) raise ParsingException
def eval_input(s): namespace = {} exec(PREEXEC, {}, namespace) def plot(f=None, **kwargs): pass namespace.update({ 'plot': plot, # prevent textplot from printing stuff 'help': lambda f: f }) transformations = list(standard_transformations) parsed = stringify_expr(s, {}, namespace, transformations) try: evaluated = eval_expr(parsed, {}, namespace) except SyntaxError: raise except Exception as e: raise ValueError(str(e)) return str(evaluated), latex(evaluated)
def eval_input(input_tree): namespace = {} exec(PREEXEC, {}, namespace) def plot(f=None, **kwargs): pass namespace.update({ 'plot': plot, # prevent textplot from printing stuff 'help': lambda f: f }) transformations = list(standard_transformations) parsed = stringify_expr(input_tree, {}, namespace, transformations) try: evaluated = eval_expr(parsed, {}, namespace) except SyntaxError: raise except Exception as e: raise ValueError(str(e)) return str(evaluated), latex(evaluated)
def evaluate_user_input(self, s): namespace = {} exec(PREEXEC, namespace) evaluator = Eval(namespace) if not len(s): return None transformations = [] transformations.append(synonyms) transformations.extend(standard_transformations) transformations.extend((convert_xor, custom_implicit_transformation)) parsed = stringify_expr(s, {}, namespace, transformations) try: evaluated = eval_expr(parsed, {}, namespace) except SyntaxError: raise except Exception as e: raise ValueError(str(e)) return parsed, arguments(parsed, evaluator), evaluator, evaluated
def eval_input(self, s): namespace = {} exec PREEXEC in {}, namespace evaluator = Eval(namespace) # change to True to spare the user from exceptions: if not len(s): return None transformations = [] transformations.append(synonyms) transformations.extend(standard_transformations) transformations.extend((convert_xor, custom_implicit_transformation)) local_dict = { 'plot': lambda *args: None # prevent textplot from printing stuff } global_dict = {} exec 'from sympy import *' in global_dict parsed = stringify_expr(s, local_dict, global_dict, transformations) evaluated = eval_expr(parsed, local_dict, global_dict) input_repr = repr(evaluated) namespace['input_evaluated'] = evaluated return parsed, arguments(parsed, evaluator), evaluator, evaluated