473,387 Members | 1,530 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Changing self: if self is a tree how to set to a different self

I am playing with some trees. In one of the procedures I wrote
for this I am trying to change self to a different tree. A tree
here has four members (val/type/left/right). I found that self = SS
does not work; I have to write self.val = SS.val and the same for
the other members (as shown below). Is there a better way to do this?

In the below self is part of a parse tree, F is the parse tree of a
function f with argument x. If a node in the parse tree is labelled
f, we should replace it by the parse tree for the function f, F, with
the remainder of the tree substituted for the input variable for the
function f, here x.

def elimF (self):
if self.val == "f":
SS = F.copy ()
SS.subst ('x', self.left)
self.val = SS.val # from here: set self to be SS
self.type = SS.type
self.left = SS.left
self.right = SS.right # completed: set self to be SS

if self.left != None: # iterate onward, inf recursion if f
# appears. Would need a check in
# real version
self.left.elimF ()
if self.right != None:
self.right.elimF ()

Best,
Bart
Jul 10 '08 #1
6 1778


Bart Kastermans wrote:
I am playing with some trees. In one of the procedures I wrote
for this I am trying to change self to a different tree. A tree
here has four members (val/type/left/right). I found that self = SS
does not work; I have to write self.val = SS.val and the same for
the other members (as shown below). Is there a better way to do this?

In the below self is part of a parse tree, F is the parse tree of a
function f with argument x. If a node in the parse tree is labelled
f, we should replace it by the parse tree for the function f, F, with
the remainder of the tree substituted for the input variable for the
function f, here x.

def elimF (self):
if self.val == "f":
SS = F.copy ()
SS.subst ('x', self.left)
self.val = SS.val # from here: set self to be SS
self.type = SS.type
self.left = SS.left
self.right = SS.right # completed: set self to be SS
If you examine nodes from their parent, I believe you can do the
substitution in one step. Something like:

for slot,child in ( ('left',self.left), ('right',self.right) ):
if child is not None:
if child.val == 'f':
setattr(self, slot, F.copy().subst('x', child.left))
child.elimF

where .subst returns the modified tree.
>
if self.left != None: # iterate onward, inf recursion if f
# appears. Would need a check in
# real version
self.left.elimF ()
if self.right != None:
self.right.elimF ()
Terry Jan Reedy

Jul 10 '08 #2
Terry Reedy <tj*****@udel.eduwrites:
Bart Kastermans wrote:
>I am playing with some trees. In one of the procedures I wrote
for this I am trying to change self to a different tree. A tree
here has four members (val/type/left/right). I found that self = SS
does not work; I have to write self.val = SS.val and the same for
the other members (as shown below). Is there a better way to do this?

In the below self is part of a parse tree, F is the parse tree of a
function f with argument x. If a node in the parse tree is labelled
f, we should replace it by the parse tree for the function f, F, with
the remainder of the tree substituted for the input variable for the
function f, here x.

def elimF (self):
if self.val == "f":
SS = F.copy ()
SS.subst ('x', self.left)
self.val = SS.val # from here: set self to be SS
self.type = SS.type
self.left = SS.left
self.right = SS.right # completed: set self to be SS

If you examine nodes from their parent, I believe you can do the
substitution in one step. Something like:

for slot,child in ( ('left',self.left), ('right',self.right) ):
if child is not None:
if child.val == 'f':
setattr(self, slot, F.copy().subst('x', child.left))
child.elimF

where .subst returns the modified tree.
That worked very well. The option that looks even better to me was
just to build a copy (the exceptional case of the root of the tree
that is needed bugged me a bit). Then self does not have to be
changed at all. Your use of setattr made me find getattr, and this
allowed for a quite smooth (I think) implementation.

def elimF (self):
""" do the substitution of all nodes labelled f.

"""
if self.val == "f":
ret_val = F.subst ('x', self.left)
ret_val.left = NoneOr (ret_val.left, 'elimF')
ret_val.right = NoneOr (ret_val.right, 'elimF')
return ret_val
else:
return Tree (self.val, self.type, \
NoneOr (self.left, 'elimF'), \
NoneOr (self.right, 'elimF') )

This uses the function:

def NoneOr (tree, mem_function, *arguments):
""" if tree is not None then tree.mem_function (arguments). """
if tree == None:
return None
else:
return getattr (tree, mem_function) (*arguments)

Bart
Jul 12 '08 #3
On Jul 12, 6:18*am, Bart Kastermans <kaste...@bart-kastermanss-
macbook.localwrote:
This uses the function:

def NoneOr (tree, mem_function, *arguments):
* * """ if tree is not None then tree.mem_function (arguments). """
* * if tree == None:
* * * * return None
* * else:
* * * * return getattr (tree, mem_function) (*arguments)

Bart
<persnickety>
This code reads wrongly to me on a couple of levels. First, I think
the general computing consensus is that if-then-else is more readable/
logical if you assert the positive condition for the then-part, and
put the alternative condition in the else-part. My impression is that
the non-None-ness of tree is actually the positive assertion, as in:

if tree != None:
return getattr(tree, mem_function)(*arguments)
else:
return None

Next, the more Pythonic test for None-ness is most clearly written as:

if tree is not None:

as there is only one None, and the identity "is not" check is simpler/
faster for Python to execute (and possibly - and more importantly -
also simpler for readers to follow, as this reads more like a
continuous sentence instead of a mixture of prose and mathematical
notations).

One might even suggest you could further abbreviate this test to:

if tree:

and get the same behavior. I would quibble with that, however, that
this merely exploits a side-effect of Python, in which None values are
always False, and *most* non-None values are True. But Python also
interprets many non-None values as False, such as 0, or empty
containers, such as lists, tuples, dicts, and strings. In fact, your
tree class sounds like a structured container to me, and it would be
reasonable to assume that you might implement __nonzero__ (pre-Python
2.6) or __bool__ (Python 2.6 and later) in your class to return False
for an empty tree, which would still be a valid and not-None tree.
You should be able to invoke methods on an empty tree just as one can
call "".upper(). So for this case, I would stick with the more
explicit "if tree is not None".

Another Pythonicity is that methods will *always* return a value, even
if you do not write a return statement - and that value is None. So
if you assert the tree-not-None as the if condition, you don't even
need the else part. You could just write:

def NoneOr (tree, mem_function, *arguments):
""" if tree is not None then tree.mem_function (arguments).
"""
if tree is not None:
return getattr(tree, mem_function)(*arguments)

Surprisingly, this actually reads almost verbatim from your doc
string! So I would guess that this implementation is probably closest
to your original intent for this method. Still, for explicitness'-
sake, you might want to keep the else-part, just to make your intent
clear and spelled-out. (Complaining about the presence or absence of
this bit of code goes beyond "persnickety"...)
</persnickety>

Note that the original code is perfectly valid Python, and will run
just as efficiently as any of my alternative suggestions, which is why
I enclosed my comments in 'persnickety' (http://
dictionary.reference.com/browse/persnickety) tags.

-- Paul
Jul 12 '08 #4
On 10 Jul., 15:19, Bart Kastermans <bkast...@gmail.comwrote:
I am playing with some trees. In one of the procedures I wrote
for this I am trying to change self to a different tree. A tree
here has four members (val/type/left/right). I found that self = SS
does not work; I have to write self.val = SS.val and the same for
the other members (as shown below). Is there a better way to do this?

In the below self is part of a parse tree, F is the parse tree of a
function f with argument x. If a node in the parse tree is labelled
f, we should replace it by the parse tree for the function f, F, with
the remainder of the tree substituted for the input variable for the
function f, here x.

def elimF (self):
if self.val == "f":
SS = F.copy ()
SS.subst ('x', self.left)
self.val = SS.val # from here: set self to be SS
self.type = SS.type
self.left = SS.left
self.right = SS.right # completed: set self to be SS

if self.left != None: # iterate onward, inf recursion if f
# appears. Would need a check in
# real version
self.left.elimF ()
if self.right != None:
self.right.elimF ()

Best,
Bart
Since it is acting on a tree why doesn't the code substitute self in
its parent by SS? That's the natural perspective if one considers a
tree as a linked structure and inserts and deletes nodes within this
structure.
Jul 12 '08 #5


Kay Schluehr wrote:
>

Since it is acting on a tree why doesn't the code substitute self in
its parent by SS? That's the natural perspective if one considers a
tree as a linked structure and inserts and deletes nodes within this
structure.
I think you are suggesting the same thing I did:
If you examine nodes from their parent, I believe you can do the
substitution in one step. Something like:

for slot,child in ( ('left',self.left), ('right',self.right) ):
if child is not None:
if child.val == 'f':
setattr(self, slot, F.copy().subst('x', child.left))
child.elimF

where .subst returns the modified tree.
Where F.copy is what was called 'SS'. If not, I don't understand.

Jul 12 '08 #6
Paul McGuire <pt***@austin.rr.comwrites:
On Jul 12, 6:18*am, Bart Kastermans <kaste...@bart-kastermanss-
macbook.localwrote:
>This uses the function:

def NoneOr (tree, mem_function, *arguments):
* * """ if tree is not None then tree.mem_function (arguments). """
* * if tree == None:
* * * * return None
* * else:
* * * * return getattr (tree, mem_function) (*arguments)

Bart

<persnickety>
First I want to say these comments are absolutely great. I *very*
much appreciated getting them. This kind of analysis and thinking
about code is exactly what I want to learn for myself; so this helped
me a lot. From the many interesting thoughts I got from this there is
only one that is a bit dissonant with me; it is the next paragraph.
This code reads wrongly to me on a couple of levels. First, I think
the general computing consensus is that if-then-else is more readable/
logical if you assert the positive condition for the then-part, and
put the alternative condition in the else-part. My impression is that
the non-None-ness of tree is actually the positive assertion, as in:
I had been experimenting with exactly this in some of my code. The
choice seemed to be between (in the cases I had in front of me):

1) filter out the bad cases and deal with them, then have the code do
the usual stuff,

2) set the conditions for being the usual case, then later deal with
the bad stuff.

I had been converging towards (1) as in

def func (inputs):
if inputs bad one way:
deal with it

if inputs bad another way:
deal with it too

take care of the generic remaining case

case (2) would result in something like:

def func (inputs):
if inputs are not bad in any way:
take care of the generic case
elif in puts bad in one way:
deal with it
else: # bad in another way
deal with it too

Did I represent the case distinction as you had it in mind? I'll keep
this more in mind when writing stuff and see how it works out.

<persnickety>
Better keep with "more readable", logically these are clearly
equivalent.
</persnickety>
>
if tree != None:
return getattr(tree, mem_function)(*arguments)
else:
return None

Next, the more Pythonic test for None-ness is most clearly written as:

if tree is not None:

as there is only one None, and the identity "is not" check is simpler/
faster for Python to execute (and possibly - and more importantly -
also simpler for readers to follow, as this reads more like a
continuous sentence instead of a mixture of prose and mathematical
notations).

One might even suggest you could further abbreviate this test to:

if tree:

and get the same behavior. I would quibble with that, however, that
this merely exploits a side-effect of Python, in which None values are
always False, and *most* non-None values are True. But Python also
interprets many non-None values as False, such as 0, or empty
containers, such as lists, tuples, dicts, and strings. In fact, your
tree class sounds like a structured container to me, and it would be
reasonable to assume that you might implement __nonzero__ (pre-Python
2.6) or __bool__ (Python 2.6 and later) in your class to return False
for an empty tree, which would still be a valid and not-None tree.
You should be able to invoke methods on an empty tree just as one can
call "".upper(). So for this case, I would stick with the more
explicit "if tree is not None".

Another Pythonicity is that methods will *always* return a value, even
if you do not write a return statement - and that value is None. So
if you assert the tree-not-None as the if condition, you don't even
need the else part. You could just write:

def NoneOr (tree, mem_function, *arguments):
""" if tree is not None then tree.mem_function (arguments).
"""
if tree is not None:
return getattr(tree, mem_function)(*arguments)

Surprisingly, this actually reads almost verbatim from your doc
string! So I would guess that this implementation is probably closest
to your original intent for this method. Still, for explicitness'-
sake, you might want to keep the else-part, just to make your intent
clear and spelled-out. (Complaining about the presence or absence of
this bit of code goes beyond "persnickety"...)
</persnickety>

Note that the original code is perfectly valid Python, and will run
just as efficiently as any of my alternative suggestions, which is why
I enclosed my comments in 'persnickety' (http://
dictionary.reference.com/browse/persnickety) tags.

-- Paul
Jul 13 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jim Jewett | last post by:
Normally, I expect a subclass to act in a manner consistent with its Base classes. In particular, I don't expect to *lose* any functionality, unless that was the whole point of the subclass. ...
31
by: Bo Peng | last post by:
Dear list, I have many dictionaries with the same set of keys and I would like to write a function to calculate something based on these values. For example, I have a = {'x':1, 'y':2} b =...
11
by: Stefan Behnel | last post by:
Hi! This somewhat puzzles me: Python 2.4 (#1, Feb 3 2005, 16:47:05) on linux2 Type "help", "copyright", "credits" or "license" for more information. ..>>> class test(object): .... def...
4
by: David Coffin | last post by:
I'd like to subclass int to support list access, treating the integer as if it were a list of bits. Assigning bits to particular indices involves changing the value of the integer itself, but...
4
by: andychambers2002 | last post by:
I'm working on a "TempFile" class that stores the data in memory until it gets larger than a specified threshold (as per PEP 42). Whilst trying to implement it, I've come across some strange...
6
by: PipedreamerGrey | last post by:
I'm using the script below (originally from http://effbot.org, given to me here) to open all of the text files in a directory and its subdirectories and combine them into one Rich text file...
5
by: Mudcat | last post by:
I was trying to design a widget that I could drag and drop anywhere in a frame and then resize by pulling at the edges with the mouse. I have fiddled with several different approaches and came...
9
by: silverburgh.meryl | last post by:
i am trying to use python to walk thru each subdirectory from a top directory. Here is my script: savedPagesDirectory = "/home/meryl/saved_pages/data" dir=open(savedPagesDirectory, 'r') ...
4
by: laxmikiran.bachu | last post by:
Can we have change a unicode string Type object to a Tuple type object.. If so how ????
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.