Intermediate · Projects: put it all together · topic 34 of 50 · 30 min
Project: quiz game with negative marking
Explanation
The plan
| Part | For our quiz |
|---|---|
| Inputs | A list of questions (dictionaries) and a list of the player's answers |
| Outputs | Score with negative marking, counts of correct, wrong and skipped, a shuffled order |
| Rule | +4 for correct, -1 for wrong, 0 for skipped (blank or None) |
The game takes answers as a list instead of calling input(). This keeps the logic separate from the screen, so the same functions work in a terminal game, a website or a phone app, and they are easy to test.
Step 1: questions as data
questions = [
{"question": "Capital of India?", "options": ["Mumbai", "New Delhi", "Kolkata"], "answer": "New Delhi"},
{"question": "5 * 6 = ?", "options": ["30", "11", "56"], "answer": "30"},
{"question": "Largest planet?", "options": ["Earth", "Mars", "Jupiter"], "answer": "Jupiter"},
]
for number, q in enumerate(questions, start=1):
print(number, q["question"], "/".join(q["options"]))Step 2: check one answer fairly
People type in different ways: "new delhi", " New Delhi ", "NEW DELHI". These should all count as correct. So we strip spaces from both ends and compare in lower case. A blank answer or None means the player skipped.
def is_skipped(given):
return given is None or given.strip() == ""
def check_answer(given, correct):
if is_skipped(given):
return False
return given.strip().lower() == correct.strip().lower()
print(check_answer(" new delhi ", "New Delhi")) # True
print(check_answer("Mumbai", "New Delhi")) # False
print(is_skipped(" ")) # TrueStep 3: score with negative marking
def is_skipped(given):
return given is None or given.strip() == ""
def check_answer(given, correct):
return not is_skipped(given) and given.strip().lower() == correct.strip().lower()
def summary(questions, answers, right=4, wrong=-1):
answers = list(answers) + [None] * (len(questions) - len(answers))
result = {"correct": 0, "wrong": 0, "skipped": 0}
for q, given in zip(questions, answers):
if is_skipped(given):
result["skipped"] += 1
elif check_answer(given, q["answer"]):
result["correct"] += 1
else:
result["wrong"] += 1
result["score"] = result["correct"] * right + result["wrong"] * wrong
result["max_score"] = len(questions) * right
return result
questions = [{"answer": "New Delhi"}, {"answer": "30"}, {"answer": "Jupiter"}, {"answer": "7"}]
print(summary(questions, ["new delhi", "56", "", "7"]))
# 2 correct, 1 wrong, 1 skipped -> score 2*4 - 1 = 7 out of 16Step 4: shuffle with a seed
Shuffling stops students copying by position. But for testing, and for showing a student the same paper again, we want to repeat a shuffle exactly. A seed is a starting number for the random generator: the same seed always gives the same order.
import random
def shuffled(questions, seed):
rng = random.Random(seed) # its own generator, does not disturb others
copy = list(questions) # never change the caller's list
rng.shuffle(copy)
return copy
qs = ["Q1", "Q2", "Q3", "Q4", "Q5"]
print(shuffled(qs, 42))
print(shuffled(qs, 42)) # same order again
print(qs) # original unchangedStep 5: test the rules
- All correct: score equals max_score.
- All wrong: score is minus the number of questions.
- All skipped, or an empty answers list: score 0.
- Same seed gives the same order; the shuffled list has the same items as the original.
Watch the lesson
Project: quiz game with negative marking · 1/6
In this project you will build the checking engine of a quiz game, with negative marking like real competitive exams.
Prefer a video by a teacher? Find free videos on “python quiz game project with score” on YouTube ↗
In real life: A coaching centre mock test
A JEE coaching centre in Kota runs a weekly mock test on tablets. The screens are built by a web developer, but the checking is done by functions like ours: answers come in as a list, the score uses +4 and -1, and each student gets the paper shuffled with their roll number as the seed.
correct, wrong, skipped = 52, 18, 20
score = correct * 4 - wrong * 1
print("Score:", score, "out of", (correct + wrong + skipped) * 4)Practice (0/3 done)
Write check_answer(given, correct). Return True when the answers match, ignoring spaces at the ends and capital letters. If given is None or only spaces, return False.
Write score_quiz(questions, answers). Each question is a dictionary with an "answer". Give +4 for a correct answer, -1 for a wrong one and 0 for a skipped one (None or blank). Compare like check_answer: ignore end spaces and case. If answers is shorter than questions, the missing ones are skipped.
Write shuffled(questions, seed) that returns a NEW list with the questions in a random order. Use random.Random(seed) so the same seed always gives the same order. Do not change the original list.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.