
= 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