python workout: exercise 14
restaurant
problem
In this exercise, I want you to create a new constant dict, called
MENU, representing the possible items you can order at a restaurant. The keys will be strings, and the val- ues will be prices (i.e., integers). You should then write a function,restaurant, that asks the user to enter an order:
- If the user enters the name of a dish on the menu, the program prints the price and the running total. It then asks the user again for their order.
- If the user enters the name of a dish not on the menu, the program scolds the user (mildly). It then asks the user again for their order.
- If the user enters an empty string, the program stops prompting and prints the total amount.
For example, a session with the user might look like this:
Order: sandwich sandwich costs 10, total is 10 Order: tea tea costs 7, total is 17 Order: elephant Sorry, we are fresh out of elephant today. Order: <enter> Your total is 17Note that you can always check to see if a key is in a dict with the
inoperator. That returnsTrueorFalse.
attempts
I don’t really like managing user input. But here goes.
We shouldn’t need a try...except block to manage input, seeing as we can test for
the empty string directly. So this should be straightforward:
MENU = {
"blueberry muffin": 3,
"croissant": 4,
"breakfast wrap": 6,
"smoothie": 5,
"green salad": 4,
"sandwich": 10,
"tea": 7
}
def restaurant():
total = 0
while True:
order = input("Order: ")
if not order:
break
if order not in MENU:
print(f"Sorry, we are fresh out of {order} today.")
continue
price = MENU[order]
total += price
print(f"{order} costs {price}, total is {total}")
print(f"Your total is {total}")
restaurant()
Order: sandwich
sandwich costs 10, total is 10
Order: tea
tea costs 7, total is 17
Order: elephant
Sorry, we are fresh out of elephant today.
Order:
Your total is 17
solution
The book’s implementation:
MENU = {'sandwich': 10, 'tea': 7, 'salad': 9}
def restaurant():
total = 0
while True:
order = input('Order: ').strip()
if not order:
break
if order in MENU:
price = MENU[order]
total += price
print(f'{order} is {price}, total is {total}')
else:
print(f'We are fresh out of {order} today')
print(f'Your total is {total}')
restaurant()
Order: sandwich
sandwich is 10, total is 10
Order: tea
tea is 7, total is 17
Order: elephant
We are fresh out of elephant today
Order:
Your total is 17
I like the use of str.strip() on the input to be a bit more resilient. And maybe
even the control flow…
beyond the exercise
user login
-
problem
Create a dict in which the keys are usernames and the values are passwords, both represented as strings. Create a tiny login system, in which the user must enter a username and password. If there is a match, then indicate that the user has successfully logged in. If not, then refuse them entry.
-
attempts
This shouldn’t be a particularly difficult extension. It doesn’t drift much away from the original problem’s solution:
users = { "alice": "password123", "bob": "letmein", "charlie": "securepass", "diana": "ilovecoffee", "eve": "123456" } def login(): username = input("Username: ").strip() if username in users: password = input(f"Passowrd for {username}: ").strip() if users[username] == password: print(f"Succesfully logged in as {username}!") else: print(f"Password for {username} was incorrect.") else: print(f"No username {username}.") login()>>> login() Username: bob Passowrd for bob: letmein Succesfully logged in as bob! >>> login() Username: bob Passowrd for bob: password Password for bob was incorrect. >>> login() Username: john No username john.
temperatures
-
problem
Define a dict whose keys are dates (represented by strings) from the most recent week and whose values are temperatures. Ask the user to enter a date, and dis- play the temperature on that date, as well as the previous and subsequent dates, if available.
-
attempts
If we assume we just have to print the immediately preceding day’s temperature and the immediately succeeding day’s one, this should again be straightforward. The only challenge is that dict keys are not sorted. So there’s not easy way of accessing the needed dates, least of all when dates are represented as strings.
So, our best bet is probably to convert strings to
datetimeobjects as and when we need to, giving something like:from datetime import datetime, timedelta TEMPS = { "2025-08-11": 22.5, "2025-08-12": 24.1, "2025-08-13": 26.3, "2025-08-14": 25.8, "2025-08-15": 23.7, "2025-08-16": 21.9, "2025-08-17": 19.4 } def temp(): date = input("Date: ").strip() template = "%Y-%m-%d" date_datetime = datetime.strptime(date, template) one_day = timedelta(1) day_before = (date_datetime-one_day).strftime(template) day_after = (date_datetime+one_day).strftime(template) print(f"Temperature on {date}: {TEMPS[date]}C") if day_before in TEMPS: print(f"Temperature the day before on {day_before}: {TEMPS[day_before]}C") if day_after in TEMPS: print(f"Temperature the day after on {day_before}: {TEMPS[day_after]}C")>>> temp() Date: 2025-08-14 Temperature on 2025-08-14: 25.8C Temperature the day before on 2025-08-13: 26.3C Temperature the day after on 2025-08-13: 23.7C >>> temp() Date: 2025-08-17 Temperature on 2025-08-17: 19.4C Temperature the day before on 2025-08-16: 21.9C >>> temp() Date: 2025-08-11 Temperature on 2025-08-11: 22.5C Temperature the day after on 2025-08-10: 24.1CIs it the most elegant solution? Probalby not. But it works and leveraging
datetimeandtimedeltamakes things easy.
age calculator
-
problem
Define a dict whose keys are names of people in your family, and whose values are their birth dates, as represented by Python
dateobjects (http://mng.bz/ jggr). Ask the user to enter the name of someone in your family, and have the program calculate how many days old that person is.
-
attempts
First things first. The exercise does make a good point of using
datetime.date. We probably should have used it overdatetime.datetimein the previous exercise.Other than that, this should be straightforward. The only challenge will be turning the
timedeltathat results from subtractingdatetime.datefromdatetime.date.today().After some quick research,
dateutil.relativedeltaseems to solve all our problems. There’s literally an example solution to our age calculation problem.So, drawing form that, we get something like:
from dateutil.relativedelta import relativedelta from datetime import date FAMILY = { "Alice Johnson": date(1985, 3, 14), "Bob Johnson": date(1982, 7, 22), "Emma Johnson": date(2010, 1, 5), "Liam Johnson": date(2015, 9, 30), "Sarah Johnson": date(2008, 11, 12) } def age(): name = input("Family member: ").strip() if name in FAMILY: today = date.today() age = relativedelta(today, FAMILY[name]) print(f"{name} is {age.years} years old.") age()>>> age() Family member: Bob Johnson Bob Johnson is 43 years old.🤦
…
The exercise only asks for the number days old a person is. Not their age in years.
So, in the end, we don’t need
dateutil.relativedelta:from datetime import date FAMILY = { "Alice Johnson": date(1985, 3, 14), "Bob Johnson": date(1982, 7, 22), "Emma Johnson": date(2010, 1, 5), "Liam Johnson": date(2015, 9, 30), "Sarah Johnson": date(2008, 11, 12) } def age(): name = input("Family member: ").strip() if name in FAMILY: print(f"{name} is {(date.today()-FAMILY[name]).days} days old.") age()>>> age() Family member: Bob Johnson Bob Johnson is 15734 days old.