OO design question / Transform object in place?

A

andy2O

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.
 
D

Dave Benjamin

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
 
A

andy2O

Dave said:
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.

Anyway, thanks again for your reply.

Yours,
Andy.
 
D

Dave Benjamin

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top