Modules

Functions are great for organising your software into self-contained, reusable blocks of code. However, as it stands, you have to copy and paste your function into every script or program in which it is used. Modules (also called libraries) provide a way of packaging up a collection of functions into a single, reusable package. In python, creating a module is very easy. Indeed, you have already done it! The python scripts you have written are actually already python modules. You can import all of the functions defined in a script by using the import command. Ensure that you are in the same directory as your completed morse.py script and then start a new ipython session by typing;

ipython

Now, in ipython you can import all of the functions in your morse.py script by typing;

import morse

The import command has loaded the script, importing the functions annd then running all of the code. This is why you can now see printed to the screen;

Instruction (encode, decode, quit) :->

Type quit now to exit this prompt.

Now in ipython, you have access to all of the functions and variables contained in morse.py. These functions are prefixed with the name morse., e.g. type;

morse.[TAB]

and you should see something similar to;

morse.decodeFromMorse  morse.letter_to_morse  morse.morse_to_letter  morse.sys
morse.encodeToMorse    morse.line             morse.py             
morse.letter           morse.morse            morse.pyc              

You can now call the encode and decode functions interactively, e.g. try typing;

print( morse.encodeToMorse("Hello World") )

and you should see printed;

'.... . .-.. .-.. --- / .-- --- .-. .-.. -..'

You can check that this is correct by decoding the above message. Type;

print( morse.decodeFromMorse(".... . .-.. .-.. --- / .-- --- .-. .-.. -..") )

This should print the string hello world.

While this is great, it was quite annoying that the actual code in morse.py was run when we imported the function (i.e. that we have to type quit to exit the while loop). We can stop this from happening by using a python hidden variable. Hidden variables begin with one or two underscores, and we can list them all using ipython TAB. Type underscore followed by hitting the TAB key, e.g.

_[TAB]

You should see something like;

_                  __IPYTHON__        __doc__            _i                 _ih                
_2                 __IPYTHON__active  __import__         _i1                _ii                
_3                 ___                __name__           _i2                _iii               
_4                 __builtin__        __package__        _i3                _oh                
__                 __debug__          _dh                _i4                _sh           

The hidden variable that we are interested in is called __name__. Type;

print( __name__ )

You should see the word __main__ printed to the screen. The value of __name__ is the name of the current function or module. The top level function is called __main__. To stop code in our morse.py script from running, we just need to make sure that it is only run if the value of “name” is “main”. For example, the below script does exactly that;

def addArrays(x, y):
    z = []
    for i in range(0,len(x)):
        z.append( x[i] + y[i] )

    return z


if __name__ == "__main__":
    # Don't run this code if this script is being
    # imported as a module 

    a = [ 1, 2, 3, 4 ]
    b = [ 5, 6, 7, 8 ]

    c = addArrays(a, b)
    print( c )

Exit ipython and copy and paste the above script into a file called checkmain.py. If you run the script from the command line, e.g. by typing;

python checkmain.py

then the whole script is executed, and you will see the array [6, 8, 10, 12] printed to the screen. However, if you import the script, then __name__ will not be equal to __main__, and so the code inside the if statement will not be executed. Try this by starting a new ipython session and typing;

import checkmain

Now you should see that nothing is printed. You can now use the addArrays function in checkmain.py by typing;

c = checkmain.addArrays( [1, 2, 3], [4, 5, 6] )
print( c )

which should print the array [5, 7, 9].

As you can see, it is very easy to turn your Python script into a reusable module. You just need to add if __name__ == "__main__": around the code that should only be run when you use the script from the command line. This will allow you to import the script when you want to re-use the functions that you have defined within the script.

It is extremely good programming practice to write all of your scripts as if they were modules (and indeed to write all of your code as if they were part of a reusable library). This makes it really easy for you to pick up and reuse all of your code, preventing you from having to continually rewrite the same functionality over and over again.


Exercise

Edit your morse.py script so that it can be re-used as a module. Do this by adding in an if __name__ == "__main__": check.

If you are really stuck, here is an example answer.

Make sure you test your script by using import to import it into a new ipython session, and try encoding and decoding the same strings, e.g. try typing;

import morse
message = "sos we have hit an iceberg"
code = morse.encode(message)
decode = morse.decode(code)
print( message == decode )

This should print True if the decoded form of the encoded message equals the original message (which you would hope it would!).

Previous Up Next