30. Designing a small class — Homework solutions
The .py solution files are in
exercises/30/homework/solutions/.
Problem 1 — Counter class
Worked solution.
class Counter:
def __init__(self):
self.count = 0
def increment(self):
self.count = self.count + 1
def get(self):
return self.count
def reset(self):
self.count = 0
c = Counter()
c.increment()
c.increment()
c.increment()
print(c.get()) # 3
c.reset()
print(c.get()) # 0Problem 2 — Clamped health
How to think about it. Enforce "stay between 0 and
max" inside heal and damage, so no caller can
push health out of range.
Worked solution.
class Health:
def __init__(self, max):
self.max = max
self.current = max
def heal(self, n):
self.current = self.current + n
if self.current > self.max:
self.current = self.max
def damage(self, n):
self.current = self.current - n
if self.current < 0:
self.current = 0
def get(self):
return self.current
h = Health(100)
h.damage(30)
print(h.get()) # 70
h.heal(1000)
print(h.get()) # 100 (capped at max)
h.damage(9999)
print(h.get()) # 0 (floored at 0)Problem 3 — Light switch
Worked solution.
class Switch:
def __init__(self):
self.on = False
def toggle(self):
self.on = not self.on
def is_on(self):
return self.on
s = Switch()
print(s.is_on()) # False
s.toggle()
print(s.is_on()) # True
s.toggle()
print(s.is_on()) # Falseself.on = not self.on flips the boolean each call — the
whole switch in one line.
Challenge — Stack with a guard
Problem. pop() on an empty stack
returns None instead of crashing.
Worked solution.
class Stack:
def __init__(self):
self.items = []
def push(self, v):
self.items.append(v)
def pop(self):
if len(self.items) == 0:
return None
return self.items.pop()
def size(self):
return len(self.items)
s = Stack()
s.push("a")
s.push("b")
print(s.size()) # 2
print(s.pop()) # b
print(s.pop()) # a
print(s.pop()) # None (empty, but no crash)
print(s.size()) # 0list.pop() on an empty list raises an
IndexError, so the guard checks length first. That is the
rule the method protects.
Done?
That is the end of Part 6. You can build classes, make many instances, inherit, override, and design a clean, safe public surface. Part 6 has two mini-projects: the Inventory System and a Monster Battle, both built from cooperating objects.