Skip to content

Instantly share code, notes, and snippets.

@mcorrigan
Created October 4, 2024 14:58
Show Gist options
  • Save mcorrigan/58332b5010547619466c867c71bb0962 to your computer and use it in GitHub Desktop.
Save mcorrigan/58332b5010547619466c867c71bb0962 to your computer and use it in GitHub Desktop.
Advanced User Input Method
import sys
import tty
import termios
def user_input(prompt, default = None, sensitive = False, ret_type = str, required = True):
prompt_default = default
# if they provided a default, the input cannot be required
if default is not None:
required = False
# if default is bool, display yes or no
if isinstance(default, bool):
prompt_default = 'yes' if default else 'no'
if isinstance(default, str) and default == '':
prompt_default = "''"
looping = True
while looping:
if default is None:
if sensitive:
ret = masked_input(f"{prompt}: ").strip()
else:
ret = input(f"{prompt}: ").strip()
else:
if sensitive:
ret = masked_input(f"{prompt} (default: {prompt_default}): ").strip() or default
else:
ret = input(f"{prompt} (default: {prompt_default}): ").strip() or default
# check if required, and that the user did not enter anything, and that the default is not empty string
if required and not ret:
print(f"{prompt} is required.")
looping = True
else:
looping = False
# if default is bool, convert to bool
if ret_type == bool or isinstance(default, bool):
return convert_to_bool(ret)
# if default is an int, convert to int
if ret_type == int or isinstance(default, int):
return int(ret)
if ret_type == float or isinstance(default, float):
return float(ret)
return ret
def convert_to_bool(val):
if isinstance(val, str):
val = val.lower()
if val in ["yes", "true", "1", "y"]:
return True
elif val in ["no", "false", "0", "n"]:
return False
else:
return True
elif isinstance(val, int):
return bool(val)
elif isinstance(val, bool):
return val
else:
return False
def masked_input(prompt=''):
print(prompt, end='', flush=True)
password = ''
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
while True:
ch = sys.stdin.read(1)
if ch == '\n' or ch == '\r': # Enter key pressed
print('\r') # Move cursor back to the start
break
elif ch == '\x7f': # Backspace key pressed
if len(password) > 0:
password = password[:-1]
print('\b \b', end='', flush=True) # Erase the last character
else:
password += ch
print('•', end='', flush=True)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return password
ret = user_input("Username")
print(f"Username entered: {ret}")
ret = user_input("Password", sensitive=True)
print(f"Password entered: {ret}")
ret = user_input("Enabled", default=True)
print(f"Enabled: {ret}")
ret = user_input("Number of people", ret_type = int)
print(f"# of People: {ret} with type {type(ret)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment