CodingNic

Functions

Mini Project: Command-Line Quiz Game

Functions 45 min read

Mini Project: Command-Line Quiz Game

Objectives

By the end of this chapter, you should be able to:

  • Combine functions, parameters, data structures, and recursion into one working program
  • Break a larger problem down into smaller functions, each with a single job

💡 Why this matters: Everything up to this point has been one concept at a time, in isolation. Real programs, even small ones, mix all of it together. This is the first project in the course big enough that you’ll need to plan its structure before writing any code.

The Project

Build a command-line quiz game: it asks the player a series of questions, keeps score, and reports the result at the end. Nothing here requires anything beyond what you’ve learned so far: variables, strings, booleans, lists, dictionaries, and functions (including recursion) are the entire toolkit.

Core Requirements

  • Store your questions as a list of dictionaries. You already know lists (Module 2) and dictionaries (Module 3) on their own; here you combine them, so each element of the list is itself a dictionary with a question, the correct answer, and a list of options, something like:
python
QUESTIONS = [
    {
        "question": "What does len() return for the string 'hello'?",
        "options": ["4", "5", "6"],
        "answer": "5",
    },
    {
        "question": "Which keyword defines a function?",
        "options": ["func", "def", "function"],
        "answer": "def",
    },
]
  • Write ask_question(question_dict): prints the question and its options, uses input() to get the player’s answer, and returns True or False depending on whether they got it right.
  • Write run_quiz(questions): loops over every question, keeps a running score using ask_question, and returns the final score.
  • Write report_result(score, total): takes the score and prints a message appropriate to how well the player did (for example, a different message for a perfect score versus a middling one versus a poor one).

A Recursive Extra: Play Again

Write play_quiz() as a recursive function: it runs the quiz once via run_quiz, reports the result, then asks “Play again? (y/n)” with input(). If the player answers "y", play_quiz() calls itself again instead of looping. If they answer anything else, it stops (the base case).

python
def play_quiz():
    score = run_quiz(QUESTIONS)
    report_result(score, len(QUESTIONS))

    again = input("Play again? (y/n) ")
    if again.lower() == "y":
        play_quiz()  # recursive case
    # anything else is the base case: the function just ends

Suggested Structure

You don’t have to follow this exactly, but it’s a reasonable shape to aim for:

python
QUESTIONS = [
    # your question dictionaries here
]

def ask_question(question_dict):
    print(question_dict["question"])
    for option in question_dict["options"]:
        print(f"  - {option}")
    answer = input("Your answer: ")
    return answer.strip() == question_dict["answer"]

def run_quiz(questions):
    score = 0
    for question in questions:
        if ask_question(question):
            score += 1
    return score

def report_result(score, total):
    if score == total:
        print(f"Perfect! {score}/{total}")
    elif score >= total / 2:
        print(f"Not bad. {score}/{total}")
    else:
        print(f"{score}/{total}. Worth another try!")

def play_quiz():
    score = run_quiz(QUESTIONS)
    report_result(score, len(QUESTIONS))
    if input("Play again? (y/n) ").lower() == "y":
        play_quiz()

play_quiz()

Bonus Extensions

  • Track and print which specific questions the player got wrong, at the end.

  • Shuffle the question order each time, so a replay isn’t identical. The random module has a shuffle() function that reorders a list in place:

    python
    import random
    
    QUESTIONS = [
        {"question": "...", "options": [...], "answer": "..."},
        {"question": "...", "options": [...], "answer": "..."},
    ]
    
    random.shuffle(QUESTIONS)  # QUESTIONS is now in a random order
    
  • Add a **kwargs-based ask_question variant that accepts an optional hint and prints it if the player answers wrong on a first attempt, giving them one retry.

  • Add at least one question whose options are computed rather than hardcoded (for example, a question about len() of a string your program generates first).

Try It

  1. Build the project following the suggested structure (or your own design), with at least five questions.
  2. Play through it once, missing at least one question on purpose, and confirm your score and report are correct.
  3. Confirm the recursive “play again” flow works: say yes once, then no, and confirm it actually stops.
  4. Attempt at least one bonus extension.

Recap

You’ve now built a complete, working program, not just answered isolated exercises, using nothing but the tools from this module: functions, parameters, data structures, and recursion. That’s the real test of whether a concept has actually sunk in: can you reach for it unprompted, as part of something bigger.

Next module: debugging your code, and working with Python’s module system.