""" https://stepik.org/lesson/701990/step/10?unit=702091 В программе необходимо объявить классы для работы с кошельками в разных валютах: MoneyR - для рублевых кошельков MoneyD - для долларовых кошельков MoneyE - для евро-кошельков Объекты этих классов могут создаваться командами: rub = MoneyR() # с нулевым балансом dl = MoneyD(1501.25) # с балансом в 1501.25 долларов euro = MoneyE(100) # с балансом в 100 евро >>> rub = MoneyR() >>> dl = MoneyD(1501.25) >>> euro = MoneyE(100) >>> rub.volume, dl.volume, euro.volume (0, 1501.25, 100) В каждом объекте этих классов должны формироваться локальные атрибуты: __cb - ссылка на класс CentralBank (центральный банк, изначально None); __volume - объем денежных средств в кошельке (если не указано, то 0). Также в классах MoneyR, MoneyD и MoneyE должны быть объекты-свойства (property) для работы с локальными атрибутами: cb - для изменения и считывания данных из переменной __cb; volume - для изменения и считывания данных из переменной __volume. Объекты классов должны поддерживать следующие операторы сравнения: rub < dl dl >= euro rub == euro # значения сравниваются по текущему курсу центрального банка с погрешностью 0.1 (плюс-минус) euro > rub При реализации операторов сравнения считываются соответствующие значения __volume из сравниваемых объектов и приводятся к рублевому эквиваленту в соответствии с курсом валют центрального банка. Чтобы каждый объект классов MoneyR, MoneyD и MoneyE "знал" текущие котировки, необходимо в программе объявить еще один класс CentralBank. Объекты класса CentralBank создаваться не должны (запретить), при выполнении команды: >>> CentralBank() должно просто возвращаться значение None. А в самом классе должен присутствовать атрибут: rates = {'rub': 72.5, 'dollar': 1.0, 'euro': 1.15} >>> CentralBank.rates {'rub': 72.5, 'dollar': 1.0, 'euro': 1.15} Здесь числа (в значениях словаря) - курс валюты по отношению к доллару. Также в CentralBank должен быть метод уровня класса: register(cls, money) - для регистрации объектов классов MoneyR, MoneyD и MoneyE. При регистрации значение __cb объекта money должно ссылаться на класс CentralBank. Через эту переменную объект имеет возможность обращаться к атрибуту rates класса CentralBank и брать нужные котировки. Если кошелек не зарегистрирован, то при операциях сравнения должно генерироваться исключение: raise ValueError("Неизвестен курс валют.") Пример использования классов (эти строчки в программе писать не нужно): >>> CentralBank.rates = {'rub': 72.5, 'dollar': 1.0, 'euro': 1.15} >>> r = MoneyR(45000) >>> d = MoneyD(500) >>> CentralBank.register(r) >>> CentralBank.register(d) >>> r > d, r.value, d.value (True, 620.6896551724138, 500.0) if r > d: print("неплохо") else: print("нужно поднажать") >>> r2 = MoneyR(100) >>> r2 > r Traceback (most recent call last): ... ValueError: Неизвестен курс валют. P.S. В программе на экран ничего выводить не нужно, только объявить классы. """ from functools import total_ordering class CentralBank: rates = {"rub": 72.5, "dollar": 1.0, "euro": 1.15} def __new__(self): ... @classmethod def register(cls, obj): obj.register_cb(cls) @total_ordering class Wallet: currency: str def __repr__(self): return f"{self.__class__.__name__}({self.volume!r})" def register_cb(self, cb: type): self.cb = cb def __init__(self, volume=0): self.cb = None self.volume = volume def __eq__(self, other): if hasattr(other, "value"): return abs(self.value - other.value) <= 0.1 return NotImplemented def __lt__(self, other): if hasattr(other, "value"): return abs(self.value - other.value) > 0.1 and self.value < other.value return NotImplemented @property def cb(self): return getattr(self, f"_{self.__class__.__name__}__cb") @cb.setter def cb(self, value): setattr(self, f"_{self.__class__.__name__}__cb", value) @property def volume(self): return getattr(self, f"_{self.__class__.__name__}__volume") @volume.setter def volume(self, value): setattr(self, f"_{self.__class__.__name__}__volume", value) @property def rate(self): if not self.cb: raise ValueError("Неизвестен курс валют.") return self.cb.rates[self.currency] @property def value(self): return self.volume / self.rate class MoneyR(Wallet): currency = "rub" class MoneyD(Wallet): currency = "dollar" class MoneyE(Wallet): currency = "euro" if __name__ == "__main__": import doctest doctest.testmod()