Before this lesson
Understand function scope, lists and dictionaries. This lesson introduces object state and module organization.
What you will be able to do
Use independent instance state and understand module entry points and reusable interfaces.
Understand the mechanism
Classes share behavior while instances hold state. Initialize per-instance mutable data on self rather than a shared class attribute. Plain dictionaries remain appropriate when a class adds no useful rules.
Encapsulation maintains invariants through a clear interface. Naming conventions are not security boundaries. Document mutation and return values rather than relying on obscure field names.
Modules are importable files whose top-level code executes on import. Guard demo entry points so importing does not unexpectedly prompt or print. Avoid filenames that shadow standard modules.
Keep dependency direction clear, with the entry point depending on reusable logic rather than the reverse. A small project can start with two coherent files instead of elaborate packaging.
Runnable example
Use Python 3.11 or later. Save lesson.py in a separate practice directory and run python3 lesson.py, or py lesson.py on Windows. Examples use only the standard library.
class Progress:
def __init__(self, total):
if type(total) is not int or total < 0:
raise ValueError("total must be a nonnegative integer")
self.total = total
self.done = 0
def complete(self):
self.done = min(self.total, self.done + 1)
def percent(self):
return 0 if self.total == 0 else self.done * 100 // self.total
if __name__ == "__main__":
first = Progress(4)
second = Progress(4)
first.complete()
print(first.percent(), second.percent())
Trace and verify
Expect 25 and zero. Repeated completion clamps at the total, and an empty course returns zero. Move the class to a module and confirm importing produces no demo output.
Common mistakes and boundaries
Public attributes can still be changed directly, so this is an introductory model rather than fully enforced domain constraints. Composition is often simpler than an inheritance hierarchy.
Practice challenge
Add undo and reset with lower-bound and instance-isolation tests.
Reference solution and reasoning
Clamp undo and reset only the current instance. Test empty-state undo and reset after completion, not just intermediate states.