Files
2026-04-01 06:58:37 +00:00

127 lines
4.0 KiB
Python

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()