jump to navigation

Python for Newbies – Part2 January 27, 2011

Posted by rm42 in Computers, Python.
trackback

This is part two of the Python for Newbies tutorial. Part 1 can be found here.


Functions

Functions are simply a set of commands or statements grouped together as a unit with a name that can be called on by other parts of the program (or even by other programs) to accomplish a certain task. Since the statements inside a function do not have to be rewritten every time the steps they perform are needed, our programs are smaller and easier to maintain. We have already used several functions that are built in to the Python core. For example, we have used the del function to delete items from Python lists and dictionaries, the tuple function to convert a string into a tuple, several math functions, and others. However, we are now going to learn how to create our own functions. Functions are simple, but there are a few new associated concepts that you will have to understand.


Defining a function

Here is a brief example that we can examine:

>>> def average(num1, num2):
...     avrg = (num1 + num2) / 2
...     return avrg

This is a small little function that calculates the average between two numbers and returns the result Notice that, as all the compound statements that we have seen, a function definition has a header that ends with a colon. The header begins with the def statement, followed by the name of the function to be. After that, we have something that you should be able to recognize, a tuple, nothing else, nothing more. That tuple is used to contain the parameters of your function. What are parameters? Well, parameters are values that can be passed to your function (and that your function will expect when called) for it to do something with them. In Python, those parameters can be anything you want: a number, a string, a list, a dictionary, a file, etc. Parameters can have default values too. For example, we could define a function with a header like this:

def personal_info(name, phone, country = 'USA'):

The third parameter of this function has a default value, the string ‘USA’. That means that when calling this function the third parameter is optional. We could call the function like this:

personal_info(Joe, 1234-5678)

The function would accept the call and use ‘USA’ as the value for the third parameter. Of course, we would also have the option of using a different third parameter, like this:

personal_info(Bob, 987-6543, 'UK')

So, defaults can come in very handy.

Notice that on the first function we defined above (average) the result was returned to the calling program with a specific statement, the return statement. Why is that? Why couldn’t we just be satisfied with having the variable avrg as the container of the result and use it in other parts of the program? In one word: namespaces.


Namespaces and Scope

Python, as most programming languages, stores names defined inside a function in a separate place from where it stores other names. This different spaces are called, appropriately so, namespaces or scopes. You can think of namespaces as Dictionaries that contain names and its values as key-value pairs. Whenever a function is defined an associated namespace is created. For reasons beyond the scope of this tutorial (pun intended), in Python, names are only accessible to your code if they are defined in one of the following four scopes:

  • The first one is called the Built-in scope. This scope is where all the core functions and constants of Python are defined. It is always available to you from anywhere in your code.
  • The second one is the Global scope. This is the namespace at the top level of a Python module. (You can see the Modules section if you want, or, for now, think of a module as a file with Python code.) In other words, any name defined outside a function or a class (we will cover classes latter as well) is in the Global scope. Names defined in this scope, like those in the built-in scope, are always available from anywhere in the module that contains it.
  • The third one is the local namespace. This is where names defined in a function reside. As mentioned before, names defined inside a function are only accessible from within that function. They are automatically destroyed once the function stops running.
  • The last namespace is called the nested scope. This namespace is defined as the namespace of the enclosing scope in which it was defined. That is, if inside a function you make reference to a name that Python does not find in the local namespace, it will then look to see if the name is defined in the enclosing namespace – the nested namespace.

Here is an example of how the nested namespace would work:

>>> operation = 1     # Variable defined in the Global namespace. Always accessible.
>>> def some_function(operation, num1, num2):
…     if operation == 1:
…         x=num1     #Variables defined in some_function’s local namespace.
…         y=num2
…         def multiply():
…             print x * y      # x and y are not in the local namespace of multiply.
…         multiply()

Without nested scopes, this function would report an error, because x and y would not be in the local namespace of multiply, or in the global namespace, or in the built-in namespace. Of course, one could pass the value of x and y as parameters to the multiply function, but certain styles of programming (most specifically functional style programming) are much happier with access to nested scopes. (In other words you may never need to use nested scopes, but at least you now know they are there).

Since variable assignment inside a function takes place in the local namespace, one cannot reassign (change) the value of a Global variable inside a function. Let’s look at an example.

>>> value= 1
>>> def change_value():
…     value = 2
…     print value

>>> change_value()
2
>>> print value
1

As you can see, when we assigned 2 as the value of value inside the change_value function, the assignment took place only in the local namespace of the function. The Global variable value remained unchanged. There is, however, a dirty little workaround that should probably be avoided as much as possible in truly efficient and well designed code. Some claim that global variables should only be changed by direct assignment at the global level, whether through direct assignment, or by the value returned from a function. (For example: value=change_value()) In any case the workaround is the use of the global statement. Let’s try it.

>>> var = 1
>>> def func(val):
…     global var
…     var =val*2

>>> func(3)   
>>> print var   
6

So, thanks to the use of the global statement, our function successfully changed the value of a variable defined in the Global namespace. If var did not exist before the function call, the function would simply create it.

To clarify the scope order, know that Python will look for names according the LNGB rule. It will first look for the name definition in the local namespace, if not found, it will then look for it in the nested scope, then in the global scope, and finally in the built-in scope. If not found, it will return an error.


Modules

We mentioned modules in the previous section. Basically, Python modules are files with Python code. Modules are the natural way to group related code. So far, all of the built-in Python functions we have seen are included as part of the core Python functionality. However, there are a lot more functions and capabilities included in a Python distribution. Most of them are included as separate modules that one has to “import” in order to use. Let’s look at an example:

>>> import os
>>> os.getcwd()
'/home/me'

The first line, above, uses the import statement to gain access to all the classes, functions and variables defined in a module called os. (As you can imagine the os module contains code related to the use of the operating system.) Notice that to access the getcwd function (get current working directory), all we had to do was type the name of the module, add a period, and type the name of the function. Let’s look at another function in this module:

>>> os.chdir('/home/me/MyDocs')
>>> os.getcwd()
'/home/me/MyDocs'

Here we used the chdir function to change our current working directory to ‘/home/me/MyDocs’. There are a couple of things to pay attention to here. First, notice that the chdir function expects a string as a parameter. That is why we used quotes to surround the path. Notice too that we used a forward slash rather that the backslash commonly used in windows. The reason for this is that in Python the backslash is a character with a special meaning – it is the ‘escape’ character. Besides, in Linux, the OS of the N900, the forward slash is the standard path separator. (If you want your code to be portable between your N900 and Windows use os.sep instead of /.)

To remove a module that we have imported we again can use the handy del function:

>>> del(os)

We could also import one or more specific items from a module. This is how we would do that:

>>> from os import listdir, getcwd
>>> listdir(getcwd())
['somefile.txt', 'Dir', 'Dir2', 'File', 'File.txt']

The listdir function is imported directly into the local scope. This means that we can use it directly without reference to the module it was originally in. This can be convenient sometimes, but is not considered a ‘best practice’ way of doing things. Nevertheless, there are some modules designed specifically to be imported into the local space. For example some Graphical User Interface (GUI) related modules are like that.
Here is another example, one we made reference to earlier.

>>> from __future__ import division
>>> 7/2
3.5

That allows you to use the new division functionality of Python 3.x within Python 2.7 (it also works with Python 2.6).

There are dozens of modules included in a Python distribution. This collection of modules is called Python’s Standard Library. It is a very good idea to become familiar with their names and what they are for, at least it is good to know what are the most commonly used ones. Probably the best way to do this is by looking at the documentation that is installed with Python. In particular, looking at the “Global Module Index” can be very useful. It contains links to detail explanations for each module of the Standard Python Library. There are also lots of third party developed modules and packages, such as the Windows extension modules that give access to all the win32 API, and to several Windows specific features. Others are the PyQt package and the PyGTK packages. These are the packages used for building GUI interfaces. One more that I recommend you look at is the py2exe package. This one allows you to distribute your Python programs as executable files to users that do not have Python installed.

Naturally, we can make our own modules simply by creating a file with Python code in it. When we import that module, all its code is executed, whether it is code that defines a function, or simple Python expressions. For example add the following commands into a regular text file, and name the file test.py:

def greet(name):
    print "Hello there, %s" %(name)
greet('John')

Now, in the Python interpreter, import your test module. Note that, since your module is likely not in the Python path, you may have to change your current working directory to the folder where you saved test.py so that Python can find it (The Python path is where Python searches, in addition to the current working directory, when trying to import a module.):

>>> import test
Hello there, John

Two things happened when we imported our module: The greet function was defined, and the greet(‘John’) function call executed. Now, we can continue to use the greet function with other function calls. For example:

>>> test.greet('Marla')
Hello there, Marla
>>> test.greet('Michael')
Hello there, Michael

Now, open a Terminal session and go to the directory that contains your module. Then, try running test.py as a script. For example:

/home/m/MyDocs/Test> python test.py
Hello there, John

The same two things happened. But, of course, since Python terminates when it is finished running the script, we can not continue using it to call the greet function.
We can also make our scripts accept command line parameters so that it uses them at run time. For example, save this as test.py:

import sys
    for item in sys.argv:
        print item

We could then run this script with a call like this:

/home/m/MyDocs/Test>python test.py First "Second" "And third"
test.py
First
Second
And third

The parameters we give to our scripts when calling them are stored in a list called argv accessible through the sys module. The first parameter (argv[0]) is the name of the script itself. So, in our example above, argv[1] would be the parameter First.

Generally, the conceptual purpose of a module is to store variables, function definitions and classes for use in other Python programs when needed. But, as you can see, there is no real difference between a module and a regular Python script. You can import any of your Python programs as a module and you can then use the functions and classes defined in them on any program where you need them. However, there is a right way to organize your code inside a module for this to be effective. To illustrate this, lets take a look at another sample Python file, lets call it unames.py.

import sys
def full_name(first, second):
    full = first + " " + second
    return full
def greet(name):
    print "Hello there, %s" %(name)
fname = full_name(sys.argv[1], sys.argv[2])
greet(fname)

What we have here is a couple of function definitions, a function call that results in variable assignment, and another function call. Now, say that you are creating a new program and want to use those two functions. You could simply import unames and access them. However, you would then have a new fname variable and the greet(fname) function call executed, and that may not be what you want. So, in order to make sure our Python modules are reusable, we need to have a way of keeping our function and class definitions separate from the calls and we need to have a way of avoiding those calls from executing when the module is imported. Fortunately, there is a very easy way to do this. Just reorganize the code like this:

def full_name(first, second):
    full = first + " " + second
    return full
def greet(name):
    print "Hello there, %s" %(name)
if __name__ =='__main__':
    import sys
    fname = full_name(sys.argv[1], sys.argv[2])
    greet(fname)

Notice that the import statement and the two function calls are only executed when a special condition is met – that the file is being run as a script. This allows you to place all your function and class definitions at the top of your modules and at the very end you can place any code that is to run when the file is run as a script, and that is not to run when the file is simply imported as a module.

One last thing to remember about modules is that if you are using a module and make changes to the code while you are using them in an interactive Python session, you will only be able to use the changes if you reload the module. To do this you have to either delete the module from Python’s memory (using the del function) and import it again, or use the reload function like this:

>>> reload(test)

Now that we are talking about files, why don’t we take a look at how we work with files from Python code.


Working with files

Working with files implies being able to open, read, and write files. Python has everything needed to do that and be able to process them with ease. In Python, files are a built in object type (like lists, dictionaries, etc). We create file objects using the open function. Depending on how we do this, we can either open an existing file or create a new one. Let’s first create a new file:

>>> f = open('MyFile.txt', 'w')

At this point the variable f represents a new file object that has been created in the file system at the current working directory. Notice that the open function expects two parameters. The first parameter is the path and file name, provided as a string. The second parameter is also a string. It can be either ‘w’, for write, or ‘r’, for read. Let’s now write something into our file:

>>> f.write('This is a line inside the file.\nThis is another line.\n')
>>> f.write('This is the third line.')
>>> f.close()

Now, if with a text editor we take a look at the file we created, the file should look like this:

This is a line inside the file.
This is another line.
This is the third line.

As you have probably figured out already, the ‘\n’ combination represents the ‘new line’ character. The write method of the file object allows us to add strings to our files. And the close method simply closes it. Easy, right? Now what if you wanted to change something in the file we just created? Well, here is an example:

>>> f = open('MyFile.txt', 'r')
>>> file_contents = f.readlines()     #The readlines method returns a list of lines.
>>> f.close()
>>> file_contents     #Just to show you the contents of file_contents.
['This is a line inside the file.12', 'This is another line.12', 'This is the third line.']
>>> f = open('MyFile.txt', 'w')     #Now we open it again to write our changes.
>>> for line in file_contents:
...     new_line = line.replace("line", "set of words")
...     f.write(new_line)
...
>>> f.close()

As you can see, to edit a file we first have to read its contents, close the file, and open it again to write. If we open an existing file with write mode, we really are just over-writing it with a new blank file of the same name. So, after executing the commands above, we have a new file, in the same location, with the same name, and almost the same contents. The only difference is that we replaced the occurrences of “line” with “set of words”.

Those are the basics of file manipulation, and that is all we are going to cover. Now, through this tutorial you may have notice that we referred several times to something called classes and objects. Let’s take a very brief look at this subject.


Classes and Objects

There are several theories of what is the best way to program. One method of programming is called Object Oriented Programming (OOP). Python was designed from the ground up, with OOP concepts in mind. Yet, Python doesn’t force us to program this way. OOP in Python is optional. Still, it may be a good thing to give you a glimpse of how this works.

We have already seen how we can save statements variables and functions inside a module, and then access them in our code by importing the module. Another way to do this is by using the class statement. Let’s look at an example:

>>> class Address:
...     def setStreet(self, value):
...         self.Street = value
...     def setCity(self, value):
...         self.City = value
...     def display(self):
...         print "The address is:"
...         print self.Street
...         print self.City

As you can see we have defined the class Address. In it we have defined three methods (method is how a function inside a class is generally called). You probably notice that the first parameter for each of the methods is the word “self”. Why? Well, to understand that, you have to understand what classes are for. A class is defined so that we can produce objects based on them. You can think of the class definition as the DNA of its objects. We can create as many objects as we want from a class, and they will all be like little clones of each other. Each object we create is referred to as an instance object. Once an instance is created, it can start to have its own particular characteristics, different values, etc. Each object is now an independent ’self’. So, the self we use when defining the methods inside a class refer to the particular instance the actions we are defining should apply to. If this is “all too wonderful” for you, don’t worry. Just remember that you have to use self as the first parameter of your method definitions. If you don’t, Python will kindly remind you with an error message when you try to use the method.

Let’s now create an instance (object) from our class:

>>> address = Address()

That is all there is to it. At this point address is an instance object based on the clsAddress class. It can now start accepting its own personal data. Let’s give it some now:

>>> address.setStreet('157 Royal Road')
>>> address.setCity('NY')

Notice that we have access to the methods defined in our class. Let’s display the contents of our object now:

>>> address.display()
The address is:
157 Royal Road
NY

You may remember, from our earlier analysis of scopes, that functions have their own local scope. Variables inside a function are destroyed as soon as the function stops running. The same is true of methods (since they are simply functions too). That is why when assigning a value to a variable inside a method, if we want it to be available latter, we qualify the variable with, again, the word self. This is as if we told Python to store the value of the variable in the global scope of our object. That’s right, objects have their own internal global namespaces. The value of variables defined this way can be retrieved by making direct reference to the particular object namespace like this:

>>> address.Street
'157 Royal Road'
>>> address.City
'NY'

Of course, we have been using this feature all along in this tutorial, but now you should have a better idea of why. Here is another way to look at the contents of an object:

>>> dir(address)
['Street', 'City']

The dir function returns a list of all the names defined in the object. Finally, here is another little trick to help inspect objects:

>>> address.__dict__
{'Street':'157 Royal Road', 'City':'NY'}

Every object has to have a built-in location to store its instance names and values. That place is the __dict__ dictionary. And, yes, it is just a regular dictionary object itself.

So, just remember, in Python, everything is an object. Even class definitions are objects:

>>> Address.__dict__
{'display': , 'setStreet': , '__doc__': None, 'setCity': , '__module__': '__main__'}

There is much more we could talk about in this subject, but this is all we are going to cover. Time is precious, and we still have a few more things to cover. For example, in this section we made reference to the fact that Python has the capacity of displaying errors. Errors are simply unavoidable in programming. So, let’s take a quick look at them now.


Errors and Error Handling

What we commonly refer to as ‘errors’ in programming are the accidental mistakes we make in our code that yield either the wrong result, or no result at all. Some programming languages leave it at that. They make no attempt at trying to explain why the program did not do what you expected. That is why people have developed special programs called ‘debuggers’ to provide some help in finding where those errors occur. Thankfully, Python is very helpful in this regard. When you commit an error in programming that would result in a break of the flow of execution, Python displays messages to help you try to identify the type and location of the error. For example:

>>> print something
Traceback (most recent call last):
File "", line 1, in ?
NameError: There is no variable named 'something'

The error message, in this case, consists of three lines:

  1. The first line simply tells you the way the error message is organized (most recent call last). This is because some errors occur, for example, when your program makes a function call, that itself calls another function, that calls another certain function (where the error resides). Python will trace back the error, letting you know what the original call was, what the next call was, and what the final call (where the error occurred) was.
  2. The second line tells you the file and line number of where the error was found. In this case, since we are using the Interactive Command Prompt, it refers to the file as stdin (standard input – right now, the keyboard input).
  3. Finally, the last line tells us the type of error (NameError), and what the error was.

So, as you can see, it is very easy to track down your errors, most of the time. Of course, if the error in your program is found in its logic, rather than in its semantics, there is very little Python can do to help you. There are some other packages designed for that. For example, there is a module called unittest that allows one to do something called “Unit Testing”. This is a very popular way to check for errors in Python programming. But, that is beyond the scope of this tutorial.

The errors that Python catches and displays, as we saw above, are really a subcategory of the larger category called exceptions. Some of the most common standard exceptions in Python are the following (there is a complete list in the manual):

Error Type Description
IOError Generated when an I/O operation fails.
ImportError Generated when a module import fails.
IndexError Generated when an attempt is made to access a non-existent element index.
KeyError Generated when an attempt is made to access a non-existent dictionary key.
MemoryError Generated when an out-of-memory error occurs.
NameError Generated when an attempt is made to access a non-existent variable.
SyntaxError Generated when the interpreter finds a syntax error.
TypeError Generated when an attempt is made to run an operation on an incompatible object type.
ValueError Generated when function receives an argument that has an inappropriate value.
ZeroDivisionError Generated when an attempt is made to divide by zero.

In Python exceptions can be intercepted quite easily. The way this is done is by the try/except/else construct. For example:

>>> try:
...     print something
... except NameError:
...     print "You should have defined it first!"
...
You should have defined it first!

As you can see, we were able to trap the error and tell Python what to do about it. We could exit the program at this time, but in this case we just printed a message. The flow of execution would continue outside of the try statement.

When we add an else block to a try construct, the code inside the else block is executed only if no exception is generated by the try construct. Here is an example:

>>> try:
...     numb1 = int(raw_input("Type a number"))
... except ValueError:
...     print "You should have typed a number."
... else:
...     print "Good job %i is a number." %(numb1)

The first line in the try statement tries to convert the input from the raw_input function into an integer number. It will only work if the input received is in the form of a number. Anything else will generate a ValueError, which we can dutifully intercept. If no error is found the else block is executed and the flow of the program continues outside the try statement.

A variation of the previous statement is the try/finally statement (no else allowed on this one). It consists of one try block followed by a finally block. The finally block always executes no matter what happens. So, this construct is useful when there is something that you want to make sure happens before the program exits. For example, you may want to make sure that some files are closed, or that some data is saved. If an exception is raised during the execution of the try statement, the flow of execution jumps to the finally block, and then it is returned the normal exception handling mechanism. For example, if we had something like this:

try:
    try:
        <statements>
    finally:
        <statements>
except:
    <statements>
    

In this example, if an exception is found in the try/finally statement, once the finally block is executed, the exception would be propagated to the try/except statement for it to be handled. If not trapped by the except statement, it would be propagated further up until it finally is handled by the Python’s standard exception handling mechanism, thus ending the program.

There is a lot more we could learn about errors or exceptions, but this at least gives you a glimpse into the basics. Let’s now try to gather a few miscellaneous tidbits that will be useful to you as write your own programs.


Other common built-in functions

In this section we are going to cover a few functions that we did not cover before. These are some of the most commonly used built-in functions from the Python core.

Note:
To see a list of all the built-in functions in the Python core use this command: dir(__builtins__)

Let’s first look at the len function. Its purpose is to tell us the length of a sequence. In other words, how many items are in it. This is how it works:

>>> L = [1, 2, 3, 4]
>>> len(L)
4

So, as you can imagine, the len function is very useful when dealing with sequences. For example, we could use it like this in a script:

#Script to process a Social Security Number
ssn = ""
while not ssn:     #Empty strings evaluate to false.
    ssn = raw_input("Enter your Social Security Number: ")
    ssn = ssn.replace("-", "") #Eliminate the dashes, if present.
    if len(ssn) != 9:     #Checks the number of digits.
        print "This is an invalid number."
        print "Try again please."
        ssn = ""     #Set ssn to false
print "Your Social Security Number is: " + ssn

On this example, we created a while loop that continues to loop until a Social Security Number of nine digits is entered.

Another common function is the range function. This function is used to create a list of successively higher numbers. It’s most common use is in conjunction with for loops, allowing us to repeat a block of statements a certain number of times. It can take up to three parameters. Here is what it does:

>>> range(5)     #One parameter, returns list of numbers from 0 to n-1.
[0, 1, 2, 3, 4]
>>> range(2, 5)     #First parameter is lower bound.
[2, 3, 4]
>>> range(0, 10, 2)     #Third parameter provides a step.
[0, 2, 4, 6, 8]

To use this in a for loop you can do something like:

def doit():
    print "Done it."
num=int(raw_input("How many times do you want to do this? "))
for i in range(num):
    doit()

This little script will simply execute the doit function however many times the user requests. So, if we execute it from the command line, it will look something like:

/home/me/MyDocs> python test.py
How many times do you want to do this? 4
Done it.
Done it.
Done it.
Done it.

As we have seen already there are times in which Python will complain if a certain input it receives is not of the correct type. For example, the range function accepts only integers as input. The raw_input function returns its input as a string, that is why we use the int function to try to convert its output into an integer.

The last function we are going to look at is the type function. All it does is return the type of its input. For example:

>>> type(5)

>>> type('5')

So we could use it, for example when we want to make sure that a certain object we are about to do something to is of the correct type. For example, let’s say that we wanted to write a function that displays the methods available to a certain object. Let’s first create a class with one variable and one method:

>>> class Obj:
...     def __init__(self):     #This is a special method that runs when instances are created.
...         self.data = 1     #In this case it just initializes a variable to 1
...     def add(self, num):     #This is a method that will be available to our instances.
...          self.data = self.data + num

Now, let’s create an instance object based on this class:

>>> ob = Obj()
>>> ob.data
1
>>> ob.add(2)
>>> ob.data
3
>>> dir(ob)
['data']
>>> ob.__dict__
{'data': 3}

As you can see, objects that we create ourselves, as opposed to the built-in objects, do not automatically display the methods they have at their disposal. (There is a not so hard way to make them do that, but we are not going to get into that.) So, now let’s create a function that lets us know what methods are available to our homemade objects.

import types
def find_methods(instance):
    clss = instance.__class__   #We find the class object of the instance
    methods = []
    for name in dir(clss):     #Get the named items from the class object
        attribute = clss.__dict__[name] #Get the value of items from the __dict__
        if type(attribute) == types.FunctionType:     #is it a function
            methods.append(attribute)
    return methods

Now, we can use this function to find the methods in our little object:

>>> find_methods(ob)
[ , ]

Note:
In Python, classes can inherit methods and variables from one or more classes too. This is called multiple inheritance. Our function would have to be a little different to be able to read functions inherited from other classes. But, as we said before, time is precious. So, why don’t we finish this part of the tutorial looking at the time module.


Time

Computers perform time calculations in reference to an “epoch” (like a pivot date). In the Unix family of operating systems the “epoch” is January 1, 1970, 0 hours, 0 seconds, UTC. Python follows that same method of handling time. The time module has several functions that we can use to handle time related tasks. In its most basic form, Python expresses the current time as the number of seconds since the “epoch”. Here is how you do it:

>>> import time
>>> time.time()
1006015080.406

Not very easy to read. However, other functions allow us to manipulate this output with ease. For example the localtime function.

>>> time.localtime(time.time())
(2001, 11, 17, 11, 40, 37, 5, 321, 0)

The localtime function returns a tuple representing: Year, month, day, hour, minute, second, weekday (0-6), Julian day (1-366), and the daylight savings time flag (-1 (force disable), 0 (default), or 1 (force enable)). There are also many other functions in this module that you should become familiar with. But, even with just this two functions we can do something useful. Let’s create a little timer class that we can use to check the time when a certain event in a program takes place and to time how long it takes our program to do its tasks. (Remember that you have to include an import time statement somewhere for this to work).

class Timer:
    def __init__(self):
        self.start_time = time.time()
    def cur_time(self):
        now = time.time()
        tt=time.localtime(now)
        if tt[3] > 12:
            hr = int(tt[3]) - 12
            ampm = 'p.m.'
        else:
            hr = int(tt[3])
            ampm = 'a.m.'
        ct = "%s:%s:%s %s %s/%s/%s" %(str(hr), tt[4], tt[5], ampm, tt[1], tt[2], tt[0])
        return ct
    def elapsed(self):
        now = time.time()
        minutes =(now - self.start_time) / 60
        secs = (now - self.start_time) % 60     #The remainder of the division
        return 'Elapsed: %s min %s sec' % (int(minutes), int(secs))

If we save that into a file called timer.py we can then import it into any of our programs. Let’s import it into the Python Command Line to play with it a little.

>>> import timer
>>> mytimer = timer.Timer()

As soon as the instance is created it records the time in the start_time variable. We can verify that like this:

>>> mytimer.start_time
1006016982.671

Now let’s check the current time.

>>> mytimer.cur_time()
'12:10:49 a.m. 11/17/2001'

And finally, check how much time has elapsed since the instance was created.

>>> mytimer.elapsed()
'Elapsed: 1 min 38 sec'

Well, that is it for this section. It didn’t take too much time now did it?

We are going to wrap up this part of the tutorial here. The remaining parts of the tutorial will be quite interesting. Hopefully it won’t be too long before they are completed. Come back and check in a little while. And remember that if you would like to contribute your help to this tutorial you are very welcome. Happy coding to all.


About this tutorial


I learned Python from a few different sources. I picked up quite a bit from several online books and tutorials, such as this one. However, neither of the online tutorials felt easy enough for me. Most of them felt like they were made by geniuses for geniuses. I wanted something that expressed the concepts more simply and more logically, without making me do intellectual gymnastics to get there. Fortunately, I found that the book Learning Python, by Mark Lutz, was exactly what I was looking for, and finally got me over the learning hump.

I first created this tutorial in 2001 while volunteering at a non-profit organization. It was originally meant to encourage the use of Python within that organization. I tried to condense the ideas and the logic found in the “Learning Python” book and make them even more simple. The book Learning Python is a lot more comprehensive and I definitely recommend it to any one seriously interested in getting into Python. This tutorial is good for those that want to ease into Python or into programing in general.

The version of Python and other libraries targeted by the tutorial will be initially 2.7. Python 3.0 has several changes in the language that make it incompatible with this tutorial. I hope to incorporate those changes into this tutorial some time in the future. Some sections of this tutorial, specifically the GUI portions, have not yet been finished.

This tutorial is made available to you under the Creative Commons Attribution-Share Alike 3.0 license:

http://creativecommons.org/licenses/by-sa/3.0/
http://creativecommons.org/licenses/by-sa/3.0/legalcode

Joe Crawford has been working on an expanded version of this tutorial. I haven’t had a chance to review it, but you may want to take a look at it. It can be found here:

http://www.teaching3d.com/w/?page_id=188

Comments»

1. Lamont - March 15, 2011

I hope you haven’t given up this blog entirely – maybe you are overcome with work these days (a good thing to be sure given the economy). Whatever the case, I hope all is well with you.

In the latest Linux Journal magazine (march 2011), Paul Barry gives us a quick & easy tutorial on how to install Python scripts for the Android. You were among the first to come to mind. I was hoping you might share your analysis on how well you think Python could fare on tasks for which Java is usually employed. Can you envision a future where Python will become a true challenger to Java’s preeminence? Will Java always be the leader?

rm42 - March 16, 2011

Python has already made huge inroads in the computer field. And I do believe its mind share is still growing quite fast at the expense of languages such as Java. However, I do not think that Python will ever completely replace Java, or any other language. Even Perl still has a a place for some tasks.

Python is a pleasure to code in. Java is a bit more troublesome. However, that is clearly not the only consideration when choosing a language for a particular task. Personally, I default to Python for any programming need, unless a specific requirement makes it not feasible or more trouble than it’s worth. That means, I rarely use anything but Python. ;)

2. CaCO3 - July 7, 2011

great tutorial!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: