Basic OOP Python

I’ve just started with object oriented programming in Python so I thought I’d cover some of the basics here. Please don’t assume this is a thorough tutorial on OOP!

The beauty of OOP is that it allows me to create a template with which I can create objects. The building blocks of the object sit in the class, while the object itself is created from that blueprint with various properties. I can then make as many of these objects as I desire from that single class. I can see this being very beneficial for certain types of programming (games especially)

Basics

I’ll start with something simple. I want to create a class called Ball. This class requires certain properties like radius and colour. I’ll create a class like so:

class Ball:
    def __init__(self, radius, colour):
        self.radius = radius
        self.colour = colour

I’ve created a class called ‘Ball’ – This requires two variables, radius and colour. Note that ‘self’ refers to the object that is being created. Once this is done, I can then call this class to create objects. I need to ensure I pass both variables otherwise:

>>>blueball = Ball("Blue")

Traceback (most recent call last):
  File "", line 1, in 
    blueball = Ball("Blue")
TypeError: __init__() takes exactly 3 arguments (2 given)

Let’s do it properly:

>>>blueball = Ball(10, "Blue")

blueball is now an object created from the class:

>>> blueball
<__main__.Ball instance at 0x10f11bdd0>
>>> print type(blueball)
type 'instance'

Each self.x in the class is a method which I can set and interrogate. If I wanted to see the current radius of blueball, I simply call the method I defined:

>>> blueball.radius
10

I can also change the variable later if I so choose:

>>> blueball.radius = 20
>>> blueball.radius
20

If I simply print blueball, I won’t get much:

>>> print blueball
<__main__.Ball instance at 0x10f11bdd0>

In order to be able to get string output from an object, I need to ensure the class has a string method. I’ll add the following to my original class:

class Ball:
	def __init__(self, radius, colour):
		self.radius = radius
		self.colour = colour
    def __str__(self):
		return "I am a " + self.colour + " ball, with a radius of " + str(self.radius)

Note that my old blueball variable has still been created from the old class so I’ll simply create a new one:

>>> blueball = Ball(10, "Blue")
>>> print str(blueball)
I am a Blue ball, with a radius of 10

I can now happily create as many objects as I want, with different properties. Each object is a separate instance:

>>> redball = Ball(20, "Red")
>>> print str(redball)
I am a Red ball, with a radius of 20


Let’s take this a step further. For this I’m going to use Scott Rixner’s CodeSkulptor as it has some nice draw capabilties built-in. It also runs in your browser directly.

I’d like to create an empty space with nothing. I then want to click a button to create a new ball with random properties. That ball should then be displayed inside the space. Each click should be a new object created from my original class. I’m going to add a few more properties to my class which will come clear later.

I’ll first get my global variables set:

list_of_balls = []
width = 1000
height = 600
colours = ["Aqua","Blue","Green","Lime","Maroon","Navy","Orange","Red","White","Yellow"]

Now comes the Ball class:

class Ball:
    def __init__(self, radius, mass, colour, x_location):
        self.radius = radius
        self.mass = mass
        self.colour = colour
        self.location = [x_location, height/2]

When I click the mouse button, I want certain random properties set for the object:

def click():
    radius = random.randint(1,40)
    mass = radius
    colour = random.choice(colours)
    x_location = random.randint(20, width-20)
    new_ball = Ball(radius, mass, colour, x_location)
    list_of_balls.append(new_ball)

The mouse click handler creates a new ball with random properties, then appends that ball to a list of balls. Each time I click a new ball is added to the list.

I now need to draw the balls. I need to iterate through my list of objects and draw each one:

def draw(canvas):
    for ball in list_of_balls:
        canvas.draw_circle((ball.location[0],ball.location[1]), ball.radius, 1, ball.colour, ball.colour)

Click here to view and run the code in CodeSkulptor. Press play in the top left corner to run the code.

Dynamic

So the above code simply creates a bunch of balls on random places on the x axis while being in the middle of the y axis. Let’s start moving these balls around based on their initial mass. Currently the bigger the ball, the bigger the mass. Let’s keep it that way for now. All balls will simply fall towards the ground. I’d like to make sure that when the ball hits the bottom of the screem it’s reflected back up. Same goes for the top of the screen.

First I need to add velocity to the object. Note that properties of an object don’t all have to be variables. I could set the velocity of all the balls exactly the same. For now I’ll use the mass of the ball:

class Ball:
    def __init__(self, radius, mass, colour, x_location):
        self.radius = radius
        self.mass = mass
        self.velocity = self.mass
        self.colour = colour
        self.location = [x_location, height/2]

I then need to update my draw handler so it updates the position of each ball. If the y location of the ball hits the top or bottom of the screen, reverse the direction:

def draw(canvas):
    for ball in list_of_balls:
        ball.location[1] += ball.velocity
        if ball.location[1] >= (height - ball.radius) or ball.location[1] <= ball.radius:
            ball.velocity = -ball.velocity
        canvas.draw_circle((ball.location[0],ball.location[1]), ball.radius, 1, ball.colour, ball.colour)

Click here to open my code in CodeSkulptor. Now every time you add a new ball, it’ll start bouncing against the top and bottom wall. Create as many balls as you like!

Conclusions

It’s still early days in my OOP work. I can see this method is perfect for applications like gaming. I’m not 100% sure if I’ll have an application for it in my type of coding, I’ll have to see.

In the interim, the basics of OOP isn’t that difficult. I’ve still got a long way to go but happy so far!

For future work on my code above, it would be trivial to set a random mass. It would also be nice to extend the balls to simply bounce like in real life, or gets the balls to bounce off each other. Either way, the properties of each ball itself is independent of the environment in which it sits.