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?
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})
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)
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)
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?
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})
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)
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 forlocals
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)