Skip to content

Instantly share code, notes, and snippets.

@adammichaelwood
Created January 11, 2018 05:10
Show Gist options
  • Save adammichaelwood/1ec370c8e6e4d240696bc8649036454d to your computer and use it in GitHub Desktop.
Save adammichaelwood/1ec370c8e6e4d240696bc8649036454d to your computer and use it in GitHub Desktop.
Better Input
import re
class AMW_input():
def __init__(
self, prompt, typ, constraint, constraint_msg,
default, feedback=None, before=lambda x: x.strip(), after=None
):
self.prompt = prompt
self.typ = typ
self.constraint = constraint
self.constraint_msg = constraint_msg
self.default = default
self.feedback = feedback
self.before = before
self.after = after
def get_input(self, prompt=None, default=None, verbose=False):
if prompt is None:
prompt = self.prompt
if verbose:
prompt = prompt + f" [ {self.typ} | {self.constraint_msg} ]"
while True:
provisional = input(prompt)
if provisional is "":
provisional = default or self.default or provisional
try:
provisional = self.before(provisional)
except:
pass
try:
provisional = self.cast_to_type(provisional)
except ValueError:
print(f"Wrong Type. Must be [{self.typ}]")
continue
if not self.check_constraint(provisional):
print("\n".join(
["Does not satisfy constraints.",
f"{self.constraint_msg}",
f"{self.constraint}"]
)
)
continue
try:
final_answer = self.after(provisional)
except:
final_answer = provisional
if self.feedback is not None:
print(self.feedback + str(final_answer))
return final_answer
def cast_to_type(self, response):
try:
return self.typ(response)
except ValueError:
raise ValueError
def check_constraint(self, response):
if not self.constraint:
return True
try: # membership in collection or range
if type(self.constraint) is not str:
return response in self.constraint
except TypeError:
pass
try: # regex
return bool(re.search(self.constraint, response))
except TypeError:
pass
try: # callable
return self.constraint(response)
except TypeError:
pass
raise TypeError("Constraint is not an iterable, a regex, or a callable.")
from amw_input import AMW_input as inp
get_even_number = inp(
"Choose an even number: ",
int,
lambda x: x%2 == 0,
"An even number is divisible by 2.",
None,
"You selected: ",
)
first = get_even_number.get_input()
second = get_even_number.get_input("Now a different one.")
third = get_even_number.get_input("Again.", True)
fourth = get_even_number.get_input(prompt="If you don't pick, I will", default=2, verbose=True)
print(fourth, third, second, first)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment