- How to Program, Part I
- How to Program, Part II
- How to Program, Part III
- How to Program, Part IV
- How to Program, Part V
- exercises
- pyMPI tutorial
- Calculating PI, Part I
- Calculating PI, Part II
- Calculating PI, Part III
- Poogle - Web Search
- Mandelbrot Sets
- Mandelbrot, The Code
- Mandelbrot, The Images
- Conway's Life, Part I
- Life Code Listing
- Conway's Life, Part II
- MPI Life Code Listing
| How to Program, Part IV
Sometimes we may want to take a calculation and re-use it several times in a program.
| file: shop.py |
| 1 | def ring_up(total,name,price): |
| 2 | tax_rate = 6 |
| 3 | tax = price * tax_rate / 100 |
| 4 | print name,price,tax |
| 5 | return total+price+tax |
| 6 | |
| 7 | total = 0 |
| 8 | total = ring_up(total,"milk",3.89) |
| 9 | total = ring_up(total,"cookies",1.55) |
| 10 | total = ring_up(total,"apples",4.99) |
> python shop.py
milk 3.89 0.2334 cookies 1.55 0.093 apples 4.99 0.2994
|
In this case, by defining the function named "ring_up" we've saved ourselves some coding. We can use ring_up() to compute the total of our purchases, along with taxes, as well as an itemized list. Each call to "ring_up" executes the four lines of code present in its definition.
Notice the syntax: the values "total", "name", and "price" are passed to the
function named ring_up. These variables are called "arguments." The "return" line causes an exit from the funtion and
returns the computed value.
Variables defined inside a function are not visible outside.
| file: nshop.py |
| 1 | def ring_up(total,name,price): |
| 2 | tax_rate = 6 |
| 3 | tax = price * tax_rate / 100 |
| 4 | print name,price,tax |
| 5 | return total+price+tax |
| 6 | |
| 7 | total = 0 |
| 8 | total = ring_up(total,"milk",3.89) |
| 9 | print tax_rate |
> python nshop.py
milk 3.89 0.2334 Traceback (most recent call last): File "nshop.py", line 9, in ? print tax_rate NameError: name 'tax_rate' is not defined
|
But ariables defined outside the function are visible inside.
| file: nshop2.py |
| 1 | tax_rate = 6 |
| 2 | def ring_up(total,name,price): |
| 3 | tax = price * tax_rate / 100 |
| 4 | print name,price,tax |
| 5 | return total+price+tax |
| 6 | |
| 7 | total = 0 |
| 8 | total = ring_up(total,"milk",3.89) |
| 9 | print tax_rate |
> python nshop2.py
milk 3.89 0.2334 6
|
It is as if the variables inside a function live in their own private
world.
Functions can have multiple return points.
| file: multi.py |
| 1 | def multi(x): |
| 2 | if x < 3: |
| 3 | return x - 100 |
| 4 | else: |
| 5 | return 2*x |
| 6 | |
| 7 | print multi(2),multi(4) |
> python multi.py
-98 8
|
In our next program, we want to make use of a function we defined in the "shop.py"
program above. We can do this using an "import."
| file: ring.py |
| 1 | import shop |
| 2 | |
| 3 | total = 0 |
| 4 | total = shop.ring_up(total,"fudge",3.25) |
| 5 | total = shop.ring_up(total,"bag of lemons",1.25) |
| 6 | total = shop.ring_up(total,"instant tea",1.89) |
| 7 | print "total =",total |
> python ring.py
milk 3.89 0.2334 cookies 1.55 0.093 apples 4.99 0.2994 fudge 3.25 0.195 bag of lemons 1.25 0.075 instant tea 1.89 0.1134 total = 6.7734
|
Notice what happened. "import shop.py" read the contents of "shop.py" and then made the function "ring_up()" available to us in our ring.py program. However, in order to use it, we have to use the prefix "shop." in front of each call to "ring_up()".
One subtle point here that you should be aware of. Integers and
floating point numbers are different:
| file: types.py |
| 1 | print 1/2 |
| 2 | print 1.0/2 |
| 3 | print 1/2.0 |
| 4 | print 1.0/2.0 |
> python types.py
0 0.5 0.5 0.5
|
When integers are used, no decimal values are ever calculated. If you
want to see decimal points in the result, you have to use them in
one of the values
involved in the computation. Thus, the tax calculation we did in "shop.py"
would fail if we used an integer for the price.
| file: shop_ohno.py |
| 1 | import shop |
| 2 | |
| 3 | total = 0 |
| 4 | total = shop.ring_up(total,"ding dongs",3) |
| 5 | print "total =",total # oh no! tax calculation failed! |
> python shop_ohno.py
milk 3.89 0.2334 cookies 1.55 0.093 apples 4.99 0.2994 ding dongs 3 0 total = 3
|
There are lots of standard functions that you can import.
| file: math1.py |
| 1 | import math |
| 2 | |
| 3 | print math.sqrt(4) |
> python math1.py
2.0
|
The above program will just print "2" (the function math.sqrt() is
the square root function), as you'd expect.
| file: math2.py |
| 1 | import math |
| 2 | |
| 3 | print math.sin(math.pi/4) |
> python math2.py
0.707106781187
|
Here we see that it is possible to import variables (in this case "math.pi") as well as functions.
| file: rand.py |
| 1 | import random |
| 2 | |
| 3 | print random.random() |
> python rand.py
0.908264820247
|
This prints a random number between 0.0 and 1.0. Try it!
This next program can be used to fetch the contents of a web page:
| file: url.py |
| 1 | import urllib |
| 2 | |
| 3 | url = urllib.urlopen("http://scifi.com") |
| 4 | text = url.readline() |
| 5 | print text |
> python url.py
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
This probably looks a bit strange to you. Some variables have methods attached to them. In this case, the variable url has a method attached to it called readline. I don't want to dwell on this too deeply, it's just a hint of things to come. We have, however, already seen this kind of thing in lesson 3. Variables of type list have an "append" method inside them.
One last point...
You can return more than one value from a function using something called "tuples." We aren't going to go into too much
detail about them here, just to show you this quick example:
| file: tuple.py |
| 1 | def div(d1,d2): |
| 2 | return (d1+d2,d1-d2) |
| 3 | |
| 4 | (a,b)=div(4,2) |
| 5 | print a,b |
> python tuple.py
6 2
|
The idea is that you can group a set of values together in both return statement (line 2),
and when the function is called (line 4).
Actually, this also works without the parenthesis, but using them might make it easier for you to read the code.
| file: tuple2.py |
| 1 | def div(d1,d2): |
| 2 | return d1+d2,d1-d2 |
| 3 | |
| 4 | a,b=div(4,2) |
| 5 | print a,b |
> python tuple2.py
6 2
|
Here is an example that combines what we know about arrays and functions.in it we will build a new array, one in which the order of elements is reversed relative to the original one.
| file: reverse.py |
| 1 | def rev(a): |
| 2 | b = [] |
| 3 | n = len(a) |
| 4 | for i in range(n): |
| 5 | b.append(a[n-i-1]) |
| 6 | return b |
| 7 | x = [1,2,3,8,20] |
| 8 | y = rev(x) |
| 9 | print x,y |
> python reverse.py
[1, 2, 3, 8, 20] [20, 8, 3, 2, 1]
|
| |