175 lines
6.8 KiB
Python
175 lines
6.8 KiB
Python
from fitness_tracker import *
|
||
import os
|
||
|
||
|
||
def save_workouts(file_path: str, workouts: list) -> None:
|
||
try:
|
||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||
|
||
with open(file_path, 'w', encoding='utf-8') as file:
|
||
json.dump(workouts, file, indent=2, ensure_ascii=False)
|
||
print(f"\nДанные сохранены в {file_path}")
|
||
except IOError as e:
|
||
print(f"\nОшибка при сохранении: {e}")
|
||
|
||
|
||
def main():
|
||
print("=" * 60)
|
||
print("ФИТНЕС ТРЕКЕР - АНАЛИЗ ТРЕНИРОВОК")
|
||
print("=" * 60)
|
||
|
||
FILE_PATH = "data/workouts.json"
|
||
|
||
workouts = load_workouts(FILE_PATH)
|
||
print(f"\nЗагружено {len(workouts)} тренировок")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("ОБЩАЯ СТАТИСТИКА")
|
||
print("=" * 60)
|
||
|
||
print(f"\nВсего тренировок: {len(workouts)}")
|
||
|
||
total_cals = total_calories(workouts)
|
||
print(f"Всего калорий: {total_cals}")
|
||
|
||
avg_dur = average_duration(workouts)
|
||
print(f"Средняя длительность: {avg_dur:.1f} минут")
|
||
|
||
best = best_distance(workouts)
|
||
if best:
|
||
print(f"Лучшая дистанция: {best['distance_km']} км ({best['type']}, {best['date']})")
|
||
else:
|
||
print("Лучшая дистанция: нет тренировок с дистанцией")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("ФИЛЬТРАЦИЯ ПО ТИПУ ТРЕНИРОВКИ")
|
||
print("=" * 60)
|
||
|
||
valid_types = ['running', 'swimming', 'cycling', 'strength']
|
||
while True:
|
||
workout_type = input("\nВведите тип тренировки (running/swimming/cycling/strength): ").lower()
|
||
if workout_type in valid_types:
|
||
break
|
||
print(f"Неверный тип. Допустимые: {valid_types}")
|
||
|
||
filtered = filter_by_type(workouts, workout_type)
|
||
print(f"\nТренировок типа '{workout_type}': {len(filtered)}")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("МЕСЯЧНЫЙ ОТЧЁТ")
|
||
print("=" * 60)
|
||
|
||
while True:
|
||
try:
|
||
year = int(input("\nВведите год (например, 2024): "))
|
||
month = int(input("Введите месяц (1-12): "))
|
||
if 1 <= month <= 12:
|
||
break
|
||
print("Месяц должен быть от 1 до 12")
|
||
except ValueError:
|
||
print("Введите целое число")
|
||
|
||
report = generate_monthly_report(workouts, year, month)
|
||
|
||
print(f"\nОТЧЁТ ЗА {year}-{month:02d}")
|
||
print("-" * 40)
|
||
print(f"Всего тренировок: {report['total_workouts']}")
|
||
print(f"Всего калорий: {report['total_calories']}")
|
||
print(f"Общая дистанция: {report['total_distance_km']} км")
|
||
print(f"Средняя длительность: {report['avg_duration_min']} мин")
|
||
print("\nРаспределение по типам:")
|
||
for w_type, count in report['workouts_by_type'].items():
|
||
print(f" {w_type}: {count}")
|
||
print(f"\nСамый частый тип: {report['most_frequent_type'] if report['most_frequent_type'] else 'нет данных'}")
|
||
|
||
month_workouts = [w for w in workouts if w.get('date', '').startswith(f"{year}-{month:02d}")]
|
||
hr_zones = get_heart_rate_zones(month_workouts)
|
||
|
||
print("\nПУЛЬСОВЫЕ ЗОНЫ (за месяц)")
|
||
print("-" * 40)
|
||
print(f"Низкая (< 120 bpm): {hr_zones['low']} тренировок")
|
||
print(f"Средняя (120-150 bpm): {hr_zones['moderate']} тренировок")
|
||
print(f"Высокая (> 150 bpm): {hr_zones['high']} тренировок")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("ДОБАВЛЕНИЕ НОВОЙ ТРЕНИРОВКИ")
|
||
print("=" * 60)
|
||
|
||
add_new = input("\nДобавить новую тренировку? (да/нет): ").lower()
|
||
|
||
if add_new in ['да', 'yes', 'y', 'д']:
|
||
print("\nВведите данные новой тренировки:")
|
||
|
||
while True:
|
||
date = input("Дата (ГГГГ-ММ-ДД): ")
|
||
if len(date) == 10 and date[4] == '-' and date[7] == '-':
|
||
break
|
||
print("Неверный формат даты. Используйте ГГГГ-ММ-ДД")
|
||
|
||
while True:
|
||
w_type = input("Тип (running/swimming/cycling/strength): ").lower()
|
||
if w_type in valid_types:
|
||
break
|
||
print(f"Неверный тип. Допустимые: {valid_types}")
|
||
|
||
while True:
|
||
try:
|
||
duration = int(input("Длительность (минуты): "))
|
||
if duration > 0:
|
||
break
|
||
print("Длительность должна быть больше 0")
|
||
except ValueError:
|
||
print("Введите целое число")
|
||
|
||
while True:
|
||
try:
|
||
distance = float(input("Дистанция (км): "))
|
||
if distance >= 0:
|
||
break
|
||
print("Дистанция не может быть отрицательной")
|
||
except ValueError:
|
||
print("Введите число")
|
||
|
||
while True:
|
||
try:
|
||
calories = int(input("Калории: "))
|
||
if calories > 0:
|
||
break
|
||
print("Калории должны быть больше 0")
|
||
except ValueError:
|
||
print("Введите целое число")
|
||
|
||
hr_input = input("Средний пульс (опционально, Enter чтобы пропустить): ")
|
||
avg_heart_rate = int(hr_input) if hr_input.strip() else None
|
||
|
||
try:
|
||
workouts = add_workout(workouts, date, w_type, duration, distance, calories, avg_heart_rate)
|
||
print(f"\nТренировка успешно добавлена")
|
||
except ValueError as e:
|
||
print(f"\nОшибка: {e}")
|
||
|
||
save_workouts(FILE_PATH, workouts)
|
||
|
||
print("\n" + "=" * 60)
|
||
print("ДЕМОНСТРАЦИЯ ФУНКЦИИ calories_per_minute")
|
||
print("=" * 60)
|
||
|
||
if workouts:
|
||
first_workout = workouts[0]
|
||
intensity = calories_per_minute(first_workout)
|
||
print(f"\nПервая тренировка в списке:")
|
||
print(f"Дата: {first_workout.get('date')}")
|
||
print(f"Тип: {first_workout.get('type')}")
|
||
print(f"Длительность: {first_workout.get('duration_min')} мин")
|
||
print(f"Калории: {first_workout.get('calories')}")
|
||
print(f"\nИнтенсивность: {intensity:.2f} калорий в минуту")
|
||
else:
|
||
print("\nНет тренировок для демонстрации")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("ПРОГРАММА ЗАВЕРШЕНА")
|
||
print("=" * 60)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |