Repository metrics
- Stars
- (10 stars)
- PR merge metrics
- (PR metrics pending)
Description
The code for taking user input to choose and run items from menus in main_menu.py and settings_menu.py deploy similar functionality which can be factored out.
take_settings_menu_input was recently refactored here and here not to use a flag to break the loop, matching the implementation in main_menu.py: https://github.com/toonarmycaptain/dionysus/blob/6046e12e01eb648d7c38d97f3948b911599ba020/dionysus_app/UI_menus/settings_menu.py#L41-L55)
To generalise the function I propose reintroducing a flag, returned by the functions corresponding to the options in a menu, that would indicate a return to a higher menu/scope. This also reintroduces using a function for breaking the loop/menu without action, as originally implemented in settings_menu.py (albeit with stdout user feedback).
This would allow any function to break the take/run menu selection loop with a flag returned to the calling menu logic, which may have a variety of uses - for example returning False if the action was unsuccessful could trigger feedback to the user before displaying the menu again eg Action unsuccessful. Please select another option: {menu options}. These implementations make assumptions about what the called functions return:
Assume only True is a relevant return value:
while True:
chosen_option = input('>>> ')
if chosen_option in possible_options:
if possible_options[chosen_option](): # or more explicitly: if possible_options[chosen_option]() is True:
return True
break # Exit loop when chosen action finishes. Returns None.
# else:
print("Invalid input.")
Or to be able to return True or False flags:
Assumes True and False are relevant return values.
while True:
chosen_option = input('>>> ')
if chosen_option in possible_options:
return_flag = possible_options[chosen_option]()
if return_flag is not None:
return return_flag
break # Exit loop when chosen action finishes. Returns None.
# else:
print("Invalid input.")
Alternatively, assuming functions will return None, True or False - or equivalent values :
A weakness of this approach is that there is a risk of bugs creeping in where functions happen to return an object (eg str, dict) that evaluates to True/False/None that the caller will then interpret as those values - which may be useful, or a source of bugs.
while True:
chosen_option = input('>>> ')
if chosen_option in possible_options:
return possible_options[chosen_option]()
# else:
print("Invalid input.")
While the above is very elegant/simple, a more explicit implementation might be preferable:
while True:
chosen_option = input('>>> ')
if chosen_option in possible_options:
return_flag = possible_options[chosen_option]()
if return_flag is True or return_flag is False or return_flag is None:
return return_flag
break # Exit loop when chosen action finishes. Returns None.
# else:
print("Invalid input.")