EXERCISE 8: Refine menu and app flow with polished sequences
- What are control flows? (revisited)
- Control flow syntax and indentation (revisited)
if(elif, andelse) statements (revisited)- Comparison operators (revisited)
- Logical operations (revisited)
whileloops (revisited)- Testing for data types (revisited)
- Menu system pattern (revisited)
- Input validation pattern (revisited)
- Sentinel loop pattern
Task: Refine menu wording and messages for usability, handle invalid inputs, and add a proper exit sequence.
Go through your code again and run your app a few times to see what the user experience is like. Even better, ask someone else to go through different flows with different inputs and ask them how they find it.
If needed, refine the messages you display to the user. Some examples of things you might like to refine:
- When the user’s input is invalid, give them more explicit feedback about what is wrong, e.g. “Simply enter the number corresponding to one of the options available”, “Enter a whole number between 5 and 20 without any additional words”.
- Make sure you have a proper exit sequence with final score and statistics, and a performance-dependent message, and encourage them to return.
- You should handle the case where the user has not yet practised any flashcards but asks for the score. Rather than letting the program fail, you can either display a message telling the user they need to practice a card before the score is available, or you can return a score of 0.
Run and check: Run your code in the terminal to make sure it works with the command
python flashcards_app.py
Try entering different inputs to check the behaviour is as your expect. If possible, ask someone else to try out the app with different inputs and flows.
Read through and add comments: Add any comments in your code that will help you understand it when you come back to it later.
Save your progress: Commit with a descriptive message, e.g. “EXERCISE 8: Refine menu and app flow with polished sequences” and save your work to Github with the standard Git workflow.
(Re)read the guides:
- What are control flows? (revisited)
- Control flow syntax and indentation (revisited)
if(elif, andelse) statements (revisited)- Comparison operators (revisited)
- Logical operations (revisited)
whileloops (revisited)- Testing for data types (revisited)
- Menu system pattern (revisited)
- Input validation pattern (revisited)
- Sentinel loop pattern
Example solution
flashcards_app.py
# Created by: Alex Ubuntu
# Date: 01.01.2026
# Purpose: A personal flashcard trainer to help with learning
### INITIAL INTERACTION WITH USER
# Welcome message
print("Welcome to your personal flashcard trainer!")
# Absolute maximum number of cards so that the user can't ask for too many
ABSOLUTE_MAX_CARDS = 100
DEFAULT_MAX_CARDS = 20
# Fetch from user and save to variable
name = input("What is your name? ")
max_cards = DEFAULT_MAX_CARDS # Set a default value for max_cards
# Confirm name
print(f"\nMy name is {name}")
# Card and score variables
num_cards_completed = 0
num_cards_correct = 0
score = 0
### APP MENU LOOP
while True:
print("\nSelect an option by entering a number")
print("1: Set the number of cards you wish to practice")
print("2: Start flashcards")
print("3: Show the current score")
print("4: Exit")
choice = input("\nChoose an option: ")
if choice == "1":
while True:
# More stringent validation for input for maximum number of cards
# Fetch input from user but don't attempt to convert the input string
# to int until certain it will work
entered_max_cards = input("\nHow many cards would you like to practice each session? ")
# Check if input string represents an integer
if entered_max_cards.isdigit():
# Convert to integer data type
entered_max_cards = int(entered_max_cards)
# Check if value is within the value range
# (between 1 and the absolute maximum number of cards)
if entered_max_cards > 0 and entered_max_cards < ABSOLUTE_MAX_CARDS:
# Set the max_cards variable with the user's preference
max_cards = entered_max_cards
# Confirm number maximum number of cards per session
print(f"\nI want to practice at most {max_cards} cards per session")
break
else:
## Let the user know what the range should be (Bonus task).
print(f"\nPlease enter a valid number bewteen 1 and {ABSOLUTE_MAX_CARDS}.")
else:
print(f"\nPlease enter a whole number number over 0.")
elif choice == "2":
print("\nStarting flashcards...")
elif choice == "3":
# Handle case where no cards have been completed yet.
if num_cards_completed <=0:
print("You need to practice before you can get a score.")
continue
score = (num_cards_correct/num_cards_completed) * 100
# Display score information
print(f"\nYou have answered {num_cards_correct} out of {num_cards_completed} correctly. Your score so far is {score}%.")
# Display feedback message based on score
if score > 90 and score <= 100:
print("Excellent work!")
elif score > 70 and score <= 90:
print("Good job!")
elif score > 50 and score <= 70:
print("Keep practicing!")
elif score > 0 and score <= 50:
print("Need more study time!")
else:
print("Score lies outside range")
elif choice == "4":
print(f"We hope you enjoyed your practice session today, {name}.")
# Display score information
print(f"You have answered {num_cards_correct} out of {num_cards_completed} correctly. Your score for this session {score}%.")
print("Look forward to seeing you again soon!")
break
else:
# Clarify instruction to get valid input
print("\nInvalid value entered. Please make sure you enter just a single digit (no other words): 1, 2, 3 or 4, to select an option.")
Take a break: 🎨
