From 6e7e00846e658cb79d0c23e18939c59fedba06dd Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Wed, 11 Mar 2026 21:16:57 +0100 Subject: Add workout logging CLI with SQLite storage Exercises CRUD, session logging with sets/reps/RPE/rest/LSRPE, session viewing and deletion. Interactive terminal menu. --- ui.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 ui.py (limited to 'ui.py') diff --git a/ui.py b/ui.py new file mode 100644 index 0000000..2d63c06 --- /dev/null +++ b/ui.py @@ -0,0 +1,77 @@ +from datetime import datetime + + +def print_header(title: str) -> None: + print(f"\n--- {title} ---\n") + + +def print_table(headers: list[str], rows: list[list[str]]) -> None: + if not rows: + print(" (empty)") + return + all_rows = [headers] + [[str(c) for c in row] for row in rows] + widths = [max(len(r[i]) for r in all_rows) for i in range(len(headers))] + fmt = " | ".join(f"{{:<{w}}}" for w in widths) + print(fmt.format(*headers)) + print("-+-".join("-" * w for w in widths)) + for row in all_rows[1:]: + print(fmt.format(*row)) + + +def prompt_int( + prompt: str, + required: bool = True, + min_val: int | None = None, + max_val: int | None = None, +) -> int | None: + while True: + val = input(prompt).strip() + if not val: + if not required: + return None + print("This field is required.") + continue + try: + n = int(val) + except ValueError: + print("Please enter a valid integer.") + continue + if min_val is not None and n < min_val: + print(f"Must be at least {min_val}.") + continue + if max_val is not None and n > max_val: + print(f"Must be at most {max_val}.") + continue + return n + + +def prompt_str(prompt: str, required: bool = True) -> str | None: + while True: + val = input(prompt).strip() + if not val: + if not required: + return None + print("This field is required.") + continue + return val + + +def prompt_datetime(prompt: str, default_now: bool = True) -> str: + while True: + default = datetime.now().strftime("%Y-%m-%d %H") + val = input(f"{prompt} [{default}]: ").strip() + if not val: + if default_now: + return default + else: + try: + datetime.strptime(val, "%Y-%m-%d %H") + return val + except ValueError: + print("Invalid format. Use YYYY-MM-DD HH.") + continue + + +def confirm(prompt: str) -> bool: + val = input(f"{prompt} [y/N]: ").strip().lower() + return val == "y" -- cgit v1.2.3