Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from typing import Generator, Any, Callable
- import argparse
- class ParserException(Exception):
- pass
- class ManagableArgparser(argparse.ArgumentParser):
- def error(self, message):
- """
- Default Argparser exits with sys.exit on error. We override error func to continue program flow
- """
- self.print_usage(argparse._sys.stderr)
- args = {'prog': self.prog, 'message': message}
- raise ParserException('%(prog)s: error: %(message)s\n' % args)
- class Rule:
- def __init__(self, func: Callable[[Any], bool], err_msg: str):
- self.func = func
- self.err_msg = err_msg
- class MyParser():
- answer_varname = "answer"
- def __init__(self):
- self.parser = ManagableArgparser()
- def add_argument(self, choices = None, type = None):
- arguments = {}
- if choices is not None:
- arguments["choices"] = choices
- if type is not None:
- arguments["type"] = type
- self.parser.add_argument(self.answer_varname, **arguments)
- return self
- def ask_question(self, question: str, rules: list[Rule]=[]) -> Generator[Any, None, None]:
- """
- handling retries and all rules :)
- """
- while True:
- userinput = input(question)
- try:
- result = self.parser.parse_args(args=[userinput])
- answer = getattr(result,self.answer_varname)
- for rule in rules:
- if not rule.func(answer):
- raise ParserException(rule.err_msg)
- return answer
- except ParserException as err:
- print(f"{str(err)=}")
- class Item:
- def __init__(self):
- self.name: str = MyParser() \
- .add_argument(type=str) \
- .ask_question("Enter item name?> ", rules=[
- Rule(lambda answer: " " not in answer, "must not contains spaces"),
- Rule(lambda answer: answer.isalpha(), "Must be out of alphabet characters only"),
- ])
- positive_number = Rule(lambda answer: answer > 0, "Must be positive number")
- self.carbs: int = MyParser().add_argument(type=int).ask_question("Enter grams of carbs?> ", rules=[positive_number])
- self.fats: int = MyParser().add_argument(type=int).ask_question("Enter grams of fats?> ", rules=[positive_number])
- self.proteins: int = MyParser().add_argument(type=int).ask_question("Enter grams of proteins?> ", rules=[positive_number])
- @property
- def calories(self) -> int:
- return self.carbs * 4 + self.fats * 9 + self.proteins * 4
- class Session:
- def __init__(self):
- self.items: list[Item] = []
- def run(self):
- while True:
- answer = MyParser().add_argument(choices=["y","n"]).ask_question("would you like to add another item?> (y/n) ")
- if answer == "n":
- break
- self.items.append(Item())
- print(f"this meal has {len(self.items)} for {sum([item.calories for item in self.items])} calories")
- if __name__=="__main__":
- session = Session()
- session.run()
Advertisement
Add Comment
Please, Sign In to add comment