Simple expression parsing throws a TypeError referencing 'AssumptionKeys'

Question:

I’m trying to get sympy to calculate the result of what should be a simple expression with three substitutions, but I’m coming up against an error I’ve not encountered before.

>>> from sympy import sympify, symbols 
>>> input_str = '100*Q+10*R+5*S+0.6*T'
>>> Q,R,S,T = symbols('Q R S T')

The above code works fine, but when I run the string though sympify, I get the following error:

>>> sympify(input_str)
ValueError: Error from parse_expr with transformed code: "Integer (100 )*Q +Integer (10 )*Symbol ('R' )+Integer (5 )*S +Float ('0.6' )*Symbol ('T' )"


The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "...ipykernel_5652212826607.py", line 1, in <cell line: 1>
    sympify(input_str)

  File "...PythonPython310site-packagessympycoresympify.py", line 496, in sympify
    expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)

  File "...PythonPython310site-packagessympyparsingsympy_parser.py", line 1101, in parse_expr
    raise e from ValueError(f"Error from parse_expr with transformed code: {code!r}")

  File "...PythonPython310site-packagessympyparsingsympy_parser.py", line 1092, in parse_expr
    rv = eval_expr(code, local_dict, global_dict)

  File "...PythonPython310site-packagessympyparsingsympy_parser.py", line 907, in eval_expr
    expr = eval(

  File "<string>", line 1, in <module>

TypeError: unsupported operand type(s) for *: 'Integer' and 'AssumptionKeys'

What on earth could be causing this error with such a simple expression?

Asked By: CDJB

||

Answers:

The problem is the character "Q". Once it gets sympified it will represent AssumptionKeys. You probably need to use something like this, in which we ask sympify to replace the character "Q" with symbol Q:

Q = symbols("Q")
sympify('100*Q+10*R+5*s+0.6*T', locals={"Q": Q})
Answered By: Davide_sd

Capital letters are reserved for other purposes in SymPy eg the singleton class is accessible as S while Q is a property of Sympy. Replace your capital letters by lower case letters and it should work:

    q, r, s, t = symbols('Q R S T')  
    input_str = '100*q +10*r + 5*s +0.6*t'  
    sympify(input_str)  
Answered By: Galo do Leste

Q is one of the single letter objects that are not symbols in SymPy. During sympification, functions (and some single-letter objects) are parsed as their SymPy definition. When used improperly (as in this case) it raises an error, just like parsing "cos + x" or "beta + alpha" would raise, the latter because beta is a function expecting 1 or 2 arguments. (For the record, all such single letter symbols are in "QOSINE"; any other letters will sympify without issues.) There is an issue opened for this here. One of the ways to deal with this is to pass the clashing symbols as locals during sympification as suggested in the abc.py file:

The module also defines some special names to help detect which names clash
with the default SymPy namespace.
_clash1 defines all the single letter variables that clash with
SymPy objects; _clash2 defines the multi-letter clashing symbols;
and _clash is the union of both. These can be passed for locals
during sympification if one desires Symbols rather than the non-Symbol
objects for those names.

>>> from sympy import S
>>> from sympy.abc import _clash1, _clash2, _clash
>>> S("Q & C", locals=_clash1)
C & Q
>>> S('pi(x)', locals=_clash2)
pi(x)
>>> S('pi(C, Q)', locals=_clash)
pi(C, Q)
Answered By: smichr
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.