A map editor needs each marker to carry its x and y together and keep them after the program ends — that is what an object is for.
Across three lessons, you will make objects, give them methods, save an object, collect objects in lists, keep lists and dictionaries as attributes, and model a changing state.
-
Define a class that makes objects.
-
Use
__init__andselfto give each new object its own attributes. -
Write methods that calculate from or change an object's attributes.
-
Save an object's data and load it into a new object.
-
Lesson 1: Build Objects with a Class
Make an object with one attribute
A class is a set of instructions for making objects.
class Marker:starts the instructions. The__init__method runs when a newMarkeris made.self.labelstores a label on that object.class Marker: def __init__(self, label): self.label = label m = Marker("A") print(m.label)Scroll the code for more ↓
Output
Am.labelis"A".selfmeans this particular marker. Now give a point two attributes, one for each coordinate.Make a point that carries two coordinates
A map editor needs one marker to keep two coordinates together instead of juggling loose values.
Point(2, 5)will store bothxandy.class Point: def __init__(self, x, y): self.x = x self.y = y home = Point(2, 5) print(home.x) print(home.y)Scroll the code for more ↓
Output
2 5Point(2, 5)makes one object. Python calls__init__automatically. The assignments store2inhome.xand5inhome.y. Values such asxandythat an object carries are called attributes.Inside a class,
selfmeans THIS particular object. Whenhomeis being built,self.xmeans this particular point'sxattribute.Two objects keep separate attributes
A class can make many objects. Each new object receives its own attributes. Watch what happens when only one point changes.
first = Point(1, 3) second = Point(8, 6) first.x = 4 print(first.x) print(second.x)Scroll the code for more ↓
Output
4 8Identity beat:
first.xchanges from 1 to 4.second.xstays 8. The two names refer to two different objects, so changing one object's attribute does not change the other object.A real map program can read two coordinates, construct a point, and show its stored attributes.
Try it x = int(input("X: ")) y = int(input("Y: ")) point = Point(x, y) print(point.x, point.y)Scroll the code for more ↓
The two entered numbers become the new object's separate coordinates.
Trap: forgetting
selfStudy this cell, but do not run it. The line
x = xonly assigns a parameter back to the same local name. It never creates anxattribute on the point.Error demo: this code stops with an error class Point: def __init__(self, x, y): x = x self.y = y broken_point = Point(3, 7) print(broken_point.x)Scroll the code for more ↓
Python reports
AttributeErrorbecausebroken_point.xwas never created. The repair isself.x = x: store the parameter in THIS particular object's attribute.Lesson 2: Methods Compute with Attributes
A poster planner needs each rectangle to know its own size and label. A method is a function written inside a class. It receives
self, uses this object's attributes, and can return a value to the caller.Start with just one method:
areauses width and height from the rectangle that calls it.class Rectangle: def __init__(self, code, width, height): self.code = code self.width = width self.height = height def area(self): return self.width * self.height poster = Rectangle("NW-14", 8, 5) print(poster.area())Scroll the code for more ↓
Output
40poster.area()returns40. The method reads this poster's width and height. Now add perimeter and description methods to the same class.class Rectangle: def __init__(self, code, width, height): self.code = code self.width = width self.height = height def area(self): return self.width * self.height def perimeter(self): return 2 * self.width + 2 * self.height def describe(self): return f"{self.code}: {self.width} by {self.height}" poster = Rectangle("NW-14", 8, 5) print(poster.area()) print(poster.perimeter()) print(poster.describe())Scroll the code for more ↓
Output
40 26 NW-14: 8 by 5poster.area()returns40. Python suppliesposterasself. The addedperimeter()returns26, anddescribe()returns"NW-14: 8 by 5". Each method returns its answer; the caller chooses to print it.describe()uses an f-string rather than a special display method.A method and a plain function
A plain function can also receive an object. Compare where the rectangle appears in these two calls.
def area_of(rectangle): return rectangle.width * rectangle.height print(poster.area()) print(area_of(poster))Scroll the code for more ↓
Output
40 40Both calls return 40. In
poster.area(), the method belongs to the rectangle instructions. Inarea_of(poster), the object is passed to a separate function.A method that draws
A rectangle can return a picture of itself. Build one row of
"#"characters per unit of height, append the rows to a list, and join them with newline characters.class Rectangle: def __init__(self, code, width, height): self.code = code self.width = width self.height = height def area(self): return self.width * self.height def draw(self): rows = [] for i in range(self.height): rows.append("#" * self.width) return "\n".join(rows) poster = Rectangle("D-1", 5, 2) print(poster.draw())Scroll the code for more ↓
Output
##### #####poster.draw()returns"#####\n#####". The caller prints the returned picture. A real program can read a width and height before constructing its rectangle.Try it width = int(input("Width: ")) height = int(input("Height: ")) poster = Rectangle("D-1", width, height) print(poster.area())Scroll the code for more ↓
The input cell builds a rectangle from the entered dimensions and prints its area.
Distance between two points
A method can receive another object as a parameter. The distance rule squares the horizontal and vertical changes, adds them, then uses
** 0.5to take the square root.**is the power operator. Here,** 0.5means "the square root".class Point: def __init__(self, x, y): self.x = x self.y = y def distance(self, other): dx = self.x - other.x dy = self.y - other.y return (dx * dx + dy * dy) ** 0.5 start = Point(0, 0) finish = Point(3, 4) print(start.distance(finish))Scroll the code for more ↓
Output
5.0The call returns
5.0. Hereselfisstart, while the parameterotherreceivesfinish.Slice an attribute string
Because
self.codeholds a string, a method can take a real slice of that attribute string.class Rectangle: def __init__(self, code, width, height): self.code = code self.width = width self.height = height def short_code(self): return self.code[0:2] def describe(self): return f"{self.code}: {self.width} by {self.height}" banner = Rectangle("SE-22", 10, 3) print(banner.short_code()) print(banner.describe())Scroll the code for more ↓
Output
SE SE-22: 10 by 3self.code[0:2]slices from position 0 up to, but not including, position 2. The call returns"SE". The slice is applied to an attribute, not to a loose name.Lesson 3: Save and Load an Object
A map editor needs a point to survive after the program ends. The object will save its attributes as text. A separate loader will read that text and return a new object.
class Point: def __init__(self, x, y): self.x = x self.y = y def save(self, path): with open(path, "w") as f: f.write(f"{self.x}\n") f.write(f"{self.y}\n") return path def load_point(path): with open(path, "r") as f: x = int(f.readline().strip()) y = int(f.readline().strip()) return Point(x, y) point_path = "lesson_point.txt" original = Point(12, 7) original.save(point_path) loaded = load_point(point_path) print(loaded.x) print(loaded.y)Scroll the code for more ↓
Output
12 7Follow the trip:
-
original.save(point_path)writes this object's two attributes with f-string lines. -
load_pointis a module-level function, outside the class. It opens the same path in explicit"r"mode. -
int(...)changes each cleaned text line back to an integer. -
return Point(x, y)makes and returns a new object.
The cell writes the file before it reads it, so it is safe to run again.
-
A method can change its own object
Some methods return a calculation. Other methods update an attribute. A counter is a small example of a changing object.
class Counter: def __init__(self, label): self.label = label self.count = 0 def increment(self): self.count = self.count + 1 return self.count visits = Counter("library") print(visits.increment()) print(visits.increment()) print(visits.count)Scroll the code for more ↓
Output
1 2 2visitsremembers its changed count. A list can also be an attribute, so one object can collect several values.A list as an attribute
A shelf starts with an empty list of books. Its
addmethod appends one title to that list.class Shelf: def __init__(self): self.books = [] def add(self, title): self.books.append(title) shelf = Shelf() shelf.add("Tide") print(shelf.books)Scroll the code for more ↓
Output
['Tide']shelf.booksis["Tide"]. The list belongs to this shelf. A dictionary can be an attribute too.A dictionary as an attribute
A scoreboard stores a separate amount under each player's name.
class Scoreboard: def __init__(self): self.points = {} def record(self, name, amount): self.points[name] = amount board = Scoreboard() board.record("Ivo", 15) print(board.points)Scroll the code for more ↓
Output
{'Ivo': 15}board.pointsis{'Ivo': 15}. The dictionary is stored on the scoreboard object. A list can also hold several objects.Objects in a list
Make three points, then visit each point's
xattribute.points = [Point(1, 2), Point(3, 4), Point(5, 6)] for point in points: print(point.x)Scroll the code for more ↓
Output
1 3 5The loop prints
1,3, and5. Each item inpointsis a whole object, sopoint.xreads its attribute.A state machine
A lamp has one current state. Pressing it switches
"off"to"on"or"on"to"off".class Lamp: def __init__(self): self.state = "off" def press(self): if self.state == "off": self.state = "on" else: self.state = "off" return self.state lamp = Lamp() print(lamp.press()) print(lamp.press())Scroll the code for more ↓
Output
on offThe calls return
"on"then"off". Each press updates the same lamp. A real shelf program can read how many titles to collect.Try it n = int(input("How many books? ")) shelf = Shelf() for i in range(n): shelf.add(input("Title: ")) print(shelf.books)Scroll the code for more ↓
The input cell collects exactly
ntitles in one shelf's list.Put it together: a class describes how to build objects.
__init__gives each new object its own attributes. Methods useselfto calculate with or change that object. Attributes can hold numbers, text, lists, or dictionaries. A list can also hold several objects. A state machine changes an object's state in a controlled sequence. A save method can write attributes, while a module-level load function reads them into a new object.-
class Point:begins instructions for making points. -
__init__runs for each new object and stores values withself.x = x. -
Each object has its own attributes, so changing one point need not change another.
-
A method reads or changes the object named by
self; a call such aspoint.distance(other)passes another object. -
An object can save its attributes as text, and a loader can make a new object from that text.
-
You can now build map points that calculate with their coordinates and survive in a saved file.