(Newbie) Restricting inherited methods to operate on element from same subclass

2005-03-11 Thread andy2o
Hi all,

Sorry if the post's title is confusing... I'll explain:

I have a class, called A say, and N>1 subclasses of A, called 
A1, A2, A3, ..., AN say.

Instances of each subclass can sensibly be joined together with other
instances of the *same subclass*. The syntax of the join method is
identical for each of the N subclasses, so it would make sense to
implement a *single* method called join in the toplevel class A, and
then do:

a = A1()
b = A1()
a.join(b) #I want the join method to be inherited from class A

d = A2()
e = A2()
d.join(e) 

But I want to raise an exception if my code finds:

f = A1()
g = A2()
f.join(g) #should raise exception, as cannot join an 
  #instance of A1 to an instance of A2.

How can I verify in a method defined in class A that the subclasses I
am joining are exactly the same? Or is there a design flaw here I
haven't spotted that makes this a bad idea? Or do I need to code N
join methods?

Many thanks,

Andy
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (Newbie) Restricting inherited methods to operate on element from same subclass

2005-03-11 Thread andy2O
>Assuming that A is a new-style class then if they have to be
>exactly the same type compare the types

Ah-ha! I didn't know that.

>if the 'other' value can be a subclass of self:
>
>   def join(self, other):
>  if not isinstance(other, type(self)):
>   raise whatever

Simple and neat!

>If A is an old-style class then you would have to compare
>the __class__ attribute: self.__class__ != other.__class__

That answered my question perfectly. I'll read up on the new style
classes and pick whichever of your solutions fits best.

Many thanks,
Andy.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (Newbie) Restricting inherited methods to operate on element from same subclass

2005-03-14 Thread andy2O
Bruno Desthuilliers wrote:
> You've already got the technical answer. About a possible design
flaw,
> it would seem to me that restricting the join() operation on specific

> subclasses breaks the LSP. OTOH, Python being dynamically typed,
> inheritence is merely an implementation detail, so that may not be
such
> a big deal after all... Anyway, you may want to document this point
to
> make it clear for the next person that'll have to work this code.
>
> My 2 cents

OK, thanks - I see your point.

I was in effect implementing mutable objects, similar in some sense to
lists, by extending an immutable class similar to Python's tuples. I
think instead I should copy the Python type hierarchy, with the
list-like and tuple-like classes each defined as sub-classes of a
'sequence' class. In this case the type checking could go away.

I'm learning object-orientated programming and dynamic typed languages
the hard way at the moment, by trial and error. Can you, or anyone
suggest a good book which will guide me? Is there a classic text on
this? The coverage of OOP in 'Learning Python' is useful, but I could
do with something more in-depth.

Thanks again,
Andy.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: problem with the 'math' module in 2.5?

2006-10-15 Thread andy2O
Chris wrote:
> sin(pi*0.5) is what I expected, but I expected to get 0 for sin(pi).

Computers in general, and Python too, usually use floating point
arithmetic in which all numbers are approximated by rational numbers of
a particular form (see http://en.wikipedia.org/wiki/Floating_point for
details).

1) pi is an irrational number, so it *cannot* be represented exactly in
floating point. Therefore the value of pi in your call to the sin
function is definitely, proveably, *not* exactly equal to the true
value of pi.

2) So, even if the function "sin" could be evaluated exactly, the fact
that you are not evaluating it exactly at the true value of pi, but
instead at a good but imperfect approximation to this value, means that
the sine function *should not* give the result = 0 for your request!

3) The function sin is also evaluated to only a finite degree of
precision - just like everything else in floating point arithmetic.
Therefore you should not expect absolutely precise results. Instead,
you need to understand the limitations of floating point arithmetic,
understand the precision you *can* expect, and work within these
bounds. It's a good system, but you do need to understand its
limitations. The links other people have posted are good resources for
this.

Best wishes,
andy

-- 
http://mail.python.org/mailman/listinfo/python-list


OO design question / Transform object in place?

2005-05-11 Thread 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.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO design question / Transform object in place?

2005-05-20 Thread andy2O
Dave Benjamin wrote:
> [EMAIL PROTECTED] 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.

Anyway, thanks again for your reply.

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

-- 
http://mail.python.org/mailman/listinfo/python-list