from decimal import Decimal, getcontext # увеличиваем точность для больших чисел до 50 значащих цифр в вычислениях getcontext().prec = 50 class Fraction: def __init__(self, numerator, denominator): self._numerator = None self._denominator = None self.set_numerator(numerator) self.set_denominator(denominator) self.validate_proper_fraction() # ------------------------ # УСТАНОВКА ЧИСЛИТЕЛЯ def set_numerator(self, numerator): self._numerator = self.validate_numerator(numerator) # ------------------------ # УСТАНОВКА ЗНАМЕНАТЕЛЯ def set_denominator(self, denominator): self._denominator = self.validate_denominator(denominator) @staticmethod def validate_numerator(numerator) -> int: try: num = Decimal(numerator) except: raise ValueError("Числитель должен быть числом") if num != num.to_integral_value(): raise ValueError("Числитель должен быть целым числом") num = int(num) return num @staticmethod def validate_denominator(denominator) -> int: try: den = Decimal(denominator) except: raise ValueError("Знаменатель должен быть числом") if den != den.to_integral_value(): raise ValueError("Знаменатель должен быть целым числом") den = int(den) if den == 0: raise ValueError("Знаменатель не может быть равен нулю") return den # ------------------------ # ПРОВЕРКА ПРАВИЛЬНОЙ ДРОБИ def validate_proper_fraction(self): if abs(self._numerator) >= abs(self._denominator): raise ValueError( "Это не правильная дробь (модуль числителя должен быть меньше модуля знаменателя)" ) # ------------------------ # МЕТОД №1: В ПРОЦЕНТЫ (всегда 2 знака) def to_percent(self) -> str: value = (Decimal(self._numerator) / Decimal(self._denominator)) * Decimal(100) return f"{value:.2f}" # ------------------------ # МЕТОД №2: СУММА ЦИФР ЗНАМЕНАТЕЛЯ def sum_digits_denominator(self) -> int: return sum(int(d) for d in str(abs(self._denominator))) # ------------------------ # СТРОКА ИНФОРМАЦИИ def info(self) -> str: return ( f"Дробь: {self._numerator}/{self._denominator} | " f"Проценты: {self.to_percent()}% | " f"Сумма цифр знаменателя: {self.sum_digits_denominator()}" ) # ------------------------ # ВВОД С ПОДДЕРЖКОЙ 1e32 def input_number(prompt: str): while True: value = input(prompt).strip() try: Decimal(value) # проверка валидности return value except: print("Ошибка: введите число (поддерживается формат 1e32)") def input_fraction() -> Fraction: while True: try: num = input_number("Введите числитель: ") den = input_number("Введите знаменатель: ") return Fraction(num, den) except ValueError as e: print("Ошибка:", e) # ------------------------ def main(): print("Ввод дроби с клавиатуры:") frac_input = input_fraction() # Константы frac1 = Fraction("1", "2") frac2 = Fraction("32", "540") fractions = [frac_input, frac1, frac2] print("\nРезультаты:") for f in fractions: print(f.info()) if __name__ == "__main__": main()