Thanks! This is working perfectly, with the small exception that I need 
globals() instead of locals().

By the way, I had already seen this in the documentation but didn't 
understand how to use it. The Sympy documentation at
https://docs.sympy.org/latest/modules/parsing.html#:~:text=A%20tuple%20of%20transformation%20functions%20used%20to%20modify,use%20of%20standard%20mathematical%20factorial%20notation%20%28e.g.%20x%21
mentions local_dict and global_dict, but doesn't say much on how to use it 
(probably documented somewhere else, but I didn't do much searching for 
that).
This site gives 17 examples:
https://www.programcreek.com/python/example/100568/sympy.parsing.sympy_parser.parse_expr
including a case that uses global_dict=global_dict, but that didn't work 
for me (it probably requires creating a dictionary called global_dict, but 
that is not part of the sample).

On Saturday, November 7, 2020 at 1:47:14 AM UTC+1 [email protected] wrote:

> parse_expr converts any unknown variable names into symbols. If you
> already have the variable Round1Bar defined as something you want it
> to use, you should pass it in the locals dictionary, like
>
> parse_expr('Round1Bar', {'Round1Bar', symbols(r'\(1\)')})
>
> Or if you already have them defined you can just use
>
> parse_expr('Round1Bar', locals())
>
> Aaron Meurer
>
> On Fri, Nov 6, 2020 at 3:54 PM Thomas Ligon <[email protected]> wrote:
> >
> > Hi Aaron,
> > this remark really throws me off. I certainly didn't think that Round 
> was a shortcut for anything. Here is how I understood Sympy:
> > When I write
> > Round1 = symbols('\\(1\\)')
> > then I assume that the right-hand side is the form used by Sympy for 
> printout, especially for print(latex(...)), and the left-hand side is just 
> a name that I invent, meaning that Round is my way of remembering what it 
> is, and the name should avoid special characters that I want in the 
> printout, such as parentheses and minus signs, because they cause unwanted 
> things to happen in an expression. By the way, that is why I have a Roundm2 
> = symbols('\\(-2\\)')
> > meaning that I have used "m" to indicate (to me) that this is minus 2, 
> but avoiding "-" in a name.
> > Now, as a bit more background, (j) is an arithmetic expression involving 
> j and m (a constant in this context), meaning that (j) is a shortcut for 
> something that would fill a lot of space in a normal printout.
> > By the way, in the recent test code
> > print(latex(Round1))
> > print(latex(parse_expr('Round1')))
> > print(latex(Round1Bar))
> > print(latex(parse_expr('Round1Bar')))
> > produces
> > \(1\)
> > Round_{1}
> > \bar{\(1\)}
> > \bar{Round1}
> > so the problem I have is that
> > print(latex(symbolname))
> > and
> > print(latex(parse_expr('symbolname')))
> > are different. My old code with static limits uses the first case, and 
> the new code with variable limits uses the second.
> > I can see now that parse_expr('string') is not converting 'string' into 
> the name of a symbol, as I expected. I also see that suffix 1 is being 
> converted to _{1} (as you mentioned earlier) and suffix Bar is being 
> converted to prefix \bar. That explains where this form is coming from.
> > Finally, here is one more test to avoid the automatic assumption about 
> suffixes (like Microsoft Word's autocorrect, but I won't go into that rant 
> here).
> > Round2BarX = symbols('\\bar{\\(2\\)}')
> > print(latex(Round2BarX))
> > print(latex(parse_expr('Round2BarX')))
> > produces
> > \bar{\(2\)}
> > Round2BarX
> >
> > On Friday, November 6, 2020 at 10:25:54 PM UTC+1 [email protected] 
> wrote:
> >>
> >> I think Round as a shortcut for putting parentheses around something
> >> is not implemented in the LaTeX printer. I've never seen that before,
> >> but if it is common, we can add it. Otherwise, if you need custom
> >> LaTeX in your symbol names you should just use it directly in the
> >> symbol name.
> >>
> >> Aaron Meurer
> >>
> >> On Fri, Nov 6, 2020 at 1:15 PM Thomas Ligon <[email protected]> 
> wrote:
> >> >
> >> > Thanks again for the very valuable help. I think I am getting very 
> close to a good solution, but I must still have a bug in there.
> >> > First, just a small piece of background: I am using some symbols like
> >> > Round1 = symbols('\\(1\\)')
> >> > Round1Bar = symbols('\\Bar{\\(1\\)}')
> >> > In other words, a "1" in parentheses and the same thing with a bar 
> over it, plus some using square brackets. These were defined and used in 
> two papers I am referring to, published in 1854 and 1896, both by famous 
> mathematicians. One version of my code used something like E_1 instead, but 
> this time I chose to stick to the old symbols, even though they are not 
> typical today, since they could be confused with normal parentheses.
> >> > Now, I have working code that has a hard-coded limit on the number of 
> symbols and I need to upgrade it so that it can handle an undetermined 
> (perhaps large) number of symbols. When creating expressions, I am using 
> functions like this one:
> >> > def getRoundjBar (j):
> >> > strJ = str(abs(j))
> >> > if j < 0:
> >> > strJ = 'm' + strJ
> >> > strSym = 'Round' + strJ + 'Bar'
> >> > return parse_expr(strSym)
> >> > and here is some test code showing it in action:
> >> > ret1 = getRoundjBar(1)
> >> > print(ret1)
> >> > print(latex(ret1))
> >> > I can see that it is important for me to understand the type of the 
> variable and, fortunately, the "Locals" window in my debugger shows that 
> ret1 contains the value Round1Bar and has type Symbol. Good, that makes 
> almost everything work well, but
> >> > print(latex(ret1))
> >> > produces
> >> > \bar{Round1}
> >> > where it should produce
> >> > \\bar{\(1\)}
> >> >
> >> > On Wednesday, November 4, 2020 at 9:46:03 PM UTC+1 [email protected] 
> wrote:
> >> >>
> >> >> You can't use exec() to do a return statement for a function that is
> >> >> not also part of the string. What you want is eval(), which evaluates
> >> >> an expression and returns it, like
> >> >>
> >> >> return eval(string)
> >> >>
> >> >> However, you should consider just using sympify() or parse_expr() if
> >> >> you are evaluating strings to SymPy expressions, as they are designed
> >> >> for that and will give you things like automatically defining the
> >> >> symbols.
> >> >>
> >> >> Actually, for what you've shown, I don't see the need to use exec() 
> or
> >> >> eval() at all. You can just create the symbols from the strings, like
> >> >> Symbol('a' + str(j)). Symbols are completely defined by name, so if
> >> >> two symbols have the same name, they will be equal.
> >> >>
> >> >> Aaron Meurer
> >> >>
> >> >> On Wed, Nov 4, 2020 at 2:24 AM Thomas Ligon <[email protected]> 
> wrote:
> >> >> >
> >> >> > Now I see a solution: forget the function and create the 
> expression exp using string manipulation and exec, something like
> >> >> > strExp = 'complex string'
> >> >> > strSym = 'exp = ' + strExp
> >> >> > exec(strSym)
> >> >> >
> >> >> > On Wednesday, November 4, 2020 at 9:51:35 AM UTC+1 Thomas Ligon 
> wrote:
> >> >> >>
> >> >> >> Thanks!
> >> >> >> The automatic subscript is just a minor irritation, and your 
> response is helpful.
> >> >> >> I have included a new test program that hopefully no longer 
> oversimplifies the situation. Currently, I have code (2000 lines) for 
> investigating a very complex series, and it runs to a maximum of 3 terms of 
> the series, requiring index values up to 6. I showed the results to the 
> mathematics professor who has mentored my work and he immediately says that 
> it is valuable and I should publish a version that can go up to a very 
> large number of terms. In order to do that, I need to produce a fully 
> automated version with a variable number of terms and indices.
> >> >> >> So, for variable j, I want to use a_j in a formula.
> >> >> >> The expression exp on line 20 does that, where I use get_a(1) to 
> represent aj for variable j, where j happens to be 1.
> >> >> >> In line 5, the return is part of a function. In line 8, I expect 
> return in exec ('return...') to be a part of a function.
> >> >> >>
> >> >> >> maxIndex = 2
> >> >> >> import sympy
> >> >> >> from sympy import symbols, latex
> >> >> >> def get_a1():
> >> >> >> return a1
> >> >> >> def get_a2():
> >> >> >> strSym = 'return a2'
> >> >> >> exec(strSym)
> >> >> >> def get_a (j):
> >> >> >> strSym = 'return a' + str(j)
> >> >> >> exec(strSym)
> >> >> >> lam = symbols('\\lambda')
> >> >> >> for ind in range(1,maxIndex+1):
> >> >> >> strSym = 'a' + str(ind) + ' = symbols(\'a_' + str(ind) + '\')'
> >> >> >> exec(strSym)
> >> >> >> #a1 = symbols('a_1')
> >> >> >> #a2 = symbols('a_2')
> >> >> >> print(latex(get_a1()))
> >> >> >> #print(latex(get_a2())) # causes 'return' outside function 
> (<string>, line 1)
> >> >> >> exp = 3*get_a(1) + 5*get_a(2)*lam**2 # causes 'return' outside 
> function (<string>, line 1)
> >> >> >> print(latex(exp))
> >> >> >> print('end testSym')
> >> >> >>
> >> >> >> On Tuesday, November 3, 2020 at 11:29:00 PM UTC+1 
> [email protected] wrote:
> >> >> >>>
> >> >> >>> I'm unclear what you're trying to achieve with the functions. 
> exec()
> >> >> >>> takes a string of Python code and executes it. The entire string 
> must
> >> >> >>> be valid Python code by itself, so exec('return x') fails 
> because a
> >> >> >>> bare "return x" is not valid Python. "return" must be inside a
> >> >> >>> function definition to be valid. But even defSym1 doesn't do 
> anything
> >> >> >>> useful beyond just returning Sym1, so there's no point to having 
> it
> >> >> >>> instead of just "Sym1" directly.
> >> >> >>>
> >> >> >>> The LaTeX version of Sym1 contains _ because SymPy automatically
> >> >> >>> assumes that symbol names ending in numbers are subscripted, so 
> it
> >> >> >>> renders it as a Sym_1 in LaTeX. If you don't want the 1 to be
> >> >> >>> subscripted, you can use something like Symbol("{Sym1}").
> >> >> >>>
> >> >> >>> Aaron Meurer
> >> >> >>>
> >> >> >>> On Tue, Nov 3, 2020 at 9:42 AM Thomas Ligon <[email protected]> 
> wrote:
> >> >> >>> >
> >> >> >>> > The following code is not working as I expected.
> >> >> >>> > Why does Sym1 contain an underline (_{1})?
> >> >> >>> > Why does return fail (unhandled exception) in line 7?
> >> >> >>> >
> >> >> >>> > Code:
> >> >> >>> > import sympy
> >> >> >>> > from sympy import symbols, latex
> >> >> >>> > def defSym1():
> >> >> >>> > return Sym1
> >> >> >>> > def defSym2():
> >> >> >>> > strSym = 'return Sym2'
> >> >> >>> > exec(strSym)
> >> >> >>> > Sym1 = symbols('Sym1')
> >> >> >>> > Sym2 = symbols('Sym2')
> >> >> >>> > print(latex(defSym1()))
> >> >> >>> > print(latex(defSym2()))
> >> >> >>> > print('end testSym')
> >> >> >>> >
> >> >> >>> > Output:
> >> >> >>> > Sym_{1}
> >> >> >>> > 'return' outside function (<string>, line 1)
> >> >> >>> >
> >> >> >>> >
> >> >> >>> >
> >> >> >>> >
> >> >> >>> > --
> >> >> >>> > 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/4a1df466-d3a3-4f7b-8a14-5e5a906f2662n%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/00d00ac2-7b0c-4ac1-b81a-dcc9f7956572n%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/24d5bbe0-8388-4564-ad2f-10fa6412c94bn%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/2c2986a7-9d96-4dba-af62-b840c0c1736en%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/69e4e4b8-bfd0-4b38-b4c7-d32eeb734c91n%40googlegroups.com.

Reply via email to