1 The Problem
We want a flashcard study tool: it shows a question, waits for you, reveals the answer, and you mark whether you knew it — tracking your score. It teaches working through a collection of question-answer pairs and tracking progress, with cards loaded from data.
2 How to Think About It
Think about the study loop, before any code:
3 The Build — explained part by part
Here is the complete flashcard app. Each part is explained below.
# A flashcard study app.
deck = [
{"q": "Capital of Japan?", "a": "Tokyo"},
{"q": "2 + 2?", "a": "4"},
{"q": "Largest planet?", "a": "Jupiter"},
]
score = 0
for card in deck:
print("\nQuestion:", card["q"])
input("Press Enter to see the answer...")
print("Answer:", card["a"])
got_it = input("Did you get it right? (y/n): ").lower()
if got_it == "y":
score += 1
print(f"\nYou knew {score} out of {len(deck)} cards.")
q) and answer (a). The deck is data, so adding cards needs no new code.for card in deck: — go through the cards one at a time.
input("Press Enter to see the answer...") — a clever use of input: we ignore what they type; we just use it to pause until they are ready to see the answer.
got_it = input(...).lower() — ask if they knew it, lowercased so “Y” and “y” both count.
if got_it == "y": score += 1 — count the cards they knew.
len(deck) — the total number of cards, for the “X out of Y” result.
score inside the loop — it zeroes every card.got_it == "y" without lowercasing — “Y” fails.4 Test & Prove Each Part
We test the scoring logic — given a set of yes/no responses, does it count correctly?
def score_session(responses):
"""Count how many cards were marked known ('y')."""
return sum(1 for r in responses if r.lower() == "y")
def test_all_known():
"""All 'y' gives full score."""
assert score_session(["y", "y", "y"]) == 3
def test_none_known():
"""All 'n' gives zero."""
assert score_session(["n", "n"]) == 0
def test_mixed():
"""Mixed responses count only the yes answers."""
assert score_session(["y", "n", "y", "n"]) == 2
Run with pytest -v. The score_session function isolates the counting so we can test it with lists of responses — no need to step through real cards.
5 The Interface
What it expects
Press Enter to see the answer...
Did you get it right? (y/n): yWhat it returns
You knew 2 out of 3 cards.6 Run It & Automate It
python3 flashcards.pyWork through the deck, revealing answers and marking your score.
Jenkins runs the tests automatically — each line explained below.
Question: Capital of Japan?
Press Enter to see the answer...
Answer: Tokyo
Did you get it right? (y/n): y
You knew 1 out of 3 cards."y", and that score starts before the loop.KeyError: 'q'.q and a.// Jenkinsfile — automated tests on every change.
pipeline {
agent any
stages {
stage('Get the code') { steps { checkout scm } } // download the code
stage('Install') { steps { sh 'python3 -m venv venv && . venv/bin/activate && pip install pytest' } } // test tool
stage('Test') { steps { sh '. venv/bin/activate && pytest -v' } } // run every test
}
post {
success { echo 'All tests passed.' }
failure { echo 'A test failed — look above.' }
}
}
- Shuffle the deck. Randomise card order each session. (Teaches:
random.shuffle.) - Repeat the missed ones. Re-quiz cards you got wrong. (Teaches: collecting and re-looping.)
- Load from a file. Read cards from a JSON file. (Teaches: external data.)
input() simply to pause, and track a score across the session. The step-through-and-record pattern reappears constantly. Related: Loops, Variables & Types.