Week 3 Tutorial: Magic Methods
Problem 1 (Easy): Cold Check (<)
You are building a weather app. Create a Temperature class that lets you compare temperatures using <.
- Create a
Temperatureclass with acelsiusattribute - Add
__str__that returns the temperature like"15°C" - Add a magic method so
<works between two Temperature objects (hint: use__lt__)
Input
t1 = Temperature(15)
t2 = Temperature(30)
print(t1 < t2)
print(t2 < t1)
print(t1)
Expected Output
True
False
15°C
Problem 2 (Easy): Weight Limit (<=)
A delivery company checks if a package is within the weight limit. Create a Package class that supports <=.
- Create a
Packageclass with aweightattribute (in kg) - Add
__str__that returns like"Package(5kg)" - Add a magic method so
<=works between two packages (hint: use__le__)
Input
p1 = Package(5)
p2 = Package(10)
p3 = Package(5)
print(p1 <= p2)
print(p2 <= p1)
print(p1 <= p3)
Expected Output
True
False
True
Problem 3 (Easy): Spice Battle (>)
A cooking app ranks dishes by spice level. Create a Dish class that supports >.
- Create a
Dishclass withnameandspice_levelattributes - Add
__str__that returns like"Pizza (spice: 3)" - Add a magic method so
>works between two dishes (hint: use__gt__)
Input
d1 = Dish("Pizza", 3)
d2 = Dish("Curry", 8)
print(d1 > d2)
print(d2 > d1)
print(d1)
Expected Output
False
True
Pizza (spice: 3)
Problem 4 (Easy): Age Check (>=)
A website checks if a user is old enough. Create a User class that supports >=.
- Create a
Userclass withnameandageattributes - Add
__str__that returns like"Alisher (age 20)" - Add a magic method so
>=works between two users (hint: use__ge__)
Input
u1 = User("Alisher", 20)
u2 = User("Bobur", 17)
u3 = User("Charos", 20)
print(u1 >= u2)
print(u2 >= u1)
print(u1 >= u3)
Expected Output
True
False
True
Problem 5 (Easy+): Color Match (!=)
A design tool checks if two colors are different. Create a Color class that supports !=.
- Create a
Colorclass withr,g,battributes (red, green, blue values) - Add
__str__that returns like"Color(255, 0, 0)" - Add a magic method so
!=works between two colors (hint: use__ne__)
Input
c1 = Color(255, 0, 0)
c2 = Color(0, 0, 255)
c3 = Color(255, 0, 0)
print(c1 != c2)
print(c1 != c3)
print(c1)
Expected Output
True
False
Color(255, 0, 0)
Problem 6 (Easy+): Movie Queue ([])
You have a movie watch list. Create a MovieQueue class that lets you access movies by position using [].
- Create a
MovieQueueclass that starts with an empty list of movies - Add an
add(movie)method to add a movie name to the list - Add
__str__that returns like"MovieQueue: 3 movies" - Add a magic method so
[]works to get a movie by its position (hint: use__getitem__)
Input
q = MovieQueue()
q.add("Inception")
q.add("Interstellar")
q.add("The Matrix")
print(q[0])
print(q[2])
print(q)
Expected Output
Inception
The Matrix
MovieQueue: 3 movies
Problem 7 (Medium): Time Tracker
You are building a study tracker app. Students log how many minutes they studied. Create a Duration class that makes working with time feel natural.
- The class stores time as total minutes
- When printed, show time in a human-readable format:
"1h 30m" - You should be able to add two durations together using
+— the result is a newDuration - You should be able to check which duration is longer using
> - A zero-minute duration should be “falsy” when used in an
ifstatement (like how an empty list is falsy)
Input
d1 = Duration(90)
d2 = Duration(45)
d3 = d1 + d2
print(d1)
print(d2)
print(d3)
print(d1 > d2)
d4 = Duration(0)
if not d4:
print("No time left")
Expected Output
1h 30m
0h 45m
2h 15m
True
No time left
Problem 8 (Medium+): Shopping Cart
You are building an online store. Create a ShoppingCart class that feels natural to use — you should be able to check its size, access items, merge two carts, compare totals, and print a summary, all using Python’s built-in syntax.
- The cart holds items, where each item has a name and a price
- Add an
add(name, price)method to add an item to the cart len(cart)should return the number of itemscart[0]should return the first item as a formatted string like"Apple: $2.50"(prices always show 2 decimal places)cart1 + cart2should create a new cart containing all items from both cartscart1 == cart2should beTrueif their total prices are the sameprint(cart)should display how many items and the total price- An empty cart should be falsy in an
ifstatement
Input
cart1 = ShoppingCart()
cart1.add("Apple", 2.50)
cart1.add("Bread", 3.00)
cart2 = ShoppingCart()
cart2.add("Milk", 4.50)
cart2.add("Eggs", 1.00)
print(len(cart1))
print(cart1[0])
print(cart1)
cart3 = cart1 + cart2
print(cart3)
print(len(cart3))
print(cart1 == cart2)
empty = ShoppingCart()
if not empty:
print("Cart is empty")
Expected Output
2
Apple: $2.50
ShoppingCart: 2 items, total $5.50
ShoppingCart: 4 items, total $11.00
4
True
Cart is empty
Problem 9 (Advanced): Game Inventory
You are building an RPG game. Create an Inventory class that behaves naturally with Python’s built-in syntax — accessing items, merging inventories, dropping items, and comparing inventories.
- An inventory has an owner name and stores items, where each item has a name and a value (in gold). Add an
add(name, value)method to add an item to the inventory - You should be able to check how many items are in the inventory and access an item by its position — it should return a string like
"Sword (50 gold)" - Printing should show a summary like
"Inventory 'Hero': 3 items, total 90 gold";repr()should show a developer-friendly version like"Inventory('Hero', 3 items)" - Merging two inventories with
+should create a new inventory containing all unique items (by name) — no duplicates - Subtracting one inventory from another with
-should create a new inventory without the items that appear in the second inventory - Two inventories are equal if they have the same total gold value
- An inventory with a higher total gold value is “greater than” another
- An empty inventory should be falsy
Input
inv1 = Inventory("Hero")
inv1.add("Sword", 50)
inv1.add("Shield", 30)
inv1.add("Potion", 10)
inv2 = Inventory("Merchant")
inv2.add("Shield", 30)
inv2.add("Bow", 40)
print(len(inv1))
print(inv1[0])
print(inv1)
print(repr(inv1))
inv3 = inv1 + inv2
print(len(inv3))
inv4 = inv1 - inv2
print(len(inv4))
print(inv4[0])
print(inv1 > inv2)
inv5 = Inventory("Traveler")
inv5.add("Ring", 20)
inv5.add("Bow", 50)
print(inv2 == inv5)
empty = Inventory("Goblin")
if not empty:
print("Inventory is empty")
Expected Output
3
Sword (50 gold)
Inventory 'Hero': 3 items, total 90 gold
Inventory('Hero', 3 items)
4
2
Sword (50 gold)
True
True
Inventory is empty
Problem 10 (Advanced): Grade Book
You are building a school management system. Create a GradeBook class that manages student grades using Python’s built-in syntax.
- A gradebook has a subject name and stores student grades as name–grade pairs. Add an
add(name, grade)method to record a student’s grade (0–100) len(gradebook)should return the number of studentsgradebook["Harry"]should return Harry’s grade (hint: use__getitem__); raiseKeyErrorif the student is not foundgradebook["Harry"] = 95should update or set Harry’s grade (hint: use__setitem__)"Harry" in gradebookshould check if a student exists (hint: use__contains__)gradebook1 + gradebook2should merge two gradebooks into a new one; if a student appears in both, keep the higher gradeprint(gradebook)should show like"GradeBook 'Potions': 3 students, avg 85.7"(average rounded to 1 decimal place)- Two gradebooks are equal if their average grades are the same (rounded to 1 decimal)
- An empty gradebook should be falsy
- Add a
top(n)method that returns a list of the topnstudent names sorted by grade descending (use sorting and slicing) - Add a
passing(min_grade=60)method that returns a list of student names with grades>= min_grade(use a list comprehension)
Input
gb1 = GradeBook("Potions")
gb1.add("Harry", 92)
gb1.add("Ron", 78)
gb1.add("Hermione", 85)
gb2 = GradeBook("Defense Against the Dark Arts")
gb2.add("Ron", 88)
gb2.add("Draco", 95)
print(len(gb1))
print(gb1["Harry"])
gb1["Ron"] = 80
print(gb1["Ron"])
print("Harry" in gb1)
print("Voldemort" in gb1)
gb3 = gb1 + gb2
print(len(gb3))
print(gb3["Ron"])
print(gb1)
print(gb1 == gb2)
empty = GradeBook("Muggle Studies")
if not empty:
print("No students yet")
print(gb1.top(2))
print(gb1.passing(82))
Expected Output
3
92
80
True
False
4
88
GradeBook 'Potions': 3 students, avg 85.7
False
No students yet
['Harry', 'Hermione']
['Harry', 'Hermione']
Problem 11 (Advanced): Potion Brewing
You are building a potion brewing system for Al-Khogwarts. Create a Potion class that manages ingredients using Python’s built-in syntax.
- A potion has a name and stores ingredients as name–quantity pairs. Add an
add(ingredient, quantity)method len(potion)should return the number of ingredientspotion["Moonstone"]should return the quantity of that ingredient; raiseKeyErrorif not founddel potion["Moonstone"]should remove an ingredient from the potion (hint: use__delitem__)potion * 3should create a new potion with all quantities tripledpotion1 + potion2should combine two potions into a new one (using the first potion’s name); if both have the same ingredient, add their quantities togetherprint(potion)should show like"Potion 'Polyjuice': 3 ingredients, total quantity 6"repr(potion)should show a developer-friendly version like"Potion('Polyjuice', 3 ingredients)"- Two potions are equal if they have the exact same ingredients with the same quantities
- An empty potion (no ingredients) should be falsy
- Add a
brew()method that returns"Brewing {name} with {n} ingredients..."if the potion has ingredients, or"Nothing to brew!"if empty - Add a
needed(other)method that takes another potion and returns a sorted list of ingredient names that are in the other potion but missing from this one (use a list comprehension)
Input
p1 = Potion("Polyjuice")
p1.add("Lacewing Flies", 3)
p1.add("Leeches", 4)
p1.add("Bicorn Horn", 1)
p1.add("Boomslang Skin", 2)
print(len(p1))
print(p1["Lacewing Flies"])
del p1["Leeches"]
print(len(p1))
p2 = p1 * 2
print(p2["Lacewing Flies"])
print(p2["Boomslang Skin"])
p3 = Potion("Felix Felicis")
p3.add("Ashwinder Egg", 1)
p3.add("Squill Bulb", 2)
p3.add("Boomslang Skin", 3)
p4 = p1 + p3
print(len(p4))
print(p4["Boomslang Skin"])
print(p1)
print(repr(p1))
p5 = Potion("Test")
p5.add("Lacewing Flies", 3)
p5.add("Bicorn Horn", 1)
p5.add("Boomslang Skin", 2)
print(p1 == p5)
print(p1 == p3)
empty = Potion("Water")
if not empty:
print("No ingredients")
print(p1.brew())
print(empty.brew())
print(p1.needed(p3))
Expected Output
4
3
3
6
4
5
5
Potion 'Polyjuice': 3 ingredients, total quantity 6
Potion('Polyjuice', 3 ingredients)
True
False
No ingredients
Brewing Polyjuice with 3 ingredients...
Nothing to brew!
['Ashwinder Egg', 'Squill Bulb']
This content will be available starting February 24, 2026.