Learning Goals
3 minBy the end of this lesson you can:
- Use the return value of a function to drive a running
scorecounter — no copy-pastedifblocks. - Track a
streakcounter to print encouragement when the player gets two or more in a row. - Write a
grade(score, total)function that converts a raw score into a percentage and a letter grade.
Warm-Up
5 minThe shape we want to add. Read it carefully:
score = 0 if ask_question("Q1. ...", "..."): score = score + 1
Two ideas in three lines. score = 0 starts the counter. The if uses the boolean return value of ask_question directly — no extra variable needed. When the return is True, the body runs and the counter goes up.
Quick predict-the-output. After this snippet, what does score equal?
score = 0 if True: score = score + 1 if False: score = score + 1 if True: score = score + 1
Show the answer
2
Two of the conditions were True, so the increment ran twice. In the real quiz, ask_question is what produces the True/False.
This is why we made ask_question return a boolean even though Part 1 didn't use it. Today the return value is the whole show.
New Concept · Score, Streak & Grade
14 min1. The score counter
score = 0 if ask_question("Q1. ...", "..."): score = score + 1 if ask_question("Q2. ...", "..."): score = score + 1 if ask_question("Q3. ...", "..."): score = score + 1 print("Score:", score)
That's the whole pattern. One counter outside the questions, an if on every call that increments it. The function did the work; the main program just keeps score.
2. The streak counter for encouragement
A streak is "how many in a row I just got right". Reset to zero on every wrong answer. When the streak hits 2 or more, print something encouraging:
score = 0 streak = 0 if ask_question("Q1. ...", "..."): score = score + 1 streak = streak + 1 else: streak = 0 if streak >= 2: print("🔥 You're on fire!")
The key trick: increment on win, reset to zero on lose. After three correct answers in a row, streak is 3 and the message prints. After a wrong answer it's back to 0 and the player has to build it up again.
3. A grade function that returns a letter
Time to use a returning function. grade(score, total) takes the raw numbers and returns a letter:
def grade(score, total): percent = score / total * 100 if percent >= 80: return "A" elif percent >= 60: return "B" elif percent >= 40: return "C" else: return "F"
Four returns, one per branch. As soon as one fires, the function exits. We can call grade(4, 5) and get back "A"; we can chain it straight into a print.
4. The final report
total = 3 # we asked 3 questions percent = score / total * 100 print("Score:", score, "/", total) print("That's", round(percent), "%") print("Grade:", grade(score, total))
That's the whole report. Three lines, all of which read like English.
Counters live in the main program. Functions compute and return. The two work together — the function judges each question, the counters track the bigger story.
Worked Example · Quiz Engine v2
13 minThe full file
Save (or update) quiz_engine.py:
Code
# quiz_engine.py — Part 2: score, streak, final grade def ask_question(prompt, answer): reply = input(prompt).strip().lower() if reply == answer.strip().lower(): print("✅ Correct!") return True else: print("❌ Wrong. The answer was:", answer) return False def grade(score, total): percent = score / total * 100 if percent >= 80: return "A" elif percent >= 60: return "B" elif percent >= 40: return "C" else: return "F" # main program — questions live as data questions = [ ["Q1. Capital of Malaysia? ", "Kuala Lumpur"], ["Q2. 7 × 8? ", "56"], ["Q3. Chemical symbol for water? ", "H2O"], ["Q4. How many continents are there? ", "7"], ["Q5. Largest planet in our solar system? ", "Jupiter"], ] print("=" * 40) print(" Welcome to the Hub Quiz!") print("=" * 40) score = 0 streak = 0 for q in questions: prompt = q[0] answer = q[1] if ask_question(prompt, answer): score = score + 1 streak = streak + 1 if streak >= 2: print("🔥 You're on a", streak, "-question streak!") else: streak = 0 # final report total = len(questions) percent = score / total * 100 print("=" * 40) print("Score: ", score, "/", total) print("That's", round(percent), "%") print("Grade: ", grade(score, total)) print("=" * 40)
Sample run · a strong performance
========================================
Welcome to the Hub Quiz!
========================================
Q1. Capital of Malaysia? kuala lumpur
✅ Correct!
Q2. 7 × 8? 56
✅ Correct!
🔥 You're on a 2 -question streak!
Q3. Chemical symbol for water? h2o
✅ Correct!
🔥 You're on a 3 -question streak!
Q4. How many continents are there? 5
❌ Wrong. The answer was: 7
Q5. Largest planet in our solar system? jupiter
✅ Correct!
========================================
Score: 4 / 5
That's 80 %
Grade: A
========================================Two things to notice
- Questions are now data. We stored them as a list-of-lists (each inner list is
[prompt, answer]). To add a sixth question, we add one row to the list — no new function call, no copy-paste. - The
ask_questionfunction from Part 1 is unchanged. All the new features (score, streak, grade) are added around it in the main program. That's the function payoff: today's work didn't touch yesterday's tested code.
In Level 2 you'll read the questions from a JSON file, and in Level 3 you'll wrap them in a Question class. The leap to those bigger programs is small because we already separated "the question text" (data) from "how to ask a question" (function).
Try It Yourself
14 minThree tasks. Build the score, then the streak, then the grade — incremental upgrades.
Start from your Part 1 file. Add a score = 0 at the top of the main program. Wrap each ask_question call in an if that increments score. At the end, print Score: <score> / <total>.
Hint
score = 0 if ask_question("Q1. ...", "..."): score = score + 1 if ask_question("Q2. ...", "..."): score = score + 1 if ask_question("Q3. ...", "..."): score = score + 1 print("Score:", score, "/ 3")
Run it with all wrong answers — should see 0/3. All right — should see 3/3. If any combination doesn't add up, double-check the return True/return False placement in ask_question.
Add a streak counter. Initialise to 0 at the top. In each if: when correct, increment streak; when wrong, reset to 0. After each correct answer, if streak >= 2, print You're on fire!.
Hint
score = 0 streak = 0 if ask_question("Q1. ...", "..."): score = score + 1 streak = streak + 1 if streak >= 2: print("🔥 You're on fire!") else: streak = 0 # repeat the pattern for Q2 and Q3...
Test by answering Q1 wrong and Q2 + Q3 right — only Q3 should fire the message (because streak hit 2 on Q3, not on Q2). Then answer all three right — Q2 and Q3 should both fire.
Add a grade(score, total) function exactly like the worked example — returns "A", "B", "C" or "F" based on percentage. Print the grade in the final report. Test scores: 3/3 → A, 2/3 → B (66%), 1/3 → C (33%? actually F), 0/3 → F.
Hint
def grade(score, total): percent = score / total * 100 if percent >= 80: return "A" elif percent >= 60: return "B" elif percent >= 40: return "C" else: return "F" # in the final report print("Grade:", grade(score, 3))
Double-check the cutoffs in your head: 1/3 is 33%, which is below 40, so it falls into the else and returns "F". The brackets are inclusive on the lower side (>=) and open on the upper side because the next elif catches it.
Mini-Challenge · Sara's Streak Bug
8 minSara's Quiz Engine v2 prints "You're on fire!" even when she gets a question wrong. Find and fix the three bugs.
# sara_quiz.py — buggy streak
score = 0
streak = 0
if ask_question("Q1. Capital of Malaysia? ", "Kuala Lumpur"):
score = score + 1
streak = streak + 1 # always runs!
if streak >= 1:
print("You're on fire!") # always prints!
if ask_question("Q2. 7 × 8? ", "56"):
score = score + 1
streak = streak + 1
# missing else: streak doesn't reset on wrong answers- Bug 1. The
streak = streak + 1line for Q1 is outside theif, so it runs even when the answer was wrong. - Bug 2. The threshold is too low.
streak >= 1triggers after the very first right answer — which makes "on fire" meaningless. Use>= 2. - Bug 3. Q2 has no
elseto resetstreakon a wrong answer. Once the streak goes up, it never goes back down. Addelse: streak = 0for every question.
Show one possible fix
# sara_quiz.py — fixed score = 0 streak = 0 if ask_question("Q1. Capital of Malaysia? ", "Kuala Lumpur"): score = score + 1 streak = streak + 1 if streak >= 2: print("🔥 You're on fire!") else: streak = 0 if ask_question("Q2. 7 × 8? ", "56"): score = score + 1 streak = streak + 1 if streak >= 2: print("🔥 You're on fire!") else: streak = 0
The repeated pattern across questions is exactly the kind of thing you'd eventually move into a loop (like the worked example does with the questions list). For now though, getting the if/else structure right per question is the lesson — once the streak resets cleanly on wrong answers, the encouragement message stops lying.
Recap
3 minThe Quiz Engine grew up. The function from Part 1 didn't change — we just used its boolean return value to drive two counters: score (how many right) and streak (how many in a row). A small returning grade function converts the raw score to a letter at the end. Most importantly, we moved the questions into a list of pairs and let a for loop run the whole quiz. To add more questions, you add rows to the list — no new code. That separation — logic in functions, content in lists — is how every real app you'll write later is structured. Next lesson is a workout: the Functions Decathlon challenge.
Vocabulary Card
- counter
- A variable like
scoreorstreakthat starts at 0 and is incremented as the program runs. - streak
- A count of consecutive successes. Increments on win, resets to 0 on loss.
- grade function
- A returning function that converts raw numbers to a label — e.g. percentage → letter grade.
- data-driven loop
- A
forloop that reads its inputs from a list of values, so adding more cases means adding more list rows. - list of pairs
- A list where each item is itself a two-item list — handy for "question / answer", "name / score", "label / value".
Homework
4 minExtend my_quiz.py from PY-L1-32 into the full Quiz Engine v2.
- Move your five questions into a
questionslist, where each entry is a 2-item list of[prompt, answer]. - Add a
score = 0andstreak = 0at the top of the main program. - Use a
forloop overquestions. Inside the loop, callask_question(q[0], q[1]). OnTrue, increment both counters; onFalse, resetstreak. - After each right answer, if
streak >= 2, print🔥 Streak of <streak>!. - Define
grade(score, total)with the four-band scale from the lesson. Call it once in the final report. - Final report should print:
Score: <score> / <total>, the percentage rounded withround(), and the letter grade.
Bring my_quiz.py next class. In PY-L1-34 — Functions Decathlon — you'll write ten tiny functions against the clock.
Sample · my_quiz.py
# my_quiz.py — Quiz Engine v2 (football edition) def ask_question(prompt, answer): reply = input(prompt).strip().lower() if reply == answer.strip().lower(): print("✅ Correct!") return True else: print("❌ Wrong. The answer was:", answer) return False def grade(score, total): percent = score / total * 100 if percent >= 80: return "A" elif percent >= 60: return "B" elif percent >= 40: return "C" else: return "F" questions = [ ["Q1. Which country won the 2022 World Cup? ", "Argentina"], ["Q2. Most career Champions League goals? ", "Cristiano Ronaldo"], ["Q3. Club in Manchester, blue half? ", "Manchester City"], ["Q4. How many players on the pitch per team? ", "11"], ["Q5. Year Liverpool's last Premier League title? ", "2020"], ] print("=" * 40) print(" Football Quiz — Hub Edition") print("=" * 40) score = 0 streak = 0 for q in questions: if ask_question(q[0], q[1]): score = score + 1 streak = streak + 1 if streak >= 2: print("🔥 Streak of", streak, "!") else: streak = 0 total = len(questions) percent = score / total * 100 print("=" * 40) print("Score: ", score, "/", total) print("That's", round(percent), "%") print("Grade: ", grade(score, total)) print("=" * 40)
The trick to notice: the "engine" (functions + main loop) is the same code regardless of subject. Swap out the questions list for K-pop, dinosaurs, history — the rest doesn't care. That's a real piece of software, written by a Level 1 student.