Object Oriented Programming, Pt. 1

Up to this point in the semester, we have only looked at built-in data structures and primitive object types. However, sometimes these methods aren’t quite suitable for our needs. For instance, what if we wanted to store information for a customer of a bank? This customer record has several attributes such as a first and last name, account number, personal identification number, account balance, etc. Furthermore, we want to be able to make changes to these accounts such as withdraw money, deposit, calculate the interest earned on the account and more.

We could store all of this information in a dictionary or list, but it would be cumbersome and not easily organized. Classes give us a way to store such information in an easy and accessible way. Classes contain attributes, or variables particular to the class, and methods, which are functions specific to the class. Creating a class allows us to tailor-make something that fits our needs.

In this lecture, we will look at implementing a Point class. Our point will have just two attributes, a xand yvalue. We can create a class like so:

class Point:
""" Our class contains x and y coordinates"""

Now that we have created our class, we can create a new instance of a class. We call this an object. 

>>> pt = Point()

Notice that when we create a Point, we must use open and closed parentheses. Once our point object is created, we can give our point attributes.

>>> pt.x = 0
>>> pt.y = 0

Each time that we create a new point, we must give it the following attributes as shown above. However, this can be done automatically be initializing each class to have some attributes. Python reserves a special function called __init__ that runs every time a new object is created. This function takes in at least one argument, which is the object itself. It can then give itself some attributes.

  def __init__(self):
self.x = 0
self.y = 0

Now, each object is created with the following attributes, x and y, and they are always initialized to 0. This is a good start, but we want to be able to do a little better. We would like to be able to initialize each Point with an x and y coordinate. We can adjust our initialization function as so to give it this functionality.

  def __init__(self, x, y):
self.x = x
self.y = y

Lastly, we can take this one step further. Our Point object now always requires a xand yvalue. We have lost the ability to create a point without specifying the location. In order to bring this back, we will create a function with default arguments. In this case, we specify what the values should be if no values are passed to the function.

  def __init__(self, x = 0, y = 0):
self.x = x
self.y = y

Our Point object now stores a x and y value, but if we  print our Point object, we don’t get back a pretty representation of our Point. Instead, we get a memory location and some additional information. We could make a function inside our Point class that prints out the value of our point.

def print_point(p):
""" This function prints the value of our point p"""

In order to call the print_point function, we need to tell Python that this function is inside of the Point class. 

>>> Point.print_point(pt)
def __str__(self):
return '('+str(self.x)+','+str(self.y)+')'

While this is one way of printing a Point object. It is somewhat cumbersome. It would be nice if we could call the print function on our object. In order to do so, Python needs to know what the string interpretation of the object looks like. We can specify what this looks like through a special function __str__.

The __str__ function only is called when the object passed to the print function. However, the __str__ does not display objects stored in other data structures such as list. To do so, we can overload the __repr__function. 

def __repr__(self):
return '('+str(self.x)+','+str(self.y)+')'