Надо было, наверное, раньше об этом подумать…
Эти слова так и срываются с языка при разработке какого либо программного обеспечения.
Все же понимают, что целые числа тоже являются дробями?! Следовательно, нам требуется изменить систему инициализации, чтобы она могла воспринимать и целые числа (причём и в виде строк). Ну и естественно, требуется переработать операторы арифметических действий и сравнения.
Примечание
Будем считать, что пользователь знает о запрете деления на ноль.
Все числа в данной задаче будут положительными.
Все поля и методы, не требуемые в задаче, следует инкапсулировать (называть с использованием ведущих символов нижнего подчёркивания).
Ваше решение должно содержать только классы и функции.
В решении не должно быть вызовов инициализации требуемых классов.
Пример
Ввод
a = Fraction(1)
b = Fraction('2')
c, d = map(Fraction.reverse, (a + 2, b - 1))
print(a, b, c, d)
print(a > b, c > d)
print(a >= 1, b >= 1, c >= 1, d >= 1)
Вывод
1/1 2/1 1/3 1/1
False False
True True False True
Ввод
a = Fraction(1, 2)
b = Fraction('2/3')
c, d = map(Fraction.reverse, (a + 2, b - 1))
print(a, b, c, d)
print(a > b, c > d)
print(a >= 1, b >= 1, c >= 1, d >= 1)
Вывод
1/2 2/3 2/5 -3/1
False True
False False False False
Решение
Благодаря тому, что мы хорошо спроектировали наш класс, особо менять ничего не нужно.
Модифицируем наш класс так, чтобы он воспринимал целое число в качестве единственного аргумента, и понимал строки, без разделителя ‘/’.
Посмотреть код
Решение
class Fraction():
def __init__(self, *args) -> None:
self.__den = 1
if isinstance(args[0], str):
splits = args[0].split('/')
if len(splits) == 1:
self.__num = int(args[0])
else:
self.__num, self.__den = [int(c) for c in splits]
elif len(args) == 1 and isinstance(args[0], int):
self.__num = args[0]
else:
self.__num = args[0]
self.__den = args[1]
self.__reduction()
def __neg__(self) -> 'Fraction':
return Fraction(-self.__num, self.__den)
def _check_other(self, other):
if isinstance(other, int):
return Fraction(other, 1)
return other
def __add__(self, other) -> 'Fraction':
other = self._check_other(other)
denominator = self.denominator() * other.denominator()
numerator = self.__num * other.__den + other.__num * self.__den
return Fraction(numerator, denominator)
def __sub__(self, other) -> 'Fraction':
other = self._check_other(other)
denominator = self.denominator() * other.denominator()
numerator = self.__num * other.__den - other.__num * self.__den
return Fraction(numerator, denominator)
def __iadd__(self, other) -> 'Fraction':
other = self._check_other(other)
self.__num = self.__num * other.__den + other.__num * self.__den
self.__den = self.__den * other.__den
self.__reduction()
return self
def __isub__(self, other) -> 'Fraction':
other = self._check_other(other)
self.__num = self.__num * other.__den - other.__num * self.__den
self.__den = self.__den * other.__den
self.__reduction()
return self
def __mul__(self, other) -> 'Fraction':
denominator = self.__den * other.__den
numerator = self.__num * other.__num
return Fraction(numerator, denominator)
def __truediv__(self, other) -> 'Fraction':
new = Fraction(self.__num, self.__den)
return new.__mul__(other.reverse())
def __imul__(self, other) -> 'Fraction':
self.__num = self.__num * other.__num
self.__den = self.__den * other.__den
self.__reduction()
return self
def __itruediv__(self, other) -> 'Fraction':
other = self._check_other(other)
return self.__imul__(other.reverse())
def __gt__(self, other) -> bool:
other = self._check_other(other)
return self.__num * other.__den > other.__num * self.__den
def __lt__(self, other) -> bool:
other = self._check_other(other)
return self.__num * other.__den < other.__num * self.__den
def __ge__(self, other) -> bool:
other = self._check_other(other)
return self.__num * other.__den >= other.__num * self.__den
def __le__(self, other) -> bool:
other = self._check_other(other)
return self.__num * other.__den <= other.__num * self.__den
def __eq__(self, other) -> bool:
other = self._check_other(other)
return self.__num * other.__den == other.__num * self.__den
def __ne__(self, other) -> bool:
other = self._check_other(other)
return self.__num * other.__den != other.__num * self.__den
def __str__(self) -> str:
return f'{self.__num}/{self.__den}'
def __repr__(self) -> str:
return f"Fraction('{self.__num}/{self.__den}')"
def numerator(self, *args) -> int:
if len(args):
self.__num = args[0] * self.__sign()
self.__reduction()
return abs(self.__num)
def __sign(self):
return -1 if self.__num < 0 else 1
def __gcd(self, a, b) -> int:
while b:
a, b = b, a % b
return abs(a)
def __reduction(self) -> tuple:
gcd = self.__gcd(self.__num, self.__den)
self.__num //= gcd
self.__den //= gcd
if self.__den < 0:
self.__num = -self.__num
self.__den = abs(self.__den)
return self.__num, self.__den
def denominator(self, *args) -> int:
if len(args):
self.__den = args[0]
self.__reduction()
return abs(self.__den)
def reverse(self) -> 'Fraction':
return Fraction(self.__den, self.__num)