\(\renewcommand\AA{\unicode{x212B}}\)

Using Modules

  • Functions allow blocks of code to be separated into reusable parts that can be called from a user’s script. Modules take this idea one step further and allow the grouping of functions and code that all perform similar tasks into a library, or in Python speak, module.

  • A module has its definitions, the functions and code that make it up, within a separate file ending with a ‘.py’ extension and this file is then imported into a user’s current script. This is most easily demonstrated through an example. We will define a mathematics module called mymath and use this from a separate script.

## File: mymath.py ##
def square(n):
    return n*n

def cube(n):
    return n*n*n

def average(values):
    nvals = len(values)
    sum = 0.0
    for v in values:
        sum += v
    return float(sum)/nvals
  • To use this module from a user script we need to tell the script about the module using the import statement. Once the definitions are imported we can then use the functions by calling them as module.functionname. This syntax is to prevent name clashes.

## My script using the math module ##
import mymath  # Note no .py

values = [2,4,6,8,10]
print('Squares:')
for v in values:
    print(mymath.square(v))
print('Cubes:')
for v in values:
    print(mymath.cube(v))

print('Average: ' + str(mymath.average(values)))
  • Another variant of the import statement, import``module``as``new-name`` can be used to have the module referred to under a different name, which can be useful for modules with long names

import mymath as mt

print(mt.square(2))
print(mt.square(3))
  • It is possible to avoid the module.functionname syntax by using an alternate version of the import statement, from``module``import *. The functions can then be used as if they were defined in the current file. This is dangerous however as you do not have any protection against name conflicts when using multiple modules.

Importing Modules from Other Locations

If the module lives within the same directory as the script that is using it, then there is no problem. For system modules, these are pre-loaded into pythons sys.path list.

For example the numpy module location is here

import numpy
print(numpy.__file__)

There are several ways to make modules available for import.

Modifying the PYTHONPATH

This environmental variable is used by python on startup to determine the locations of any additional modules. You can extend it before launching your python console. For example on linux:

export PYTHONPATH=$PYTONPATH:{Path to mymodule directory}
python

On windows, it would look like this

SET PYTHONPATH=%PYTHONPATH%;{Path to mymodule directory}
python

Appending to sys.path

Another way to make modules available for import is to append their directory paths onto sys.path within your python session.

python
>>> import sys
>>> sys.path.append({Path to mymodule directory})
>>> import mymodule

Python’s Standarad Library

  • Python comes with a large number of standard modules that offer a wealth of functionality. The documentation for these modules can be found at http://www.python.org.

  • They are used in exactly the same manner as user-defined modules using the import statement. Some examples of two useful modules are shown below.

datetime

import datetime as dt
format = '%Y-%m-%dT%H:%M:%S'
t1 = dt.datetime.strptime('2008-10-12T14:45:52', format)
print('Day ' + str(t1.day))
print('Month ' + str(t1.month))
print('Minute ' + str(t1.minute))
print('Second ' + str(t1.second))

# Define todays date and time
t2 = dt.datetime.now()
diff = t2 - t1

Gives the output:

Day 12
Month 10
Minute 45
Second 52

os.path

import os.path

directory = 'C:/Users/Files'
file1 = 'run1.txt'
fullpath = os.path.join(directory, file1)  # Join the paths together in
                                           # the correct manner

# print stuff about the path
print(os.path.basename(fullpath))  # prints 'run1.txt'
print(os.path.dirname(fullpath))  # prints 'C:\Users\Files'

# A userful function is expanduser which can expand the '~' token to a
# user's directory (Documents and Settings\username on WinXP  and
# /home/username on Linux/OSX)
print(os.path.expanduser('~/test')) # prints /home/[MYUSERNAME]/test on
                                   # this machine where [MYUSERNAME] is
                                   # replaced with the login

Numpy Introduction

  • Python extension designed for fast numerical computation: http://numpy.scipy.org/

  • Numpy provides multidimensional array objects, including masked arrays and matrices

  • Numpy uses c-style arrays, which provide locality of reference for fast access

  • Numpy comes with a vast assortment of inbuilt mathematical functions which can operate on the ndarrays. These functions are implemented in c, and optimised to give good performance

  • Now available as standard within Mantid on all three platforms. Full tutorial: http://www.scipy.org/Tentative_NumPy_Tutorial.

  • To use Numpy in a script you must first import the module at the top of your script

import numpy

Numpy Arrays

  • Python lists are flexible as they can store any type.

  • Iteration can be slow though as they are not designed for efficiency in this area.

  • Numpy arrays only store a single type and provide optimized operations on these arrays.

  • Arrays can be created from standard python lists

import numpy
x = numpy.array([1.3, 4.5, 6.8, 9.0])
  • There is also a function, arange, which is numpy’s counterpart to range, i.e. it creates an array from a start to and end with a given increment

x = numpy.arange(start=0.0, stop=10.0, step=1.0)

Numpy Functions

  • Numpy arrays carry attributes around with them. The most important ones are:

    • ndim: The number of axes or rank of the array

    • shape: A tuple containing the length in each dimension

    • size: The total number of elements

import numpy

x = numpy.array([[1,2,3], [4,5,6], [7,8,9]]) # 3x3 matrix
print(x.ndim) # Prints 2
print(x.shape) # Prints (3L, 3L)
print(x.size) # Prints 9

Gives the output:

2
(3, 3)
9
  • Can be used just like Python lists

    • x[1] will access the second element

    • x[-1] will access the last element

  • Arithmetic operations apply element wise

import numpy
a = numpy.array( [20, 30, 40, 50] )
b = numpy.arange( 4 )
c = a-b
print(c)

Gives the output:

[20 29 38 47]

Built-in Methods

  • Many standard numerical functions are available as methods out of the box:

x = numpy.array([1,2,3,4,5])
avg = x.mean()
sum = x.sum()
sx = numpy.sin(x)