Python Arena
Step 2 of 4

Methods that change the object

The values of an object's attributes at any moment are called its state. A method can change the state, and it's the usual way to do it. Here is a counter:

class Counter:
    def __init__(self):
        self.value = 0

    def increase(self):
        self.value += 1

    def add(self, amount):
        self.value += amount

    def reset(self):
        self.value = 0


clicks = Counter()
clicks.increase()
clicks.increase()
clicks.add(10)
print(clicks.value)
clicks.reset()
print(clicks.value)
Output
12
0

These methods don't return anything: their whole job is to change the object. They change the object that they are called on, and only that one:

class Counter:
    def __init__(self):
        self.value = 0

    def increase(self):
        self.value += 1


home = Counter()
away = Counter()
home.increase()
home.increase()
away.increase()
print(home.value, away.value)
Output
2 1

home.increase() runs the method with self as home, so self.value += 1 adds to the home counter. The away counter has a value of its own.

One call, every update

A method can update several attributes at once, so that they always fit together. A car that drives also uses fuel:

class Car:
    def __init__(self, fuel, consumption):
        self.fuel = fuel
        self.consumption = consumption
        self.odometer = 0

    def drive(self, km):
        self.odometer += km
        self.fuel -= km * self.consumption / 100

    def km_left(self):
        return self.fuel / self.consumption * 100


car = Car(40, 5)
car.drive(120)
car.drive(80)
print(car.odometer, car.fuel)
print(car.km_left())
Output
200 30.0
600.0

(fuel is in liters and consumption in liters per 100 km.) The rest of the program only says car.drive(120). It doesn't need to know how the fuel is worked out, and it can't forget to update one of the attributes. This is the big idea of object-oriented programming: the class takes care of its own data.

A method can also change the state and return something, as the list method pop does: it removes an item and gives it to you.

Naming methods

Name a method after what it does. A method that changes the object usually gets a verb: increase, drive, reset. A method that only gives an answer is named after the answer, such as area or km_left, or it starts with is_ when the answer is yes or no: is_empty. Then the client code reads almost like a sentence: car.drive(120), if counter.is_empty():.

Your task

Challenge 1 of 3

What does this program print? Type each line it prints.

Challenge 2

Write a class PiggyBank. A new piggy bank has the attribute cents set to 0. Give it these methods:

  • insert(cents) adds the coins to the bank.
  • euros() returns how many euros the bank holds: the cents divided by 100.
  • smash() returns all the cents in the bank, and leaves the bank empty.

This code:

bank = PiggyBank()
bank.insert(50)
bank.insert(200)
print(bank.cents, bank.euros())
print(bank.smash())
print(bank.cents)

prints

250 2.5
250
0

Challenge 3

Write a class Reading that keeps track of reading a book. Its constructor takes the book's title and its number of pages, and stores them in the attributes title and pages. It also sets the attribute page, the page the reader is on, to 0. Give it these methods:

  • read(pages) moves the reader forward that many pages. (You can assume it never goes past the end.)
  • percent() returns how much of the book has been read, as a whole number of percent: use round.
  • finished() returns True when the reader is on the last page.

This code:

book = Reading("Moby-Dick", 600)
book.read(150)
print(book.page, book.percent(), book.finished())
book.read(400)
book.read(50)
print(book.page, book.percent(), book.finished())

prints

150 25 False
600 100 True