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