Home / Week 3 Exercises / Generic LTI Simulator / OOP

Object-Oriented Programming

You are not logged in.

If you are a current student, please Log In for full access to this page.

The easiest way to start learning about classes and objects is to use Python's builtin classes---for example, strings, lists, and dictionaries.


x = 'A string'
# x is now a string object.  Thus, it "knows" how to do some things.

# For example, it knows how to make an uppercase version of itself.
# You ask it by using one of its "methods" (a function defined in
# the "string" class).  Here's how:
>>> x.upper()
'A STRING'

# You can also ask for a lowercase version of the string:
>>> x.lower()
'a string'

# NOTE.  The preceding operations do not change x itself
>>> x
'A string'

We can define our own classes and, using them, make our own objects. Here's how to define a new data type (a class) representing a simple bank account.


class Account:
    def __init__(self):
        self.balance = 0

The "Account" is the name of the class. In the preceding procedure definition, the "self" refers to the object being created (here, the particular account). You make an object of this class (a bank account) as follows:

>>> checking = Account()

It has a balance:

>>> checking.balance
0

You can add money to the account:

>>> checking.balance += 10
>>> checking.balance
10

But it is considered bad style to manipulate the internal state by hand. Instead, we'll augment the class with a procedure (a "method") that knows how to make a deposit:


class Account:
    def __init__(self):
        self.balance = 0
    def deposit(self, n):
        self.balance += n

Let's remake the checking account using this new class definition, and then let's add 20 to the account using the new method:

>>> checking = Account()

In the preceding step, Python creates a new object (an Account) and then runs its init method (with the newly-created instance passed in as self). Here, that method creates a variable 'balance' and sets it to 0. You can look into the account to find the balance:

>>> checking.balance
0

You can make a deposit in a few different ways. The first is not used commonly in practice, but is quite explicit as to what is happening:

>>> Account.deposit(checking, 20)

This tells Python to look inside of the Account class for a method called deposit, and to call that method with checking passed in as self (so that when we do self.balance += n, it will do checking.balance += n).

Python provides a nice short-hand ("syntactic sugar") to make this process easier. Instead of doing the above, you can simply do:

>>> checking.deposit(20)

Behind the scenes, Python translates this into the earlier style. It will look up what class checking is, and will look up the deposit method from above. Even though, in this style, you do not explicitly tell Python what to use as self, it figures out that it should use checking (i.e., the instance from which the method was called) as self.

After doing both of the above deposits, we have:

>>> checking.balance
40

You can make another account:

>>> savings = Account()

It too has a balance:

>>> savings.balance
0

Each account has its own balance:

>>> savings.deposit(25)
>>> savings.balance
25
>>> checking.balance
20

Let's augment the Account class to allow withdrawals, so that you can do the following:

>>> savings.withdrawal(10)
>>> savings.balance
15

Enter your updated definition of the Account class below:

Suppose that you want to know what your balance is, but in Euros (now a Euro is worth about $1.13), rounded to the nearest Euro penny. Extend the Account class so that you can do the following:

>>> savings.how_much_in_euros()
22.12

Check Yourself 1:

If you are having trouble figuring out how to round a number in Python, look at the documentation for Python's round function.

Check Yourself 2:

Implement the how_much_in_euros method (this will be checked by the tutor in a bit).

Normally when you open a bank account, you deposit some funds right away. Let's extend the class definition to allow you to specify the initial balance:


class Account:
    def __init__(self, initial_balance):
        self.balance = initial_balance
    def deposit(self, n):
        self.balance += n
    # ...

Now you create an account as follows:

>>> checking = Account(12)
>>> checking.balance
12

Check Yourself 3:

What happens when you try to use the previous syntax (as shown below, without specifying an inital balance) to create an instance of Account?

x = Account()

>>> checking = Account()

Extend the definition of init so that the previous syntax still works, and just makes the initial balance 0. Enter your final definition of Account into the box below:

Enter your updated definition of the Account class below: