472,090 Members | 1,398 Online

# OO design question / Transform object in place?

Hello comp.lang.py,

Can you help me with ideas for the following (somewhat newbie) OO
design question in Python? Note, I'm using psuedo-code, not actual
Python for the examples!

Background:
-----------
I need to represent a small variety of mathematical constructs
symbolically using Python classes.

1) I have classes, representing numbers, symbolic variables etc.
2) I have classes for groups of these objects, such as a symbolic Sums.
3) To simplify the mathematical constructs, I've provided each of the
classes with a simplify(self) method.

The following psuedo-code gives an example

a = Variable('a')
b = Variable('b')
two = Number(2) #Yes there are good reason not
#to just use Python's int object! :-)

expression1 = Sum([a,b,a,a,two]) #This represents a+b+a+a+2

then calling "expression1.simplify()" would invoke Sum.simplify() and
reduce expression1 to 3*a+b+2

Question:
---------

Now suppose I set "expression2 = Sum([a,-a])" and Sum.simplify()
recognises that the two terms cancel and the Sum has value 0.

Can I make "expression2.simplify()" transform expression2 from an
instance of Sum to an instance of Number(0) **in place**? Is that
possibe, or do I really have to write

expression2 = SimplifyFunction(expression2)

and use the function return to set expression2 to be a Number(0)
object, which is annoying for a variety of reasons! Have I made a
mistake in the design?

Many thanks,
andy.

Jul 19 '05 #1
3 1424
an****@hotmail.com wrote:
Now suppose I set "expression2 = Sum([a,-a])" and Sum.simplify()
recognises that the two terms cancel and the Sum has value 0.

Can I make "expression2.simplify()" transform expression2 from an
instance of Sum to an instance of Number(0) **in place**? Is that
possibe, or do I really have to write
I think it's much better for simplify() to return a new object always,
and leave the original object unmodified. You can still write:

expression2 = expression2.simplify()

if you don't care about the old value.
expression2 = SimplifyFunction(expression2)
This is another valid solution, but it's not an OO solution (you will
need to use "isinstance" to write "SimplifyFunction").
and use the function return to set expression2 to be a Number(0)
object, which is annoying for a variety of reasons! Have I made a
mistake in the design?

It's usually considered poor OO style to have an object change its class
at runtime, although I'm sure you could do it in Python ("__bases__"
would be a place to start) if you really wanted. For what you're trying
to do, I don't think it's necessary, though.

Dave
Jul 19 '05 #2
Dave Benjamin wrote:
an****@hotmail.com wrote:
Now suppose I set "expression2 = Sum([a,-a])" and Sum.simplify()
recognises that the two terms cancel and the Sum has value 0.

Can I make "expression2.simplify()" transform expression2 from an
instance of Sum to an instance of Number(0) **in place**? Is that
possibe, or do I really have to write
I think it's much better for simplify() to return a new object

always, and leave the original object unmodified. You can still write:

expression2 = expression2.simplify()
Dave,

A belated thank-you message for your reply to my posting. I took your
advice, and made all the simplify methods return new objects and this
has simplified my code structure a great deal (and any slow down in run
time just doesn't matter!).

Am I right that to make "expression2.simplify()" return a new object I
will need use copy.copy a lot, as in:

def simplify(self):
newreturnvalue=copy.copy(self)
#
#....now the code does lots of complicated things
# to newreturnvalue object...
#
return newreturnvalue

I have a nagging doubt as to whether this is what you meant, or if I've
missed a trick again.

Yours,
Andy.

if you don't care about the old value.
expression2 = SimplifyFunction(expression2)
This is another valid solution, but it's not an OO solution (you will

need to use "isinstance" to write "SimplifyFunction").
and use the function return to set expression2 to be a Number(0)
object, which is annoying for a variety of reasons! Have I made a
mistake in the design?
It's usually considered poor OO style to have an object change its

class at runtime, although I'm sure you could do it in Python ("__bases__"
would be a place to start) if you really wanted. For what you're trying to do, I don't think it's necessary, though.

Dave

Jul 19 '05 #3
an****@hotmail.com wrote:
Dave Benjamin wrote:
I think it's much better for simplify() to return a new object
and leave the original object unmodified. You can still write:
expression2 = expression2.simplify()
A belated thank-you message for your reply to my posting. I took your
advice, and made all the simplify methods return new objects and this
has simplified my code structure a great deal (and any slow down in run
time just doesn't matter!).

No problem. Glad it helped. =)
Am I right that to make "expression2.simplify()" return a new object I
will need use copy.copy a lot, as in:

def simplify(self):
newreturnvalue=copy.copy(self)
#
#....now the code does lots of complicated things
# to newreturnvalue object...
#
return newreturnvalue

You could use copy.copy(), as long as you want a shallow copy and you
don't want to change from one class to another. However, it may be to
your advantage to use the constructor of one or more classes to build
the result; this allows you to conditionally pick the result object's
class. Also, there may be situations where an object can't be
simplified, in which case you can just return "self", and avoid copying
entirely.

Dave
Jul 19 '05 #4

### This discussion thread is closed

Replies have been disabled for this discussion.