OOP: Extra Practice
The exam is problem-solving focused. OOP is just about organizing code cleanly. If you get the logic, the syntax follows. Don't memorize — understand.
Exercise 1: Clock
Build a clock step by step.
Part A: Basic structure
Create a Clock class with:
hours,minutes,seconds(all start at 0, or passed to constructor)- A
tick()method that adds 1 second
Part B: Handle overflow
Make tick() handle:
- 60 seconds → 1 minute
- 60 minutes → 1 hour
- 24 hours → back to 0
Part C: Display
Add __str__ to show time as "HH:MM:SS" (with leading zeros).
c = Clock(23, 59, 59)
print(c) # 23:59:59
c.tick()
print(c) # 00:00:00
Part D: Add seconds
Add __add__ to add an integer number of seconds:
c = Clock(10, 30, 0)
c2 = c + 90 # Add 90 seconds
print(c2) # 10:31:30
You can call tick() in a loop, or be smart and use division/modulo.
Exercise 2: Fraction
Create a Fraction class for exact arithmetic (no floating point nonsense).
Part A: Constructor and display
f = Fraction(1, 2)
print(f) # 1/2
Part B: Simplify automatically
Use math.gcd to always store fractions in simplest form:
f = Fraction(4, 8)
print(f) # 1/2 (not 4/8)
Part C: Arithmetic
Add these special methods:
__add__→Fraction(1,2) + Fraction(1,3)=Fraction(5,6)__sub__→ subtraction__mul__→ multiplication__eq__→Fraction(1,2) == Fraction(2,4)→True
Part D: Test these expressions
# Expression 1
f1 = Fraction(1, 4)
f2 = Fraction(1, 6)
f3 = Fraction(3, 2)
result = f1 + f2 * f3
print(result) # Should be 1/2
# Expression 2
f4 = Fraction(1, 4)
f5 = Fraction(1, 4)
f6 = Fraction(1, 2)
print(f4 + f5 == f6) # Should be True
* happens before +, just like normal math. Python handles this automatically with your special methods.
Exercise 3: Calculator
A calculator that remembers its state.
Part A: Basic operations
class Calculator:
# value starts at 0
# add(x) → adds x to value
# subtract(x) → subtracts x
# multiply(x) → multiplies
# divide(x) → divides
# clear() → resets to 0
# result() → returns current value
calc = Calculator()
calc.add(10)
calc.multiply(2)
calc.subtract(5)
print(calc.result()) # 15
Part B: Chain operations
Make methods return self so you can chain:
calc = Calculator()
calc.add(10).multiply(2).subtract(5)
print(calc.result()) # 15
Each method should end with return self
Part C: Memory
Add:
memory_store()→ saves current valuememory_recall()→ adds stored value to currentmemory_clear()→ clears memory
Exercise 4: Playlist
Part A: Song class
class Song:
# title, artist, duration (in seconds)
# __str__ returns "Artist - Title (M:SS)"
s = Song("Bohemian Rhapsody", "Queen", 354)
print(s) # Queen - Bohemian Rhapsody (5:54)
Part B: Playlist class
class Playlist:
# name
# songs (list)
# add_song(song)
# total_duration() → returns total seconds
# __len__ → number of songs
# __getitem__ → access by index
# __str__ → shows playlist name and song count
p = Playlist("Road Trip")
p.add_song(Song("Song A", "Artist 1", 180))
p.add_song(Song("Song B", "Artist 2", 240))
print(len(p)) # 2
print(p[0]) # Artist 1 - Song A (3:00)
print(p.total_duration()) # 420
Exercise 5: Quick Concepts
No code — just answer:
5.1: What's the difference between a class and an object?
5.2: Why do methods have self as first parameter?
5.3: What happens if you forget __str__ and try to print an object?
5.4: When would you use __eq__ instead of just comparing with ==?
5.5: What's encapsulation and why should you care?
Exercise 6: Debug This
class BankAccount:
def __init__(self, balance):
balance = balance
def deposit(amount):
balance += amount
def __str__(self):
return f"Balance: {self.balance}"
acc = BankAccount(100)
acc.deposit(50)
print(acc)
This crashes. Find all the bugs.
There are 3 bugs. All involve a missing word.
If you can do these, you understand OOP basics. I would be proud.