skip to navigation
skip to content

feed icon RSS хранилка

Примерно решение на задача 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)