Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert sympy Symbol to string such that it can always be parsed?

I'm looking for a way to convert an arbitrary sympy symbol to a string such that it can later be parsed back into the same symbol. For example, I would like to be able to do something like this:

from sympy.parsing.sympy_parser import parse_expr
from sympy import Symbol

A = Symbol("A")
B = Symbol("B")
pathological = Symbol("A B")
parsed = parse_expr(str(pathological)) # this raises an error
assert parsed == pathological

Instead of parsing str(pathological) as representing the pathological symbol, the parser parses A and B separately and we get the following error:

File "<string>", line 1
Symbol ('A' )Symbol ('B' )
                  ^
SyntaxError: invalid syntax

Is there a way to create an escaped string from pathological that is guaranteed to be parsed back to pathological?

The reason I am trying to do this is so that I can store sympy expressions as JSON and reconstruct them. If there is a completely different way to do that, I would be happy to hear.

like image 471
Paul Wintz Avatar asked Oct 15 '25 20:10

Paul Wintz


2 Answers

For such symbols I would store the srepr() form. It may be too much to store that for the whole expression so perhaps it would be useful to make a custom printer that does what StrPrinter does except when necessary falls back to ReprPrinter. See https://docs.sympy.org/latest/modules/printing.html

like image 117
asmeurer Avatar answered Oct 18 '25 10:10

asmeurer


If you have access to the pathological symbols before they are converted to strings then you can create a "kerned" version that will parse ok and pass the kerned version with the desired version in a local_dict. re.escape will put a backslash in front of the space and the kerned version will replace that \ with something unique:

>>> kerned = re.escape(str(pathological)).replace('\\ ','_kern_')
>>> d = {kerned: pathological}
>>> parse_expr(kerned, d)
A B
like image 38
smichr Avatar answered Oct 18 '25 10:10

smichr