Пример #1
0
    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
Пример #2
0
 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]
Пример #3
0
    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
Пример #4
0
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
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
    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
Пример #9
0
    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