divisor.cli_input

CLI helper functions for interactive input handling and state management.

  1# SPDX-License-Identifier: MPL-2.0 AND LicenseRef-Commons-Clause-License-Condition-1.0
  2# <!-- // /*  d a r k s h a p e s */ -->d
  3
  4"""CLI helper functions for interactive input handling and state management."""
  5
  6from typing import Callable, Optional
  7
  8from nnll.console import nfo
  9
 10from divisor.controller import ManualTimestepController
 11from divisor.state import MenuState
 12
 13
 14def get_float_input(
 15    prompt: str,
 16    current_value: float,
 17    default_value: float = 0.0,
 18    allow_empty: bool = True,
 19) -> Optional[float]:
 20    """Get float input with optional reset to default.\n
 21    :param prompt: Input prompt string
 22    :param current_value: Current value to display
 23    :param default_value: Value to use if input is empty
 24    :param allow_empty: Whether empty input is allowed
 25    :returns: Parsed float value or None if invalid
 26    """
 27    try:
 28        user_input = input(prompt).strip()
 29        if allow_empty and user_input == "":
 30            return default_value
 31        return float(user_input)
 32    except ValueError:
 33        return None
 34
 35
 36def get_int_input(
 37    prompt: str,
 38    current_value: int,
 39    generate_random: Optional[Callable[[], int]] = None,
 40) -> Optional[int]:
 41    """Get integer input with optional random generation.\n
 42    :param prompt: Input prompt string
 43    :param current_value: Current value to display
 44    :param generate_random: Optional function to generate random value if input is empty
 45    :returns: Parsed integer value or None if invalid
 46    """
 47    try:
 48        user_input = input(prompt).strip()
 49        if user_input == "" and generate_random is not None:
 50            return generate_random()
 51        return int(user_input)
 52    except ValueError:
 53        return None
 54
 55
 56def handle_toggle(
 57    controller: ManualTimestepController,
 58    state: MenuState,
 59    current_value: bool,
 60    setter_func: Callable[[bool], None],
 61    clear_prediction_cache: Optional[Callable[[], None]] = None,
 62    enabled_msg: str = "ENABLED",
 63    disabled_msg: str = "DISABLED",
 64) -> MenuState:
 65    """Generic toggle handler.\n
 66    :param controller: ManualTimestepController instance
 67    :param state: Current input state
 68    :param current_value: Current boolean value
 69    :param setter_func: Controller setter method
 70    :param clear_prediction_cache: Optional function to clear cache
 71    :param enabled_msg: Message when enabled
 72    :param disabled_msg: Message when disabled
 73    :returns: Updated input state
 74    """
 75    new_value = not current_value
 76    setter_func(new_value)
 77    if clear_prediction_cache is not None:
 78        clear_prediction_cache()
 79    state = controller.current_state
 80    status = enabled_msg if new_value else disabled_msg
 81    nfo(f"{status}")
 82    return state
 83
 84
 85def handle_float_setting(
 86    controller: ManualTimestepController,
 87    state: MenuState,
 88    prompt: str,
 89    current_value: float,
 90    setter_func: Callable[[float], None],
 91    clear_prediction_cache: Callable[[], None],
 92    default_value: float = 0.0,
 93    value_name: str = "value",
 94    format_str: str = ".4f",
 95) -> MenuState:
 96    """Handle float setting with reset option.\n
 97    :param controller: ManualTimestepController instance
 98    :param state: Current input state
 99    :param prompt: Input prompt
100    :param current_value: Current float value
101    :param setter_func: Controller setter method
102    :param clear_prediction_cache: Function to clear cache
103    :param default_value: Default value for empty input
104    :param value_name: Name of the value for messages
105    :param format_str: Format string for display
106    :returns: Updated input state
107    """
108    try:
109        user_input = input(prompt).strip()
110        if user_input == "":
111            new_value = default_value
112            reset_msg = f"{value_name} reset to {default_value:{format_str}}"
113        else:
114            new_value = float(user_input)
115            reset_msg = f"{value_name} set to {new_value:{format_str}}"
116
117        setter_func(new_value)
118        clear_prediction_cache()
119        state = controller.current_state
120        nfo(reset_msg)
121    except ValueError:
122        nfo(f"Invalid {value_name}, keeping current value")
123    return state
def get_float_input( prompt: str, current_value: float, default_value: float = 0.0, allow_empty: bool = True) -> Optional[float]:
15def get_float_input(
16    prompt: str,
17    current_value: float,
18    default_value: float = 0.0,
19    allow_empty: bool = True,
20) -> Optional[float]:
21    """Get float input with optional reset to default.\n
22    :param prompt: Input prompt string
23    :param current_value: Current value to display
24    :param default_value: Value to use if input is empty
25    :param allow_empty: Whether empty input is allowed
26    :returns: Parsed float value or None if invalid
27    """
28    try:
29        user_input = input(prompt).strip()
30        if allow_empty and user_input == "":
31            return default_value
32        return float(user_input)
33    except ValueError:
34        return None

Get float input with optional reset to default.

Parameters
  • prompt: Input prompt string
  • current_value: Current value to display
  • default_value: Value to use if input is empty
  • allow_empty: Whether empty input is allowed :returns: Parsed float value or None if invalid
def get_int_input( prompt: str, current_value: int, generate_random: Optional[Callable[[], int]] = None) -> Optional[int]:
37def get_int_input(
38    prompt: str,
39    current_value: int,
40    generate_random: Optional[Callable[[], int]] = None,
41) -> Optional[int]:
42    """Get integer input with optional random generation.\n
43    :param prompt: Input prompt string
44    :param current_value: Current value to display
45    :param generate_random: Optional function to generate random value if input is empty
46    :returns: Parsed integer value or None if invalid
47    """
48    try:
49        user_input = input(prompt).strip()
50        if user_input == "" and generate_random is not None:
51            return generate_random()
52        return int(user_input)
53    except ValueError:
54        return None

Get integer input with optional random generation.

Parameters
  • prompt: Input prompt string
  • current_value: Current value to display
  • generate_random: Optional function to generate random value if input is empty :returns: Parsed integer value or None if invalid
def handle_toggle( controller: divisor.controller.ManualTimestepController, state: divisor.state.MenuState, current_value: bool, setter_func: Callable[[bool], NoneType], clear_prediction_cache: Optional[Callable[[], NoneType]] = None, enabled_msg: str = 'ENABLED', disabled_msg: str = 'DISABLED') -> divisor.state.MenuState:
57def handle_toggle(
58    controller: ManualTimestepController,
59    state: MenuState,
60    current_value: bool,
61    setter_func: Callable[[bool], None],
62    clear_prediction_cache: Optional[Callable[[], None]] = None,
63    enabled_msg: str = "ENABLED",
64    disabled_msg: str = "DISABLED",
65) -> MenuState:
66    """Generic toggle handler.\n
67    :param controller: ManualTimestepController instance
68    :param state: Current input state
69    :param current_value: Current boolean value
70    :param setter_func: Controller setter method
71    :param clear_prediction_cache: Optional function to clear cache
72    :param enabled_msg: Message when enabled
73    :param disabled_msg: Message when disabled
74    :returns: Updated input state
75    """
76    new_value = not current_value
77    setter_func(new_value)
78    if clear_prediction_cache is not None:
79        clear_prediction_cache()
80    state = controller.current_state
81    status = enabled_msg if new_value else disabled_msg
82    nfo(f"{status}")
83    return state

Generic toggle handler.

Parameters
  • controller: ManualTimestepController instance
  • state: Current input state
  • current_value: Current boolean value
  • setter_func: Controller setter method
  • clear_prediction_cache: Optional function to clear cache
  • enabled_msg: Message when enabled
  • disabled_msg: Message when disabled :returns: Updated input state
def handle_float_setting( controller: divisor.controller.ManualTimestepController, state: divisor.state.MenuState, prompt: str, current_value: float, setter_func: Callable[[float], NoneType], clear_prediction_cache: Callable[[], NoneType], default_value: float = 0.0, value_name: str = 'value', format_str: str = '.4f') -> divisor.state.MenuState:
 86def handle_float_setting(
 87    controller: ManualTimestepController,
 88    state: MenuState,
 89    prompt: str,
 90    current_value: float,
 91    setter_func: Callable[[float], None],
 92    clear_prediction_cache: Callable[[], None],
 93    default_value: float = 0.0,
 94    value_name: str = "value",
 95    format_str: str = ".4f",
 96) -> MenuState:
 97    """Handle float setting with reset option.\n
 98    :param controller: ManualTimestepController instance
 99    :param state: Current input state
100    :param prompt: Input prompt
101    :param current_value: Current float value
102    :param setter_func: Controller setter method
103    :param clear_prediction_cache: Function to clear cache
104    :param default_value: Default value for empty input
105    :param value_name: Name of the value for messages
106    :param format_str: Format string for display
107    :returns: Updated input state
108    """
109    try:
110        user_input = input(prompt).strip()
111        if user_input == "":
112            new_value = default_value
113            reset_msg = f"{value_name} reset to {default_value:{format_str}}"
114        else:
115            new_value = float(user_input)
116            reset_msg = f"{value_name} set to {new_value:{format_str}}"
117
118        setter_func(new_value)
119        clear_prediction_cache()
120        state = controller.current_state
121        nfo(reset_msg)
122    except ValueError:
123        nfo(f"Invalid {value_name}, keeping current value")
124    return state

Handle float setting with reset option.

Parameters
  • controller: ManualTimestepController instance
  • state: Current input state
  • prompt: Input prompt
  • current_value: Current float value
  • setter_func: Controller setter method
  • clear_prediction_cache: Function to clear cache
  • default_value: Default value for empty input
  • value_name: Name of the value for messages
  • format_str: Format string for display :returns: Updated input state