Примерно решение на задача 5
Публикувано на 29.05.2008 11:10 от Митьо
Тази публикация е от предишно издание на курса, моля не разчитайте на актуалността на информацията.
Ето една примерна реализация на поставения от задача 5 проблем — клас, представляващ рационално число. Решението е сравнително просто и няма нужда от сериозен коментар. Ако все пак ви се коментира нещо по това, пишете във форума.
class rational: def __init__(self, num, den=1): if den == 0: raise ValueError if den < 0: num, den = -num, -den gcd = self.gcd(num, den) self._num, self._den = num / gcd, den / gcd def num(self): return self._num def den(self): return self._den def __str__(self): if self.den() == 1: return str(self.num()) else: return "%d/%d" % (self.num(), self.den()) def __repr__(self): return self.__class__.__name__ + "(%d, %d)" % (self.num(), self.den()) def lcd(self, other): return self.den() * other.den() / self.gcd(self.den(), other.den()) # Comparison def __cmp__(self, other): if self.num() < 0 and other.num() < 0: return - (-self).__cmp__(-other) return self.num() * other.den() - self.den() * other.num() def __coerce__(self, other): if isinstance(other, (int, long)): return (self, rational(other)) # Arithmetic operations def __neg__(self): "The unary - operator." return rational(-self.num(), self.den()) def __invert__(self): "The ~ operator -- inversion." return rational(self.den(), self.num()) def __abs__(self): "Return the absolute value of the current rational number." return rational(abs(self.num()), self.den()) def __add__(self, other): if not isinstance(other, rational): other = rational(other) return rational(self.num() * other.den() + self.den() * other.num(), \\ self.den() * other.den()) def __sub__(self, other): return self + -other def __mul__(self, other): if not isinstance(other, rational): other = rational(other) return rational(self.num() * other.num(), self.den() * other.den()) def __div__(self, other): if not isinstance(other, rational): other = rational(other) return self * ~other def __pow__(self, other): if isinstance(other, rational) and rational(other.num()) == other: # The __coerce__ method converts the "3" in rational(2, 3) ** 3 # into rational(3), so we need to convert it back. other = other.num() if isinstance(other, (int, long)): if other < 0: return rational(self.den() ** (-other), self.num() ** (-other)) else: return rational(self.num() ** other, self.den() ** other) raise TypeError __radd__ = __add__ __rsub__ = __sub__ __rmul__ = __mul__ __rdiv__ = __div__ # Methods and conversions def sign(self): if self.num() > 0: return 1 if self.num() < 0: return -1 return 0 def partition(self): wholePart = abs(self.num()) / self.den() rationalPart = abs(self) - rational(wholePart) return (self.sign() * wholePart, self.sign() * rationalPart) def __int__(self): return abs(self.num()) / self.den() * self.sign() def __long__(self): return long(abs(self.num())) / self.den() * self.sign() def __float__(self): return float(self.num()) / self.den() @staticmethod def gcd(a, b): if b == 0: return a return rational.gcd(b, a % b)