ACSE-1

Exercise: Find the primes

The following code will work.

N = 20
test = 2
primes = []
while len(primes)<N:
    for p in primes:
        if p**2>test:
            primes.append(test)
            break
        if test%p==0:
            break
    # special case
    if len(primes)==0:
        primes.append(test)
    test += 1
print(primes)
This version uses the fact that a non-prime must have at least one prime factor smaller than its square root to maximise search efficiency, by using break statements to fail fast. There is a school of thought which feels that this makes code harder to understand.

Exercise: Find the mean: short version

For the short exercise the following code will work.

import sys
def mean(X):
    return sum(X)/float(len(X))
print(mean([float(x) for x in sys.argv[1:]]))
Note that the extra float command in the mean function is protection for Python 2, where integer division behaves differently from floating point division by default.

Exercise: Find the mean: version with options parsing

For the version with options parsing, the following code will work.

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("number", nargs='+', help="numbers to take mean of")
parser.add_argument("-b", "--binary", help="numbers are in binary",
                    action="store_true")
parser.add_argument("-o", "--octal", help="numbers are in octal",
                    action="store_true")
parser.add_argument("-x", "--hex", help="numbers are in hexadecimal",
                    action="store_true")
args = parser.parse_args()

if sum([args.hex, args.binary, args.octal]) not in [0, 1]:
    raise ArgumentError

def a2num(x):
    """Transfer string into number."""
    if args.binary:
        return int(x, 2)
    elif args.octal:
        return int(x, 8)
    elif args.hex:
        return int(x, 16)
    return float(x)

def mean(X):
    """ Take mean of X."""
    return sum(X)/float(len(X))

print(mean([a2num(x) for x in args.number]))

Exercise: Plots in scripts

import numpy as np
import matplotlib.pyplot as pyplot

x = np.linspace(0, 2.0*np.pi)

pyplot.plot(x, np.sin(x))
pyplot.plot(x, np.cos(x))
pyplot.plot(x, np.tan(x))

pyplot.axis([0, 2.0*np.pi, -1, 1])
pyplot.show()

pyplot.savefig('fig.png')
pyplot.savefig('fig.pdf')
This is the "do everything version. We use the axis command to scale everything so the sine and cosine functions can be seen.

Exercise: Complex square root

The following code is acceptable. Note that the primary interest here is the documentation

def sqrt(x):
    """
    Calculate complex roots of a real input.

    This returns a tuple for all inputs except 0.

    Parameters
    ----------

    x : real
        real number

    Returns
    -------

    tuple or 0.0
        Both complex square roots of x 

    """

    from math import sqrt

    if x is 0.0:
         return 0.0

    surd = sqrt(abs(x))

    if x > 0.0:
        return (-surd, surd)
    else:
        return (-surd*1j, surd*1j)

Exercise: A primes module

""" Module to calculate prime numbers."""

import sys

def find_nth_prime(n, primes=None):
    primes = primes or [2]
    test = primes[-1]+1
    while len(primes)<n:
    	for p in primes:
            if p**2>test:
                primes.append(test)
                break
            if test%p==0:
                break
        # special case
        if len(primes)==0:
            primes.append(test)
        test += 1
    return primes

if __name__=="__main__":
    print(find_nth_prime(int(sys.argv[0])))

Exercise: A primes package

Download and unzip the following file to obtain the example primes Python package. The prime factors function looks something like the following:
def prime_factors(x, primes=None):
    primes = primes or [2]
    factors = []
    primes = primes_up_to(x, primes)
    while x>1:
        for p in primes:
            while x%p==0:
                factors.append(p)
	        x/=p

    return factors

def primes_up_to(x, primes=None):
    primes = primes or [2]
    test = primes[-1]+1
    while primes[-1]<x:
    	for p in primes:
            if p**2>test:
                primes.append(test)
                break
            if test%p==0:
                break
        # special case
        if len(primes)==0:
            primes.append(test)
	test += 1
    return primes[:-2]