Python Tutorial

From DANSE

Learning Python: A Guide for Students of Science and Engineering

This tutorial assumes some basic knowledge of the Python language, and its focus is on using Python for tackling scientific and engineering problems.

So for true newcomers to the language, the official python tutorial (http://docs.python.org/tut/tut.html) is a good place to start.

Dive into python (http://diveintopython.org/) is a wondeful book by Mark Pilgrim available online.

Table of contents


Introduction

Put the following into your python startup file (as pointed to by your PYTHONSTARTUP environment variable.) The first one enables tab-completion, and the second allows you to look at source code easily.

# the python startup file

print "enabling readline"
try:
    import readline
except ImportError:
    print "    readline not available"
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")

def src(object):
    """Write source for this object to output.
    """
    import inspect, string, tempfile, os
    try:
        print "In file: %s\n" % inspect.getsourcefile(object)
        lines, lnum = inspect.getsourcelines(object)
        lines = string.join(lines,'')
        a = tempfile.NamedTemporaryFile()
        a.write(lines)
        a.flush()
        os.system('more %s' % a.name)
    
    except:
        print "Not available for this object."

My startup file is named .python, and the src function defined above lets me quickly look at how (and where) the code is defined. (This works only when the code is defined in Python, and when the dot-py is readable. Sometimes a package or a module may be installed with only a dot-pyc availabe.)

>>> import pylab
>>> pylab.plot
<function plot at 0x4a3e930>
>>> src(pylab.plot)
In file: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/matplotlib/pylab.py

def plot(*args, **kwargs):
    # allow callers to override the hold state by passing hold=True|False
    b = ishold()
    h = popd(kwargs, 'hold', None)
    if h is not None:
        hold(h)
    try:
        ret =  gca().plot(*args, **kwargs)
        draw_if_interactive()
    except:
        hold(b)
        raise
    
    hold(b)
    return ret
>>> 

Permuations

Exercise 1

Complete the following function without using random.shuffle (and its moral equivalents).

def random_permute(n):
    """Given a positive integer n>0, return a random permutation of range(1,n+1)"""
    pass

I welcome solutions in any languages as well.


Exercise 2

Compare the efficiency of your algorithm against random.shuffle.

You can use the following decorator for easy timing runs.

# the following decorator snippet comes from 
# http://www.daniweb.com/code/snippet368.html
def print_timing(func):
    def wrapper(*arg):
        t1 = time.time()
        res = func(*arg)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return res
    return wrapper

@print_timing
def runRandomPermute(n, m):
    # this function runs random_permute(m) n times
    # the decorator will wrap this function inside a timing construct
    for i in xrange(n):
        random_permute(m)
    return



Exercise 3

Correctness is more important than efficiency, so this exercies should precede #2. But it is here because it is a bit more difficult.

By inspecting the output of the algorithm you constructed, suggest how you can verify its correctness (probabilistically). Discuss necessary and sufficient tests. Implement some.


Exercise 4

This is a continuation of the above exercise.

Complete the following function

def count_unmoved(list):
    """Given a list that is a permutation of range(1,n+1),
returns the number of items that are 'unmoved.'
e.g., {1,2,3,4,5} -> 5 (all the items are in the original position
e.g., {5,4,3,2,1} -> 0 
e.g., [1,3,2,5,4] -> 1 (1 hasn't moved, but the rest have). """
    pass

With the above completed, each output of random_permtuation can be passed into count_unmoved to obtain a non-negative integer. i.e., a little more precisely, count_unmoved(random_permute(n)) -> {0, 1, ..., n}.

Now do the following simulation

  1. Run count_unmoved a large number of times to get a list like [0, 1, 3, 2, 0, 5, 1, 0, 1, ...] (for definiteness so I can talk about it)
  2. Do a histogram on the above list. For n=5, 10000 simulations, I will get a list like [3530, 3801, 1712, 872, 0, 5] where the numbers sum to 10000, and the 3530 means that out of 10000 simulations, 3530 of them correspond to complete derangements.


Exercise 5

This is a continuation of exercise 4. We are almost done playing with permutations.

Complete the following function

def tries_until_m(n, m):
    """
 -  Sorry the function name is not better, feel free to change it.
 -  Given n: number of things to shuffle 
 -  and m: number of fix-points (i.e., 0 is a complete derangement, see
      above exercise
 -  Returns an integer count of the number of tries before we get a success.
 i.e., if n = 5, m = 0, and the first call to random_permute gives 5,4,3,2,1,
 then we only had to wait "once" before a complete derangement. 
 so the return value should be strictly positive.
    """
    pass

With the above function in place, each time it is called we'll get a positive integer. Run the function N (e.g., N=1000, or 10,000) times, with input n = 5, m = 0, and plot the histogram.

We'll use the data found for the next exercise.


Exercise 6 (Density estimation)

Image:ph_tutorial_hist1.png

Treat the histogram (an example is shown above) computed in the previous exercise and normalize it (i.e., scale so that the heighs of the bars sum to 1).

Consider the model

f(p) = p(1 - p)k - 1,

where k is the length of the wait (i.e., k = 1,2,....), find the p that best fits the data of the histogram.


Solutions

Python_Tutorial_Discussion: Discussions, solutions, and more.

Document Uploads/Links