The exercise numbers refer to the numbers used in the book Python Scripting for Computational Science, by H. P. Langtangen. Exercise numbers of the form X.y, where y is an integer, are extra exercises not found in the book.
cd $HOME mkdir scripting cd scripting export scripting=`pwd` wget http://folk.uio.no/hpl/scripting/TCSE3-3rd-examples.tar.gz wget http://folk.uio.no/hpl/scripting/scitools.tar.gz gunzip TCSE3-3rd-examples.tar.gz scitools.tar.gz tar xvf TCSE3-3rd-examples.tar rm TCSE3-3rd-examples.tar tar xvf scitools.tar rm scitools.tarInsert the following commands in your .bashrc start-up file:
export scripting=$HOME/scripting export PYTHONPATH=$scripting/src/tools:$scripting/scitools/lib PATH=$PATH:$scripting/src/tools:$scripting/scitools/binStart a new terminal window, or log in and out again, and check that you can do the following session: following:
Unix> python $scripting/src/py/intro/hw.py 3.14159 Hello, World! sin(3.14159)=2.65358979335e-06Unix> python -c 'from scitools.all import *' scitools.easyviz backend is gnuplot
Unix> python -c 'import Tkinter, Pmw'
To get access to the oscillator code, used in the simviz*.py family of introductory scripts, run the commands
Unix> cat > $scripting/src/tools/oscillator #!/bin/bash python $scripting/src/app/oscillator/Python/oscillator.py Ctrl-D Unix> chmod a+rx $scripting/src/tools/oscillatorNow, try to run the code:
Unix> oscillatorThe program just hangs (waiting for input). Kill it with Ctrl-C. If you encounter problems with installing the oscillator code, it is not that important - it means that you cannot run the simviz1.py script, but you can work with all the other examples.
To create the script file, you can use a standard editor such as Emacs or Vim on Unix-like systems. On Windows you must use an editor for pure text files - Notepad is a possibility, but I prefer to use Emacs or the ``IDLE'' editor that comes with Python (you usually find IDLE on the start menu, choose File--New Window to open up the editor). IDLE supports standard key bindings from Unix, Windows, or Mac (choose Options--Configure IDLE... and Keys to get a menu where you can choose between the three classes of key bindings).
The standard Python module for generation of uniform random numbers is called random. To figure out how to use this module, you can look up the description of the module in the Python Library Reference. Load the file $scripting/doc.html into a Web browser and click on the link Python Library Reference: Index. You will then see the index of Python functions, modules, data structures, etc. Find the item random (standard module) in the index and follow the link. This will bring you to the manual page for the random module. In the bottom part of this page you will find information about functions for drawing random numbers from various distributions (do not use the classes in the module, use plain functions). Also apply pydoc to look up documentation of the random module: just write pydoc random on the command line.
#!/usr/bin/ env pythonThere are five errors in this file - find them!import sys, random def compute(n): i = 0; s = 0 while i <= n: s += random.random() i += 1 return s/n
n = sys.argv[1] print 'the average of %d random numbers is %g" % (n, compute(n))
python hw2a.py 1.4 -0.1 4 99and the program writes out
Hello, World! sin(1.4)=0.98545 sin(-0.1)=-0.0998334 sin(4)=-0.756802 sin(99)=-0.999207Traverse the command-line arguments using a for loop. The complete list of the command-line arguments can be written sys.argv[1:] (i.e., the entries in sys.argv, starting with index 1 and ending with the last valid index). The for loop can then be written as for r in sys.argv[1:].
Make an alternative script, hw2b.py, where a while loop construction is used for handling each number on the command line.
In a third version of the script, hw2c.py, you should take the natural logarithm of the numbers on the command line. Look up the documentation of the math module in the Python Library Reference to see how to compute the natural logarithm of a number. Include an if test to ensure that you only take the logarithm of positive numbers. Running, for instance,
python hw2c.py 1.4 -0.1 4 99should give this output:
Hello, World! ln(1.4)=0.336472 ln(-0.1) is illegal ln(4)=1.38629 ln(99)=4.59512
You can feed data into the script directly from the terminal window (after you have started the script, of course) and terminate input with Ctrl-D. Alternatively, you can on Unix systems send a file into the script using a pipe, and if desired, redirect output to a file:
cat inputfile | datatrans1stdio.py > res(datatrans1stdio.py is the name of the modified script.) A suitable input file for testing the script is src/py/intro/.datatrans_infile.
from f77module import calc print calc()
from f77module2 import sumdiff a = 1; b = -10 sum, diff = sumdiff(a, b) print 'The sum of %g and %g is %g and the difference is %g' % (a, b, sum, diff)
Create a GUI as shown in figure above, where the user can write a number and click on sin, cos, tan, or sqrt to take the sine, cosine, etc. of the number. The GUI consists of an entry field, four buttons, and a label (with sunken relief). After the GUI is functioning, adjust the layout such that the computed number appears to the right in the label field. (Hint: Look up the man page for the Label widget. The 'Introduction to Tkinter' link in doc.html is a starting point.)
Name of scriptfile: hwGUI1b.py (exercise class: GUI)
Name of scriptfile: hwGUI1c.py (exercise class: GUI)
A = array([[1, 2, 3], [4, 5, 6], [7, 8, 10]]) b = array([-3, -2, -1])Use the NumPy manual to find a function that computes the standard matrix-vector product A times b.
(You will see that f(x,t) models waves that are moving to the right (when x is a space coordinate and t is time). The velocity of the individual waves and the packet is different, demonstrating a case in physics when the phase velocity of waves is different from the group velocity.)
from scitools.all import * x = linspace(0, 2, 20) y = x*(2 - x) plot(x, y)Then you alter the second statement to y = cos(18*pi*x). Judge the resulting plot. Is it correct? Display the cos(18*x) function with 1000 points in the same plot.
s1 = Simple(4) for i in range(4): s1.double() print s1.iBefore you run this code, convince yourself what the output of the print statements will be.s2 = Simple('Hello') s2.double(); s2.double() print s2.i s2.i = 100 print s2.i
>>> from Vec3D import Vec3D >>> u = Vec3D(1, 0, 0) # (1,0,0) vector >>> v = Vec3D(0, 1, 0) >>> str(u) # pretty print '(1, 0, 0)' >>> repr(u) # u = eval(repr(u)) 'Vec3D(1, 0, 0)' >>> u.len() # Eucledian norm 1.0 >>> u[1] # subscripting 0.0 >>> v[2]=2.5 # subscripting w/assignment >>> print u**v # cross product (0, -2.5, 1) # (output applies __str__) >>> u+v # vector addition Vec3D(1, 1, 2.5) # (output applies __repr__) >>> u-v # vector subtraction Vec3D(1, -1, -2.5) >>> u*v # inner (scalar, dot) product 0.0We remark that class Vec3D is just aimed at being an illustrating exercise. Serious computations with a class for 3D vectors should utilize either a NumPy array (see Chapter 4), or better, the Vector class in the Scientific.Geometry.Vector module, which is a part of ScientificPython (see Chapter 4.4.1).
Name of scriptfile: vec3d.py
u = Vec3D(1, 0, 0) v = Vec3D(0, -0.2, 8) a = 1.2 u+v # vector addition a+v # scalar plus vector, yields (1.2, 1, 9.2) v+a # vector plus scalar, yields (1.2, 1, 9.2)In the same way we should be able to do a-v, v-a, a*v, v*a, and v/a (a/v is not defined).
Name of scriptfile: vec3d_ext.py
def initial_condition(x): return 3.0does not work properly when x is a NumPy array. In that case the function should return a NumPy array with the same shape as x and with all entries equal to 3.0. Perform the necessary modifications such that the function works for both scalar types and NumPy arrays.
Create a script that in a loop from 1 to n draws two uniform random numbers between 1 and 6 and counts how many times p a 6 shows up. Write out the estimated probability p/float(n) together with the exact result 11/36. Run the script a few times with different n values (preferably read from the command line) and determine from the experiments how large n must be to get the first three decimals (0.306) of the probability correct.
Hint: Check out the random module to see how to draw random uniformly distributed integers in a specified interval.
Remark. Division of integers (p/n) yields in this case zero, since p is always smaller than n. Integer p divided by integer n implies in Python, and in most other languages, integer division, i.e., p/n is the largest integer that when multiplied by n becomes less than or equal to p. Converting at least one of the integers to float (p/float(n)) ensures floating-point division, which is what we need.
(The name DAXPY originates from the name of the subroutine in the standard BLAS library offering this computation.)