Title: Unexpected behaviour when parsing string with sympy
Tags: python;python-3.x;math;sympy;symbolic-math
Question: I'm trying to perform the derivative of an equation with sympy, but, while if I write the equation by hand the derivative is correct; when I pass the equation as a string, the output is wrong. Can anyone explain me how to solve this issue? I'm using python 3.6 and sympy 1.5.1.
&gt;&gt;&gt;from sympy import *
&gt;&gt;&gt;from operator import *
&gt;&gt;&gt; x1 = symbols('x1')
&gt;&gt;&gt; f = add(sin(x1), mul(x1, x1))
&gt;&gt;&gt; diff(f, x1)
2*x1 + cos(x1)   ## Correct output
&gt;&gt;&gt;&gt; f = 'add(sin(x1), mul(x1, x1))'  ## Equation provided as string
&gt;&gt;&gt;&gt; diff(f, x1)
(Subs(Derivative(mul(_xi_1, x1), _xi_1), _xi_1, x1) + Subs(Derivative(mul(x1, _xi_2), _xi_2), _xi_2, x1))*Subs(Derivative(add(sin(x1), _xi_2), _xi_2), _xi_2, mul(x1, x1)) + cos(x1)*Subs(Derivative(add(_xi_1, mul(x1, x1)), _xi_1), _xi_1, sin(x1))  ## Wrong output

Here is the accepted answer: This is happening because f = 'add(sin(x1), mul(x1, x1))' is not a valid mathematical equation that can be parsed by parse_expr. This function is designed to parse equations written in mathematical syntax, not in terms of Sympy functions. To get this function in particular to be parsed correctly, you would need to use, for example:
&gt;&gt;&gt; f = 'sin(x1) +  x1^2'
&gt;&gt;&gt; diff(f, x1)
2*x1 + cos(x1)
If you really need to use that specific string, you could use eval():
&gt;&gt;&gt; f = 'add(sin(x1), mul(x1, x1))'
&gt;&gt;&gt; diff(eval(f), x1)
2*x1 + cos(x1)

Here is another answer: If you want to write it in this fashion, be sure to use the actual SymPy object names (which are capitalized). I use S(...) to interpret the expression and that is the same thing that any function would do, too:
&gt;&gt;&gt; S('Add(sin(x1), Mul(x1, x1))')
x1**2 + sin(x1)
But you can also use the mathematical operators + and *:
&gt;&gt;&gt; S('sin(x1) + x1*x1')
x1**2 + sin(x1)

Here is another answer: Sympy provides parser functions to turn string into sympy object, see doc parse_expr.
For custom functions translation you can make a mapping with those provide by sympy and pass it as argument, local_dict,  to the parser.
from sympy import Add, Mul, sin
from sympy.parsing.sympy_parser import parse_expr
f = parse_expr('add(sin(x1), mul(x1, x1))', local_dict={'add': Add, 'mul': Mul})
f.diff('x1')
Output
2x1 + cos(x1)

Here is another answer: You shouldn't pass strings directly to SymPy functions. Rather, first parse them with sympify (which is the same as S). You can pass a dictionary of names as the second argument to sympify if you want non-standard names like add to map to existing SymPy ones, like
sympify('add(x, y)', {'add': Add}) # Gives x + y
Otherwise sympify will assume that any unknown functions are undefined functions like f(x).

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2020:00:01/31/20', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<python><python-3.x><math><sympy><symbolic-math>', 'Title': 'Unexpected behaviour when parsing string with sympy', 'ViewCount': 144, 'id': 60002903, 'user_AboutMe': None, 'user_AccountId': 15958726.0, 'user_DisplayName': 'Francesco', 'user_Reputation': 23.0, 'user_Views': 2.0, 'user_id': 11516376.0}}