Year 1 · Week 12
Chapter 12: What Is an Object, Anyway?
This week we cross a big bridge in programming: from loose variables and functions to objects. An object bundles data (attributes) and actions (methods) into one neat package. A class is the blueprint that tells Python what every object of that type should look like. By the end of this session you will build your own objects and understand why programmers organize code this way.
Learning Goals
- Explain the difference between a class and an object in plain English
- Identify attributes and methods for any real-world "thing"
- Write a Python function with parameters and an if statement from memory
- Create your own class using the
classkeyword and make objects from it
Warm-Up (10 min) — Be a Pokémon!
Each student gets a blank index card. Write down:
- Name (e.g. Pikachu)
- Type (e.g. Electric)
- HP (pick a number between 1–100)
- One attack name (e.g. Thunderbolt)
- Attack damage (e.g. 30)
Pair up with a partner and "battle": say "I attack with Thunderbolt for 30 damage!" Your partner subtracts 30 from their HP.
After the battle, your teacher will ask:
- What information does every card share? — Those are attributes.
- What actions can every Pokémon do? — Those are methods.
Why Classes? The Messy Way First
Before classes existed, programmers stored data in separate variables. Watch how quickly it gets messy:
# The messy way — no classes pikachu_name = 'Pikachu' pikachu_hp = 100 pikachu_damage = 20 charmander_name = 'Charmander' charmander_hp = 90 charmander_damage = 18 def attack(attacker_name, attacker_damage, target_hp): new_hp = target_hp - attacker_damage print(attacker_name, 'attacks for', attacker_damage, 'damage!') return new_hp charmander_hp = attack(pikachu_name, pikachu_damage, charmander_hp) print('Charmander HP:', charmander_hp)
Imagine doing this for 100 Pokémon. You would have 300 variables! Classes let us wrap all of an object's data and actions into one tidy package.
Your First Class
Here is a Pokémon class without __init__ yet — we'll improve it next session. For now, watch how we attach information directly to the object:
# A class is just a blueprint for now class Pokemon: pass # 'pass' means 'empty for now' # Create an object from the class pikachu = Pokemon() pikachu.name = 'Pikachu' pikachu.hp = 100 pikachu.damage = 20 print(pikachu.name) # Pikachu print(pikachu.hp) # 100 # Make a second Pokémon charmander = Pokemon() charmander.name = 'Charmander' charmander.hp = 90 charmander.damage = 18
Notice how we use the dot to access and set attributes:
pikachu.name— object name + dot + attribute namepikachu.hp— each object has its own independent HP value
Practice (25 min)
Open Thonny and work through the exercises below. Try each one on your own first, then click "Show Answer" to check your work.
Q1. Create a Minecraft class
Write an empty Minecraft class (use pass, just like the Pokemon class above). Then create an object called creeper and give it three attributes:
nameset to'Creeper'hpset to20colorset to'green'
Finally, use print to display creeper.name, creeper.hp, and creeper.color.
Show Answer
class Minecraft: pass creeper = Minecraft() creeper.name = 'Creeper' creeper.hp = 20 creeper.color = 'green' print(creeper.name) print(creeper.hp) print(creeper.color)
Define the class first, then create the object with Minecraft(), then set attributes with the dot operator.
Q2. Create a second Minecraft mob
Using the same Minecraft class, create a second object called zombie:
nameset to'Zombie'hpset to25colorset to'dark green'
Then print zombie.name and zombie.hp.
Show Answer
zombie = Minecraft() zombie.name = 'Zombie' zombie.hp = 25 zombie.color = 'dark green' print(zombie.name) print(zombie.hp)
You do not need to write class Minecraft again. The class is defined once and can produce as many objects as you need.
Q3. Concept check — Class vs Object
Answer these two questions:
- In Q1 and Q2 above, what is the class and what are the objects?
- If
creeper.hpchanges from 20 to 0, doeszombie.hpchange too? Why or why not?
Show Answer
Answer 1: Minecraft is the class (the blueprint). creeper and zombie are two separate objects (instances).
Answer 2: No. Each object has its own independent attribute values. creeper.hp and zombie.hp are two separate "boxes" — changing one does not affect the other. This is called object independence.
Q4. Find attributes and methods
Imagine a "school locker." Write down:
- At least 3 attributes (information it stores)
- At least 2 methods (actions it can perform)
Show Answer
Attributes (data it holds):
locker_number— its number (e.g. 42)owner— the student's name (e.g. 'Alice')is_open— whether it's open (True or False)color— the locker's color
Methods (actions it can do):
open()— open the locker doorclose()— close the locker doorchange_owner(new_name)— assign a new student
Remember: attributes are nouns (what it has), methods are verbs (what it does).
Q5. Model a locker in code
Create a Locker class, then make one locker object with these attributes:
number= 42owner= 'Alice'is_open= False
Write an if/else: if is_open is True, print "The locker is open"; otherwise print "The locker is closed".
Show Answer
class Locker: pass my_locker = Locker() my_locker.number = 42 my_locker.owner = 'Alice' my_locker.is_open = False if my_locker.is_open: print("The locker is open") else: print("The locker is closed")
You just combined creating objects with if/else conditionals — objects and control flow work together!
Q6. Write an attack function
Write a function attack(attacker, target) that does two things:
- Prints
"[attacker's name] attacks [target's name]!" - Subtracts the attacker's damage from the target's HP and prints the target's new HP
Then call the function to make creeper attack zombie.
Show Answer
def attack(attacker, target): print(attacker.name + ' attacks ' + target.name + '!') target.hp = target.hp - attacker.damage print(target.name + ' HP: ' + str(target.hp)) attack(creeper, zombie)
This function takes two objects as parameters and uses the dot operator to read and modify their attributes. After running this, zombie's HP drops from 25 to 5 (25 - 20 = 5).
Q7. Attack again
Using the attack function from Q6, make creeper attack zombie one more time. Then write an if/else to check zombie's HP:
- If HP <= 0, print
"[zombie's name] is defeated!" - Otherwise, print
"[zombie's name] survived with [HP] HP!"
Show Answer
attack(creeper, zombie) # second attack if zombie.hp <= 0: print(zombie.name + ' is defeated!') else: print(zombie.name + ' survived with ' + str(zombie.hp) + ' HP!')
After the first attack zombie's HP is 5. The second attack drops it to 5 - 20 = -15. Since -15 <= 0, the code prints "Zombie is defeated!".
Q8. Challenge — Create your own class
Pick something you like (a car, phone, pet, food — anything!) and do the following:
- Create a class (pick your own name, in English, capitalized — e.g.
Car,Phone) - Create two different objects from that class
- Each object should have at least 3 attributes (set with the dot operator)
- Write a function that takes your object as a parameter and prints at least two of its attributes
- Call your function with both objects
Show Example Answer (using a car)
class Car: pass car1 = Car() car1.brand = 'Toyota' car1.color = 'red' car1.speed = 0 car2 = Car() car2.brand = 'Tesla' car2.color = 'white' car2.speed = 60 def show_car(car): print('Brand:', car.brand) print('Color:', car.color) print('Speed:', car.speed) show_car(car1) show_car(car2)
You can choose anything! The key steps are: define the class, create multiple objects, set attributes with dots, and write a function that works with your objects.
Session 2: __init__, self, and Many Objects
Duration: 60 minutes
Learning Goals
- Write a class with an
__init__method - Understand what
selfrefers to - Create multiple objects that each have different attribute values
Cookie Cutter Demo (10 min)
In Python:
class Pokemon: # ← the cutter pikachu = Pokemon() # ← one cookie charmander = Pokemon() # ← another cookie
Last session we attached attributes after creating the object. That's messy and error-prone. __init__ is the setup recipe that runs automatically every time you make a new object.
Introducing __init__ and self (25 min)
class Pokemon: def __init__(self, name, hp, damage): self.name = name # store 'name' ON this object self.hp = hp # store 'hp' ON this object self.damage = damage # store 'damage' ON this object # Now creating a Pokémon is one clean line: pikachu = Pokemon('Pikachu', 100, 20) charmander = Pokemon('Charmander', 90, 18) squirtle = Pokemon('Squirtle', 95, 15) print(pikachu.name) # Pikachu print(charmander.hp) # 90 print(squirtle.damage) # 15
Common Mistake — Don't Do This!
# WRONG — forgetting self. before the attribute name class Pokemon: def __init__(self, name, hp): name = name # ERROR: this just creates a local variable! hp = hp # It disappears when __init__ finishes. # CORRECT class Pokemon: def __init__(self, name, hp): self.name = name # stored ON the object self.hp = hp # stored ON the object
Practice — Make Your Team (20 min)
Create 3 Pokémon (or pets, or Minecraft mobs — your choice). Print one attribute from each object to check it works.
Exit Ticket
On paper, write the __init__ for this class:
class Spaceship: # It should store: name, fuel, speed def __init__(self, ???): ...
Looking Ahead
This week you learned how to use a class as a blueprint, create objects with the dot operator, and use __init__ to set up attributes all at once. Next week we'll learn how to add methods to a class — so objects don't just store data, they can perform actions too.