Skip to content

Commit c5e46d0

Browse files
committed
improved simple snack suggestion
1 parent 4389364 commit c5e46d0

File tree

1 file changed

+57
-31
lines changed

1 file changed

+57
-31
lines changed

learning/snack_suggestions.py

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,87 @@
44

55
import logging
66
import sys
7+
from typing import Optional
78

89
logger = logging.getLogger(__name__)
910

10-
# Define available snacks as a constant
11+
# Error message constants
12+
ERROR_MESSAGES = {
13+
"no_input": "No input provided",
14+
"interrupted": "User interrupted input",
15+
"no_data": "No input received",
16+
"invalid_choice": "Invalid snack choice",
17+
}
18+
1119
AVAILABLE_SNACKS = {"pizza", "pasta"}
1220

1321

14-
def get_user_input() -> str:
15-
"""Get user input from console.
22+
class SnackSelectorError(Exception):
23+
"""Base exception for snack selector errors."""
24+
25+
26+
class InvalidInputError(SnackSelectorError):
27+
"""Raised when user provides invalid input."""
1628

17-
Returns:
18-
str: User input in lowercase, or 'error' if invalid
19-
"""
29+
def __init__(self, error_code: str):
30+
self.error_code = error_code
31+
messages = {
32+
"no_input": "No input provided",
33+
"interrupted": "User interrupted input",
34+
"no_data": "No input received",
35+
}
36+
super().__init__(messages.get(error_code, "Unknown input error"))
37+
38+
39+
def get_user_input() -> str:
40+
"""Get user input from console."""
2041
try:
2142
user_input = input("\nPlease provide your choice of snack: ")
22-
# Better validation - check if input is not empty after stripping
2343
cleaned_input = user_input.strip()
24-
return cleaned_input.lower() if cleaned_input else "error"
25-
except KeyboardInterrupt:
26-
logger.info("\nGoodbye!")
27-
sys.exit(0)
28-
except EOFError:
29-
logger.info("\nNo input received. Exiting...")
30-
sys.exit(0)
3144

45+
if not cleaned_input:
46+
raise InvalidInputError(ERROR_MESSAGES["no_input"])
3247

33-
def is_snack_available(snack: str) -> bool:
34-
"""Check if the requested snack is available.
48+
return cleaned_input.lower()
3549

36-
Args:
37-
snack: The snack to check
50+
except KeyboardInterrupt as e:
51+
raise InvalidInputError(ERROR_MESSAGES["interrupted"]) from e
52+
except EOFError as e:
53+
raise InvalidInputError(ERROR_MESSAGES["no_data"]) from e
3854

39-
Returns:
40-
bool: True if snack is available, False otherwise
41-
"""
55+
56+
def is_snack_available(snack: str) -> bool:
57+
"""Check if the requested snack is available."""
4258
return snack in AVAILABLE_SNACKS
4359

4460

45-
def main():
61+
def process_snack_request(snack: str) -> None:
62+
"""Process the snack request and log the appropriate response."""
63+
if is_snack_available(snack):
64+
logger.info("Here you go %s", snack)
65+
else:
66+
available_list = ", ".join(sorted(AVAILABLE_SNACKS))
67+
logger.info("Sorry, we don't have %s in our menu. Available options: %s", snack, available_list)
68+
69+
70+
def main() -> None:
4671
"""Main function to run the snack selector."""
4772
logging.basicConfig(
4873
level=logging.INFO,
4974
format="%(asctime)s.%(msecs)03d - %(levelname)s - %(module)s:%(lineno)d - %(message)s",
5075
datefmt="%Y-%m-%d %H:%M:%S",
5176
)
5277

53-
user_input = get_user_input()
54-
55-
if user_input == "error":
56-
logger.error("Invalid input provided. Exiting...")
57-
sys.exit(1) # Use exit code 1 for error
58-
elif is_snack_available(user_input):
59-
logger.info("Here you go %s", user_input)
60-
else:
61-
logger.info("Sorry, we don't have %s in our menu. Please try something else.", user_input)
78+
try:
79+
user_input = get_user_input()
80+
process_snack_request(user_input)
81+
82+
except InvalidInputError as e:
83+
logger.exception("Invalid input: %s", e)
84+
sys.exit(1)
85+
except Exception as e:
86+
logger.exception("Unexpected error: %s", e)
87+
sys.exit(1)
6288

6389

6490
if __name__ == "__main__":

0 commit comments

Comments
 (0)