diff options
Diffstat (limited to 'ui.py')
| -rw-r--r-- | ui.py | 77 |
1 files changed, 77 insertions, 0 deletions
@@ -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" |
