Introduction to Programming Week 9


Part 1: Dice

Last week we saw the __init__ and __str__ methods, but there are many more of these "special" methods that we can implement.

For example, we might want to be able to add our object together. We can tell Python how to do this by implementing __add__. In our Die class this is straightforward:

def __add__(self, other):
    return self.__top + other.__top

Now, we can add our dice:

sum = die1 + die2

Similarly, we can implement __lt__, __gt__, etc. for < (less than), > (greater than), and more. See classes.

Part 2: Funky Dice

Another advantage of classes and object-oriented programming is that everything is easily extensible. We can, for example, realtively easily modify our Die class to support dice with different numbers of sides, and different numbers or labels on each side. For the code we wrote look at the class transcript.

As our Die grows in complexity we might want to change how we can construct it. We can make our __init__ function more flexible with optional parameters.

In Python, we can assign a default value to some or all of the parameters to a method (or function). Then, if the user specifies a value Python will use that one, but if the user doesn't it will use the default value. The only catch is that these optional parameters must always come last in the parameter list, otherwise it might be ambiguous which parameters a user is supplying. For example, we could give the user the option of specifying a list of values in our Die init with

def __init__(self, numSides, values = []):

Then if the user specifies a list of values init will use that, but if the user doesn't it'll will use [].

Unlike many programming languages, Python is dynamically typed. This means we don't need to declare what class of object a variable will contain when we create it (in many languages, you can't store a string in a variable you declared to be an integer, for example).

This is often convenient, but this also means we sometimes need a way to find out what class an object belongs to. That's where the built-in isinstance function becomes useful.

See Also