On Thu, Aug 30, 2012 at 12:41 AM, Juha Jeronen <[email protected]> wrote:
> Hi,
>
> On 29/08/12 20:29, Ronan Lamy wrote:
>>>
>>>>>>> dir(S)
>>>> ['Catalan', 'ComplexInfinity', 'EmptySet', 'EulerGamma', 'Exp1',
>>>> 'GoldenRatio', 'Half', 'IdentityFunction', 'ImaginaryUnit',
>>>> 'Infinity', 'Integers', 'NaN', 'Naturals', 'NegativeInfinity',
>>>> 'NegativeOne', 'NumberSymbol', 'One', 'Pi', 'Reals', 'UniversalSet',
>>>> 'Zero', '__call__', '__class__', '__delattr__', '__doc__',
>>>> '__format__', '__getattribute__', '__hash__', '__init__',
>>>> '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
>>>> '__setattr__', '__sizeof__', '__slots__', '__str__',
>>>> '__subclasshook__']
>>> Thanks!
>>>
>>> So, dir(S) is the preferred way of getting a complete list :)
>>>
>>> It also works in both old and new versions, so that's good. I think the
>>> only remaining question is if this is likely to stay working for the
>>> foreseeable future?
>>
>> Actually, if you use sympify(), almost everything in the sympy
>> namespace is handled specially ('C' is probably the only significant
>> exception, for obscure reasons), so IIUC the list you want is
>> dir(sympy). The way parsing works now is hackish and probably unsafe,
>> so don't count on it remaining the same.
>
> Ah, thanks.
>
> dir(sympy) looks applicable at least on first glance.
>
> I think you did understand correctly - the aim is to obtain a list of
> reserved strings which sympify() will parse into something else than a
> generic Symbol. This list is then used to ensure that any user-defined
> quantities (in the FEM solver) will parse as expected, before the
> user-given expressions are given to SymPy.
>
>
> It seems, though, that just the string is not enough information. For
> example, in 0.7.x there is the LT() function (to get the leading term),
> but e.g. the following is nevertheless valid:
>
> expr = sy.sympify("LT*a")  # no error, expr will have Symbols "LT" and "a"
> # artificial example: let's replace the symbol "LT" by sin(x)
> my_LT = sy.symbols("LT")  # refer to the Symbol "LT", not function LT()
> expr.subs( {my_LT : sy.sympify("sin(x)")} )

This works in the latest version. The reason is that LT was not added
until 0.7.0.

Aaron Meurer

>
> So maybe functions should be ignored? But on the third hand,
>
> expr = sy.sympify("sin*a")
>
> triggers a TypeError; "sin" is recognized as the standard sine function
> even if it has no parentheses to denote a function call. (At least in
> 0.6.7; I have 0.7.1 only at home, so can't check it right now.)
>
> So it seems there is no general rule?
>
>
> (The way I ran into this was that when developing with 0.6.x, I happened
> to decide that I would use the prefix "L" to denote the Laplacian of a
> quantity in my equation processor. Then, running the code on 0.7.1
> later, with a quantity named "T", produced a surprise...)
>
>
>>>>> And finally, a related question: is there a way to get a
>>>>> human-readable
>>>>> description for a reserved name (e.g. "zoo" -> "complex infinity")? I
>>>>> didn't find anything in the API for this.
>>>> Not sure how to go further than
>>>>
>>>>>>> type(oo)
>>>> <class 'sympy.core.numbers.Infinity'>
>>> Aaaahh, the type! Nice.
>>>
>>> Thanks!
>> You can also access the attributes of the type, e.g. type(oo).__name__
>
> Ok. Thanks for the tip.
>
>
>>> The final code that I ended up using (modulo variable naming and
>>> comments) is:
>>>
>>> ---8<---8<---8<---
>>>
>>> rawnames = filter( lambda name: re.match("__", name) is None,
>>> dir(sy.S) )
>>> objs = map( lambda name: eval("sy.S.%s" % name),  rawnames )
>>> objs = filter( lambda obj: not obj.is_Number,  objs )
>>> strs = map( lambda obj: str(obj),  objs )
>> Using eval() is dangerous, and should be avoided. Here you just need
>> getattr(sy.S, name).
>
> Ah, of course. Thanks.
>
>
>> BTW, whenever you want to put a lambda inside a map, you should really
>> use a list comprehension instead, as it's much more readable, and can
>> be combined with a filter, as in:
>>
>> objs = [getattr(sy.S, name) for name in dis(sy.S) if not
>> name.startswith("__")]
>> strs = [str(obj) for obj in objs if not obj.is_Number]
>>
>> (NB: I don't think this is exactly the right code, cf. my first comment)
>
> Ok. I think both ways are equally readable, but if the list
> comprehension is more Pythonic, then why not.
>
> Thanks for this tip, too. I've been programming for a long time, but
> only started Python recently :)
>
>
>  -J
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/sympy?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to