Download Beginner`s Guide to Progamming in Python

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Beginner’s Guide to Progamming in Python
Arthur H. Lee
Department of Mathematics & Computer Science
Claremont McKenna College
Claremont, CA 91711
This tutorial assumes that the reader has no previous programming experience
but has access to an installation of Python. It is operating system independent
(good for both Widows or OS X) and intended to be read in the given order. A
table of contents is given at the end.
1
Key references
There is an excellent book available free online that will teach you the basics of
Python and some important concepts in computer science at the same time. It
is: Think Python: How to Think Like a Computer Scientist by Allen B. Downey
(http://www.greenteapress .com/thinkpython/thinkpython.html),
which I will refer to as [Downey] in the remainder of this tutorial.
2
How to run a Python interpreter
Two different ways of running a Python program are described. Use script mode
if you have a long list of Python commands to run (or execute) in order; otherwise
interactive mode may be more convenient.
2.1
Interactive mode
First, start a Python session. Here, I am using prompt> to mean whatever prompt
you happen to be on when you start a command session with Windows or OS X.
1
Below are two sample sessions using python and ipython in that order on a
Mac OS X in an interactive mode.
prompt> python
Enthought Python Distribution -- www.enthought.com
Version: 7.1-2 (64-bit)
Python 2.7.2 |EPD 7.1-2 (64-bit)| (default, Jul 27 2011, 14:50:45)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "packages", "demo" or "enthought" for more information.
>>> 3 + 4
7
>>> exit()
prompt> ipython
[TerminalIPythonApp] Staging bundled ipython_config.py from default
into u’/Users/alee/.ipython/profile_default’
Enthought Python Distribution -- www.enthought.com
Python 2.7.2 |EPD 7.1-2 (64-bit)| (default, Jul 27 2011, 14:50:45)
Type "copyright", "credits" or "license" for more information.
IPython 0.11
?
->
%quickref ->
help
->
object?
->
-- An enhanced Interactive Python.
Introduction and overview of IPython’s features.
Quick reference.
Python’s own help system.
Details about ’object’, use ’object??’ for extra details.
In [1]: 3 + 4
Out[1]: 7
In [2]: exit()
2.2
Script mode
You would prepare a Python script file containing a Python program and execute
the program.
2
First, using a text editor of your choice create a file named hello.py containing the following as its content:
print "\nHello world!"
print "Welcome to the world of Python!"
print "We will have some fun!!!"
This script file contains only three lines of print commands. To run this script, do
the following:
1. Open a command (terminal) window. Here again I am assuming that you
get prompt> as the prompt when you start your command window.
2. Go to the folder where hello.py is located. The cd command will be
useful as you move around the folders in your file system along with the ls
command for Mac and dir command for Windows.
3. Try the python command with the script file (hello.py in this case) as
follows. The result of executing the program will be displayed.
prompt> python hello.py
Hello world!
Welcome to the world of Python!
We will have some fun!!!
prompt>
The program files that I included in this tutorial are all valid Python script
files.
Try the following and see what happens:
prompt> ipython hello.py
You can run a script from ipython in addition to the usual interaction with the
interpreter. Here is a log of one such interaction:
3
prompt> ipython
Enthought Python Distribution -- www.enthought.com
Python 2.7.2 |EPD 7.1-2 (64-bit)| (default, Jul 27 2011, 14:50:45)
Type "copyright", "credits" or "license" for more information.
IPython 0.11
?
->
%quickref ->
help
->
object?
->
-- An enhanced Interactive Python.
Introduction and overview of IPython’s features.
Quick reference.
Python’s own help system.
Details about ’object’, use ’object??’ for extra details.
In [1]: pwd
Out[1]: u’/Users/alee’
# To see where I am in the file system
In [2]: cd python_2013
/Users/alee/python_2013
# To move to the folder python_2013
In [3]: pwd
Out[3]: u’/Users/alee/python_2013’
In [4]: execfile("hello.py")
# Finally to run the script
Hello world!
Welcome to the world of Python!
We will have some fun!!!
In [5]: exit()
Some of these interactions, e.g., the execfile command, are also available in
a regular interactive python session. However, pwd and cd (the usual unix commands) are not available in regular python although they are available in ipython.
Whether you are using an interactive mode or a script mode, you can import
other modules into your python program. See the ”Modules” section later for
detail.
4
3
Basic data types and their values
These are basic type values Python supports and some examples are given below
without much explanation. If you are not familiar with them, [Downey] is a good
source for more information.
• Integers: 34, 2, -300, etc.
• Real numbers (floating point numbers): 3.4, 2.0, -300.0, 3.14159, etc.
• Booleans (logical values): True and False.
• Strings: ’A’, ’a’, ”A”, ”a”, ”This is a string of letters”, ”Hello world!”, etc.
Strings are defined by enclosing a string of text in a pair of single or double
quotes. Python as in most languages recognizes them as a single entity
(value) that can be manipulated much like a number (integer or a floating
point number) can be, of course using some operators that make sense with
strings.
Try the following with Python. The function type given an argument, say 3,
returns the type of the value, e.g., integer for 3. The integer type is represented
as <type ’int’> in Python.
>>> type (3)
<type ’int’>
Now, real numbers (also known as floating point numbers) without listing output
(try it yourself to see what output you get):
>>> type (3.14)
And, two boolean values:
>>> type (True)
>>> type (False)
And, strings this time:
>>> type ("3")
>>> type ("It is a nice day outside.")
5
As you may have recognized it by now, any value the language Python, or any programming language in general, deals with has a type associated with the value. By
using the type information a language processor (interpreter in the case of Python)
understands what it is dealing with and distinguishes one type of value from another. That way, it would not try to do things that would not make sense, for
example, trying to add a number to a string. It also uses the type information to
decide how much memory to use to represent a value in memory. An integer is
typically represented using a smaller amount of memory (say 32 bits) than the
amount of memory used to represent a real number (say 64 bits). So, type information for any value we use in a program is important for the language processor
as well as for the programmers who write application programs.
In this tutorial we will deal with only a small number of types which will still
be sufficient for the kinds of programs that we will write.
Types such as int, float, boolean are called primitive data types. Later
we will see some compound data types such as string, list, tuples, etc.
4
Comments
Any line starting with a pound sign (#) in your Python program is considered a
comment and will be ignored by the Python interpreter. I often add my explanation
as a comment in a program file.
5
Use of the print command in a script file
Create a Python script file named print.py containing the following two lines:
3 + 4 + 2
print 4 + 8
# Line 1
# Line 2
Now run that script in script mode, i.e., run it like this:
prompt> python print.py
then you will see output for only one of the two lines.
The python interpreter in script mode will evaluate each line of your program
(script) and do exactly what you asked it to do. Line 1 above tells the interpreter
to evaluate the expression (3 + 4 + 2) and do nothing else. So, it will evaluate it and produce 9 and that is all it does. Line 2 tells the interpreter to evaluate
6
the expression (4 + 8) and print it to the standard output device, which is your
computer screen. Prepare your script files with a print command sprinkled here
and there if it would make the program easier to understand when you run it.
You might wonder what is going on in an interactive mode as in ipython.
When Python runs in an interactive mode, the interpreter works a little differently
in that it interprets a line and furthermore prints the result to the screen which
makes sense since you are expecting to see the result on the screen. When you
are in script mode, most likely you will write a series of lines of code and many
of those lines will be for some intermediate steps of your program. You wouldn’t
want to see the value of each line of your entire program printed on the screen.
That would be too confusing.
6
Variables
In most programming we store a value with a name so we can refer to the value
repeatedly by the name, often updating the value if necessary. Once a name is
given a value, we can even update the value of the variable by assigning a new
value, using an assignment operator (=), as many times as we want if the logic of
the program that we write demands it. Let us see some examples next.
Establishing a variable name with a value associated with the name (again
omitting output values – please try them as you read):
>>> message = "What’s up?"
>>> message
Updating the value of the variable with a new value:
>>> message = "What’s down?"
>>> message
Establishing a name with a value initially and then updating the value as you compute in your program is a pattern we use a lot, specially in Python. So, remember
this pattern.
The variable message here happens to have a string value at this point, but
you can even assign an integer as its value at this point in the program like this:
>>> message = 234
>>> message
7
But, it is usually not a good idea (not a good programming style) to mix different
types of values for a given variable unless it is logically necessary to do so in
your program. Programs are much easier to understand if you keep the variables
with values of the same type throughout the lifetime of the variables. In other
languages such as Java changing the type of a variable like this in mid-stream is
not even allowed. Here are some more variables with some values assigned.
>>>
>>>
>>>
>>>
>>>
>>>
n = 22
n
n = 23
n
pi = 3.14159
pi
We already know how to get the types. Let us try them again here.
>>>
>>>
>>>
>>>
>>>
type (message)
message = "back to string again"
type (message)
type (n)
type (pi)
We can try some boolean variables, i.e., the variables with boolean values (aka
logical values, namely, True or False). For example,
>>>
>>>
>>>
>>>
>>>
>>>
>>>
larger = (45 > 10)
larger
larger = (45 < 10)
larger
same = (34 == 34)
same
type(same)
You will find variables useful as you write more complex programs.
7
Operating on values: operators and operands
Combining simple data values you can construct an arbitrarily complex expression
using operators available in Python. I will try to give you a flavor of them here.
You can find other operators and form more complex expressions.
8
>>> 22 + 33 - 10
Create some variables with a value assigned to each and try some expressions:
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
hour = 5
minute = 30
hour - 2
hour*60 + minute
(3+4)*(40/10)+100
this = "Ham"
that = " and cheese"
more = " for breakfast!"
The + operator has a different meaning depending on what type of operands it
operates on. If it is dealing with numbers, it will just add as usual. If the operands
are of string type, it will concatenate the operands.
>>> this+that+more
>>> this + that + more
’==’ is the operator that tests if its two operands are equal or not. The result will
be True or False. Be careful not to use ’=’ when you actually mean ’==’. ’=’ is
an assignment operator, whereas ’==’ is an equality testing operator. What would
be the type of issame after the line below is executed?
>>> issame = this == that
If you are not sure of operator precedence between two operators, use a pair of
parentheses to indicate your intention like this. ’not’ is the negation operator.
>>>
>>>
>>>
>>>
>>>
isequal = (not (this == that))
issame
type(issame)
isequal
type(isequal)
8
Order of precedence among operators
The rules on operator precedence in Python is the same as what you would expect
for common operators, e.g., 4 + 3 * 2 evaluates to 10, not 14. If you are
not sure, use parentheses to indicate your intention. We have also seen some
operations on strings in the previous section.
9
9
Input from keyboard
There are two built-in functions for getting keyboard input, and they are: raw input
and input. Let us try these. When you run the program below, try ’4 + 5’
(without the quotes) as your input both times and see what the differences are between raw input and input. What you type in as input will not be evaluated
if you use raw input:
>>> n = raw_input("Enter a numerical expression, e.g., 3 + 4: ")
>>> n
This one will evaluate the input and print the evaluated result:
>>> n = input("Enter a numerical expression, e.g., 3 + 4: ")
>>> n
10
Functions and packages (libraries)
Let us start with something that we are all familiar with. In Math, we first define
and next apply a function in 2 steps in that order like this:
(1) Definition: f(x) = 3xˆ2 + 2x + 1
(2) Application: f(2) = 12 + 4 + 1 = 17
f(3) = 27 + 6 + 1 = 34
Once you define a function, you can call (apply/invoke/use) that function as many
times as you wish.
In Python, the idea is the same. We only happen to be using a different language: different syntax, same semantics (at least for now):
(1) Definition:
def f (x):
return 3*x**2 + 2*x + 1
(2) Application:
f(2)
which would compute 17 as its value.
Let’s look at it in more detail. In Python, a function must be defined using the
following syntax:
10
def <name>(<list_of_parameters>):
<statements>
You can make up any name you want for the function that you create, except that
you can’t use a name that is a Python keyword. For example, def is a keyword
reserved in the language Python, and you must avoid using it as a name that you
create. The list of parameters specifies what information, if any, you have to
provide in order to use the function. There can be one or more of statements
inside the function, but they must be indented from the def. In my examples, I
will use the standard indentation of four blank spaces.
Function definitions are the first of several compound statements we will see,
all of which have the same pattern:
1. A header, which begins with a keyword and ends with a colon (:). In case
you have not noticed it, the right parenthesis, the left parenthesis, and the
colon are all required. Seemingly insignificant letters like these are part of
the language syntax and Python like any other programming language is
very picky about the exact syntax.
2. A body consisting of one or more Python statements, each indented the
same amount from the header. In a function definition, the keyword in the
header is def, which is followed by the name of the function and a list of
parameters enclosed in parentheses. The parameter list may be empty, or it
may contain any number of parameters. In either case, the parentheses are
required as is the colon (:).
Here are a few examples:
>>> def f(x):
return 3*x**2 + 2*x + 1
>>> f(1)
>>> def g(x, y, z):
return x * y + z
>>> g(2, 3, 4)
Try the above fragments of Python code in the given order.
11
pow for power and abs for absolute are two of the many functions that are already defined in the language that we can use. Those language provided functions
are called built-in functions as opposed to the ones that we programmers create,
which are called user-defined functions. For example, f and g above are examples
of user-defined functions.
>>> f(pow(abs(-2), 3))
There are some libraries (packages) that need to be imported into the current module before we can use any function that is defined in the library. math is one such
library that contains many math related functions. We import a library by the
import command like below:
>>> import math
Let us define a function named distance that computes the distance between
two points: p1(x1, y1) and p2(x2, y2):
>>> def distance(x1, y1, x2, y2):
dx = x2 - x1
dy = y2 - y1
dsquared = dx**2 + dy**2
result = math.sqrt(dsquared)
return result
>>> distance(0, 0, 3, 4)
Note that when we want to call a function defined in a library (aka package)
other than the default package, we must specify the name of the package followed
by a dot (.) followed by the function that we want to use in the package. Note
that we did not have to use any package qualifier when we used the ones like
print and def because they are included in the base Python language package,
i.e., default package. A few more example functions follow: isEven tells if a
given number is even or odd. % computes modulo and == tests to see if two values
are equal or not producing a boolean value, i.e., True or False.
>>> def isEven(x):
return ((x % 2) == 0)
>>> isEven(3)
12
>>> def isDivisible(x,y):
return (x % y) == 0
>>> isDivisible(30, 3)
Exercise 1. Define a function that converts a Celsius temperature value to a
Fahrenheit temperature and call it with some values such as 100, 0, -40, etc. I will
provide my answer to this exercise at the end of this file, but try it yourself before
you see mine.
Exercise 2. This time let us combine functions and input. Define a function
that reads a number from the user through keyboard input, calls the function that
converts the number as Celsius temperature into Fahrenheit temperature, and returns the computed Fahrenheit temperature. After that you can run this program
three times: once each with 100, 0, and -40 as input values.
Exercise 3. Define a function with three string parameters and returns a string
that is the result of concatenating the three with a space as a separating character
between strings. Now, call the function with three strings as its actual arguments.
Exercise 4. See Section 3.15 of [Downey] if you want to see more exercise
problems.
Sample solutions to Exercises 1 and 2.
def c2f(c):
return c * (9.0/5.0) + 32
def c2ftest():
n = input("Enter a number: ")
n = c2f(n)
return n
c2ftest()
# use 100, 0, or -40
# Note that c2ftest may be rewritten more succinctly this way:
def c2ftest2():
return c2f(input("Enter a number: "))
c2ftest2()
# use 100, 0, or -40
13
11
Conditionals: doing it conditionally
You need to understand boolean expressions to understand conditionals. If you
are not familiar with them, consult [Downey].
absolute taking one argument returns the absolute value of the given number. To compute the absolute value, it uses a conditional expression, i.e., if...else...
Both syntax and semantics of a conditional expression is intuitive.
>>> def absolute(x):
if x < 0:
return -x
else:
return x
>>> absolute(-34)
A conditional expression can be of the cascaded if...elif... ...else...
form if you need to have multiple cases to handle, again intuitive (see examples
below).
Note that if you define functions with the same name multiple times, the last
one overwrites all the previous ones even if their signatures are different.
>>> def absolute(x):
if x < 0:
return -x
elif x > 0:
return x
else:
return 0
>>> absolute(-34)
>>> absolute(34)
>>> absolute(0)
Exercise 1. Write a boolean function that determines if a given speed value is
within the legal freeway speed on I-10 outside of the city limits. Once you define
the function, write a piece of code that calls the defined function and prints the
computed result (True or False).
Exercise 2. Given a score out of 100, return a letter grade for the score. Let’s
assign the letter grade using the grading scale given by the following table:
14
above
above
above
above
below
89: A
79 and below 90: B
69 and below 80: C
59 and below 70: D
60: F
and call the function at least five times, each time producing a different letter
grade. It is okay to produce the final grade as a string value, e.g., ”A” for an A.
A side note: In Python a function name cannot be overloaded (unlike how it is
in Java. Java supports function name overloading, but not in Python.). That is, you
cannot define a function with different parameter lists to mean different functions.
For example, if you redefine absolute with two parameters in the same session
where absolute was defined earlier with one parameter, the earlier one is lost.
So, you can call absolute with one argument okay here:
>>> absolute(-23)
>>> def absolute(x, y):
return x + y
But, you cannot call absolute with one parameter here any longer, thus I commented it out here.
# >>> absolute(-23)
#
# Of course, this one below would certainly be okay.
#
>>> absolute(2, 3)
12
Loops: doing it repeatedly
Let us see what ’while’ does in the program below. ’while’ is used to create
a while loop. That is, the body of the while loop, the two lines indented inside
the ’while’ loop in the example below, will be executed repeatedly as long as the
boolean expression (n > 0) evaluates to True. So, for this style of loop to
terminate eventually the value of n (called a loop control variable) must change
inside the loop body in such a way that the boolean expression is moving toward
evaluating to True.
15
If you call countdown with a negative number initially, what would happen?
Well, it will get into an infinite loop... sort of... it will run until the computer gets
into a corrupted state or it runs out of memory depending on how the underlying
interpreter behaves. At least you see a possible problem! If you do not update
the value of the loop control variable inside the while loop, we will end up with
a similar result. Create a file named loops.py with the following as its content
and run.
# We know what import does, right?
import math
# precondition: n > 0 [the condition that must satisfy at the time the
#
function is called, i.e., before it is executed
def countdown(n):
while n > 0:
print n
n = n - 1
print "Blastoff!"
countdown(5)
# Let us write a function that prints when called a log table.
# The character sequence ’\t’ generates a tab character.
#
def print_table():
x = 1.0
while x < 10.0:
print x, ’\t’, math.log(x)
x = x + 1.0
# An annotation as part of output (human readability is important!)
print "print_table()"
# Finally, generate the table itself by calling the function.
print_table()
# Let us improve the earlier definition of print_table by making it mo
# general. We will parameterize the function by allowing the ’from’ v
16
# and the ’to’ value to be user definable as the function is called.
# is one of the very important techniques in programming - generalizat
# abstraction! That is, we abstract with functions and generalize the
# when it makes sense to do so.
def print_table2(fr, to):
while fr < to:
print fr, ’\t’, math.log(fr)
fr = fr + 1.0
print "print_table2(10.0, 20.0)"
# As before generate a table, but using two values as actual arguments
# the two parameters that we introduced in the definition.
#
print_table2(10.0, 20.0)
# What would happen if you called it this way?
#
print "print_table2(30.0, 20.0)"
print_table2(30.0, 20.0)
See how I used the print statements liberally in the code above to make it more
readable when we execute the program.
Exercise 1. Write a function that prints a table of a number, its square, and its
square root in a range defined by two numbers. For example, numbers between 10
and 20 and their squares and square roots in a table. Once the function is defined,
call it and be sure that your program generates the table correctly.
Exercise 2. Write a function that reads two numbers from keyboard and use
those two numbers as lower and upper limits of the range that you would need
for the function that you wrote in Exercise 1 above. If the input values that your
function reads in are invalid, e.g., first number is larger than the second, your
program must read a pair of numbers repeatedly until you have two valid numbers.
Once you have a good pair of numbers, then you can call the function defined in
Exercise 1 above. To make it a little more interesting, define a separate function
that determines if two given numbers are valid or not, and use it as part of your
reader function. Yes, you could easily do all that in a single function, but this will
give you a chance to practise with multiple functions that make up a program. In
fact, as you will learn later if you continue to write more complex programs, this
17
is a good way to deal with complexity in your program design.
Exercise 3. See Section 7.9 of [Downey] if you want to see more exercise
problems.
13
Compound data types: strings, lists, tuples
So far we have mainly dealt with primitive data type values (and a little bit about
strings). That is, we have seen the following four data types: int (for integers),
float (for real numbers), bool (for booleans), and str (for strings).
Strings are compound data whereas the other three are atomic. That is, a string
is made up of smaller pieces, namely characters. To be more precise, a string is a
sequence of characters.
Our main focus so far has been learning the basic language constructs and
programming elements such as operators, conditionals, loops, functions, input,
etc. using simple data types.
Using the basic language constructs that we have already learned, we can enrich the data types. We do so by learning compound data types. The compound
data types we will learn include strings (in more detail), lists, and tuples. To write
interesting programs, we will need to know these compound data types as well.
Let us do it.
14
Strings
A string is an ordered sequence of characters.
String is a data structure and just like integer is a data structure. Integer is a
very simple data structure whereas string is a more complex data structure. Every
time you encounter a new data structure in any language that you learn, figure out
four things:
1. How to create an instance of that data structure and give a name to it. Here
is an example of how to create a string variable with a value:
sports = "basketball"
2. How to view the value of the data structure? This is what we call read
access. Here are a few examples:
18
letter = sports[0]
sports[1]
# to access the first character
# to access the second character
3. How to change the value of the data structure, if possible? For example, if
we want to modify the contents of sports so that it holds "Baseball"
instead of "baseball", we would have to assign a new character in that
location of the sports string by using an assignment operator like this:
sports[0] = ’B’
but modifying an element in place in string is not allowed in Python. So, we
call string an immutable data structure in Python. The best you can do is to
create a new string with a ’B’ in the first location and reassign the whole
string to be the new value of the variable sports. When we study lists
later, we will be able to modify an element in a list in place. Stay tuned.
Changing the value of a variable is called write access, and there are two
forms of write access we can think of when we deal with a string.
(a) Changing a character in the string, e.g., by doing something like:
sports[0] = ’B’
but that is not allowed with a string because string is immutable in
Python.
(b) Setting a new string to be the value of the variable, e.g.,
sports = Baseball
which is allowed in Python.
4. How to destroy the data structure when we are done using it. In a language
such as C or C++ you would have to worry about that, but not in Python.
So, there are only three things to worry about when you encounter a new
data structure in Python. Sometimes, only two as with strings. I will tell
you which ones to worry about each time a new data structure is introduced
below.
19
Let us see some strings and related functions that we can use to manipulate
strings. Define a variable with the string value ’banana" as its initial value:
>>> fruit = "banana"
String is a compound value and we can access individual pieces in it. Here we are
accessing the second character in fruit.
>>> letter = fruit[1]
>>> letter
Indices in Python are 0-based as in most other programming languages. So,
fruit[1] is accessing the second character in the string.
>>> fruit[0]
Length of a string is available too.
>>> len(fruit)
More looping using strings would be instructive. Let us print fruit using a
while loop:
>>> i = 0
>>> while i < len(fruit):
print fruit[i]
i = i + 1
Exercise: Create a function that takes one string argument and prints the letters backward.
14.1
The for loop
We have learned one kind of a loop in Python so far: the while loop. Well, there
is another looping construct in Python: the for loop. As you can see below, it has
a very simple intuitive form. This loop is often referred to as the for-each loop
because that is what it really means. So, the example below can be read as: ’for
each letter referred to as c in the string fruit, print
the character c’, thus printing each letter in the string to the standard output device, i.e., the computer screen. Remember that the body of a for loop as
with a body of a while loop or a function needs to be indented.
20
>>> for c in fruit:
print c
Here is a simple yet fun thing to do. I think you can figure out what this does:
>>> prefixes = "JKLMNOPQ"
>>> suffix = "ack"
>>> for letter in prefixes:
print letter + suffix
Slicing a string: by using the ’:’ operator we can specify a range within the
string.
>>>
>>>
>>>
>>>
>>>
>>>
s = "Peter, Paul, and Mary"
s[0:5]
# 0 to 5, but 0 inclusive, 5 exclusive
s[7:11]
s[17:21]
s[:3]
# 0 to 3, but 0 inclusive, 3 exclusive
s[17:]
# 17 to the end, with 17 inclusive
Comparing strings: we can use the usual comparison operators that we use for
numbers to compare two strings.
word = "apple"
if word == "banana":
print "Yes, we have a banana!"
else:
print "No, we don’t have a banana!"
if word <
print
elif word
print
else:
print
"banana":
"Your word, " + word + ", comes before banana."
> "banana":
"Your word, " + word + ", comes after banana."
"Yes, we have a banana!"
Finding a letter in a string: we can define a function that does that like this:
def find(str, ch):
index = 0
while index < len(str):
21
if str[index] == ch:
return index
index = index + 1
return -1
find("apple", ’l’)
find("apple", ’p’)
Counting: count the occurrences of a letter in a string:
def count(str, ch):
count = 0
for char in str:
if char == ch:
count = count + 1
return count
count("apple", ’p’)
There is a built-in string module that we can import:
import string
To see what things are included in the module:
dir(string)
Two of those are digits and find:
string.digits
string.find
If you want to find the documentation on find, try this. Similarly you can find
documentation on other functions as well.
string.find.__doc__
Based on the information obtained from the documentation, we can now call
find:
string.find("banana", "nan")
22
15
Lists
Remember that a string is an ordered sequence of characters? Well, a list is an
ordered sequence of values of any type. Both strings and lists and other things
that behave like an ordered sequence are called sequences.
Since a list is a data structure, think about four things about a new data structure: (1) How do you create one? (2) How do you access an element in it? (3)
How do you modify an element in it in place if possible? (4) How do you destroy
it when we don’t need it any more? (don’t worry about destroying one in Python)
Let us see some lists and related functions that we can use to manipulate lists.
Also think about where lists would be useful as you write your programs.
Let us create a list on the fly and print it to the standard output device:
>>> [10, 20, 30, 40, 50]
Once more with different type of elements:
>>> ["Let", "us", "stop", "spams!"]
Once more with an element itself as a list:
>>> ["hello", 2.0, 5, ["nested", 2, True]]
Here is another way of creating a list:
>>> range(1, 7)
# 1 inclusive, 7 exclusive
From 0 to 9 inclusive this time:
>>> range(10)
How about 1 to 10 in 2 or 3 increments?:
>>> range(1, 10, 2)
>>> range(1, 10, 3)
Let us see how we access elements in a list. First create a list and make sure it is
indeed created:
>>> numbers = [10, 20, 30, 40, 50]
>>> numbers
23
Remember that strings are immutable? Well, lists are mutable, which means that
we can modify an element in a list in place. Let us try it and see if indeed the
modification was done correctly in place.
>>> numbers[2] = 3
>>> numbers
Use a for loop as we did with a string:
>>> for n in numbers:
print n
Concatenating two lists together:
>>>
>>>
>>>
>>>
>>>
a
b
a
c
c
=
=
+
=
[1,
[3,
b
a +
2, 3]
4, 5]
# note that neither a nor b has been changed.
b
# note that neither a nor b has been changed. c is new.
What would you expect this to do? Well, verify your answer by running it.
>>> [0] * 4
How about this one? Again run it to see what it does.
>>> [1, 2, 3] * 3
Slicing lists, much like we did with strings:
>>>
>>>
>>>
>>>
>>>
alist = [’a’, ’b’, ’c’, ’d’, ’e’, ’f’]
alist[1:3]
# 1 inclusive, 3 exclusive
alist[:4]
# 0 to 3 inclusive
alist[3:]
# 3 and the rest
alist[:]
# everything
Deleting elements of a list in place:
>>>
>>>
>>>
>>>
del alist[2]
alist
del alist[2:4]
alist
# This is a destructive operation
# 2 to 3 inclusive
24
Inserting elements into a list: this is useful enough that we create a function for it:
def insert(u, v, i):
u[i:i] = v
numbers
insert(numbers, [111], 1)
numbers
insert(numbers, [22, 33, 44], 2)
numbers
insert(numbers, [[222, 333, 444]], 2)
numbers
insert(numbers, range(1000, 2000, 500), 2)
numbers
def sum(u):
sum = 0
for e in u:
sum = sum + e
return sum
def ave(u):
return sum(u) / len(u)
def makeList(u):
return [u, ave(u)]
insert(numbers, [makeList(range(1, 5))], 2)
numbers
Converting strings to lists: sometimes it is useful to convert a string into a list and
manipulate it as a list:
s1 = "Stop that!"
list(s1)
Some basic functions dealing with lists:
25
def del_head(u):
del u[0]
aa = [11, 22, 33, 44, 55]
del_head(aa)
aa
def tail(u):
return u[1:]
tail(aa)
aa
x = range(1, 11)
x
What does this do? For each element in x double it and include
them all in a list - neat, huh?
y = [j * 2 for j in x]
y
Matrices can be represented as lists in Python. For example,
# | 1 2 3 |
# | 4 5 6 |
# | 7 8 9 |
m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
m
m[1]
m[1] = [40, 50, 60]
m
m[1][2]
m[1][2] = 300
m[1][2]
We can print the 3 rows in order like this:
26
for r in m:
print r
We can print the 9 elements in order like this:
for r in m:
for e in r:
print e
This is a rather inefficient way to deal with matrices in Python. To deal with
matrices more efficiently, learn how to use Numpy arrays.
16
Modules
Tuples and dictionaries are also compound data types and we will study them, but
let us study modules first before we continue with them.
Namespace is a concept used in programming languages. As we create functions, thus function names, we may want to create the same function name to mean
different things in different contexts. For example, count may mean counting
students or beans depending on which program you are dealing with. Rather than
naming them studentCount and beanCount we may want to name them
both count, but in different contexts. We create a namespace in which names
are contained. So if we have a namespace that contains all the names that deal
with students and another containing all the names that deal with beans, then we
can use the same name, e.g., count, as long as we distinguish one from the other
by using the name of the namespace it belongs to. Namespace is used to manage
names in a programming language. After all, a program consists of a bunch of
names such as variable names, function names, etc. When there are many names,
it is easier to deal with them if we partition them into different spaces. Python like
many other languages supports this mechanism and it is implemented by modules.
A module is a file containing Python definitions that are intended to be used
in other Python programs. There are many Python modules that come with the
language Python as part of the standard library. We have seen two of those already:
the string module and the math module.
Let us learn how to create a module of our own now. All we need to create a
module is a Python program file with a .py extension in the filename. For example, functions.py that I created earlier is one such module. Let us create one
as follows: we will create a file named seqtools.py that contains two definitions named remove at and insert at. The file would contain the following:
27
# seqtools.py
def remove_at(seq, pos):
return seq[:pos] + seq[pos+1:]
def insert_at(seq, pos, item):
return seq[:pos] + item + seq[pos:]
Now, that we created a module seqtools.py, let us learn how to use it.
Start a Python session in an interactive mode, and try the following.
>>>
>>>
>>>
’Thi
from seqtools import remove_at
s = "This is fun!"
remove_at(s, 3)
is fun!’
As you can see, we are using the ’from . . . import’ command to import a
specific name (remove at) from a module (seqtools). We have imported
only one definition out of two in seqtools.py.
In this particular situation we imported the name (remove at) into the current module, which is the top-level, interactive module. Once you import it, you
can use the imported name as if the name was created in the current module that
you are in.
One bad thing about the way it was just done is the following: if you already
had the same name in the current module, the old one will be lost. To avoid this
situation, there is another way of importing. Here again I am showing you an
interactive session using an interactive mode to illustrate how it is done, like this:
>>> import seqtools
>>> s = "This is fun!"
>>> seqtools.remove_at(s, 3)
’Thi is fun!’
As you can see here we are importing everything from the module seqtools. Note
that we don’t say ’import seqtools.py’, but rather ’import seqtools’
without the file extension (.py). Since there are two definitions in seqtools,
both are imported. If we import it this way, we must specify the module name
along with the name in the module if we want to use a name in the imported
module.
28
We use the dot (’.’) operator to separate the module name and a name in the
module, e.g., seqtools.insert at. Suppose there was already a definition
named insert at in the current module. Then, insert at alone would refer
to the one in the current module, and seqtools.insert at would refer to the
one from seqtools module.
Note that this works because we have the file seqtools.py located in the
same folder where the current python session was started at. If the module to be
imported is located in a different folder, we would have to do a little more work.
I will explain that a little later. Some programming languages use packages to
mean modules. I may use that term inadvertently in the future, and you will know
what I mean if I do.
The ’from . . . import’ version also has a wildcard option: We can use
’from modulename import *’ to mean import everything from the named
module, e.g.,
>>> from seqtools import *
This would import all the names from seqtools into the current module thus
overwriting any existing names if there are names that are the same in the current
module as the ones being imported from seqtools.
The dir(. . . ) function is useful. Once you import a module, you can use the
dir function to see all the functions defined in the module. For example, try the
following:
>>> import math
>>> dir(math)
Getting back to the case where the module that you want to import is located
elsewhere, what would we have to do if the module to be imported is located in
a different folder than the folder where the current python session was started at?
Well, if the module file is located in one of the folders that is included in the
current ’path’ for the python session, then you don’t need to do anything. If
not, we will have do some more work. So, how do we find out if the folder where
the module to be imported is located is in the path or not? Try this in your current
Python session:
>>> import sys
>>> sys.path
29
The value of sys.path is returned and it will show all the folders that are included in the path. If the folder where the module is located is in the the path,
you are done. If not, we have to include that folder in the path. Assuming that the
module to be imported is located in the folder: /Users/alee/python, this is
what we would do:
>>>
>>>
>>>
>>>
import os
os.path.join
## Just to see if join is available
<function join at 0x00A12F70>
sys.path
## Tried on a Mac machine (Unix)
## see init.py for Windows version
[’’,
’/Library/Frameworks/Python.framework/Versions/5.1.1/bin’,
’/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2
(some omitted)
u’/Users/alee/.ipython’]
>>> sys.path.append(os.path.join("/Users", "alee", "python"))
>>> sys.path
[’’,
’/Library/Frameworks/Python.framework/Versions/5.1.1/bin’,
’/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2
(some omitted)
u’/Users/alee/.ipython’,
’/Users/alee/python’]
Now, you can see that /Users/alee/python is included in the path, and
you should be able to import a module located in that folder, as you can see below:
>>> import seqtools
>>> s = "Thisisfun..."
>>> seqtools.remove_at(s, 3)
’Thiisfun...’
Note that remove at(s, 3) without seqtools. would not work. However,
if you imported it using ’from seqtools import *’ then remove at(s,
3) alone would work.
We can encapsulate all this stuff that I just did into a file named init.py so
that we can use it to add something into the path. You may then use it every time
30
you want to do something like this. If you are using Windows, create init.py
with the following as its contents. Of course, you will have to use the appropriate
names that are meaningful for your situation. (The one I used above works for
Mac OS X.):
import sys
import os
sys.path.append(os.path.join("C:\\", "alee", "python"))
With init.py available, just do the following right after you start a new
Python session:
>>> execfile("init.py")
and then continue with whatever you wanted to do in your current Python session.
17
Tuples
Remember that a string is an ordered sequence of characters? Also remember that
a list is an ordered sequence of values of any type? We said both strings and lists
and other things that behave like ordered sequences are called sequences. Also
remember that strings are immutable and lists are mutable?
A tuple, like a list, is a sequence of items of any type. Unlike lists, however,
tuples are immutable. The values of a tuple are indexed by integers as with the
values in a list or string. As you will see below, sequences (strings, lists, and
tuples) share some common operators.
Since a tuple is a data structure, think about four things you want to know
about a new data structure: (1) How do you create one? (2) How do you access an
element in it? (3) How do you modify an element in it in place if possible? Note
that tuples are immutable! (4) How do you destroy it when we don’t need it any
more? (don’t worry about destroying one).
Let us see some tuples and related functions that we can use to manipulate
tuples. Also think about where tuples would be useful in programming. Syntactically, a tuple is a comma-separated sequence of values.
a = 2, 3, 4, 6, 7, 10
a
# (2, 3, 4, 6, 7, 10)
Although it is not necessary, it is conventional to enclose tuples in parentheses:
31
b = (20, 30, 40, 60, 70, 100)
b
# (20, 30, 40, 60, 70, 100)
To create a tuple with a single element, we have to include the final comma. Without the comma, Python treats (5) as an integer in parentheses.
tup = (22,)
type(tup)
# <type ’tuple>
Another way to create a tuple is the built-in function tuple. With no argument,
it creates an empty tuple:
t = tuple()
t
# ()
If the argument is a sequence (string, list, or tuple), the result is a tuple with the
elements of the sequence:
t = tuple(’apple’)
t
# (’a’, ’p’, ’p’, ’l’, ’e’)
Most list operators work on tuples. The bracket operator indexes an element:
tup = (’a’, ’b’, ’c’, ’d’, ’e’)
tup[0]
# ’a’
And, the slice operator selects a range of elements:
tup[1:3]
# (’b’, ’c’)
As expected you can’t modify an element in place–immutable!
# tup[2] = ’K’
# this would produce an error. What kind of error?
Although we can’t replace an element in place, we can rebind the variable with a
new tuple:
tup = (’a’, ’b’, ’K’, ’d’, ’e’)
Tuple assignments: It is often useful to swap the values of two variables.
Tuple assignment is convenient. To swap the values of a and b we can do the
following:
32
a
b
a, b = b, a
a
b
The left side is a tuple of variables; the right side is a tuple of expressions. Each
value is assigned to its corresponding variable. All the expressions on the right
side are evaluated before any of the assignments. The number of variables on the
left and the number of values on the right have to be the same. More generally,
the right side can be any kind of sequence (string, list, or tuple). For example, to
split an email address into a user name and a domain, you could write:
addr = ’[email protected]’
uname, domain = addr.split(’@’)
Tuple as return values: Functions can return tuples as return values. For
example, we could write a function that swap two parameters like this:
def swap(x, y):
return y, x
Then, do the following to swap:
a, b = swap(a, b)
What would this definition of swap (called swapbad) do?
def swapbad(x, y):
x, y = y, x
If we call this function like this:
swapbad(a, b)
then changing x inside swapbad makes x refer to a different value, but it has no
effect on a in the main frame. Similarly, changing y has no effect on b.
This would do the right thing, but a function like this would be redundant. I am
using this example to illustrate local variables and their relationship with variables
outside a function, i.e., global variables.
33
def swapgood(x, y):
x, y = y, x
return x, y
a, b = swapgood(a, b)
Lists and tuples: zip is a built-in function that takes two or more sequences
and zips them into a list of tuples where each tuple contains one element from
each sequence. This example zips a string and a list:
s = ’abc’
t = [0, 1, 2]
zip(s,t)
# [(’a’, 0), (’b’, 1), (’c’, 2)]
You can use tuple assignment in a for loop to traverse a list of tuples:
t = [(’a’, 0), (’b’, 1), (’c’, 2)]
for letter, number in t:
print number, letter
Each time through the loop, Python selects the next tuple in the list and assigns
the elements to letter and number. Try it to see what output you get if it is not
obvious.
If you combine zip, for, and tuple assignment, you get a useful idiom for
traversing two (or more) sequences at the same time. For example, has match
takes two sequences, t1 and t2, and returns True if there is an index i such that
t1[i] == t2[i]:
def has_match(t1, t2):
for x, y in zip(t1, t2):
if x == y:
return True
return False
If you need to traverse the elements of a sequence and their indices, you can use
the built-in function enumerate. Try the following:
for index, element in enumerate(’abc’):
print index, element
34
18
Dictionaries
All of the compound data types that we have studied so far–strings, lists, and
tuples–are sequence types, which use integers as indices to access the values that
are contained in them. If you try to use any other type as an index, you get an
error.
A dictionary is also a compound data type. It is Python’s built-in mapping
type. It maps keys, which can be any immutable type, to values, which can be any
type, just like the values of a list or tuple.
Abstractly and conceptually, a dictionary is a sequence of key-value pairs.
For example, a phone book is a dictionary: name-number pairs, i.e., mapping of
names to phone numbers.
Remember we should know how to (1) create a new instance of this type, (2)
do write access, (3) do read access, and (4) destroy it when you are done using
it? Well, we will do (1), (2), and (3) by writing an example that maps English
words to Spanish equivalents. For this dictionary, the indices are strings. As usual
we won’t worry about destroying one since it will be done automatically by the
Python system when you stop using the data structure that you created. It is called
garbage collection. We are talking about destroying the entire dictionary instance
itself, not an entry in the dictionary. For individual entries, we will be able to
remove a value from a dictionary which will then be destroyed by the language
system if it is not shared by any other data structure.
One way to create a dictionary is to start with an empty dictionary and start
adding elements, i.e., pairs. Here is how you do it. I am creating a dictionary
named ’e2s’ (English to Spanish) initialized with an empty dictionary.
e2s = {}
This is how you put a key-value pair, i.e., ’one’ as the key and ’uno’ as the
value of the pair:
e2s[’one’] = ’uno’
One more with the two-dos pair:
e2s[’two’] = ’dos’
This is how you retrieve the value associated with a key:
e2s[’one’]
e2s[’one’]
# Just to do a read access
# If you want it to be printed on the screen
35
This will display the contents of the entire dictionary so far:
e2s
The elements of a dictionary appear in a comma-separated list as you can see in
the printed result above–you are using an interpreter to execute these lines, aren’t
you?
Each entry (pair) contains an index and a value separated by a colon. In a
dictionary, the indices are called keys, so the elements are called key-value pairs.
Dictionaries are also called association lists, the original term used in the Lisp
programming language for the same concept.
You can create one dictionary with some initial pairs explicitly like this:
e2s = {’one’: ’uno’, ’two’: ’dos’, ’three’: ’tres’}
Order of the pairs in a dictionary is not important. You can use a list of tuples to
initialize a new dictionary:
t = [(’a’, 0), (’b’, 1), (’c’, 2)]
d = dict(t)
d
# {’a’: 0, ’b’: 1, ’c’: 1}
Combining dict and zip yields a concise way to create a dictionary:
d = dict(zip(’abc’, range(3)))
d
# {’a’: 0, ’c’: 2, ’b’: 1}
Here is another dictionary:
inventory = {’apples’: 430, ’bananas’: 312, ’oranges’: 525, ’pears’: 2
inventory
Deleting an entry (pair) from a dictionary:
del inventory[’pears’]
inventory
Updating the value of a pair:
inventory[’apples’] = inventory[’apples’] + 10
inventory
Updating the value of a pair once more:
36
inventory[’oranges’] = 0
inventory
Note: index (key) must be unique in a dictionary, i.e., no two keys can be identical
although values do not need to be unique. This is like a function in math! Length
of a dictionary:
len(inventory)
Retrieve all the keys in a dictionary into a list:
e2s.keys()
Retrieve all the values in a dictionary into a list:
e2s.values()
Retrieve all the pairs in a dictionary into a list:
e2s.items()
Check if a key is contained in a dictionary
e2s.has_key(’one’)
e2s.has_key(’deux’)
If you want to iterate through the pairs and add 10 to each:
for key in inventory.keys():
inventory[key] = inventory[key] + 10
inventory.values()
If you want to iterate through the pairs and add 10 to each this way this time for
key in e2s.keys():
e2s[key] = e2s[key] + str(10)
e2s.values()
Combining items, tuple assignment, and for, you get the idiom for traversing
the keys and values of a dictionary. Try the following:
for key, val in e2s.items():
print val, key
37
It is common to use tuples as keys in dictionaries (primarily because you can’t use
lists). For example, pbook (a phone book dictionary) might map from last-name,
first-name pairs to phone numbers.
first = ’john’
last = ’doe’
number = 9096070410
pbook = {}
pbook[last,first] = number
pbook[’jones’,’amy’] = 2133223333
The expression in the brackets is a tuple. We could use tuple assignment to traverse this pbook.
for last, first in pbook:
print first, last, pbook[last,first]
This loop traverses the keys in pbook, which are tuples. It assigns the elements
of each tuple to last and first, then prints the name and the corresponding
phone number.
Using an alias vs. a copy: Let us create another map first:
opposites = {’up’: ’down’, ’right’: ’wrong’, ’true’: ’false’}
This assignment creates an alias where both names reference the same identical
dictionary object.
alias = opposites
The ’copy’ command below creates a distinct copy of the original. There are two
copies now with different names: one called opposites and another called cp.
cp = opposites.copy()
Exercise 1. We can write a function that counts the number of occurrences of
a letter in a string. Or, a more general version of this problem would be to form a
histogram of the letters in the string, that is, how many times each letter appears.
Such a histogram might be useful for compressing a text file. Because different
letters appear with different frequencies, we can compress a file by using shorter
codes for common letters and longer codes for letters that appear less frequently.
Dictionaries provide an elegant way to generate a histogram. Here is a simple
program that would do that:
38
>>> letter_counts = {}
>>> for letter in "Mississippi":
...
letter_counts[letter] = letter_counts.get(letter, 0) + 1
...
>>> letter_counts
{’M’: 1, ’s’: 4, ’p’: 2, ’i’: 4}
We start with an empty dictionary. For each letter in the string, we find the current
count (possibly zero) and increment it. At the end, the dictionary contains pairs of
letters and their frequencies. It might be more appealing to display the histogram
in alphabetical order. We can do that with the items and sort methods:
>>> letter_items = letter_counts.items()
>>> letter_items.sort()
>>> letter_items
[(’M’, 1), (’i’, 4), (’p’, 2), (’s’, 4)]
You have seen the items method before, but sort is one of the first methods
you have encountered that applies to lists. There are several other list methods,
including append, extend, and reverse. Consult the Python documentation
for details on these methods and some additional ones.
19
Files
We have now seen enough basic data structures that you will need in Python to
write some interesting programs. We will now study how to deal with data in a
file.
While a program is running, its data is in memory. When the program ends,
or the computer shuts down, data in memory disappears. One of the easiest ways
of storing the data permanently is to save it in a file. Files are usually stored on a
hard drive, USB drive, CD, etc.
When there are a large number of files, they are often organized into directories
(also called folders) in the file system of your computer. Each file is identified by
a unique name, or a combination of a file name and a directory name.
Working with files is a lot like working with notebooks. To use a notebook,
you have to open it. When you are done, you have to close it. While the notebook
is open, you can either write in it or read from it. In either case, you know where
you are in the notebook. Most of the time, you read the whole notebook in its
natural order, but you can also skip around.
39
All of this applies to files as well. To open a file, you specify its name and
indicate whether you want to read or write. Opening a file creates a file object. In
this example, the variable f refers to the new file object.
f = open("test.dat", "w")
f
# <open file ’test.dat’, mode ’w’ at 0x2aaaaab80cd8>
The open function takes two arguments: the first is the name of the file, and the
second is the mode. Mode "w" means that we are opening the file for writing.
If there is no file named test.dat, it will be created when you are accessing it
with the ’w’ mode. If there already is one, it will be replaced by the file we are
writing.
When we print the file object, we see the name of the file, the mode, and the
location of the object. To put data in the file we invoke the write method on the
file object:
f.write("Now is the time")
f.write("to close the file")
Closing the file tells the system that we are done writing and makes the file available for reading:
f.close()
Now, we can open the file again, this time for reading, and read the contents into
a string. This time, the mode argument is "r" for reading:
f = open("test.dat", "r")
If we try to open a file with the read mode that does not exist, we get an error:
#f = open("test.cat","r")
# IOError: [Errno 2] No such file or directory: ’test.cat’
f = open("test.dat","r")
Not surprisingly, the read method reads data from the file. With no arguments, it
reads the entire contents of the file:
text = f.read()
text
Now is the timeto close the file
40
read can also take an argument that indicates how many characters to read:
f = open("test.dat","r")
f.read(5)
Now i
If not enough characters are left in the file, read returns the remaining characters.
When we get to the end of the file, read returns the empty string:
f.read(1000006)
s the timeto close the file
f.read()
<Nothing this time>
Writing a function that copies a file: It reads and writes up to fifty characters at
a time. The first argument is the name of the original file; the second is the name
of the new file:
def copyFile(oldFile, newFile):
f1 = open(oldFile, "r")
f2 = open(newFile, "w")
while True:
# infinite loop
text = f1.read(50)
if text == "":
break
# break out of the current loop
f2.write(text)
f1.close()
f2.close()
return
The break statement is new. Executing it breaks out of the current loop; the flow
of execution moves to the first statement after the loop. In this example, the while
loop is infinite because the value True is always true. The only way to get out of
the loop is to execute break, which happens when text is the empty string, which
happens when we get to the end of the file.
19.1
Text files
A text file is a file that contains printable characters and whitespace, organized
into lines separated by newline characters. Since Python is specifically designed
to process text files, it provides methods that make the job easy.
41
To demonstrate, we will create a text file with three lines of text separated by
newlines:
f = open("test1.dat", "w")
f.write("line one\nline two\nline three\n")
f.close()
The readline() method reads all the characters up to and including the next
newline character (’\n’):
f = open("test1.dat", "r")
f.readline()
readlines() returns all of the remaining lines as a list of strings:
f.readlines()
In this case, the output is in a list format, which means that the strings appear with
quotation marks and the newline character appears as the escape sequence \n.
At the end of the file, readline returns the empty string and readlines
returns the empty list:
>>> f.readline()
>>> f.readlines()
[]
Exercise 1: The following is an example of a line-processing program. filterFile
makes a copy of oldFile, omitting any lines that begin with a #:
def filterFile(oldFile, newFile):
f1 = open(oldFile, "r")
f2 = open(newFile, "w")
while True:
text = f1.readline()
if text == "":
break
if text[0] == ’#’:
continue
f2.write(text)
f1.close()
f2.close()
return
42
The continue statement ends the current iteration of the loop, but continues
looping. The flow of execution moves to the top of the loop, checks the condition,
and proceeds accordingly. Thus, if text is the empty string, the loop exits. If the
first character of text is a hash mark, the flow of execution goes to the top of the
loop. Only if both conditions fail do we copy text into the new file.
19.2
Exception handling
Whenever a runtime error occurs, it creates an exception. Usually, the program
stops and Python prints an error message. For example, dividing by zero creates
an exception:
>>> 55/0
ZeroDivisionError: integer division or modulo
So does accessing a nonexistent list item:
>>> a = []
>>> a[5]
IndexError: list index out of range
Or, accessing a key that isn’t in the dictionary:
>>> b = {}
>>> b[’what’]
KeyError: what
In each case, the error message has two parts: (1) the type of error before the
colon, and (2) specifics about the error after the colon. Normally, Python also
prints a traceback of where the program was at the time of error, but we have
omitted that from the examples.
Sometimes, we want to execute an operation that could cause an exception,
but we don’t want the program to stop. We can handle the exception using the
try and except statements. For example, we might prompt the user for the
name of a file and then try to open it. If the file doesn’t exist, we don’t want the
program to crash; we want to handle the exception. Here is one way to handle the
situation:
filename = raw_input(’Enter a file name: ’)
try:
43
f = open (filename, "r")
except:
print ’There is no file named’, filename
The try statement executes the statements in the first block. If no exceptions
occur, it ignores the except statement. If any exception occurs, it executes the
statements in the except branch and then continues.
We can encapsulate this capability in a function: exists takes a filename
and returns True if the file exists, False if it doesn’t:
def exists(filename):
try:
f = open(filename)
f.close()
return True
except:
return False
20
More Python
The online tutorial that I wrote can be found at http://www.cmc.edu/pages/faculty/alee/
python/. This tutorial is a subset of the online version which covers some additional topics: classes, objects, and arrays.
21
NumPy, SciPy, etc.
The online tutorial at http://www.cmc.edu/pages/faculty/alee/python/
also discusses these topics briefly, which are useful for scientific computing.
You can find additional information on these topics at http://fperez.org/py4science/
starter kit.html.
44