Example #1
0
def close_matches(s, global_dict):
    """
    Checks undefined names to see if they are close matches to a defined name.
    """

    tokens = sympy_tokenize.generate_tokens(StringIO(s.strip()).readline)
    result = []
    has_result = False
    all_names = set(global_dict).union(SYNONYMS)

    # strip the token location info to avoid strange untokenize results
    tokens = [(tok[0], tok[1]) for tok in tokens]
    for token in tokens:
        if (token[0] == NAME and
            token[1] not in all_names and
            len(token[1]) > 1):
            matches = difflib.get_close_matches(token[1], all_names)

            if matches and matches[0] == token[1]:
                matches = matches[1:]
            if matches:
                result.append((NAME, matches[0]))
                has_result = True
                continue
        result.append(token)
    if has_result:
        return sympy_tokenize.untokenize(result).strip()
    return None
Example #2
0
def close_matches(s, global_dict):
    """
    Checks undefined names to see if they are close matches to a defined name.
    """

    tokens = sympy_tokenize.generate_tokens(StringIO(s.strip()).readline)
    result = []
    has_result = False
    all_names = set(global_dict).union(SYNONYMS)

    for token in tokens:
        if (token[0] == NAME and
            token[1] not in all_names and
            len(token[1]) > 1):
            matches = difflib.get_close_matches(token[1], all_names)

            if matches and matches[0] == token[1]:
                matches = matches[1:]
            if matches:
                result.append((NAME, matches[0]))
                has_result = True
                continue
        result.append(token)
    if has_result:
        return sympy_tokenize.untokenize(result).strip()
    return None
Example #3
0
def parse_to_sympy(expr, local_dict=None):
    '''
    Parses a string into a sympy expression. The reason for not using `sympify`
    directly is that sympify does a ``from sympy import *``, adding all functions
    to its namespace. This leads to issues when trying to use sympy function
    names as variable names. For example, both ``beta`` and ``factor`` -- quite
    reasonable names for variables -- are sympy functions, using them as
    variables would lead to a parsing error.
    
    Parameters
    ----------
    expr : str
        The string expression to parse.
    local_dict : dict
        A dictionary mapping names to objects. These names will be left
        untouched and not wrapped in Symbol(...).
    
    Returns
    -------
    s_expr
        A sympy expression
    
    Raises
    ------
    SyntaxError
        In case of any problems during parsing.
    
    Notes
    -----
    This function is basically a stripped down version of sympy's
    `~sympy.parsing.sympy_parser._transform` function.  Sympy is licensed
    using the new BSD license:
    https://github.com/sympy/sympy/blob/master/LICENSE
    '''
    if local_dict is None:
        local_dict = {}
    
    tokens = generate_tokens(StringIO(expr).readline)
    
    result = []
    for toknum, tokval, _, _, _ in tokens:
        
        if toknum == NUMBER:
            postfix = []
            number = tokval
            
            # complex numbers
            if number.endswith('j') or number.endswith('J'):
                number = number[:-1]
                postfix = [(OP, '*'), (NAME, 'I')]

            # floating point numbers
            if '.' in number or (('e' in number or 'E' in number) and
                    not (number.startswith('0x') or number.startswith('0X'))):
                seq = [(NAME, 'Float'), (OP, '('), (NUMBER, repr(str(number))), (OP, ')')]
            # integers
            else:                
                seq = [(NAME, 'Integer'), (OP, '('), (NUMBER, number), (OP, ')')]

            result.extend(seq + postfix)
        elif toknum == NAME:
            name = tokval

            if name in ['True', 'False', 'None'] or name in local_dict:
                result.append((NAME, name))
                continue

            result.extend([
                (NAME, 'Symbol'),
                (OP, '('),
                (NAME, repr(str(name))),
                (OP, ')'),
            ])
        elif toknum == OP:
            op = tokval

            if op == '^':
                result.append((OP, '**'))            
            else:
                result.append((OP, op))
        else:
            result.append((toknum, tokval))

    code = untokenize(result)
    
    try:
        s_expr = eval(code, SYMPY_DICT, local_dict)
    except Exception as ex:
        raise SyntaxError('Expression "%s" could not be parsed: %s' %
                          (expr, str(ex)))

    return s_expr