EXERCISE 17: Read from a flashcard data file
Task: Create a simple text (.csv) file with flashcard data and write code to load flashcards from the text file instead of hard-coding them.
Right now, your flashcards are hard-coded directly in your Python file:
flashcards = {
"Largest mammal on Earth": "Blue whale",
"Tallest type of tree": "Coast redwood",
"Process by which plants make food": "Photosynthesis",
...
}
This means if you want to change flashcards, you have to edit your code. This isn’t ideal and prevents non-technical colleagues from contributing to your app content. To remedy this, you are going to move the flashcard data to a separate file.
Start by creating a new file in your data folder:
- Right-click on the
datafolder - Select “New File”
- Name it
flashcards.txt
Add some flashcard data to flashcards.txt (this might be the same as in your dictionary):
Largest mammal on Earth,Blue whale
Tallest type of tree,Coast redwood
Process by which plants make food,Photosynthesis
Fastest land animal,Cheetah
Largest ocean on Earth,Pacific Ocean
Make sure you keep the separator consistent between lines. For example, in the above example, none of the lines have a space between the comma and the words. It doesn’t matter what the separator is, but it needs to be consistent, e.g. this would also be valid:
Largest mammal on Earth|Blue whale
Tallest type of tree|Coast redwood
Process by which plants make food|Photosynthesis
Fastest land animal|Cheetah
Largest ocean on Earth|Pacific Ocean
Now return to your hard-coded flashcards dictionary, e.g.
fflashcards = {
"Largest mammal on Earth": "Blue whale",
"Tallest type of tree": "Coast redwood",
"Process by which plants make food": "Photosynthesis",
...
}
You need to replace the hard-coded dictionary with code to set the dictionary items from the data you read in from flashcards.txt.
For ease of testing, add a line of code the prints out a message with the number of flashcards in the dictionary, e.g.
f"{len(flashcards)} flashcards loaded!"
Run and check: Run your code in the terminal to make sure it works with the command
python flashcards_app`
- The number of flashcards loaded should correspond to the number of rows in your
flashcards.txtfile. - Try adding more rows representing flashcards in
data/flashcards.txtand run again. Now you should see the new number of flashcards from the additional rows.
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 message “EXERCISE 17: Read from a flashcard data file” and save your work to Github with the standard Git workflow.
(Re)read the guides:
Example solution
flashcards_app.py
# Created by: Alex Ubuntu
# Date: 01.01.2026
# Purpose: A personal flashcard trainer to help with learning
# Import the random module
import random
### LOAD FLASHCARDS
# Set flashcards list from file
# Initialize empty list
flashcards_list = []
file_separator = ','
# Open and read the file
flashcard_file = "flashcards.txt"
try:
with open(flashcard_file, 'r') as file:
lines = file.readlines()
except:
# Handle scenario where file is not found
# and display comprehensible message to user.
print(f"The file {flashcard_file} is missing. Please add it to initialise your flashcards.")
exit()
# Process each line
# Each line has: question,answer
for line in lines:
# Remove whitespace/newlines
line = line.strip()
# Split by ',' separator
parts = line.split(file_separator)
# Extract question and answer
question = parts[0]
answer = parts[1]
# Or in one line with pattern matching assuming two comma
# separated values in a row:
# question, answer = line.split(file_separator)
# Add to list
flashcards_list.append((question, answer))
# Confirm loaded
print(f"{len(flashcards_list)} flashcards loaded!")
### 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
### FUNCTIONS
# Function to calculate and display score information
def display_score_info():
# 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.")
else:
score = (num_cards_correct/num_cards_completed) * 100
print(f"\nYou have answered {num_cards_correct} out of {num_cards_completed} correctly. Your score is {score}%.")
### 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":
# Reset the number of cards completed for each session
num_cards_completed = 0
num_cards_correct = 0
# Iterate through flashcards list of tuples
# Each tuple element of the list contains a question, answer pair
# Using a for loop means that the number of flashcards displayed
# is limited by the number of items in flashcards so the user
# may end up practicing fewer cards than they specified
for q, a in flashcards_list:
# Ask user question and save response into variable
user_answer = input(f"\nQuestion: {q}\n")
# Increment the count of cards completed
num_cards_completed += 1
# Display user's answer and correct answer
print(f"Your answer: {user_answer}, Correct answer: {a}")
# Response deemed to be correct even if given in different case
if user_answer.lower() == a.lower():
# Increment count of cards answered correctly
num_cards_correct += 1
print("Correct")
else:
print("Incorrect")
# Check if number of cards completed has hit the user's
# preferred maximum number of cards
if num_cards_completed >= max_cards:
break
print("\nWell done on completing your practice session!")
# Display score info at the end of a session
display_score_info()
elif choice == "3":
display_score_info()
elif choice == "4":
print(f"We hope you enjoyed your practice session today, {name}.")
display_score_info()
# 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!")
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.")
This works with this flashcards.txt, where the separator is a comma (,)
dog,Mammalia
cat,Mammalia
pig,Mammalia
parrot,Aves
cow,Mammalia
Take a break: ☕
