Le 29/08/2012 13:56, Juha Jeronen a écrit :
Hi,
On 29/08/12 12:51, Chris Smith wrote:
On Wed, Aug 29, 2012 at 2:27 PM, Juha Jeronen <[email protected]> wrote:
Hi all,
This time a question: is there a preferred way of getting a complete
list of symbols reserved by SymPy, i.e. atoms which have a default
meaning (E, pi, EulerGamma, oo, etc.)?
These are the singletoms (below, ignore methods with `__`). But they
can all be overwritten. The only reserved symbols that don't become
symbols upon sympification are Q-COSINE (the C will actually parse
like a symbol so in that sense it's not reserved; the "-" could help
you remember that).
Thanks for the quick reply.
Ok.
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.
(The point being, at least my mind would be more at ease if there was a
dedicated API method.)
Proceeding from this point, it seems that in order to get the
corresponding strings that sympify() converts into these objects, the
additional map(...) step is needed. What I mean is:
import re
import sympy as sy
L = dir(sy.S)
objnames = filter( lambda name: re.match("__", name) is None, L )
strs = map( lambda name: str(eval("sy.S.%s" % name)), objnames )
print objnames
print strs
For example, running this on 0.6.7 (sorry for the old version; running
on Debian Stable at the moment) we get
objnames = ['Catalan', 'ComplexInfinity', 'EulerGamma', 'Exp1',
'GoldenRatio', 'ImaginaryUnit', 'Infinity', 'NaN', 'NegativeInfinity',
'NegativeOne', 'One', 'Pi', 'Zero']
strs = ['Catalan', 'zoo', 'EulerGamma', 'E', 'GoldenRatio', 'I', 'oo',
'nan', '-oo', '-1', '1', 'pi', '0']
with "strs" being what I was after. (In real-world use, I would further
filter out anything that matches is_Number, in order to drop the obvious
0, -1, 1.)
This further conversion is important because:
import sympy as sy
pi = sy.sympify("pi")
print type(pi) # => sympy.core.numbers.Pi
# but:
pi = sy.sympify("Pi")
print type(pi) # => sympy.core.symbol.Symbol (<--- !!!)
...so the "reserved symbol" (in the sense I intended) should be
lowercase "pi".
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__
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).
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)
descs = {}
for obj,name in zip(objs,strs):
descs[name] = str(type(obj))
# now:
# - strs[] contains all reserved atoms, except literal numbers
# - descs{} contains a human-readable description of each item.
---8<---8<---8<---
I would like to suggest adding an API method for this (e.g. with the
is_Number check made optional), unless my use case is too specific for
general use :)
-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.