Untitled
unknown
plain_text
a year ago
5.6 kB
5
Indexable
Never
from dataclasses import dataclass @dataclass class InfoMessage: """Информационное сообщение о тренировке.""" training_type: str duration: float distance: float speed: float calories: float def get_message(self) -> str: """Возвращает сообщение о тренировке.""" return (f'Тип тренировки: {self.training_type}; ' f'Длительность: {self.duration:.3f} ч.; ' f'Дистанция: {self.distance:.3f} км; ' f'Ср. скорость: {self.speed:.3f} км/ч; ' f'Потрачено ккал: {self.calories:.3f}.') @dataclass() class Training: """Базовый класс тренировки.""" action: int duration: float weight: float LEN_STEP = 0.65 M_IN_KM = 1000 CONVERT_H_TO_MIN = 60 def get_distance(self) -> float: """Получить дистанцию в км.""" return self.action * self.LEN_STEP / self.M_IN_KM def get_mean_speed(self) -> float: """Получить среднюю скорость движения.""" return self.get_distance() / self.duration def get_spent_calories(self) -> float: """Получить количество затраченных калорий.""" raise NotImplementedError('Данная функция переопределена' ' для каждого класса') def show_training_info(self) -> InfoMessage: """Вернуть информационное сообщение о выполненной тренировке.""" return InfoMessage( training_type=self.__class__.__name__, duration=self.duration, distance=self.get_distance(), speed=self.get_mean_speed(), calories=self.get_spent_calories() ) @dataclass class Running(Training): """Тренировка: бег.""" CALORIES_MEAN_SPEED_MULTIPLIER = 18 CALORIES_MEAN_SPEED_SHIFT = 1.79 def get_spent_calories(self) -> float: """Переопределенная формула потраченных ккал.""" return ( self.CALORIES_MEAN_SPEED_MULTIPLIER * self.get_mean_speed() + self.CALORIES_MEAN_SPEED_SHIFT ) * self.weight / self.M_IN_KM * ( self.duration * self.CONVERT_H_TO_MIN ) @dataclass class SportsWalking(Training): """Тренировка: спортивная ходьба.""" height: int CONVERT_SPEED_IN_H_TO_SEC = 0.278 CONVERT_HEIGHT = 100 K1_FOR_COUNTING_CALORIES = 0.035 K2_FOR_COUNTING_CALORIES = 0.029 def get_spent_calories(self) -> float: """Переопределенная формула потраченных ккал.""" speed_in_mps = self.get_mean_speed() * self.CONVERT_SPEED_IN_H_TO_SEC height_in_m = self.height / self.CONVERT_HEIGHT duration_in_min = self.duration * self.CONVERT_H_TO_MIN return ( self.K1_FOR_COUNTING_CALORIES * self.weight + ( speed_in_mps ** 2 / height_in_m ) * self.K2_FOR_COUNTING_CALORIES * self.weight ) * duration_in_min @dataclass class Swimming(Training): """Тренировка: плавание.""" length_pool: int count_pool: int LEN_STEP = 1.38 COEFF_SWM_1 = 1.1 COEFF_SWM_2 = 2 def get_mean_speed(self) -> float: """Переопределение метода средней скорости для плавания.""" mean_speed_swimming = ( self.length_pool * self.count_pool / self.M_IN_KM / self.duration ) return mean_speed_swimming def get_spent_calories(self) -> float: """Переопределение расчёта израсходованных калорий.""" total_calories = ( self.get_mean_speed() + self.COEFF_SWM_1 ) * self.COEFF_SWM_2 * self.weight * self.duration return total_calories TRAININGS: dict[str: Training] = { 'SWM': Swimming, 'RUN': Running, 'WLK': SportsWalking, } def read_package(workout_type: str, data: list) -> Training: """Прочитать данные полученные от датчиков.""" if not isinstance(workout_type, str): raise TypeError('Неверный тип данных для workout_type') if not isinstance(data, list): raise TypeError('Неверный тип данных для data') try: training_class = TRAININGS[workout_type] except KeyError: raise ValueError('Фитнес-трекер пока ' 'не поддерживает данный тип тренировки') return training_class(*data) def main(training: Training) -> None: """Главная функция.""" info = training.show_training_info() print(info.get_message()) if __name__ == '__main__': packages = [ ('SWM', [720, 1, 80, 25, 40]), ('RUN', [15000, 1, 75]), ('WLK', [9000, 1, 75, 180]), ] for workout_type, data in packages: training = read_package(workout_type, data) main(training)