Lecture: Introduction to Object-Oriented Programming
Lecture script · about 15–20 minutes spoken · Week 15
Opening
Picture a health-science student whose app keeps a separate record for each clinic visit. Or a business major tracking a separate balance for every customer. Or a game designer giving each character in a game its own position and its own energy. In all three, one plan gets used again and again, and each thing built from it keeps its own data.
That idea is the subject of this lecture. You already have the pieces. In Week 7 you wrote functions with parameters, and you learned that return hands back a value while print only displays one. In Week 9 you called methods on lists, like append, and you learned that a second name for a list is an alias, not a copy. In Week 14 you saw that every call opens its own frame. This week those pieces come together into one new tool: the class.
Here's the plan. We'll build objects from a class, watch a setup method run by itself, and store values on an object. Then we'll run the reading log as a class, hunt the most common bug, and look back along the path this course has taken.
1. Bundle data with its methods
Think about a recipe card for pancakes. The card isn't a pancake. Cook from it twice, and you get two separate stacks; blueberries in one don't change the other.
Programs work the same way. Object-oriented programming is a way of organizing a program around objects, each of which bundles its own data with the methods that work on that data, instead of keeping the numbers in loose variables and the functions somewhere else.
A class is a blueprint for a kind of object, written with the keyword class, that says which attributes each new object starts with and which methods it can run. An object is one thing built from a class, with its own attribute values and the methods its class defines. And an instance is another word for an object, used to stress which class built it.
Here's the surprise. You've been using objects since early in this course. Take a string, the river book, and call its upper method. The run displays THE RIVER BOOK in capitals. Take a list holding 12 and 40, and call its append method with 25. Print the list, and it holds 12, 40, and 25. Every time you wrote a dot after a value, you called a method that belongs to that value.
Pause and try this. In the line that calls upper on the string named book, which part is the object, and which part is the method?
Look at which side of the dot each name sits on.
Here's the answer. The string named book is the object, on the left of the dot. Upper is the method, on the right, and it belongs to that string.
The value before the dot is the object; the name after it is what the object can do.
2. Build two objects from one class
Picture two museum guards at two doors, each holding a tally clicker. The two clickers end up with different numbers, because each counts only its own door.
The pinned counter program builds exactly that. A class called Counter has a setup method that sets the count to 0, and a method called increment that adds 1 to the count. The program builds two counters, c1 and c2, by calling the class twice. Then it increments c1 twice and c2 once, and prints both counts.
Trace it with me. The first counter goes from 0 to 1, then from 1 to 2. The second goes from 0 to 1. So the run displays 2 and 1.
Writing the class is like writing a def: nothing runs until a line calls it. Each call to the class built a new, separate object with its own count.
Pause and try this. Someone predicts the last line will read 3 and 3, because both counters came from one class. What did they get wrong?
Think about how many objects the program built.
Here's the answer. The program built two objects, each with its own count. Incrementing c1 never touches c2, so the counts stay 2 and 1.
Two objects, two counts.
3. Watch the setup method run for you
When you take a new phone out of the box and switch it on, the clock is already set and the photo album is already empty. You didn't run a setup program by hand. It ran when the phone was made.
A class has a setup method like that. __init__ is the method Python runs automatically, once, on each new object when the class is called, so that the object starts with its attributes set; the program never calls it by name. Say it as "init", and notice the two underscores before and two after.
Calling the class does two jobs at once. Calling ReadingLog with 300 makes a new object, and then it runs init on that object, handing in 300 as the goal.
Here's a version of the reading log whose init prints a line, so you can catch it in the act. The program builds a log called mine with a goal of 300 and a log called yours with a goal of 150, then prints both goals. The run displays "building a log with goal 300", then "building a log with goal 150", then 300 and 150.
Pause and try this. The program never writes init as a call. So how many times did the line inside init print, and why?
Count the calls to the class.
Here's the answer. It printed twice, because the program called the class twice. Each call to the class runs init on the new object.
Call the class, and Python runs init for you.
4. Store values on self
A luggage tag tied to a suitcase travels with that suitcase. A note scribbled on a scrap of paper in your pocket doesn't. Inside a method, writing self dot in front of a name is tying the tag on.
An attribute is a value stored on an object under a name, such as self dot goal inside a class or mine dot goal outside it; each instance holds its own attribute values. Dot notation is writing an object's name, a dot, and then the name of one of its attributes or methods, to reach that part of that particular object.
In the reading log's init, two lines do the storing. Self dot goal gets the goal, and self dot pages read gets 0. Build mine with a goal of 300 and print mine dot goal and mine dot pages read. The run displays 300 and 0.
Inside the class, the object is called self. Outside, it's called whatever name you gave it, here mine.
Pause and try this. Right after mine is built, what are its goal and its pages read, and which line set each one?
Look inside init.
Here's the answer. The goal is 300, set by self dot goal getting goal. Pages read is 0, set by self dot pages read getting 0.
If it isn't on self, it isn't on the object.
5. Pass self: methods take the object first
A barista picks up a cup and asks one question before writing anything: whose order is this? Every method asks the same first question: which object am I working on?
self is the conventional name of the first parameter of every method, which receives the object the method was called on; Python passes it automatically, so the caller never writes it in the call.
The add day method has two parameters, self and pages. When you write mine dot add day with 45, Python hands mine to self and 45 to pages. You can even write the same call out by hand: the class name, dot, add day, with mine and 30 in the parentheses. Do both, print mine dot pages read, and the run displays 75, because 45 plus 30 is 75.
Now pass the object yourself, as mine dot add day with mine and 45. Nothing prints. The run stops with TypeError, because Python already passed mine as self, and you handed in one value too many.
One honest caveat. The name self is a convention, not a keyword. Python would accept another name, but every Python programmer writes self.
Pause and try this. Why does the call with mine and 45 inside the parentheses stop with TypeError?
Count the values Python receives.
Here's the answer. The object before the dot is already passed as self, so the method receives mine twice plus 45. That's one value too many.
The object before the dot is self.
6. Report or return
A kitchen timer can do two things. It can ring a bell, or it can hand you a number you write down. Only the number can be used later.
A method is a function that lives inside a class, so everything you learned in Week 7 still holds. A method that returns hands a value back to the line that called it. A method that only prints displays something for a person and hands back None.
Give the reading log a report method that prints the pages read, the word "of", and the goal. Add one day of 45 pages, then store the result of calling report and print that result. The run displays 45 of 300, then None. The report method printed its line and handed the program nothing.
Now call pages left. It returns 300 minus 45, which is 255. Floor-divide that by 30, and the run displays 8. A returned value can go into more arithmetic. A printed one can't.
Now call add day with 45 on its own, with no object and no dot in front. The run stops with NameError, because the method lives inside the class and needs an object to reach it.
Pause and try this. The report method displayed 45 of 300. So why did printing its result display None?
Ask what the method handed back.
Here's the answer. Report has no return line, so it hands back None. Displaying text isn't the same as returning a value.
Print shows a person; return hands the program a value.
7. Run the reading log as a class
Two friends start a book club challenge together. One aims for 300 pages and the other for 150. One friend's busy weekend doesn't change the other's count.
State is the current values of all of an object's attributes, such as 75 pages read toward a goal of 300; methods can change an object's state, and changing one instance leaves every other instance as it was.
Here's the pinned Week 15 stage of your reading log. It builds mine with a goal of 300 and yours with a goal of 150. It adds 45 and then 30 to mine, and 45 to yours. Then it prints each one's pages read and pages left. The run displays 75 and 225 for mine, because 45 plus 30 is 75 and 300 minus 75 is 225. It displays 45 and 105 for yours, because 150 minus 45 is 105.
Now an alias. After mine has 45 pages, the program writes same equals mine, and then adds 30 through same. Printing mine's pages read and whether same is mine displays 75 and True. Same is a second name for the one log, like a second name for a list in Week 9.
One more, from a bike-share dock that starts with 2 bikes. Its rent method lends a bike and returns True when one is left, and False when none are. Three rentals display True, True, False, and the dock is left with 0 bikes.
Pause and try this. After same equals mine, how many reading log objects exist, and how do you know?
Count the calls to the class.
Here's the answer. One. Only a call to the class builds an object, and the alias program called it once. The True from the is test confirms both names point at the same object.
One call to the class, one object.
8. Find the missing-self bug
You fill out a change-of-address form and leave it on your own desk, so the post office never hears. A method that forgets self dot does the same thing.
The missing-self bug is the mistake of assigning to a plain name such as name equals name inside a method instead of to self dot name. Nothing is stored on the object, and the value is lost when the method ends. And AttributeError is the exception Python raises when a program asks an object for an attribute or method it does not have.
The pinned version is a Cat class. Its init says name equals name, and its speak method returns self dot name plus "says Meow". Build a cat called Milo, call speak, and the run stops with AttributeError. Nothing was ever stored on the object. Change that line to self dot name equals name, and the run displays "Milo says Meow".
There's a quieter version too. Write add day so that it computes self dot pages read plus pages but stores the result in a plain local name. Add 45 to mine, print mine's pages read, and the run displays 0. No error at all. That's a logic error, the hardest kind to spot.
And a chatbot moment. Suppose a chatbot tells you two objects of one class share the same pages read. Run the Week 15 stage. It displayed 75 and 225 for mine and 45 and 105 for yours. Two different counts. The computer does exactly what you wrote, not what you meant, and not what a chatbot says it will do.
Pause and try this. In the quiet version, the method did compute 45. Why does mine still report 0 pages read?
Ask where the 45 was stored.
Here's the answer. It went into a local name that vanished when the method ended. The attribute on self never changed, so it still holds 0.
A missing self dot is a value with nowhere to live.
9. Look back at the course's path
A hiking trail map makes the most sense at the end of the walk. Your reading log is that map for this course.
In Week 1 it was one print that displayed "Reading log: day 1". In Week 2 it subtracted 45 from 300 and got 255. In Week 7 that subtraction became a function called pages left. In Week 9 the log became a list of daily pages that summed to 154. In Week 12 it saved its pages to a file and read back 77. In Week 14 it summed the same list recursively and got 154 again. And this week it became a class, with two objects that keep their own counts.
Look inside any method from this week. It's the same assignment, arithmetic, and return you've used since Week 2, bundled.
One honest limit of this lecture: inheritance, polymorphism, class variables, and the other special methods are ideas from a second course.
Pause and try this. This week's pages left method does the same job as a function from an earlier week. Which week, and what changed?
Think back to the function that took two numbers.
Here's the answer. Week 7's pages left function. Back then you handed it the goal and the pages read every time; now the method reads both from self.
Predict, then run, from the first print to the last class.
Closing
Let me pull it together. A class is the blueprint, and each object built from it is a separate instance. Two counters from one class displayed 2 and 1. Calling the class runs init for you. Values stored on self are attributes, and dot notation reaches them. Python passes the object as self, so passing it again is a TypeError. A method that only prints hands back None, while pages left returned 255. Each instance keeps its own state, so the reading log displayed 75 and 225 for mine and 45 and 105 for yours, and an alias is one object with two names. A missing self dot means AttributeError or a value stuck at 0. And the reading log's path shows every idea of this course still at work inside a class.
Next in this module come the slide deck, the Readings and Resources page, the lecture tutorial, the practice set, the quiz, and the Coding Lab. After that comes the cumulative final, which draws on every objective of the course. Carry the habit you've practiced since Week 1: predict, then run.
Built with The Course Maker · samples.thecoursemaker.com