Lab #11: OOP in Python

Last class, we did a very fast flyby of how OOP applies to another language: Python! Click here to review the lecture. We're going to practice some of that by making some very simple programs that use objects in Python.

Step 0: Hello, World!

Of course, it's always a good idea to make sure you understand the basics, so before we build any classes, let's do that. First, a hello, world program. Make a file called hello.py, and paste the following text into it:

print("Hello, world!")

Then, run python3 hello.py ... Success!

Let's make a loop. Use Google to find how to make for loops in Python. Modify hello.py so that it prints out "Hello, world!" one thousand times, printing the number of times it has print before after, as follows:

Hello, world! 0
Hello, world! 1
...
Hello, world! 999

Modify it again with an if statement so it only prints out ones where the number is divisible by 5:

Hello, world! 0
Hello, world! 5
...
Hello, world! 995

If the syntax confuses you, ask your instructor!

Great! Now, let's make a class.

Step 1: A Point class

Here's a Java file called Point.java:

public class Point {
  private double x,y;

  public Point(double x, double y){
    this.x = x;
    this.y = y;
  }

  public double distFromOrigin(){
    return x*x + y*y;
  }
}

Open a file called point.py, and create an equivalent class in Python. Paste the following at the bottom of the file (no indents since it's outside the class definition):

p1 = Point(5, 3)
p2 = Point(5.3, 3)
print(p1, p1.dist_from_origin())
print(p2, p2.dist_from_origin())

When your class is correct, you should be able to run this, and get something like the following:

$ python3 point.py
<__main__.Point object at 0x7f159e845da0> 34
<__main__.Point object at 0x7f159e845e80> 37.09

Now, wouldn't it be great if our Python class had an equivalent of a toString() function? In fact, it does, we just need to override it (this, of course, makes it exactly like toString()). In Python, the name of that function is __str__(self).

Variables can be cast to strings with the str function (for example, str(someVariable)). Strings can be concatenated together with plus signs, just like Java. Add a __str__(self) function to your Point class, so it prints them out nicely, like points should. When you run it again, you should get something like this:

$ python3 point.py
(5,3) 34
(5.3,3) 37.09

Step 2: Multiple Inheritance!

First, download this tarball to your folder for this lab and extract it from the terminal with the command tar xzf clockCalendar.tgz. You'll see you have two useful files which define a Clock class and a Calendar class. We want to make a class that can be both a Clock AND a Calendar! In Java, we'd be hosed, because you're only allowed to extend one class, but with Python, we do what we want!

Make a file called clockcalendar.py. At the top, import both classes (no, unlike Java, just having them in the same directory isn't enough) with:

from clock import Clock
from calendar import Calendar

Now build a class ClockCalendar, which extends both Clock and Calendar. Give it a constructor (initializer), which accepts month, day, year, hour, minute, and second. Without creating any new variables of its own, this constructor should call both superclasses' constructors. You should then be able to run the following code after your class:

c = ClockCalendar(4, 23, 2019, 9, 55, 0)
print(c.days)
print(c.months)
print(c.years)
print(c.hours)
print(c.minutes)
print(c.seconds)

and observe that you're getting all the right values back; the fields of Clock and Calendar have been inherited by your ClockCalendar object!

Add a function tick to your ClockCalendar that moves it forward in time one second. Rather than duplicating code, make full use of the functions your superclasses have.

Add a __str__(self) function, so that it prints out month/day/year,hour:minute:second. Probably, this too is best done by making full use of your superclasses' functions.

Here's some code to test it with. Does your object get it right?

x = ClockCalendar(12,31,2013,23,59,59)
print("One tick from ",x, end=" ")
x.tick()
print("to ", x)

x = ClockCalendar(2,28,1900,23,59,59)
print("One tick from ",x, end=" ")
x.tick()
print("to ", x)

x = ClockCalendar(2,28,2000,23,59,59)
print("One tick from ",x, end=" ")
x.tick()
print("to ", x)

x = ClockCalendar(2,7,2013,13,55,40)
print("One tick from ",x, end=" ")
x.tick()
print("to ", x)

Submission

Submit your python files with the following terminal command:

~/bin/submit -c=IC211 -p=Lab11 hello.py point.py clockcalendar.py

You must pass all online tests.