Интегрирован wesp в сайт
CI / quality (push) Canceled after 0s

This commit is contained in:
влад
2026-07-17 12:57:18 +03:00
parent 5dfa06ddbe
commit 355c0ef9f1
883 changed files with 194576 additions and 177 deletions
+94
View File
@@ -0,0 +1,94 @@
"""Динамические нормы по уравнениям GfE (Германия)."""
from __future__ import annotations
from typing import Any
USP_DYNAMIC_KEY = "usp"
NEL_DYNAMIC_KEY = "nel"
# GfE 2001 Milchkühe — Erhaltung + Milch (Standardmilch / FCM)
NEL_MAINTENANCE_COEFF = 0.293 # MJ NEL / (kg LM)^0,75 / Tag
NEL_PER_KG_MILK_MJ = 3.3 # MJ NEL / kg Milch (FCM)
def gfe_usp_min_g(
mass_kg: float | None,
milk_yield_kg: float | None = None,
) -> float | None:
"""
Минимальная суточная потребность в усвояемом протеине (уСП / nXP), г/сут.
GfE: 0,09 × (масса^0,75) × 6,25 + удой × 85 г.
"""
if mass_kg is None or mass_kg <= 0:
return None
maintenance = 0.09 * (mass_kg**0.75) * 6.25
milk = max(float(milk_yield_kg or 0), 0.0) * 85.0
return maintenance + milk
def gfe_nel_min_mj(
mass_kg: float | None,
milk_yield_kg: float | None = None,
) -> float | None:
"""
Минимальная суточная потребность в ЧЭЛ (NEL), МДж/сут.
GfE 2001: 0,293 × LM^0,75 + удой × 3,3 (MJ NEL на кг молока).
"""
if mass_kg is None or mass_kg <= 0:
return None
maintenance = NEL_MAINTENANCE_COEFF * (mass_kg**0.75)
milk = max(float(milk_yield_kg or 0), 0.0) * NEL_PER_KG_MILK_MJ
return maintenance + milk
def preview_dynamic_norms(
mass_kg: float | None,
milk_yield_kg: float | None = None,
) -> dict[str, Any]:
"""Расчётные min по GfE для UI (без учёта сохранённых норм)."""
_, dynamic = apply_dynamic_norms(
{},
mass_kg=mass_kg,
milk_yield_kg=milk_yield_kg,
)
return dynamic
def apply_dynamic_norms(
stored: dict[str, dict[str, float | None]],
*,
mass_kg: float | None,
milk_yield_kg: float | None,
ration_type: str | None = None,
force_dynamic: bool = False,
) -> tuple[dict[str, dict[str, float | None]], dict[str, Any]]:
"""
Заполняет нормы по GfE, если в БД min не задан.
force_dynamic=True — пересчитать min уСП/ЧЭЛ по массе и удою даже при нормах в БД
(автоготовка с явными mass_kg / milk_yield_kg).
Возвращает (resolved_norms, dynamic_meta).
"""
del ration_type
resolved: dict[str, dict[str, float | None]] = {
key: {"min": bounds.get("min"), "max": bounds.get("max")}
for key, bounds in stored.items()
}
dynamic: dict[str, Any] = {}
for key, compute, formula in (
(USP_DYNAMIC_KEY, gfe_usp_min_g, "0.09×масса^0.75×6.25 + удой×85"),
(NEL_DYNAMIC_KEY, gfe_nel_min_mj, "0.293×масса^0.75 + удой×3.3"),
):
bounds = resolved.get(key, {"min": None, "max": None})
if force_dynamic or bounds.get("min") is None:
computed = compute(mass_kg, milk_yield_kg)
if computed is not None:
entry = dict(bounds)
entry["min"] = computed
resolved[key] = entry
dynamic[key] = {"min": computed, "formula": formula}
return resolved, dynamic