Home Practicum 1 Practicum 2 Practicum 3 Practicum 4 Practicum 5 Practicum 6 Practicum 7 Practicum 8 Practicum 9 Practicum 10

Object-oriented programming

Important disclaimer: you do not need to use object-oriented programming in your final project unless you have good reason for it (no extra points just for using it!). It's still an important programming concept, so we will practice it today.

Classes and objects

Class is a blueprint, a concept that describes attributes and abilities (methods) of potential objects. Objects are instances of classes. Human is a class, its attributes include for example name, age and height, its abilities include greeting fellow humans. piotr is an object of that class, named 'Piotr', and you might have already been greeted.

The class definition starts with the keyword class followed by the name of the class. Inside the class definition we describe the attributes and methods:

class Human:
    name = ''

    def greet(self):
        return 'Hello, my name is {}'.format(self.name)

The "self" in as the first argument of every method definition inside the function means that it will run only on a particular object. Whenever we want use attributes inside methods, we refer to them as self. followed by the name of the attribute, here name.

We can then create an instance of that class by calling its name with round brackets as if it was a function. Once we have the object, we can instruct it to use its abilities:

piotr = Human()
piotr.greet()

Paste this code in a new file and run it:

class Human:
    name = ''

    def greet(self):
        print('Hello, my name is {}'.format(self.name))

piotr = Human()
piotr.greet()

Constructors

You might have noticed that our human in the example still has no name - naming the object didn't teach it the name of the human it represents. We can use a constructor that will allow us to name the humans as they are created. We do so by creating a method called __init__. Like every other method, its first argument is self, then there can be more arguments. Look at the code below, then paste it and run:

class Human:
    name = ''

    def __init__(self, name):
        self.name = name

    def greet(self):
        print('Hello, my name is {}'.format(self.name))

piotr = Human('Piotr') # name the human at creation time
piotr.greet()

In these exercises we will use Forecast as a class that has city, description, and temperature as attributes, and it can update itself to the most recent version, summarize in human readable format, and comapare itself to another forecast. Objects of this class will be actual forecast for different cities.

Excercise 1: Turning the weather forecast into an class #1

  1. Download the starter file.
  2. You will see that I moved some functionality from last week into this file. Make sure to update your API_KEY to the one you set up last week!
  3. Our forecast is instatiated with a city name as an argument.
  4. You will see that the constructor calls the update() function, so that when we instatiate a forecast it actually downloads the data from the internet at that moment.
  5. Implement the update() method. so it:
    • Downloads the weather for the city that's stored as self.city
    • Extracts the interesting values (temperature and description) from the forecast and stores them as values of attributes. If you don't remember what the forecast dictionary looks like, check back last week's exercise, or print the forecast you're downloading!
  6. In the main() try printing the city, description, and the temperature of the boston object to see if it worked.

Accessing attribute values

By convention, we use the self variable to refer to the current object. When a method sets values for an attribute, these values persist outside of the method that set them. Note that we set the name in the constructor (__init__) and then we refer to it in the greet(self) method. It works because once one method set its value, it persists outside of this method.

Excercise 2: Turning the weather forecast into an class #2

  1. Implement a summarize() method that it prints the values of the object's attributes nicely, like: Boston will see light rain with the temperature of 53.
  2. Create a new object with the forecast for your hometown, use its summarize function to see if it still works (no need to replace Boston, we can have many objects of the same class existing at the same time!)

More objects!

There can be many objects of the same class in one program. So far we created just one human, but we can create more:

piotr = Human('Piotr') # name the human at creation time
piotr.greet()
frank = Human('Frank') # we can have more than one human at the time!
frank.greet()

The class definiton does not have to be repeated to make another human, they are similar (in that they are both human), but have different names stored as their name attribute.

Have a look at the code below, where I added the greet_another(self, another) method. It takes a human object as input argument. When Piotr greets Frank, he doesn't create a new Frank, he greets an existing one.

class Human:
    name = ''

    def __init__(self, name):
        self.name = name

    def greet(self):
        print('Hello, my name is {}'.format(self.name))

    def greet_another(self, another):
        print('Hello {}, my name is {}'.format(another.name, self.name))

piotr = Human('Piotr') # name the human at creation time
frank = Human('Frank') # we can have more than one human at the time!
piotr.greet_another(frank)

Excercise 3: Turning the weather forecast into an class #3

  1. Implement a compare() method of the Forecast class, so that it:
    • takes a forecast for another city as input argument (an instance of a Forecast class, not a string with the name of the city!
    • compares the temperature between the two,
    • and prints out the answer, like: Boston will be colder than New York. (first the name of the city represented by the forecast on which the method is called, then the name of the city that was passed as argument).
  2. Call that function on the boston object, passing your hometown forecast as argument.
  3. Call that function on your hometown forecast, passing the boston object as argument.