Modules

You have seen how you can reuse code in your program by defining functions once. What if you wanted to reuse a number of functions in other programs that you write? As you might have guessed, the answer is modules.

There are various methods of writing modules, but the simplest way is to create a file with a .py extension that contains functions and variables.

Another method is to write the modules in the native language in which the Python interpreter itself was written. For example, you can write modules in the C programming language and when compiled, they can be used from your Python code when using the standard Python interpreter.

A module can be imported by another program to make use of its functionality. This is how we can use the Python standard library as well. First, we will see how to use the standard library modules.

Example: Module

import math

print('The value of pi is', math.pi)
print('The square root of 4 is', math.sqrt(4))

Output:

The value of pi is 3.141592653589793
The square root of 4 is 2.0

How It Works

First, we import the math module using the import statement. Basically, this translates to us telling Python that we want to use this module. The math module contains various mathematical functions – like sin, cos, and tan – as well as constants such as pi and e.

When Python executes the import math statement, it looks for the math module. In this case, it is one of the built-in modules, and hence Python knows where to find it.

If it was not a compiled module i.e. a module written in Python, then the Python interpreter will search for it in the directories listed in system path which was set up when Python was installed. If the module is found, then the statements in the body of that module are run and the module is made available for you to use. Note that the initialization is done only the first time that we import a module.

The pi variable in the math module is accessed using the dotted notation i.e. math.pi. It clearly indicates that this name is part of the math module. Another advantage of this approach is that the name does not clash with any pi variable used in your program.

The math.pi variable is a 15-decimal approximation of the value of pi π.

The sqrt() function in the math module calculates the square root of any integer or floating point number entered as an argument. Just like with pi, it is accessed using the dotted notation of math.sqrt().

Launch Exercise

Example: More from the Math Module

Code Output Notes
import math

signal_power = 100
noise_power = 17

ratio = signal_power/noise_power
decibels = 10 * math.log10(ratio)

print(decibels)
7.695510786217261

This example uses the function math.log10() to compute the logarithm base 10 of the signal-to-noise ratio.

import math

degrees = 45

radians = degrees/360*2*math.pi

print(math.sin(radians))
0.7071067811865475

The second example finds the sine of 45 degrees.  First, it converts the degrees to radians (divide by 360 and multiply by 2 π) and then it uses the math.sin() function to calculate sine.

The expression math.pi gets the variable pi from the math module. The value of this variable is an approximation of π, accurate to about 15 digits.

Here is a selection of the various functions available within the math module.

Function Description Example Code Example Output
ceil(x)

Return the ceiling of x as an Integral. This is the smallest integer >= x.

math.ceil(4.5) 5
cos(x)

Return the cosine of x (measured in radians).

math.cos(math.pi) -1.0
degrees(x)

Convert angle x from radians to degrees.

math.degrees(math.pi) 180.0
factorial(x)

Find x!. Raise a ValueError if x is negative or non-integral.

math.factorial(5) 120
floor(x)

Return the floor of x as an Integral. This is the largest integer <= x.

math.floor(4.5) 4
gcd(x, y)

Returns the greatest common divisor of x and y

math.gcd(28,91) 7
log(x[, base])

Return the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x.

math.log(10,2) 3.3219280948873626
log10(x)

Return the base 10 logarithm of x.

math.log10(2) 0.3010299956639812
pow(x, y)

Return x**y (x to the power of y).

math.pow(2,10) 1024.0
radians(x)

Convert angle x from degrees to radians.

math.radians(180) 3.141592653589793
sin(x)

Return the sine of x (measured in radians).

math.sin(1.777) 0.9788152469968777
sqrt(x)

Return the square root of x.

math.sqrt(10) 3.1622776601683795
tan(x)

Return the tangent of x (measured in radians).

math.tan(1.777) -4.780643944967509

The from-import statement

If you want to directly import a specific variable or function into your program (to avoid having to type the dot notation every time), then you can use the from-import statement.

from [module] import [function or variable]

Code Output
from math import sqrt
print('The square root of 8 is', sqrt(8))
The square root of 8 is 2.8284271247461903
from math import pi
print('pi * 2 =', (pi*2))
pi * 2 = 6.283185307179586

Notice that you do not need to type math and a dot in front of pi or sqrt().  This is great if you are lazy, but bad if you have your own variable called pi or your own function called sqrt().

In general, avoid using the from-import statement, use the import statement instead. This way your program will avoid name clashes and will be more readable.

Launch Exercise

Byte-compiled .pyc files

Importing a module is a relatively costly affair, so Python does some tricks to make it faster. One way is to create byte-compiled files with the extension .pyc which is an intermediate form that Python transforms the program into (remember the introduction section on how Python works?). This .pyc file is useful when you import the module the next time from a different program - it will be much faster since a portion of the processing required in importing a module is already done. Also, these byte-compiled files are platform-independent.

NOTE: These .pyc files are usually created in the same directory as the corresponding .py files. If Python does not have permission to write to files in that directory, then the .pyc files will not be created.

Making Your Own Modules

Creating your own modules is easy, you've been doing it all along! This is because every Python program is also a module. You just have to make sure it has a .py extension. The following example should make it clear.

Example: Creating My Module

def say_hi():
    print('Hi, this is mymodule speaking.')

word = 'Hi!'

We save this code in a file called mymodule.py.

The above was a sample module. As you can see, there is nothing particularly special about it compared to our usual Python program. We will next see how to use this module in our other Python programs.

Remember that the module should be placed either in the same directory as the program from which we import it, or in one of the directories listed in the system path.  Now let's import our new module:

Example: Using My Module

import mymodule

mymodule.say_hi()
print(mymodule.__version__)

Output:

Hi, this is mymodule speaking.
Version 0.1

How It Works

Notice that we use the same dotted notation to access members of the module. Python makes good reuse of the same notation to give the distinctive 'Pythonic' feel to it so that we don't have to keep learning new ways to do things.

Example: Using My Module with from-import

from mymodule import say_hi, __version__

say_hi()
print('Version', __version__)

Output:

Hi, this is mymodule speaking.
Version 0.1

Look!  The output is the same!

Notice that if there was already a __version__ name declared in the module that imports mymodule, there would be a clash. This is also likely because it is common practice for each module to declare its version number using this name. Hence, it is always recommended to prefer the import statement even though it might make your program a little longer.

Zen of Python

One of Python's guiding principles is that "Explicit is better than Implicit". Run import this in Python to learn more.

Launch Exercise

The Random Module

Given the same inputs, most computer programs generate the same outputs every time, so they are said to be deterministic. Determinism is usually a good thing, since we expect the same calculation to yield the same result. For some applications, though, we want the computer to be unpredictable. Games are an obvious example, but there are more.

Making a program truly nondeterministic turns out to be not so easy, but there are ways to make it at least seem nondeterministic. One of them is to use algorithms that generate pseudorandom numbers. Pseudorandom numbers are not truly random because they are generated by a deterministic computation, but just by looking at the numbers it is all but impossible to distinguish them from random.

The random module provides functions that generate pseudorandom numbers (which I will simply call “random” from here on).

The function random returns a random float between 0.0 and 1.0 (including 0.0 but not 1.0). Each time you call random, you get the next number in a long series.

Code Output
import random

for i in range(10):
    x = random.random()
    print(x)
0.301927091705
0.513787075867
0.319470430881
0.285145917252
0.839069045123
0.322027080731
0.550722110248
0.366591677812
0.396981483964
0.838116437404

The random function is only one of many functions that handle random numbers. The function randint takes the parameters low and high, and returns an integer between low and high (including both).

Code Output
import random

for i in range(10):
    x = random.randint(5, 10)
    print(x)
5
6
9
5
6
5
10
9
7
5

The random module also provides functions to generate random values from continuous distributions including Gaussian, exponential, gamma, and a few more.

Launch Exercise

Another useful function in the random module is randrange.  The randrange function accepts parameters for low, high, and step – which allows you to generate a random list of numbers in specific increments.

Code Output
import random

for i in range(10):
    x = random.randrange(100, 1500, 50)
    print(x)
250
100
250
700
1100
600
300
1200
650
1450

In this example, we generated a list of numbers from (and including) 100 to (and excluding) 1500 in increments of 50.

Launch Exercise