Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Preferred way of getting reserved symbols?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  17 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Juha Jeronen  
View profile  
 More options Aug 29 2012, 4:42 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Wed, 29 Aug 2012 11:42:24 +0300
Local: Wed, Aug 29 2012 4:42 am
Subject: Preferred way of getting reserved symbols?
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.)?

By experimenting and reading the source, I found out that in the old
0.6.x this can be done with

import sympy as sy
L = sy.Basic.singleton.keys()

and in the more recent 0.7.x with

import re
import sympy as sy
L = filter( lambda name: re.match("__", name) is None,  dir(sy.S) )
L = map( lambda name: str(eval("sy.S.%s" % name)),  L )

The reason I'm asking is of course that the internals may change in
later versions, so an API-stable way to do this would be preferable.

The (current) use case is custom validation for user input that is going
to be sympified. It is foreseeable this could also be used in GUI
applications to build a list of default constants.

My aim here is to avoid unpleasant surprises in user-defined quantities
in the FEM project; e.g. if the user happened to pick the symbol E for
(say) a Young modulus, SymPy would interpret that as exp(1) in any
expression that was sympified. This in turn could confuse the expression
processing. Currently I use the above code to fetch the reserved names,
but is there a better way to get them?

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.

 -J


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chris Smith  
View profile  
 More options Aug 29 2012, 5:51 am
From: Chris Smith <smi...@gmail.com>
Date: Wed, 29 Aug 2012 15:36:06 +0545
Local: Wed, Aug 29 2012 5:51 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?

On Wed, Aug 29, 2012 at 2:27 PM, Juha Jeronen <juha.jero...@jyu.fi> 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).

>>> 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__']

> 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'>

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 29 2012, 7:57 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Wed, 29 Aug 2012 14:56:52 +0300
Local: Wed, Aug 29 2012 7:56 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Hi,

On 29/08/12 12:51, Chris Smith wrote:

> On Wed, Aug 29, 2012 at 2:27 PM, Juha Jeronen <juha.jero...@jyu.fi> 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?

(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!

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 )

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 must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 29 2012, 8:45 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Wed, 29 Aug 2012 15:45:35 +0300
Local: Wed, Aug 29 2012 8:45 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Aaaahh, and I'm partly missing your point!

So, query the singleton system and then add Q-COSINE...

Updated code:

---8<---8<---8<---

def get_reserved_symbols(ignore_numbers=True):
    rawnames = filter( lambda name: re.match("__", name) is None,
dir(sy.S) )
    objs = map( lambda name: eval("sy.S.%s" % name),  rawnames )
    if ignore_numbers:
        objs = filter( lambda obj: not obj.is_Number,  objs )
    strs = map( lambda obj: str(obj),  objs )

    descs = {}
    for obj,name in zip(objs,strs):
        descs[name] = str(type(obj))

    # Handle the set "Q-COSINE".
    #
    # C parses to Symbol, so strictly speaking it is not reserved
    # in the sense meant here. Hence, we leave it out.
    #
    for s in "QOSINE":
        obj = sy.sympify(s)
        if obj not in objs:  # I and E are likely to end up in twice, so
check first
            objs.append( obj )
            strs.append( s )
            descs[s] = str(obj)  # for most of these this is ok
    descs["S"] = "the SymPy singleton system"  # str(obj) == "S", not
helpful
    descs["N"] = "the SymPy numerical evaluator"  # str(obj) ==
"<function N at...>"

    # Now:
    #    - strs[] contains names of all reserved symbols
    #      (except literal numbers if ignore_numbers is True)
    #    - descs{} contains a human-readable description of each item,
    #      keyed by the items in strs[].
    #
    return (strs,descs)

---8<---8<---8<---

This still leaves open the possibility of the user overwriting the
default singleton atoms, but I'm not sure how to handle that.

That depends on what is meant by overwriting - if the updated symbol is
stored into the singleton system, overwriting the old one, then this
approach already takes that into account. The whole idea here is to
dynamically query the state of the singleton system at that point of
program execution where the list is needed.

But of course stuff like

pi = sy.sympify("3")
expr = sy.sin(2*pi)  # actually, sin(6)

(which does not involve sympification for expr) is outside the scope of
this solution.

 -J

On 29/08/12 14:56, Juha Jeronen wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ronan Lamy  
View profile  
 More options Aug 29 2012, 1:29 pm
From: Ronan Lamy <ronan.l...@gmail.com>
Date: Wed, 29 Aug 2012 19:29:15 +0200
Local: Wed, Aug 29 2012 1:29 pm
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Le 29/08/2012 13:56, Juha Jeronen a écrit :

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.

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)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Joachim Durchholz  
View profile  
 More options Aug 29 2012, 6:45 pm
From: Joachim Durchholz <j...@durchholz.org>
Date: Thu, 30 Aug 2012 00:45:38 +0200
Local: Wed, Aug 29 2012 6:45 pm
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Am 29.08.2012 13:56, schrieb Juha Jeronen:

> So, dir(S) is the preferred way of getting a complete list :)

The problem with S is that code analysis tools find references to the
names in S but don't find them in S because the names are created at
runtime.
I think it's desirable to fix this, and while it would be desirable to
keep S' API, it might be necessary to change it.

Unless anybody comes up with something better, I guess dict(S) is still
your best bet for now.
I'd also like to point out that I'm not aware that "making S more
static" is on anybody's agenda. I have been meaning to work on that a
bit (by way of discussing the issues), but I never had the time to
really commit to such an undertaking. It's possible that it won't ever
happen.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 30 2012, 2:41 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Thu, 30 Aug 2012 09:41:26 +0300
Local: Thurs, Aug 30 2012 2:41 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Hi,

On 29/08/12 20:29, Ronan Lamy wrote:

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)")} )

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 must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Aaron Meurer  
View profile  
 More options Aug 30 2012, 1:17 pm
From: Aaron Meurer <asmeu...@gmail.com>
Date: Thu, 30 Aug 2012 11:16:55 -0600
Local: Thurs, Aug 30 2012 1:16 pm
Subject: Re: [sympy] Preferred way of getting reserved symbols?

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

Aaron Meurer


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 31 2012, 3:01 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Fri, 31 Aug 2012 10:01:17 +0300
Local: Fri, Aug 31 2012 3:01 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
On 30/08/12 01:45, Joachim Durchholz wrote:

Thanks for the heads-up. This is good to know :)

 -J


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 31 2012, 3:23 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Fri, 31 Aug 2012 10:23:03 +0300
Local: Fri, Aug 31 2012 3:23 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
On 30/08/12 20:16, Aaron Meurer wrote:

> On Thu, Aug 30, 2012 at 12:41 AM, Juha Jeronen <juha.jero...@jyu.fi> wrote:
>> 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.

Ah, I was originally running on 0.7.1, which does have LT(), but it
turns out there was a mistake in the above artificial example.

What my original code actually did in the case I tested, was only the
last two lines. The my_LT = ... line does work on 0.7.1, but as you say,
it's not possible to sympify() strings containing "LT" as a custom
symbol; instead, the string "LT" will always be interpreted as referring
to the function LT().

The catch is that while I did use sympify() in the original code, the
expression did not contain any "LT". If it did, the TypeError would have
been triggered... so there is a bug in my code. Thanks for discovering it ;)

(The using code has later been optimized so that it won't do unnecessary
subs(); the artificial example was based on how I recalled to have
discovered this.)

So, please disregard my previous comment - correcting, it seems the
string alone *is* enough information to decide whether the name is
reserved or not.

Thus, dir(sympy) and some processing should give a proper list...

 -J


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 31 2012, 4:39 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Fri, 31 Aug 2012 11:38:53 +0300
Local: Fri, Aug 31 2012 4:38 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Hi all,

Here is a new version based on dir(sympy). This approach still misses
"Q" and "O", so those are added in manually.

These get-reserved-symbols experiments are archived here:

https://yousource.it.jyu.fi/jjrandom2/freya/blobs/master/docs/ressym.py

Included below is the relevant part.

This seems to work, but probably it's still not completely robust.

---8<---8<---8<---

def method2(ignore_numbers=True):
     """Get reserved names in SymPy.

     Method 2: dir(sympy), and add "Q" and "O".

     Return value:  (strs, descs), where
         - strs[] contains names of all reserved symbols
           (except literal numbers if ignore_numbers is True)
         - descs{} contains a human-readable description of each item,
           keyed by the items in strs[].

     Parameters:
         ignore_numbers = bool. If True, ignore literal numbers such as
-1, 0, 1/2, 1.
                          Default True.

     """
     objs = [getattr(sy, name) for name in dir(sy) if not
name.startswith("__")]
     if ignore_numbers:
         objs = [obj for obj in objs if (not hasattr(obj, "is_Number")  
or  not obj.is_Number) ]

     # For most objects, we can extract the string recognized by
sympify() with str(obj).
     #
     # However, for functions and classes we must do something else.
     #
     def get_name(obj):
         s = str(obj)
         if not s.startswith('<'):
             return s
         else:
             if hasattr(obj, "__name__"):
                 return obj.__name__
             elif hasattr(obj, "__class__"):
                 return str(obj.__class__)   # e.g. sympy.C
             else:
                 raise NotImplementedError(s)  # TODO: reasonable fallback
     strs = map( get_name, objs )

     # Handle the set "Q-COSINE".
     #
     # C parses to Symbol, so strictly speaking it is not reserved
     # in the sense meant here. Hence, we leave it out.
     #
     # dir(sy) misses "Q" and "O", so we need to handle only those.
     #
     for s in "QO":
         objs.append( sy.sympify(s) )
         strs.append( s )

     # Generate human-readable descriptions, indicating the module
     # where the symbol comes from, and its name.
     #
     descs = {}
     for obj,name in zip(objs,strs):
         m = "%s." % obj.__module__ if hasattr(obj, "__module__") else ""
         n = obj.__name__ if hasattr(obj, "__name__") else str(obj)
         descs[name] = "%s%s" % (m,n)

     return (strs,descs)

---8<---8<---8<---

  -J

On 31.08.2012 10:23, Juha Jeronen wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 31 2012, 5:45 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Fri, 31 Aug 2012 12:45:06 +0300
Local: Fri, Aug 31 2012 5:45 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Hi all (again),

And here's a fixed version. The code I just posted returned some
nonsensical results, because it didn't filter out modules and classes.

Apart from that, it seems that sympy.core.core.ClassRegistry must be
filtered out separately, and sympy.ntheory.generate.Sieve (a classobj
with no __name__ or __class__, neither str() nor repr() matching the
sympifiable string) must be handled as a special case.

I updated the version in my repo. This has been tested on SymPy 0.7.1.

For convenience, the relevant part is included below (in case someone
else needs this). An API function for retrieving the reserved strings
would be nice, but I guess this hack will do for now :)

Thanks for the help on this, everyone!

---8<--8<---8<---

import sympy as sy

def method2(ignore_numbers=True):
     """Get reserved names in SymPy.

     Method 2: dir(sympy), and add "Q" and "O".

     Return value:  (strs, descs), where
         - strs[] contains names of all reserved symbols
           (except literal numbers if ignore_numbers is True)
         - descs{} contains a human-readable description of each item,
           keyed by the items in strs[].

     Parameters:
         ignore_numbers = bool. If True, ignore literal numbers such as
-1, 0, 1/2, 1.
                          Default True.

     """
     objs = [getattr(sy, name) for name in dir(sy) if not
name.startswith("__")]
     if ignore_numbers:
         objs = [obj for obj in objs if (not hasattr(obj, "is_Number")  
or  not obj.is_Number) ]

     # ignore module and class objects
     from types import ModuleType
     from types import ClassType
     objs = [obj for obj in objs if not isinstance(obj, ModuleType) and
not isinstance(obj, ClassType)]

     # ignore sympy.C
     from sympy.core.core import ClassRegistry
     objs = [obj for obj in objs if not isinstance(obj, ClassRegistry) ]

     # For most objects, we can extract the string recognized by
sympify() with str(obj).
     #
     # However, for functions and classobjs we must do something else.
     #
     def get_name(obj):
         s = str(obj)
         if not s.startswith('<'):
             return s
         else:
             if hasattr(obj, "__name__"):
                 return obj.__name__
             else:
                 # XXX HACK: sympy.ntheory.generate.Sieve is of type
classobj
                 # and has no __name__ or __class_.
                 # Its repr() is "<Sieve with X primes sieved: ...>";
                 # we trigger on that.
                 #
                 if repr(obj).find("Sieve"):
                     return "Sieve"

                 raise NotImplementedError("get_name(): cannot handle
(%s, %s, %s)" % (obj, type(obj), s))
     strs = map( get_name, objs )

     # Handle the set "Q-COSINE".
     #
     # C parses to Symbol, so strictly speaking it is not reserved
     # in the sense meant here. Hence, we leave it out.
     #
     # dir(sy) misses "Q" and "O", so we need to handle only those.
     #
     for s in "QO":
         objs.append( sy.sympify(s) )
         strs.append( s )

     # Generate human-readable descriptions, indicating the module
     # where the symbol comes from, and its name.
     #
     descs = {}
     for obj,name in zip(objs,strs):
         m = "%s." % obj.__module__ if hasattr(obj, "__module__") else ""
         n = obj.__name__ if hasattr(obj, "__name__") else str(obj)
         descs[name] = "%s%s" % (m,n)

     return (sorted(strs),descs)

---8<--8<---8<---

  -J

On 31.08.2012 11:38, Juha Jeronen wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chris Smith  
View profile  
 More options Aug 31 2012, 6:03 am
From: Chris Smith <smi...@gmail.com>
Date: Fri, 31 Aug 2012 15:48:31 +0545
Local: Fri, Aug 31 2012 6:03 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?

On Fri, Aug 31, 2012 at 3:30 PM, Juha Jeronen <juha.jero...@jyu.fi> wrote:
> Hi all (again),

> And here's a fixed version. The code I just posted returned some nonsensical
> results, because it didn't filter out modules and classes.

Another way to maybe approach this problem (getting a non-clashing
form of an expression sympified) is this:

* the user must know what functions they are using: they/you give a
list of these and this list must agree with the representation of that
function's name in sympy
* they give an expressions
* let python parse this (I don't recall which does that now -- there's
some module for parsing python code character by character) and when
it identifies a variable either 1) it is a function that has already
been identified or it is intended as a symbol and 2a) sympy agrees or
2b) sympy disagrees and wants to make it a class or anything other
than a symbol.
* in case of 2b the user's symbol must be de-clashed, by appending
underscores until the clash goes away; this symbol replaces what the
user chose
* the modified input function is returned.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Joachim Durchholz  
View profile  
 More options Aug 31 2012, 6:24 am
From: Joachim Durchholz <j...@durchholz.org>
Date: Fri, 31 Aug 2012 12:24:09 +0200
Local: Fri, Aug 31 2012 6:24 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
Am 31.08.2012 11:45, schrieb Juha Jeronen:

> Apart from that, it seems that sympy.core.core.ClassRegistry must be
> filtered out separately, and sympy.ntheory.generate.Sieve (a classobj
> with no __name__ or __class__, neither str() nor repr() matching the
> sympifiable string) must be handled as a special case.

That one is supposed to be an implementation detail. It's providing the
implementation for a singleton, namely "the" Sieve of Erasthotenes.
That's the view for SymPy-using code anyway; some tests that check
caching internals of Sieve do indeed create multiple instances.

I suspect you don't want such classes in your results.
However, I have not idea how to detect that category. Checking for a
__name__ or __class__ might fit or not; maybe some better convention
exists, or should be created. Aaron or Ondrej should be able to answer that.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Aug 31 2012, 7:12 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Fri, 31 Aug 2012 14:11:56 +0300
Local: Fri, Aug 31 2012 7:11 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
On 31.08.2012 13:03, Chris Smith wrote:

Thanks for the idea! I hadn't considered this approach.

This would be pretty easy to do the other way around: undefined symbols
are not allowed in my particular use case, and the code already builds a
list of user-defined symbols. Anything not explicitly defined is
intended to be taken from the library...

Related to which, I have one more question. In 0.6.x sympify() used to
add an undefined_Function attribute to unknown functions in the expression:

import sympy as sy
s = sy.sympify("a*f(x) + b + c*x")
L = list(s.atoms(sy.Function))
f = L[0]
hasattr(f, "undefined_Function")
   => True

but 0.7.x no longer does this.

Is it possible to dynamically detect in the new version whether a
function object is evaluatable or not, and user-defined or not? At least
I couldn't find anything obvious in the attributes...

What I'd like to do with this is to check that all function references
in a user-given expression refer to existing library functions only. I
could utilize the get-reserved-symbols-by-dir(sympy) hack and check the
object type, but that's hardly an elegant solution.

  -J


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Aaron Meurer  
View profile  
 More options Aug 31 2012, 10:42 am
From: Aaron Meurer <asmeu...@gmail.com>
Date: Fri, 31 Aug 2012 08:42:01 -0600
Local: Fri, Aug 31 2012 10:42 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
On Aug 31, 2012, at 5:12 AM, Juha Jeronen <juha.jero...@jyu.fi> wrote:

The tokenize module will split a string of valid python code into its
tokens, which you can then search for names. Or if you don't need 2.5
support, you can use the ast module.

If you want, you could then sympify the name and see if you get a
Symbol or not (caching the results).

In 0.7.2 you will be able to check if it is a subclass of
UndefinedFunction. I don't know if that works in 0.7.1 or what would
be a work around if not.

Aaron Meurer


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juha Jeronen  
View profile  
 More options Sep 3 2012, 3:03 am
From: Juha Jeronen <juha.jero...@jyu.fi>
Date: Mon, 03 Sep 2012 10:03:39 +0300
Local: Mon, Sep 3 2012 3:03 am
Subject: Re: [sympy] Preferred way of getting reserved symbols?
On 31/08/12 17:42, Aaron Meurer wrote:

Ok. Thanks for the tip.

The ast module should be fine.

>> Is it possible to dynamically detect in the new version whether a function object is evaluatable or not, and user-defined or not? At least I couldn't find anything obvious in the attributes...
> In 0.7.2 you will be able to check if it is a subclass of
> UndefinedFunction. I don't know if that works in 0.7.1 or what would
> be a work around if not.

Ok. Thanks.

It seems 0.7.1 doesn't have an UndefinedFunction. But I suppose I can
wait for 0.7.2 for this. (It's not absolutely critical, though it
improves user-friendliness by catching errors early.)

 -J


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »