Book-matched resources · Chapter 05 · Challenges 041–050

Lists and Data

Try the printed challenge before revealing a hint or the example solution. Starter files are available only where the book supplies one.

Challenge hints & worked solutions

CHALLENGE 041 · BUILD IT

Build a Playlist

A music club needs a five-track playlist. Begin with the two titles Night Drive and Sunrise Beat, then ask the user to add three more non-blank song titles. Preserve the order in which songs were added.

Start from a blank Python file; no starter supplied for this challenge.Download worked solution .py ↓
Reveal a hint (from the printed book)

Start with a list of two tracks. Use append() for each new entry and enumerate(playlist, start=1) when listing.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 41 - Build a Playlist
playlist = ["Night Drive", "Sunrise Beat"]
added = 0
while added < 3:
    song = input("Add a song: ").strip()
    if not song:
        print("Please enter a song title.")
        continue
    playlist.append(song)
    added += 1
for position, song in enumerate(playlist, start=1):
    print(f"{position}. {song}")
Save this Python file ↓
CHALLENGE 042 · IMPROVE IT

Tidy a Shopping List

Improve the supplied shopping-list program. It starts with bread, milk and apples, but adds duplicates and crashes when asked to remove a missing item. Make both operations safe and keep item numbers correct.

Reveal a hint (from the printed book)

Before adding, compare casefold() versions of each item. Before calling remove(), locate an existing match.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 42 - Tidy a Shopping List
items = ["bread", "milk", "apples"]
new_item = input("Add an item (blank to skip): ").strip()
if new_item:
    if new_item.casefold() in [item.casefold() for item in items]:
        print("Item already listed.")
    else:
        items.append(new_item)
remove_item = input("Remove an item (blank to skip): ").strip()
if remove_item:
    found = next((item for item in items
                  if item.casefold() == remove_item.casefold()), None)
    if found is None:
        print("Item not found.")
    else:
        items.remove(found)
for number, item in enumerate(items, start=1):
    print(f"{number}. {item}")
Save this Python file ↓
CHALLENGE 043 · BUILD IT

Average Test Marks

A teacher has fictitious scores of 70, 80, 90 and 60. Write a program that calculates the mean from a list and displays it with two decimal places. Do not type the final answer into the program.

Start from a blank Python file; no starter supplied for this challenge.Download worked solution .py ↓
Reveal a hint (from the printed book)

Use sum(marks) / len(marks) only when the list is not empty. Format the result with :.2f.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 43 - Average Test Marks
marks = [70, 80, 90, 60]
if marks:
    average = sum(marks) / len(marks)
    print(f"Average: {average:.2f}")
else:
    print("No marks to average.")
Save this Python file ↓
CHALLENGE 044 · DEBUG IT

Leaderboard Leader

The faulty leaderboard awards the win to the lowest score, and it stops as soon as it prints one winner. Correct both errors using a list of (name, score) pairs.

Reveal a hint (from the printed book)

Use max() to find the best score. Look through all pairs to collect every name sharing that score.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 44 - Leaderboard Leader
results = [("Alex", 18), ("Bea", 22), ("Chen", 22), ("Dee", 15)]
if not results:
    print("No scores yet.")
else:
    top_score = max(score for name, score in results)
    winners = [name for name, score in results if score == top_score]
    if len(winners) == 1:
        print(f"Winner: {winners[0]} ({top_score})")
    else:
        print(f"Tie: {', '.join(winners)} ({top_score})")
Save this Python file ↓
CHALLENGE 045 · SOLVE IT

Sort the Results

A quiz system recorded scores [18, 12, 18, 26, 25, 26, 12, 24]. Find the three highest distinct values and display them in descending order. The original list must stay unchanged.

Start from a blank Python file; no starter supplied for this challenge.Download worked solution .py ↓
Reveal a hint (from the printed book)

Make an empty unique_scores list; append each value only once, then use sorted(..., reverse=True) [:3].

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 45 - Sort the Results
scores = [18, 12, 18, 26, 25, 26, 12, 24]
unique_scores = []
for score in scores:
    if score not in unique_scores:
        unique_scores.append(score)
top_three = sorted(unique_scores, reverse=True)[:3]
print("Top distinct scores:", top_three)
print("Original scores:", scores)
Save this Python file ↓
CHALLENGE 046 · BUILD IT

Who's on the Register?

A club has a fictional register: Amira, Bella, Chen and Daniel. Ask for a first name and state whether that exact name is on the list. Treat capital letters as significant for the core task.

Start from a blank Python file; no starter supplied for this challenge.Download worked solution .py ↓
Reveal a hint (from the printed book)

A simple name in register check is case-sensitive. Remember to strip spaces first.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 46 - Who's on the Register?
register = ["Amira", "Bella", "Chen", "Daniel"]
name = input("First name to check: ").strip()
if name in register:
    print(f"Registered: {name}")
else:
    print(f"Not registered: {name}")
Save this Python file ↓
CHALLENGE 047 · IMPROVE IT

No Duplicate Names

The register starter checks exact spelling, so " sam " can be added even though Sam is already present. Improve it to recognise the same name despite stray surrounding spaces or capitalisation.

Reveal a hint (from the printed book)

Use .strip() on new input. Compare .casefold() versions of the new and stored names.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 47 - No Duplicate Names
register = ["Sam", "Alex", "Rory"]
name = input("Add a name: ").strip()
if not name:
    print("Please enter a name.")
elif name.casefold() in [person.casefold() for person in register]:
    print("Duplicate name: not added.")
else:
    register.append(name)
    print(f"Added: {name}")
print("Register:", ", ".join(register))
Save this Python file ↓
CHALLENGE 048 · SOLVE IT

Count the Votes

Count ballots in a fictional class election for Ava, Ben and Cara. Show votes for every candidate and identify a single winner or a tie. Work with lists of candidate names, votes and counts.

Start from a blank Python file; no starter supplied for this challenge.Download worked solution .py ↓
Reveal a hint (from the printed book)

Keep a count for each candidate. Increase the matching position; after counting, find all tied leaders.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 48 - Count the Votes
candidates = ["Ava", "Ben", "Cara"]
ballots = ["Ava", "Ben", "Ava", "Cara", "Ben", "Ava"]
counts = [0] * len(candidates)
for ballot in ballots:
    if ballot in candidates:
        counts[candidates.index(ballot)] += 1
for index, candidate in enumerate(candidates):
    print(f"{candidate}: {counts[index]}")
print(f"Valid ballots: {sum(counts)}")
if not candidates or sum(counts) == 0:
    print("No valid votes.")
else:
    best = max(counts)
    leaders = [candidates[i] for i in range(len(candidates))
               if counts[i] == best]
    print(("Winner: " if len(leaders) == 1 else "Tie: ")
          + ", ".join(leaders))
Save this Python file ↓
CHALLENGE 049 · BUILD IT

Make Balanced Teams

Split the ordered names Alex, Bea, Chen, Dee and Eli into two teams by alternating names. Every student must be in exactly one team, and team sizes can differ by no more than one.

Start from a blank Python file; no starter supplied for this challenge.Download worked solution .py ↓
Reveal a hint (from the printed book)

Try names[::2] for positions 0, 2, 4... and names[1::2] for positions 1, 3, 5...

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 49 - Make Balanced Teams
names = ["Alex", "Bea", "Chen", "Dee", "Eli"]
team_a = names[::2]
team_b = names[1::2]
print("Team A:", ", ".join(team_a) if team_a else "none")
print("Team B:", ", ".join(team_b) if team_b else "none")
Save this Python file ↓
CHALLENGE 050 · DEBUG IT

The Wrong List Item

The starter displays a colour from a five-item list. It asks the user for position 1 to 5 but uses that number directly as a list index, so position 5 crashes. Fix the off-by-one error and handle invalid choices.

Reveal a hint (from the printed book)

Confirm a number was entered, then check it is in the valid range before using position - 1 as the index.

Reveal a worked Python solution

One possible implementation. Check the book's tests and try an extension after comparing.

# Challenge 50 - The Wrong List Item
colours = ["red", "blue", "green", "yellow", "purple"]
position_text = input("Choose a position (1-5): ").strip()
if not position_text.isdigit():
    print("Enter a whole number from 1 to 5.")
else:
    position = int(position_text)
    if 1 <= position <= len(colours):
        print(f"Item: {colours[position - 1]}")
    else:
        print("Position must be from 1 to 5.")
Save this Python file ↓