from typing import Any ACTIVITY_MULTIPLIERS = { "sedentary": 1.2, "light": 1.375, "moderate": 1.55, "active": 1.725, "very_active": 1.9, } GOAL_CALORIE_ADJUST = { "lose": -500, "maintain": 0, "gain": 300, } def bmr_mifflin(*, sex: str, weight_kg: float, height_cm: float, age: int) -> float: base = 10 * weight_kg + 6.25 * height_cm - 5 * age if sex.lower() in ("m", "male", "м", "мужской"): return base + 5 return base - 161 def tdee( *, sex: str, weight_kg: float, height_cm: float, age: int, activity_level: str = "moderate", ) -> float: bmr = bmr_mifflin(sex=sex, weight_kg=weight_kg, height_cm=height_cm, age=age) mult = ACTIVITY_MULTIPLIERS.get(activity_level, 1.55) return bmr * mult def bmi(weight_kg: float, height_cm: float) -> float: if height_cm <= 0: return 0.0 h = height_cm / 100 return weight_kg / (h * h) def water_target_l(weight_kg: float) -> float: return round(weight_kg * 0.033, 1) def macro_targets( calorie_target: float, weight_kg: float, goal: str = "maintain", ) -> dict[str, float]: protein_g = round(weight_kg * (2.0 if goal == "gain" else 1.8), 0) fat_g = round((calorie_target * 0.25) / 9, 0) protein_cal = protein_g * 4 fat_cal = fat_g * 9 carbs_g = max(0, round((calorie_target - protein_cal - fat_cal) / 4, 0)) return {"protein_g": protein_g, "fat_g": fat_g, "carbs_g": carbs_g} def one_rep_max(weight_kg: float, reps: int) -> float: if reps <= 0: return weight_kg if reps == 1: return weight_kg return round(weight_kg * (1 + reps / 30), 1) def compute_targets(profile: dict[str, Any]) -> dict[str, Any]: weight = float(profile.get("weight_kg") or 70) height = float(profile.get("height_cm") or 170) age = int(profile.get("age") or 30) sex = str(profile.get("sex") or "male") activity = str(profile.get("activity_level") or "moderate") goal = str(profile.get("goal") or "maintain") tdee_val = tdee( sex=sex, weight_kg=weight, height_cm=height, age=age, activity_level=activity ) calorie_target = round(tdee_val + GOAL_CALORIE_ADJUST.get(goal, 0), 0) macros = macro_targets(calorie_target, weight, goal) water = water_target_l(weight) return { "bmr": round(bmr_mifflin(sex=sex, weight_kg=weight, height_cm=height, age=age), 0), "tdee": round(tdee_val, 0), "bmi": round(bmi(weight, height), 1), "calorie_target": calorie_target, "protein_g": macros["protein_g"], "fat_g": macros["fat_g"], "carbs_g": macros["carbs_g"], "water_l": water, }