I would suggest not even working with strings at all, especially if
you are just going to parse everything with parse_expr or sympify. You
can make expr1 and expr2 symbols, and map the symbols to expressions
with a dict:

expr2 = symbols('expr1 expr2')
repl_dict = {expr2: 1.01 * a**1.01 * b**0.99}

Then when you encounter an expression that has expr2 and you want it
to instead contain 1.01 * a**1.01 * b**0.99, use
expression.subs(repl_dict).

If you find yourself doing a lot of string manipulation in SymPy, it's
generally a sign that you're doing something incorrectly, and you
should just use symbolic expressions directly instead. For example, in
your verify_ratio() function, instead of

print(vstr1 + ' / ' + vstr2, '=', sp.N(ratio))

you could just have

ratio = v1/v2
print(ratio, '=', sp.N(ratio.subs(repl_dict)))

where v1 and v2 are just the symbols expr1 and expr2.

And in fact, unless you are dealing with arbitrary user input, the
string parsing is unnecessary too.

Aaron Meurer

On Mon, Jan 9, 2023 at 3:55 PM Oscar Benjamin
<[email protected]> wrote:
>
> This question was also asked and answered in other places:
>
> https://github.com/sympy/sympy/discussions/24483
> https://stackoverflow.com/questions/75057460/convert-string-of-a-named-expression-in-sympy-to-the-expression-itself
>
> The OP wants eval:
>
> In [1]: expr1 = x*y + 1
>
> In [2]: expr1
> Out[2]: x⋅y + 1
>
> In [3]: eval('expr1')
> Out[3]: x⋅y + 1
>
> However this is not a good approach. A better one would be to avoid
> global variables and use a data structure such as a dict:
>
> In [4]: my_dict = {'expr1': x*y + 1}
>
> In [5]: my_dict['expr1']
> Out[5]: x⋅y + 1
>
> --
> Oscar
>
> On Mon, 9 Jan 2023 at 21:12, [email protected] <[email protected]> wrote:
> >
> > If you really do need to process strings, I think I see where you are 
> > having an issue with your experiment. 'expr2' does not give you the string 
> > representation of 'expr2'. I think you want this sequence of commands:
> > ```
> > >>> import sympy as sp
> > >>> a, b = sp.symbols('a,b', real=True, positive=True)
> > >>> expr2 = 1.01 * a**1.01 * b**0.99
> > >>> print(type(expr2),'->',expr2)
> > <class 'sympy.core.mul.Mul'> -> 1.01*a**1.01*b**0.99
> > >>> expr2b = sp.parsing.sympy_parser.parse_expr(str(expr2))
> > >>> print(type(expr2b),'->',expr2b)
> > <class 'sympy.core.mul.Mul'> -> 1.01*a**1.01*b**0.99
> > ```
> >
> > Is that the behavior you are trying to achieve?
> >
> > One comment. This is a place where sympy does not quite abide by python 
> > standards. In sympy the call str(expression) yields the sympy code for the 
> > expression. By python standards that should actually be returned by a call 
> > to repr(expression), while str(expression) should return a human readable 
> > representation. Most of the time there is not a difference anyway for sympy 
> > expressions. If you want to abide by python standards you can replace 
> > str(expression) with repr(expression). Others may know of problems, but I 
> > have not encountered any place where repr(expression) does not work.
> > On Monday, January 9, 2023 at 2:45:26 PM UTC-6 Santiago S wrote:
> >>
> >> Because I want to build the name of the expressions to check by 
> >> concatenating other strings, and then evaluate.
> >> All this within loops, etc.
> >>
> >>
> >>
> >> On Monday, January 9, 2023 at 1:42:26 PM UTC-3 [email protected] wrote:
> >>>
> >>> I am not clear why you are working with strings and not just the 
> >>> expressions? I think the following may be what you want:
> >>> ```
> >>> >>> import sympy as sp
> >>> >>> a,b = sp.symbols('a b', positive = True)
> >>> >>> expr = 1.01*a**1.01*b**0.99
> >>> >>> expr
> >>> 1.01*a**1.01*b**0.99
> >>> >>> expr1 = 2*expr
> >>> >>> expr1
> >>> 2.02*a**1.01*b**0.99
> >>> >>> expr1/expr
> >>> 2.00000000000000
> >>> ```
> >>> Your "verify ratio function" would then just take the two expressions 
> >>> directly. If you are trying to do something where you need to have 
> >>> intermediate strings, we will need more explicit details to provide some 
> >>> direction.
> >>>
> >>> On Monday, January 9, 2023 at 10:00:04 AM UTC-6 Santiago S wrote:
> >>>>
> >>>> I have the following code
> >>>>
> >>>>     import sympy as sp
> >>>>     a, b = sp.symbols('a,b', real=True, positive=True)
> >>>>     expr2 = 1.01 * a**1.01 * b**0.99
> >>>>     print(type(expr2), '->', expr2)
> >>>>
> >>>>
> >>>> Now I want a function that takes the string `'expr2'` and returns the 
> >>>> expression `1.01 * a**1.01 * b**0.99`.
> >>>> The ultimate objective is to put together the strings for two different 
> >>>> expressions `'expr2'` and `'expr3'`, which should presumably give the 
> >>>> same result, and verify their ratio, as in
> >>>>
> >>>>     def verify_ratio(vstr1, vstr2):
> >>>>         """Compare the result of two different computations of the same 
> >>>> quantity"""
> >>>>         ratio = sp.N(sp.parsing.sympy_parser.parse_expr(vstr1)) / 
> >>>> sp.parsing.sympy_parser.parse_expr(vstr2)
> >>>>         print(vstr1 + ' / ' + vstr2, '=', sp.N(ratio))
> >>>>         return
> >>>>
> >>>> which does not work, as per what I tried:
> >>>>
> >>>>     expr2 = 1.01 * a**1.01 * b**0.99
> >>>>     print(type(expr2), '->', expr2)
> >>>>
> >>>>     expr2b = sp.parsing.sympy_parser.parse_expr('expr2')
> >>>>     print(type(expr2b), '->', expr2b)
> >>>>
> >>>>     expr2c = sp.N(sp.parsing.sympy_parser.parse_expr('expr2'))
> >>>>     print(type(expr2c), '->', expr2c)
> >>>>     #print(sp.N(sp.parsing.sympy_parser.parse_expr('expr2')))
> >>>>
> >>>>     expr2d = sp.sympify('expr2')
> >>>>     print(type(expr2d), '->', expr2d)
> >>>>
> >>>> with output
> >>>>
> >>>>     <class 'sympy.core.mul.Mul'> -> 1.01*a**1.01*b**0.99
> >>>>     <class 'sympy.core.symbol.Symbol'> -> expr2
> >>>>     <class 'sympy.core.symbol.Symbol'> -> expr2
> >>>>     <class 'sympy.core.symbol.Symbol'> -> expr2
> >>>>
> >>>> None of my attempts achieved the objective.
> >>>> Questions or links which did not help (at least for me):
> >>>>
> >>>>  1. 
> >>>> https://stackoverflow.com/questions/33606667/from-string-to-sympy-expression
> >>>>  2. 
> >>>> https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html
> >>>>  3. https://docs.sympy.org/latest/modules/parsing.html
> >>>>  4. 
> >>>> https://docs.sympy.org/latest/modules/core.html#sympy.core.sympify.sympify
> >>>>  5. 
> >>>> https://docs.sympy.org/latest/tutorials/intro-tutorial/manipulation.html
> >>>>
> >>>>
> >>>> **Note**:
> >>>> Besides the practical aspects of my objective, I don't know if there is 
> >>>> any formal difference between `Symbol` (which is a specific class) and 
> >>>> *expression*. From the sources I read (e.g., [this][1]) I did not arrive 
> >>>> to a conclusion.
> >>>> This understanding may help in solving the question.
> >>>>
> >>>>
> >>>>   [1]: 
> >>>> https://docs.sympy.org/latest/tutorials/intro-tutorial/manipulation.html
> >
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "sympy" group.
> > To unsubscribe from this group and stop receiving emails from it, send an 
> > email to [email protected].
> > To view this discussion on the web visit 
> > https://groups.google.com/d/msgid/sympy/a71eff85-9948-45cd-aab0-0a1cad1f2c4cn%40googlegroups.com.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sympy/CAHVvXxRnCPP%2BTJU1xpMf_LiLRuvoTSDQJKg1ts-RhMC4kPpO8A%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/CAKgW%3D6Jpe2tdqMpoKCDcASUVG1fDT7Xtwp5gcY0SxsuBEVw%2Bfw%40mail.gmail.com.

Reply via email to