Skip to main content

A Python Tale on Object Oriented Programming (Part II)

Hello my friends, today’s entry is going to be the second part about Object Oriented Programming with Python, if you haven't read the first part of this set please go to with this link, now let's create a table to summarize what we have so far of our Clock Class.


Properties
Methods
·         Seconds
·         Tick
·         getHours
·         getMinutes
·         getSeconds
·         setHours
·         setMinues
·         setSeconds
·         setTime
·         getTime
·         reset

Now for this second part we are going to override some of the built-in Python methods on objects so we can use operators and some helpful functions. The first ones are those methods that will allow us to use the logical operators.
Operator
Description
Method
·         ==
·         !=
·      Equal
·      Not equal
·         __eq__
·         __ne__

When we are using theses operators on the construction of conditions for flow control (if-else, while) statements, we can use objects as the variables in the comparisons, but is this methods are not coded in the Class of the object, the execution will crash, so let's start by coding this examples using our Clock Class template, for simplicity in the code the methods already described in the first part will not be showed in this part.
class Clock(object):

    def __init__(selfhours=0, minutes=0seconds=0):

        self.seconds = 0

        self.seconds += seconds
        self.seconds += minutes * 60
        self.seconds += hours * 3600
 
    def Tick(self, seconds=1):
 
        self.seconds += seconds

    def __eq__(selfother):

        """Return True if seconds are equal."""

        return self.seconds == other.seconds

    def __ne__(selfother):

        """Return True if seconds are not equal."""

        return self.seconds != other.seconds

As you can see in this code, these methods usually uses the same format of double underscore, the keywords eq and ne mean equal and not equal, in the definition of these methods the self parameter must be provided as the first argument followed by a name variable referencing the other object passed for comparison, it is recommended to use other for readability. Then you need to return a Boolean type, this can be directly achieved by returning a comparison of the data that actually is being used for the purpose of comparison, in this case is the seconds instance variable, in the previous part was not clear why to use only one variable for the Clock representation instead of one variable for each of seconds, minutes and hours, now it is more clear because we can have a smaller code in these methods between others advantages, let's code a little using this methods for comparisons.
>>> clock1 = Clock(6, 0, 0)
>>> clock2 = Clock(5, 30, 0)
>>> print clock1
06:00:00
>>> print clock2
05:30:00
>>> print clock1 == clock2
False
>>> print clock1 != clock2
True
>>> clock2.Tick(1800)
>>> print clock1 == clock2
True
>>> print clock1 != clock2
False

In this ways there is no need to use the public interface of the Class to access the seconds data for making comparisons, you can make these comparisons by just using these methods and the comparison operators, let's code the rest of these methods and operators
Operator
Description
Method
·         < 
·         <=
·         > 
·         >=
·         Less than
·         Less or equal than
·         Greater than
·         Greater or equal than
·         __lt__
·         __le__
·         __gt__
·         __ge__
And their respective code
class Clock(object):
 
    def __init__(self, hours=0, minutes=0, seconds=0):
 
        self.seconds = 0
 
        self.seconds += seconds
        self.seconds += minutes * 60
        self.seconds += hours * 3600
 
    def Tick(self, seconds=1):
 
        self.seconds += seconds
 
    def __eq__(self, other):
 
        """Return True if seconds are equal."""
 
        return self.seconds == other.seconds
 
    def __ne__(self, other):
 
        """Return True if seconds are not equal."""
 
        return self.seconds != other.seconds
 
    def __lt__(self, other):
 
        """ Return True if rank of self < seconds of other. """
 
        return self.seconds < other.seconds
 
    def __le__(self, other):
 
        """ Return True if rank of self <= seconds of other. """
 
        return self.seconds <= other.seconds
 
    def __gt__(self, other):
 
        """ Return True if rank of self > seconds of other. """
 
        return self.seconds > other.seconds
 
    def __ge__(self, other):
 
        """ Return True if rank of self >= seconds of other. """
 
        return self.seconds >= other.seconds
    
    def __str__(self):
 
        result = "{0:02d}:{1:02d}:{2:02d}"
 
        return  result.format(self.getHours(), self.getMinutes(), self.getSeconds())

Let's do some basic examples with these
>>> clock1 = Clock(6, 25, 0)
>>> clock2 = Clock(8, 15, 0)
>>> print clock1, clock2
06:25:00 08:15:00
>>> clock1 > clock2
False
>>> clock1 < clock2
True
>>> clock1 <= clock2
True
>>> clock1.Tick(6600)
>>> clock1 < clock2
False
>>> clock1 > clock2
False
>>> clock1 >= clock2
True

Pretty cool ha? If you go to the Python official documentation on operators, you will see the entire list of operators and how to code your objects to have compatibility with them, but sometimes the nature of your objects has no real meaning for some operators, for instance you can use the addition operator +, for integers but what about Clock instances? Well you can, but adding both seconds and produce a new object with this result, but what about division? Can you divide one Clock with other Clock? Does this question even has sense?, well before we get philosophical let's code the addition operator (__add__).
class Clock(object):
 
    def __init__(self, hours=0, minutes=0, seconds=0):
 
        self.seconds = 0
 
        self.seconds += seconds
        self.seconds += minutes * 60
        self.seconds += hours * 3600
 
    def Tick(self, seconds=1):
 
        self.seconds += seconds
 
.
.
.
.
    
    def __add__(self, other):
 
        """ Return Clock instance with self.seconds + other.seconds """
 
        result = Clock()
        result.seconds = self.seconds + other.seconds
 
        return result
 
    def __str__(self):
 
        result = "{0:02d}:{1:02d}:{2:02d}"

And let's try an example of this.
>>> clock1 = Clock(10, 25, 0)
>>> clock2 = Clock(2, 10, 0)
>>> clock3 = clock1 + clock2
>>> print clock3
12:35:00

And that's it, we have covered enough for now, so try building your own Python Classes, I can give you some hints on prototypes, a Card Class and Deck Class is really useful for programming Card Games. , I hope you have found this entry helpful to you. So thanks for coming by my new entry and I hope you have enjoyed this as much as I enjoyed writing it, stop by the comments if you want to discuss about this. Don't forget to share this with your Python Peers. Cheers my friends.

Popular posts from this blog

Multithreading web scraping with Python

Hello my friends today in this entry we are going to talk about a very trendy topic, web scraping and how to do it with our beautiful Python programming language, so open your Python Idle and get set because in this Tutorial Entry we are going to code once again.

Python Free Books

Hello my friends in an earlier post I talked about some dive deep Python Books that you could purchase to start learning Python, you can check that entry in this link, and now I have decided to write this entry to give you a list of online and free Python books.


These books are supposed to be hosted documentation; they are written in restructured text (reStructuredText) and translated into beautiful HTML or PDF with a tool called Sphinx. This documentation format is supposed to be used for writing your own packages and modules documentation, but experts also use them to write practical books and tutorials of different languages and they can be uploaded and hosted for free in different online platforms, one of them is read the docs website.

Singleton - Design Patterns in Python

Hello my friends, here in this quickly entry we are going to talk about the most basic but very useful Design Pattern and that is the Singleton, but first let's discuss as always a little about theory.
Design PatternsThis is the next step in the programing learning curve, after Object Oriented Programming there is a list of topics that you could learn next, I strongly recommend Python Design Patterns. Accordingly to the Wikipedia, “a software design pattern is a general reusable solution to a commonly occurring problem within a given context in software design”, in other words is the same code to the same kind of problems; in general we tend to find the same kind of problems when we are designing our software, and we tend to solve this problems with the same solution, in time and each time this solution is improved and finally is considered a standard or a pattern in software design, so it becomes a design pattern.