[Edu-sig] Algebra + Python
Kirby Urner
pdx4d@teleport.com
Sun, 6 May 2001 20:12:58 -0700
> = Ka-Ping Yee
= Kirby
> Python has a built-in function "isinstance" to help you do this.
Yes, that cleans up my syntax quite a bit. I'd played around
with isinstance before and drew some wrong conclusions -- it's
more useful than I'd realized.
The only advantage of doing it the other way is my pyfractions module
could remain ignorant of Poly and Matrix objects and yet still refer
back to their methods: i.e. n.__class__.__name__ == "Matrix" can be
truth-tested without the global name Matrix having any meaning in
this module (pyfraction). But it's a very small price to pay to put:
from simplematrix import Matrix (and similar for Poly) at the top
(since I'm testing for these kinds of object, I might as well make
this module aware of them).
Note: I've also added Sqmatrix as a subclass of Matrix (for square
matrices), as so many matrix ops only make sense when applied to
square matrices.
> In addition, my personal preference would be to simply use *
> instead of calling __mul__ explicitly, although that's more of
> a style issue. Anyway here's what i would write:
I was hesitant to do this because the reason I'm in Fraction's
__mul__ method in the first place is the Matrix or Poly __mul__
method was ignored in favor of Fraction's in some "poly * fraction"
or "fraction * matrix" type expression.
By putting: print -> "Fraction" in Fraction's __mul__, I can
see when it's being called:
>>> I = Sqmatrix([[1,0,0],[0,1,0],[0,0,1]])
>>> f = Fraction(1,2)
>>> f*I
-> Fraction
[(1/2), 0, 0]
[0, (1/2), 0]
[0, 0, (1/2)]
>>> I*f
[(1/2), 0, 0]
[0, (1/2), 0]
[0, 0, (1/2)]
So Fraction is trapping these cases and forcing us to use the
passed object's __mul__ method instead of Fraction's. I was
thinking that using * in place of n.__mul__ might just trigger
a repeat of the same situation (i.e. might beget the same
ambiguity I'm coding to avoid).... But so far, going with *
is working OK. You must have clearer insight into this issue,
or at least aren't quite so confused. Is it the case that
__mul__ always takes precedence over __rmul__ if both are
defined? That would explain the above I think.
>
> class Fraction:
> ...
> def __mul__(self, n):
> if isinstance(n, Poly) or isinstance(n, Matrix):
> return n * self
> f = self.mkfract(n)
> return Fraction(self.numer * f.numer, self.denom
> * f.denom)
>
> Very nice work, by the way!
Thanks. I appreciate the tips -- thanks to which, I'm gradually
getting more proficient with this nifty language.
>
> -- ?!ng
Kirby