Skip to content

Commit

Permalink
input: Rework input_str and use it in _input_number & input_file
Browse files Browse the repository at this point in the history
  • Loading branch information
TBM13 committed Jul 13, 2023
1 parent 7c88791 commit e05d0d0
Showing 1 changed file with 51 additions and 42 deletions.
93 changes: 51 additions & 42 deletions src/tbm13_utils/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,56 @@ def ask(msg: str, yes_default: bool = False) -> bool:

return selection == 'Y'

def _input_number(type: type, msg: str, fallback = None,
min = None, max = None, accepted_values = None):
def input_str(msg: str, fallback = None,
min_len: int|None = None, max_len: int|None = None) -> str:
"""Asks the user to input a string. Returns it.
If `fallback` isn't `None`, it will be returned as-is if the user doesn't input anything.\n
If `min_len` isn't `None`, the user won't be allowed to input a shorter string.\n
If `max_len` isn't `None`, the user won't be allowed to input a longer string.
"""

msg += ': '
print()
while 1:
clear_last_line()
value = color_input(msg + ': ')
# Print fallback value
if fallback is not None:
color_print((' ' * len(msg)) + f'[darkgray]{fallback}', end='\r')

value = color_input(msg)
if not IN_COLAB:
# If fallback value is larger than the input, the gray
# text will still be there so print the whole line again
clear_last_line()
if len(value) == 0 and fallback is not None:
color_print(f'{msg}{fallback}')
else:
color_print(f'{msg}{value}')

if len(value) == 0:
if fallback is not None:
return fallback

continue
if min_len is not None and len(value) < min_len:
info_input(f"Input must have more than {min_len} chars")
clear_last_line()
continue
if max_len is not None and len(value) > max_len:
info_input(f"Input must have less than {max_len} chars")
clear_last_line()
continue
return value

def _input_number(type: type, msg: str, fallback = None,
min = None, max = None, accepted_values = None):
print()
while 1:
clear_last_line()
value = input_str(msg, fallback)
if value == fallback:
# Return fallback as-is. Don't apply checks to it.
return fallback

try:
result = type(value)
Expand All @@ -98,76 +137,46 @@ def _input_number(type: type, msg: str, fallback = None,

return result

def input_float(msg: str, fallback: float|None = None,
def input_float(msg: str, fallback = None,
min: float|None = None, max: float|None = None,
accepted_values: list[float]|None = None) -> float:
"""Asks the user to input a float. Returns it.
If `fallback` isn't `None`, it will be returned if the user doesn't input anything.\n
If `fallback` isn't `None`, it will be returned as-is if the user doesn't input anything.\n
If `min` isn't `None`, the user won't be allowed to input a lower number.\n
If `max` isn't `None`, the user won't be allowed to input a higher number.\n
If `accepted_values` isn't `None`, the user won't be allowed to input any value not inside it.
"""

return _input_number(float, msg, fallback, min, max, accepted_values)

def input_int(msg: str, fallback: int|None = None,
def input_int(msg: str, fallback = None,
min: int|None = None, max: int|None = None,
accepted_values: list[int]|None = None) -> int:
"""Asks the user to input an integer. Returns it.
If `fallback` isn't `None`, it will be returned if the user doesn't input anything.\n
If `fallback` isn't `None`, it will be returned as-is if the user doesn't input anything.\n
If `min` isn't `None`, the user won't be allowed to input a lower number.\n
If `max` isn't `None`, the user won't be allowed to input a higher number.\n
If `accepted_values` isn't `None`, the user won't be allowed to input any value not inside it.
"""

return _input_number(int, msg, fallback, min, max, accepted_values)

def input_str(msg: str, fallback: str|None = None,
min_len: int|None = None, max_len: int|None = None) -> str:
"""Asks the user to input a string. Returns it.
If `fallback` isn't `None`, it will be returned if the user doesn't input anything.\n
If `min_len` isn't `None`, the user won't be allowed to input a shorter string.\n
If `max_len` isn't `None`, the user won't be allowed to input a longer string.
"""

print()
while 1:
clear_last_line()
value = color_input(msg + ': ')
if len(value) == 0:
if fallback is not None:
return fallback

continue

if min_len is not None and len(value) < min_len:
info_input(f"Input must have more than {min_len} chars")
clear_last_line()
continue
if max_len is not None and len(value) > max_len:
info_input(f"Input must have less than {max_len} chars")
clear_last_line()
continue

return value

def input_file(msg: str, fallback: str|None = None) -> str:
"""Asks the user to input a valid path of a file. Returns it.
If `fallback` isn't `None` and user gives no input, returns `fallback`."""
If `fallback` isn't `None`, it will be returned if the user
doesn't input anything AND `fallback` is a valid file path.
"""

while 1:
file = input(f'{msg}: ')
file = input_str(msg, fallback)
# Strip quotes, this is useful because on Windows the
# file explorer has an option to copy the path of a folder/file,
# and it adds quotes to it
file = file.strip('"')

if fallback is not None and len(file) == 0:
return fallback
if os.path.isfile(file):
break
clear_last_line()
Expand Down

0 comments on commit e05d0d0

Please sign in to comment.