Lesson Complete!

Stats Tracking

You finished the third lesson of Expand PyQuiz. The quiz now tracks your session performance and shows it at the start of each round.

Here is the complete quiz.py:

QUESTIONS = [
    {"text": "What is the type of the value 3.14?", "options": ["int", "str", "float", "bool"], "correct": 3, "category": "types"},
    {"text": "What keyword defines a function in Python?", "options": ["for", "def", "if", "class"], "correct": 2, "category": "functions"},
    {"text": "What does print() do?", "options": ["Stores a value", "Returns a number", "Displays output", "Reads input"], "correct": 3, "category": "output"},
    {"text": "What type does input() always return?", "options": ["int", "float", "str", "bool"], "correct": 3, "category": "output"},
    {"text": "Which keyword starts a for loop?", "options": ["loop", "repeat", "for", "each"], "correct": 3, "category": "loops"},
    {"text": "What does len() return?", "options": ["The first item", "The last item", "The number of items", "The sum"], "correct": 3, "category": "basics"},
    {"text": "What is the result of 10 // 3?", "options": ["3.33", "3", "1", "0"], "correct": 2, "category": "basics"},
    {"text": "Which keyword exits a loop early?", "options": ["exit", "return", "stop", "break"], "correct": 4, "category": "loops"},
    {"text": "What does elif stand for?", "options": ["else if", "elif loop", "end loop if", "extra loop"], "correct": 1, "category": "conditionals"},
    {"text": "What does a function return with no return statement?", "options": ["0", "False", "None", "Error"], "correct": 3, "category": "functions"},
]

STATS = {
    "games": 0,
    "best_score": 0,
    "best_total": 0,
    "total_correct": 0,
    "total_questions": 0,
}

def ask_question(q):
    print(q["text"])
    print()
    print(f"  1) {q['options'][0]}")
    print(f"  2) {q['options'][1]}")
    print(f"  3) {q['options'][2]}")
    print(f"  4) {q['options'][3]}")
    print()
    while True:
        answer_text = input("Your answer (1-4): ")
        try:
            answer = int(answer_text)
        except ValueError:
            print("Please enter 1, 2, 3, or 4.")
            continue
        if answer < 1 or answer > 4:
            print("Please enter 1, 2, 3, or 4.")
            continue
        break
    is_correct = answer == q["correct"]
    print()
    print(f"You answered: {answer}")
    if is_correct:
        print("Correct!")
    else:
        print(f"Wrong! The correct answer was option {q['correct']}.")
    return is_correct

def show_results(score, total):
    print(f"Score: {score}/{total}")
    if score == total:
        print("Perfect score!")
    elif score >= 2:
        print("Great job!")
    elif score >= 1:
        print("Not bad!")
    else:
        print("Keep practicing!")

def show_stats():
    if STATS["games"] == 0:
        print("No games played yet.")
        return
    print(f"Games played: {STATS['games']}")
    print(f"Best round: {STATS['best_score']}/{STATS['best_total']}")
    print(f"Total correct: {STATS['total_correct']} out of {STATS['total_questions']}")

def run_quiz(questions=QUESTIONS, num=None):
    if num is None:
        num = len(questions)
    score = 0
    streak = 0
    questions_for_round = questions[:num]
    total = len(questions_for_round)
    print(f"=== Python Quiz ({total} questions) ===")
    print()
    for q in questions_for_round:
        result = ask_question(q)
        if result:
            score = score + 1
            streak = streak + 1
            if streak >= 3:
                print(f"  Hot streak! ({streak} in a row)")
        else:
            streak = 0
    show_results(score, total)
    return score, total

while True:
    show_stats()
    print()
    categories = sorted(set(q["category"] for q in QUESTIONS))
    print("Categories: " + ", ".join(categories))
    category = input("Category (enter for all): ").strip()
    if category:
        pool = [q for q in QUESTIONS if q["category"] == category]
        if not pool:
            print("Category not found. Playing all.")
            pool = QUESTIONS
    else:
        pool = QUESTIONS
    try:
        num_input = input(f"How many questions? (1-{len(pool)}, enter for all): ").strip()
        if num_input:
            num = int(num_input)
        else:
            num = len(pool)
    except ValueError:
        num = len(pool)
    print()
    score, total = run_quiz(pool, num)
    STATS["games"] = STATS["games"] + 1
    STATS["total_correct"] = STATS["total_correct"] + score
    STATS["total_questions"] = STATS["total_questions"] + total
    if score > STATS["best_score"]:
        STATS["best_score"] = score
        STATS["best_total"] = total
    print()
    again = input("Play again? (y/n): ")
    if again != "y":
        break

print("Thanks for playing!")

What you added:

  • STATS dict — five keys track games, best round, and cumulative totals
  • return score, totalrun_quiz hands its results back to the caller
  • Tuple unpackingscore, total = run_quiz(pool, num) captures both return values
  • show_stats() — displays session performance before each round; skipped on the first round

What's still missing: your stats reset every time you restart the quiz. In the next lesson, you will save STATS to a file when the player quits and load it back on startup, so your history persists across sessions.