mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-10 19:07:15 +01:00
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
file-length / file length <= 250 lines (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
release-apk / release (APK) (push) Has been cancelled
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
63 lines
2.1 KiB
Python
63 lines
2.1 KiB
Python
"""Parse and seed the Body tab's inputs -- pure over the tab's variables.
|
|
|
|
Split from :mod:`diet_guard._gatelock_body` for the 250-line cap. No widget
|
|
is built here; the functions only read and write ``StringVar``-likes.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date
|
|
from typing import TYPE_CHECKING
|
|
|
|
from diet_guard._body_energy import ACTIVITY_CHOICES, activity_label
|
|
from diet_guard._body_prefs import goal_from_json
|
|
|
|
if TYPE_CHECKING:
|
|
from diet_guard._body_energy import Goal
|
|
from diet_guard._gatelock_body_vars import GoalVars
|
|
|
|
__all__ = ["HEIGHT_CM", "goal_choice", "load_goal", "parse_day", "parse_float"]
|
|
|
|
# Outside this range (cm) a height is a typo rather than a person.
|
|
HEIGHT_CM = (50.0, 260.0)
|
|
|
|
|
|
def parse_float(text: str) -> float | None:
|
|
"""``text`` as a float (comma decimals accepted), or None."""
|
|
try:
|
|
return float(text.strip().replace(",", "."))
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def parse_day(text: str) -> str | None:
|
|
"""``text`` as a normalised ``YYYY-MM-DD``, or None."""
|
|
try:
|
|
return date.fromisoformat(text.strip()).isoformat()
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def load_goal(goal_vars: GoalVars, goal: Goal) -> None:
|
|
"""Put ``goal`` into the sentence's pickers."""
|
|
goal_vars.direction.set(goal.direction)
|
|
goal_vars.amount.set(f"{goal.amount:g}")
|
|
goal_vars.weight_unit.set(goal.weight_unit)
|
|
goal_vars.time_unit.set(goal.time_unit)
|
|
goal_vars.activity.set(activity_label(goal.activity))
|
|
|
|
|
|
def goal_choice(goal_vars: GoalVars, fallback: Goal) -> Goal:
|
|
"""The goal the pickers show; an unreadable amount keeps ``fallback``'s."""
|
|
labels = {activity_label(key): key for key in ACTIVITY_CHOICES}
|
|
amount = parse_float(goal_vars.amount.get())
|
|
return goal_from_json(
|
|
{
|
|
"dir": goal_vars.direction.get(),
|
|
"amt": fallback.amount if amount is None or amount < 0 else amount,
|
|
"wu": goal_vars.weight_unit.get(),
|
|
"tu": goal_vars.time_unit.get(),
|
|
"act": labels.get(goal_vars.activity.get(), fallback.activity),
|
|
}
|
|
)
|