Files
Home_assistant/backend/app/fitness/calculators.py
T
2026-06-10 09:12:50 +03:00

95 lines
2.6 KiB
Python

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,
}