Python3 Notes
Python3 Notes
>>> numbers.sort()
The function does not
return the sorted list.
>>> print(numbers)
It sorts the
[1, 4, 5, 7]
list itself.
Numerical order.
215
Similarly, the sort() method doesn’t return a sorted list but silently sorts
the list internally.
215
Other methods on lists: sort()
>>> greek.sort()
>>> print(greek)
Alphabetical order
of the words.
216
More or less any type can be sorted. Text sorting carries all the cautions
about the complexities of collation that we covered under comparisons.
216
Other methods on lists: insert()
0 1 2
>>> greek
0 1
Displaced 217
The append() method sticks an item on the end of a list. If you want to
insert an item elsewhere in the list we have the insert() method.
The insert() method takes two arguments:
The first is the item to be inserted.
The second is in index where it should go. This does not replace the original
item but rather “shuffles up” all the items beyond it by one place to make
room.
217
Other methods on lists: remove()
>>> print(numbers)
[7, 4, 7, 2, 5, 4]
218
Other methods on lists: remove()
>>> print(numbers)
[7, 4, 7, 2, 5, 4]
There are two instances of 4.
>>> numbers.remove(4)
>>> print(numbers)
[7, 7, 2, 5, 4]
If the value appears more than once in a list then only the first instance is
removed.
Trying to remove something that isn’t there will lead to an error.
219
What methods are there?
>>> help(numbers)
class list(object)
...
| append(...)
| L.append(object) -- append object to end
...
That’s a lot of methods, and it’s only some of them. How can we know all of
them?
You can always ask for help on any Python object and you will be told all
about the methods it possesses. It is a very formal documentation but the
information is there.
Incidentally, Python uses a program to paginate its help output. press the
space bar to move on one page, “B” to move back a page and “Q” to quit.
220
Help on a single method
>>> help(numbers.append)
append(...)
L.append(object) -- append object to end
221
You can also get help on a single method which is often simpler to deal with.
221
Sorting a list redux
>>> print(greek)
222
We noted that the sort() method sorts the list itself. Experience shows that
sorting is one of those operations where people want a sorted copy of the
list quite often.
222
Sorting a list redux: “sorted()”
223
Adding to a list redux: “+”
>>> primes
224
The list method we saw first appended a single item to the end of a list.
What happens if we want to add a whole list of items at the end?
In this regard, lists are like strings. The “+” operator performs concatenation
and creates a new list which is one concatenated after the other.
224
Concatenation
Create a new list
Augmented assignment
225
We can use this to update a list in place. Note that the augmented
assignment operator “+=” also works and is more than syntactic sugar this
time. It is actually more efficient than the long hand version because it
updates the list in place rather than creating a new one.
225
Creating lists from text ― 1
str 5 H e l l o str 1 l
str 1 l
str 1 o
226
226
Creating lists from text ― 2
Built in method
>>> 'Hello, world!'.split()
str 13 H e l l o , ␣ w o r l d !
list
2 str 6 H e l l o ,
str 6 w o r l d !
227
The string type has methods of its own. One of these is split() which returns
a list of the components of the string as separated by white space.
The split() method can take an argument identifying other characters to
split on. If you want to get into more complex splitting of text we recommend
you investigate regular expressions or format-specific techniques (e.g. for
comma-separated values.
227
Progress
“Methods” object.method(arguments)
append(item)
reverse()
sort()
insert(index,item)
remove(item)
Help help(object)
help(object.method)
Sorting list.sort()
sorted(list)
Concatenation
+ [1,2,3] + [4,5,6] 228
+= primes += [29, 31]
228
Exercise 12
5 minutes
229
229
Is an item in a list? ― 1
✗ x must be in the
list before it can
be removed
230
Recall that a list’s remove() method will give an error if the value to be
removed is not in the list to start with.
We need to be able to test for whether an item is in a list or not.
230
Is an item in a list? ― 2
>>> odds = [3, 5, 7, 9]
>>> 2 in odds
False
>>> 3 in odds
True
True 231
Python uses the keyword “in” for this purpose. It can be used on its own or
as part of “not in”. “value in list” evaluates to a boolean: True or
False.
231
Precedence
First
x not in y x in y
These operators fit naturally into the order of precedence. While Python
does contain other operators that belong in this list, we will not be meeting
them in this introductory course.
232
Safe removal
if number in numbers :
numbers.remove(number)
What’s the
difference?
numbers.remove(number)
233
We now have a safe way to remove values from lists, testing before we
remove them.
Quick question: What’s the difference between the two code snippets in the
slide?
233
Working through a list ― 1
The
cat
sat
on
the
mat.
234
234
Working through a list ― 2
203
235
235
Working through a list ― 3
[4, 7, -2, 9, 1]
236
Finally, we might want to convert one list into another where each item in the
output list is the result of some operation on the corresponding item in the
input list.
236
The “for loop” ― 1
Python has a construct precisely for stepping through the elements of a list.
This is the third and final construct we will meet in this course. We have
already seen if… and while… in this course. Now we meet for….
This a looping construct, but rather than repeat while a test evaluates to
True, it loops once for each item in a list. Furthermore it defines a name
which it attaches to one item after another in the list as it repeats the loop.
237
The “for loop” ― 2
keywords
238
238
The “for loop” ― 3
␣␣␣␣print(word)
239
The “for loop” for printing
␣␣␣␣print(word)
for1.py
240
$ python3 for1.py
The
cat
sat
on
the
mat.
$
240
The “for loop” for adding
241
print(sum) Results after the loop
$ python3 for2.py
203
$
241
The “for loop” for creating a new list
242
print(squares) Results after the loop
Our third example made a new list from the elements of an old list. For
example, we might want to take a list of numbers and produce the list of
their squares.
In this case the usual process is that rather than have an accumulator with
an initial value we start with an empty list and, as we loop through the input
values, we append() the corresponding output values.
$ python3 for3.py
[16, 49, 4, 81, 1]
$
242
The loop variable persists!
numbers = [4, 7, -2, 9, 1]
squares = [ ]
243
243
“for loop hygeine”
numbers = [4, 7, -2, 9, 1]
squares = [ ]
␣␣␣␣squares.append(number**2)
244
It is good practice to delete the name after we have finished using it. So we
will follow our for… loops with a del statement.
This is not required by the Python language but we recommend it as good
practice.
244
Progress
245
Exercise 13
numbers = [0, 1, 2, 3, 4, 5]
sum = 0
sum_so_far = []
print(sum_so_far) 5 minutes
246
246
“Sort-of-lists”
Python “magic”:
247
We have seen already that every Python type comes with a function that
attempts to convert other Python objects into that type. So the list type
has a list() function.
However, with lists Python goes further and puts a lot of work into making
this transparent and convenient. In very many cases in Python you can drop
an object into a list construct and it will act as if it was a list, and a
convenient list at that.
247
Strings as lists
Recall:
$ python for4.py
H
e
l
l
o
$
248
Creating lists of numbers
Built in to Python:
range(start,limit)
There are other Python objects which, while not lists exactly, can be treated
like lists in a for… loop. A very important case is a “range” object.
Note that the range defined by 3 and 8 starts at 3 but ends one short. This is
part of the whole “count from zero” business.
249
ranges of numbers
range(0,5)
[0, 1, 2, 3, 4]
Strictly speaking a range is not a list. But it is close enough to a list that
when you drop it into a for… loop, which is its most common use by far,
then it behaves like the list of numbers.
250
Why not just a list?
Inefficient to make a
huge list just for this
251
251
Ranges of numbers again
via list()
range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Start at 0
range(3, 10) [3, 4, 5, 6, 7, 8, 9]
252
252
Indices of lists
>>> primes = [ 2, 3, 5, 7, 11, 13, 17, 19]
>>> len(primes)
>>> list(range(8))
0 1 2 3 4 5 6 7
Now that we have the range object we can move on to one of the most
important uses of it.
So far we have used a for… loop to step through the values in a list. From
time to time it is important to be able to step through the valid indices of the
list.
Observe that if we apply the range() function to a single number which is
the length of a list then we get a list of the valid indices for that list.
253
Direct value or via the index?
primes = [2, 3, 5, 7, 11, 13, 17, 19]
254
254
Working with two lists: “dot product”
∙ × × ×
list2 = [ 0.2, 0.5, 0.6]
255
255
Working with two lists: indices
0 1 2
list1 = [0.3, 0.0, 0.4]
indices
list2 = [0.2, 0.5, 0.6]
sum = 0.0
sum += list1[index]*list2[index]
Dealing with
print(sum)
values from
both lists at
the same time.256
We can approach this problem by running through the valid indices and
looking up the corresponding values from each list in the body of the for…
loop.
256
Iterables
range(from,to,stride)
“Iterable”
257
The range object is one of the most commonly met examples of an iterable,
something that isn’t a list but is “close enough”.
257
A little more about iterables ― 1
>>> greek = ['alpha', 'beta', 'gamma', 'delta']
'beta'
str 5 d e l t a
258
We will look a little more closely at iterables so that we can recognise them
when we meet them later.
If we start with a list then we can turn it into an iterable with the iter()
function.
An iterable ceated from a list is essentially the same as the list with a note of
how far through the list we have read. This reference starts at zero,
obviously.
Python provides a next() function which can act on any iterable which
returns the next value (or the first if we’ve not started) and increments this
internal counter.
258
A little more about iterables ― 2
iter
>>> next(greek_i) str 5 a l p h a
4
'gamma'
✗ str 4 b e t a
>>> next(greek_i)
str 5 g a m m a
'delta'
str 5 d e l t a
>>> next(greek_i)
Note that next() complains vigorously if we try to run off the end. For this
course, where these errors are all fatal it means that we can’t use next()
directly. we don’t need to; we have the for… loop which handles the error
for us.
259
Progress
Non-lists as lists for letter in 'Hello':
...
range() range(limit)
range(start,limit)
range(start,limit,step)
range(3,7) [3,4,5,6]
260
Parallel lists
260
Exercise 14
Complete exercise14.py
This exercise develops the Python to calculate the square of the distance
between two 3D points. We could use our square root Python from earlier to
calculate the distance itself but we will meet the “real” square root function
later in this course so we’ll hold back from that for now.
261
List “slices”
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29] The list
>>> primes[3]
7 An item
>>> primes[3:9]
[7, 11, 13, 17, 19, 23] Part of the list
262
262
Slices ― 1
from
Up to but not
to
including…
primes[3:9]
3 9
The last index is omitted as part of the “count from zero” thing.
263
Slices ― 2
primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
We can omit either or both of the numbers. Missing the first number means
“from the start” and missing the second means “right up to the end”.
264
Slices ― 3
primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
primes[3:9:3] [7, 17 ]
265
We can also add a second colon which is followed by a stride, just as with
range().
265
Copies and slices ― 1
list
str 1 a
letters 3
str 1 b
alphabet
str 1 c
266
266
Copies and slices ― 2
>>> letters[0] = 'A'
>>> print(alphabet)
list
str 1 A
letters 3
str 1 b
alphabet
str 1 c
267
Changing an item in the list via one name shows up via the other name.
267
Copies and slices ― 3
>>> letters = ['a','b','c'] Slices are
copies.
>>> alphabet = letters[:]
letters alphabet
list list
str 1 a
3 3
str 1 b
str 1 c 268
268
Copies and slices ― 4
>>> letters[0] = 'A' Slices are
copies.
>>> print(alphabet)
['a', 'b', 'c'] alphabet
letters
list list
str 1 A str 1 a
3 3
str 1 b
str 1 c 269
So changes in one don’t show in the other because they are not the same
list.
269
Progress
Slices
End-limit excluded
items[from:to] items[from:to:stride]
items[:to] items[:to:stride]
items[from:] items[from::stride]
270
Exercise 15
foo = [4, 6, 2, 7, 3, 1, 9, 4, 2, 7, 4, 6, 0, 2]
bar = foo[3:12:3]
bar[2] += foo[4]
foo[0] = bar[1]
print(bar)
5 minutes
271
271
Files
Input Output
.txt
.dat
.csv
Reading Writing
272
Now we will look at something completely different that will turn out to be
just like a list: Files.
We want our Python scripts to be able to read in and write out files of text or
data.
We will consider reading files first and writing them second.
272
Reading a text file
273
Opening a text file
Python function
File name
Read-only [text]
>>> book = open('treasure.txt', 'r') “mode”
Read-only is
the default
book = open('treasure.txt' ) 274
274
Reading from a file object
File object
>>> line1 = next(book)
Now that we have this hook into the file itself, how do we read the data from
it?
File objects are iterators, so we can apply the next() function to them to get
the next line, starting with the first.
275
File object are iterable
>>> line2 = next(book)
Second line of file
>>> line2
'\n' A blank line
Note that a “blank” line actually contains the end of line character. It has
length 1, and is not an empty string, length 0.
276
Closing the file
277
When we are done reading the data we need to signal that we are done with
it. Python file objects have a close() method built into them which does
precisely this.
277
The file object ― 1
<_io.TextIOWrapper
name='treasure.txt' File name
encoding='UTF-8'>
Character encoding:
how to represent
letters as numbers.
278
278
The file object ― 2
File name
Text encoding
TREASURE ISLAND↵
“offset”: how far into ↵
the file we have read PART ONE↵
☞ ↵
The Old Buccaneer↵
↵
Pointer to the file
on the file system
279
The Python file object contains a lot of different bits of information. There
are also lots of different sorts of file object, but we are glossing over that in
this introductory course.
What they share is a reference into the operating system’s file system that
identifies the specific file and acts as the declaration to the operating system
that the Python process is using the file.
They also share an “offset”. This is a number that identifies how far into the
file the program has read so far. The next() function reads from the offset
to the next new line and increases the offset to be the distance into the file
of the new line character.
The file object also records the name it was opened from and the text
encoding it is using to convert bytes in the file to characters in the program.
279
Reading through a file
Treat it like a list and
it will behave like a list
>>> print(lines)
280
Given that a file is an iterable, we can smply convert it into a list and we get
the list of lines.
280
Reading a file moves the offset
>>> book = open('treasure.txt', 'r')
!
>>> lines_a = list(book)
>>> print(lines_a)
… Huge output
>>> print(lines_b)
Note, however, that the act of reading the file to get the lines reads through
the file, so doing it twice gives an empty result second time round.
281
Reading a file moves the offset
>>> book = open('treasure.txt', 'r')
File object starts with offset at start.
>>> lines_a = list(book)
Operation reads entire file from offset.
>>> print(lines_a)
Offset changed to end of file.
…
recall that the reading starts at the offset and reads forwards — to the end of
the file in this example. It also moves the offset to what was last read. So
the offset is changed to refer to the end of the file.
282
Resetting the offset
>>> book = open('treasure.txt', 'r')
>>> print(lines_a)
We can deliberately change the offset. For text files with lines of different
lengths this can be more complex that you would imagine. The only safe
value to change the offset to is zero which takes us back to the start of the
file.
283
Older file object methods
>>> book = open('treasure.txt', 'r')
>>> book.readline()
'TREASURE ISLAND\n'
>>> book.readlines()
284
There are other ways to read in the data. Earlier versions of Python only
supported a couple of built-in methods. You may still see these in other
people’s scripts but we don’ recommend writing them in scripts that you
create.
284
Typical way to process a file
book = open('treasure.txt', 'r')
285
Being able to read a single line of a file is all very well. Converting an entire
book into a list of its lines might prove to be unwieldy.
What is the typical way to do it?
Given that files can be treated like lists the easiest way to process each line
of a file is with a for… loop.
285
Example: lines in a file
book = open('treasure.txt', 'r')
286
book.close()
For example, we could just increment a counter for each line to count the
number of lines.
286
Example: characters in a file
book = open('treasure.txt', 'r')
n_chars = 0
n_chars += len(line)
287
book.close()
We could measure the length of the line and increment the counter by the
number of characters in the line to count the total number of characters in
the file.
287
Progress
Reading files
288
Exercise 16
5 minutes
289
289
Writing files
Enough of reading files Robert Louis Stephenson has prepared for us. Let’s
write our own.
This is again a three phase process. We will open a file for writing, write to it
and then close it.
290
Opening a text file for writing
Open for
writing [text]
Opening a file for writing is the same as opening it for reading except that
the mode is 'w' for writing.
If the file already exists then this overwrites it. The file gets truncated to zero
bytes long because you haven’t written to it yet.
291
Writing to a file object ― 1
File object
Method built in
to file object
>>> output.write(line1)
292
A writeable file object has a method write() which takes a text string
(typically but not necessarily a line) and writes it to the file.
292
Writing to a file object ― 2
>>> output.write('be')
Doesn’t have
to be whole lines
>>> output.write('ta\n')
>>> output.write('gamma\ndelta\n')
293
Closing the file object
294
294
Importance of closing
!
Data “flushed” to disc on closure.
write “flush”
Closing files is even more important for written files that read ones.
It is only when a file is closed that the data you have written to the Python
file object is definitely sent to the operating system’s file. This is a process
called “flushing the file to disc”.
Writing to disc is slow by computing standards so, for efficiency reasons,
systems like Python tend to wait until they have at least a certain amount of
data for a file before they flush it to disc. If your program exists before
flushing then the data may be lost. Closing a file signals that there will be no
more data coming for it so Python flushes whatever it has in hand to the disc
as part of the closure process.
295
Importance of closing promptly !
Files locked for other access
open ['w']
✗ open ['r']
296
(More a problem for Windows than Unix)
There’s more to it than just flushing, though. Holding a file open signals to
the underlying computer operating system that you have an interest in the
file. How the operating system reacts to this varies from system to system,
but Microsoft Windows™ will lock a file so that if you have it open for writing
nobody else can open it for reading, even if you don’t plan to write any more
to it than you have already.
296
Progress
Writing files
Flushing book.flush()
297
297
Exercise 17
5 minutes
298
298
Functions
y = f(x)
299
299
Functions we have met
input(prompt) bool(thing)
len(thing) float(thing)
print(line) list(thing)
This is the complete set of Python functions that we have met to date.
Actually it’s surprising how few there are, not how many. Python’s
philosophy leads to functions that only make sense for a particular sort of
object being methods of that object, not free-standing functions.
We are now going to write our own functions.
300
Why write our own functions?
Easier to …
… read
… write
… test
… fix
… improve
… add to
“Structured
programming”
… develop
301
Why?
Moving our scripts’ functionality into functions and then calling those
functions is going to make everything better. This is the first step towards
“structured programming” which is where programming goes when your
scripts get too long to write in one go without really thinking about it.
301
Defining a function
302
302
A function to define: total()
Sum a list
[1, 2, 3] 6
[7, -4, 1, 6, 0] 10
[] 0 “Edge case”
303
To give ourselves a simple but concrete example to keep in mind we will set
ourselves the challenge of writing a function that sums the elements of a list.
This may sound trivial but immediately raises some interesting cases that
need to be considered.
What is the sum of an empty list? Zero? Is that an integer zero or a floating
point zero? (Or a complex zero?)
We will say it should sum to an integer zero.
303
Defining a Python function ― 1
define a function called …
name of function
inputs
def total( … ): colon
304
304
Defining a Python function ― 2
305
305
Defining a Python function ― 3
306
306
Defining a Python function ― 4
def total(numbers):
sum_so_far = 0
307
307
Defining a Python function ― 4
def total(numbers):
These variables exist only
sum_so_far = 0
within the function’s body.
for number in numbers:
sum_so_far += number
308
The numbers name we specified on the def line is visible to Python only
within the function definition. Similarly any names that get created within the
function body exist only within that function body and will not be visible
outside. Nor will they clash with any other uses of those names outside the
function body.
In our example code the name “numbers” is defined in the def line, the
“sum_so_far” name is defined explicitly in the function body and the
“number” name is defined by the for… loop as its loop variable.
None of these interact with the Python outside the function definition.
308
Defining a Python function ― 5
def total(numbers):
sum_so_far = 0
Finally we need to specify exactly what value the function is going to return.
We do this with another Python keyword, “return”. The value that follows
the return keyword is the value returned by the function.
When Python reaches the return statement in a function definition it hands
back the value and ends the execution of the function body itself.
309
Defining a Python function ― 6
sum_so_far = 0
return sum_so_far
Unindented
after this 310
310
Defining a Python function ― 7
311
Note that because of this isolation of names we don’t have to worry about
not using names that are used elsewhere in the script.
Also, as part of this isolation all these function-internal names are
automatically cleared when the function finishes. We do not need to worry
about deleting them.
311
Using a Python function ― 1
def total(numbers):
sum_so_far = 0
return sum_so_far
print(total([1, 2, 3]))
The list we
want to add up
312
We use this function we have defined in exactly the same way as we would
use a function provided by Python.
312
Using a Python function ― 2
def total(numbers):
sum_so_far = 0
return sum_so_far
print(total([1, 2, 3]))
The function we
have just written
313
313
Using a Python function ― 3
def total(numbers):
sum_so_far = 0
return sum_so_far
print(total([1, 2, 3]))
Printing out
the answer
314
314
Using a Python function ― 4
def total(numbers):
nb: Unix prompt
sum_so_far = 0
$ python3 total1.py
for number in numbers:
sum_so_far += number 6
return sum_so_far
print(total([1, 2, 3]))
total1.py
315
The file total1.py in your home directories contains exactly the code you see
here.
315
Using a Python function ― 5
def total(numbers):
sum_so_far = 0
$ python3 total2.py
for number in numbers:
sum_so_far += number 6
10
return sum_so_far 0
print(total([1, 2, 3]))
print(total([7,-4,1,6,0])) Use the function
multiple times
print(total([]))
total2.py
316
316
Progress
Functions
“Structured programming”
317
317
Exercise 18
5 minutes
318
318
Reminder about indices
def total(numbers):
sum_so_far = 0
for number in numbers:
sum_so_far += number total2.py
return sum_so_far
Equivalent
def total(numbers):
sum_so_far = 0
for index in range(len(numbers)):
sum_so_far += numbers[index] total3.py
return sum_so_far
319
Let’s quickly remind ourselves about how we can uses indices for lists rather
than values from lists directly.
We found this particularly useful when we were traversing more than one list
at once.
319
Example of multiple inputs
Want a function to add two lists of the same length term-by-term:
Two inputs
320
So how do we build functions that take in more than one input at once?
320
Functions with multiple inputs
Multiple inputs are
separated by commas
def add_lists(a_list, b_list):
sum_list = []
sum_list.append(sum)
return sum_list
321
The Python syntax for multiple inputs is much the same as it is for a
mathemtical function: we separate the inputs by commas.
321
Functions with multiple inputs
We have
two lists…
def add_lists(a_list, b_list):
sum_list.append(sum)
return sum_list
322
Note that functions that take in more than one list typically need to use
indices.
322
Multiple outputs
Write a function to find minimum and maximum value in a list
[1, 2, 3] 1 & 3
[3, 7, 4, 1, 7] 1 & 7
Two outputs
323
323
Finding just the minimum
def min_list(a_list): minlist.py
for a in a_list :
if a < min_so_far:
min_so_far = a
324
324
Finding just the maximum
def max_list(a_list): maxlist.py
max_so_far = a_list[0]
for a in a_list :
325
325
Finding both
def minmax_list(a_list):
min_so_far = a_list[0]
max_so_far = a_list[0]
for a in a_list :
if a < min_so_far:
min_so_far = a
if a > max_so_far:
max_so_far = a
326
return what? This is the real question
326
Returning both
def minmax_list(a_list): minmaxlist.py
min_so_far = a_list[0]
max_so_far = a_list[0]
for a in a_list :
if a < min_so_far:
min_so_far = a
if a > max_so_far:
max_so_far = a
327
return min_so_far, max_so_far A pair of values
Two return two values we simply put them both after the return statement
separated by a comma, just as we would have done with the inputs.
327
“Tuples”
Commas
(min_value, max_value)
328
328
Using tuples to return values
def … In the function definition
329
329
Using tuples to attach names
alpha = 12
(alpha , beta) = ( 12, 56 )
beta = 56
330
330
Swapping values
>>> alpha = 12
>>> beta = 56
>>> print(alpha)
56
>>> print(beta)
12 331
Because the entire right hand side is evaluated before the left hand side is
considered this lets us use tuples for some particularly useful tricks. perhaps
the most useful is swapping two values.
331
Assignment works right to left
alpha = 12
beta = 56
332
The values associated with the names are evaluated first. Then the names
get reattached to those values, regardless of what names they might have
had before.
332
Recall this “gotcha”:
!
a = 10
b = 7
b = a - b b = a - b b ≠ 10 - 7 = 3
= 17 - 7
= 10
333
333
Again: assignment works right to left
a = 10
b = 7
(a, b) = (a + b, a - b)
334
334
Progress
“Tuples” (a, b, c)
335
335
Exercise 19
5 minutes
336
336
One object or many?
two objects
“a pair of objects”
one object
337
Tuples tend to blur the boundary between multiple objects and a single
object.
337
Tuples as single objects ― 1
>>> x = 20
>>> type(x)
<class 'int'>
>>> y = 3.14
>>> type(y)
<class 'float'>
338
Tuples as single objects ― 2
>>> print(z)
(20, 3.14)
>>> print(w)
(20, 3.14)
339
339
Splitting up a tuple
>>> print(z)
(20, 3.14)
>>> print(a)
20
>>> print(b)
3.14
340
But a tuple is fundamentally made of separable pieces and can be split up.
340
How tuples are like lists
3.14
341
How tuples are not like lists
>>> z[0] = 10
342
They have one critical difference, though. A tuple is “immutable”. You cannot
change individual elements in a tuple. You get the whole tuple and you can’t
fiddle with it.
342
Progress
Immutability thing[0] = 10 ✗
343
343
Functions we have written so far
total(list)
squares(N)
add_lists(list1,list2)
minmax_list(list)
344
344
Reusing functions within a script
def square(limit):
... One definition
...
squares_a = square(34)
...
squares_b = squares(56)
...
Easy! 345
345
Reusing functions between scripts?
def squares(limit):
... One definition
...
squares_a = squares(34)
Multiple uses in
...
... multiple files
five_squares = squares(5)
... ...
squares_b = squares(56)
...
How? 346
But what happens if we want to use a function in more than one script?
346
“Modules”
Definition Use
347
Modules: a worked example ― 1a
def squares(limit):
answer = []
utils.py for n in range(0,limit):
answer.append(n**2)
return answer
def total(numbers):
Starts empty sum_so_far = 0
for number in numbers:
sum_so_far += number
return sum_so_far
We will start with a file called sum_squares.py which uses two functions
to add up the squares of numbers from zero to some limit. We want to
transfer those function definitions into a different file which we will call
utils.py (which starts empty) but still be able to use them in our original
file.
348
Modules: a worked example ― 1b
$ python3 sum_squares.py
Number? 5
30 = 0 + 1 + 4 + 9 + 16
$ python3 sum_squares.py
Number? 7
91 = 0 + 1 + 4 + 9 + 16 + 25 + 36
349
Just to prove I’m not fibbing, here it is working before we move anything
about.
349
Modules: a worked example ― 2a
def squares(limit):
answer = []
for n in range(0,limit):
answer.append(n**2) text = input('Number? ')
return answer number = int(text)
squares_n = squares(number)
def total(numbers): total_n = total(squares_n)
sum_so_far = 0 print(total_n)
for number in numbers:
sum_so_far += number
return sum_so_far
sum_squares.py
utils.py
Move the definitions
into the other file.
350
350
Modules: a worked example ― 2b
$ python3 sum_squares.py
Number? 5
351
351
Modules: a worked example ― 3a
def squares(limit): import utils
answer = []
for n in range(0,limit):
answer.append(n**2) text = input('Number? ')
return answer number = int(text)
squares_n = squares(number)
def total(numbers): total_n = total(squares_n)
sum_so_far = 0 print(total_n)
for number in numbers:
sum_so_far += number
return sum_so_far
sum_squares.py
utils.py
import: Make
import utils a reference to
and not the other file.
352
import utils.py
352
Modules: a worked example ― 3b
$ python3 sum_squares.py
Number? 5
353
353
Modules: a worked example ― 4a
import utils
utils.total()
sum_squares.py
utils.…: Identify
the functions
as coming from
354
the module.
354
Modules: a worked example ― 4b
$ python3 sum_squares.py
Number? 5
30
$ python3 sum_squares.py
Number? 7
91
Working again!
☺
355
355
Progress
“Modules”
356
356
Exercise 20
5 minutes
357
357
The Python philosophy
A small core … plus lots
language … of modules
math
sys
“Batteries
included”
string 358
We have met the majority of the Python language already! But obviously
Python has facilities to do much more than we have seen so far. The trick is
that Python comes with a large number of modules of its own which have
functions for performing no end of useful things.
This philosophy is called “batteries included”. You probably already have the
module you need to do your specialist application.
358
Example: the “math” module
359
Let’s see an example of an “included battery”. At the very start of this course
we write ourselves a square root program. Now let’s see what Python offers
as an alternative.
We import the “math” module. (No trailing “s”; this is the American spelling.)
In the math module is a sqrt() function. We can access this as
math.sqrt().
Most of the fundamental mathematical operations can be found in the math
moWe will see how to find out exactly what is in a module in a few slides’
time.
359
import module as alias
1.4142135623730951
>>> m.sqrt(2.0)
1.4142135623730951 360
There are those who object to typing. If “math” is too long then we can use
an aliasing trick to give the module a shorter name.
(The problem is rarely with math. There is a built-in module called
“multiprocessing” though which might get tiresome.)
360
Don’t do these
>>> sqrt(2.0)
!!
1.4142135623730951
361
python does permit you to do slightly more than that. You can suppress the
name of the module altogether.
You are beginners so please take it from an old hand on trust that this turns
out to be a very bad idea. You want to keep track of where your functions
came from!
361
What system modules are there?
Python 3.2.3 comes with over 250 modules.
362
“Batteries included”
>>> help('modules')
To find out exactly what modules come with your version of Python ask the
help system.
A word of warning, though. The text at the bottom “Enter any module
name…” is not quite right.
If you give the help() command with no argument then you are dropped
into an interactive help system. There you can type the name of a module or
type “modules spam”, etc.
>>> help()
help> quit
>>>
363
Additional downloadable modules
Numerical Databases
numpy pyodbc
MySQLdb MySQL
cx_oracle Oracle
364
But, of course, there’s never the particular module you want. There are
modules provided by people who want Python to interoperate with whatever
it is they are offering.
There are three sets of additional modules that you may end up needing to
know about.
The numerical and scientific world has a collection of modules called
Numerical Python (“numpy”) and “scientific python” (”scipy”) which contain
enormous amounts of useful functions and types for numerical processing.
Every database under the sun offers a module to let Python access it.
Finally there is a module to offer very powerful 2D graphics for data
visualisation and presentation.
364
An example system module: sys
import sys $ python3 argv.py one two three
print(sys.argv)
['argv.py', 'one', 'two', 'three']
index 0 1 2 3
argv.py
$ python3 argv.py 1 2 3
Always strings
365
365
sys.exit()
0: Everything was OK
366
An example system module: sys
But also…
367
Modules in Python
“How do I do
X in Python?”
“Where do I find
Python modules?”
368
368
Finding modules
http://docs.python.org/py3k/py-modindex.html
This contains the list of all the “batteries included” modules that come with
Python. For each module it links through to their documentation.
http://www.scipy.org/Topical_Software
http://numpy.scipy.org/
Scientific Python contains very many subject-specific modules for Python.
Most depend on the Numerical Python module numpy.
http://www.google.co.uk/
And for everything else there’s Google (who are big Python users, by the
way).
369
Help with modules
>>> help(math)
NAME
math
DESCRIPTION
This module is always available. It provides
access to the mathematical functions defined
by the C standard.
… 370
370
Help with module functions
…
FUNCTIONS
acos(x)
Return the arc cosine (measured in
radians) of x.
…
>>> math.acos(1.0)
0.0
371
The help will always include information on every function in the module…
371
Help with module constants
…
DATA
e = 2.718281828459045
pi = 3.141592653589793
…
>>> math.pi
3.141592653589793
372
372
Help for our own modules?
def squares(limit): >>> import utils
answer = []
for n in range(0,limit):
answer.append(n**2)
>>> help(utils)
return answer
NAME
def total(numbers): utils
sum_so_far = 0
for number in numbers:
sum_so_far += number FUNCTIONS
return sum_so_far squares(limit)
total(numbers)
utils.py
Basic help already FILE
provided by Python /home/y550/utils.py
373
373
Adding extra help text
"""Some utility functions >>> import utils Fresh start
from the Python for
Absolute Beginners course
"""
>>> help(utils)
utils.py total(numbers)
374
Adding extra help text to functions
"""Some utility functions >>> import utils Fresh start
from the Python for
Absolute Beginners course
"""
>>> help(utils)
utils.py
If we put text immediately after a def line and before the body of the
function it becomes the help text for that function, both in the module-as-a-
whole help text…
375
Adding extra help text to functions
"""Some utility functions >>> import utils Fresh start
from the Python for
Absolute Beginners course
"""
>>> help(utils.squares)
376
utils.py
376
Progress
Python a small language… Functionality Module
System modules
Foreign modules
377
Exercise 21
Add help text to your utils.py file.
5 minutes
378
378
Recap: Lists & Indices
list
str 5 a l p h a greek[0]
3
379
We have one last Python type to learn about. To give it some context, we
will recap the list type that we have spent so much time using.
A list is basically an ordered sequence of values. The position in that
sequence is known as the index.
379
“Index in ― Value out”
1 greek[1] 'beta'
380
380
Other “indices”: Strings?
'cat' 'gato'
'mouse' 'ratón'
381
Can we generalise on this idea by moving away from the input (the index)
needing to be a number?
Can we model a dictionary where we take in a string (a word in English, say)
and give out a different string (the corresponding word in Spanish, say).
(Note: the author is fully aware that translation is not as simple as this. This
is just a toy example.)
381
Other “indices”: Tuples?
(2,5) 'Treasure'
dictionary
(4,5) 'Fortress'
382
382
Python “dictionaries”
>>> en_to_es['cat']
'gato'
383
Python does have exactly such a general purpose mapper which it calls a
“dict”, short for “dictionary”.
Here is the Python for establishing a (very small) English to Spanish
dictionary that knows about two words.
We also see the Python for looking up a word in the dictionary.
We will review this syntax in some detail…
383
Creating a dictionary — 1
Curly brackets
Comma
{ 'cat':'gato' , 'dog':'perro' }
384
First we will look at creating a dictionary. In the same way that we can
create a list with square brackets, we can create a dictionary with curly
ones.
Each item in a dictionary is a pair of values separated by a colo
They are separated by commas.n.
384
Creating a dictionary — 2
'cat' : 'gato'
{ 'cat':'gato' , 'dog':'perro' }
“key” : “value”
385
The pairs of items separated by colons are known as the “key” and “value”.
The key is what you put in (the English word in this example) that you look
up in the dictionary and the value is what you get out (the translation into
Spanish in this example).
385
Using a dictionary — 1
'gato'
386
Now we have seen how to create a (small) dictionary we should look at how
to use it.
386
Using a dictionary — 2
Square brackets
387
387
Missing keys
>>> en_to_es['dog']
'perro' ✓
>>> en_to_es['mouse']
✗
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'mouse' Error message
388
The equivalent to shooting off the end of a list is asking for a key that’s not
in a dictionary.
388
Dictionaries are one-way
!
>>> en_to_es = { 'cat':'gato' , 'dog':'perro' }
>>> en_to_es['dog']
'perro' ✓
>>> en_to_es['perro']
✗
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'perro'
389
Looking for a key
389
Adding to a dictionary
>>> en_to_es['mouse']
'ratón'
390
Adding key-value pairs to a dictionary is a lot easier than it is with lists. With
lists we needed to append on the end of a list. With dictionaries, because
there is no inherent order, we can simply define them with a simple
expression on the left hand side.
390
Removing from a dictionary
>>> print(en_to_es)
>>> print(en_to_es)
391
We can use del to remove from a dictionary just as we did with lists.
391
Progress
392
Exercise 22
cat chat
dog chien
mouse souris
snake serpent
5 minutes
393
393
What’s in a dictionary? ― 1
>>> en_to_es
{'mouse': 'ratón', 'dog': 'perror', 'cat': 'gato'}
>>> en_to_es.keys()
dict_keys(['mouse', 'dog', 'cat'])
Orders
match
>>> en_to_es.values()
dict_values(['ratón', 'perro', 'gato'])
Just treat them like lists (or convert them to lists) 394
To date we have created our own dictionaries. If we are handed one how do
we find out what keys and values are in it?
Dictionaries support two methods which return the sort-of-lists of the keys
and values. We mention them here only for completeness.
Don’t forget that you can always convert a sort-of-list into a list with the
list() function.
394
What’s in a dictionary? ― 2
>>> en_to_es.items() Most useful method
dict_items([('mouse', 'ratón'), ('dog', 'perro'),
('cat', 'gato')])
(Key,Value) pairs/tuples
By far the best way to get at the contents of a dictionary is to use the
items() method which generates a sort-of-list of the key-value pairs as
tuples. Running a for… loop over this list is the easiest way to process the
contents of a directory.
395
What’s in a dictionary? ― 3
Common simplification
>>> list(en_to_es.items())
[('mouse','ratón'), ('dog','perro'),('cat','gato')]
396
396
Getting the list of keys
list() list of
dictionary
keys
{'the': 2, 'cat': 1, 'sat': 1, 'on': 1, 'mat': 1}
397
Unfortunately when you convert a dictionary directly into a list you get the
list of keys not the list of )(key,value) pairs. This is a shame but is a
compromise for back compatibility with previous versions.
397
Is a key in a dictionary?
>>> en_to_es['snake']
398
398
Example: Counting words ― 1
words = ['the','cat','sat','on','the','mat']
counts = {'the':2,'cat':1,'sat':1,'on':1,'mat':1}
399
399
Example: Counting words ― 2
words = ['the','cat','sat','on','the','mat']
Do something
400
400
Example: Counting words ― 3
words = ['the','cat','sat','on','the','mat']
counts = {}
counter1.py
401
401
Why doesn’t it work?
counts = {'the':1, 'cat':1}
counts['the'] = counts['the'] + 1
Key is not in
✗ counts['sat'] += 1
the dictionary!
counts['sat'] = counts['sat'] + 1
402
We cannot increment a value that isn’t there. Until the program meets a
word for the first time it has no entry in the dictionary, and certainly not an
entry with numerical value 0.
402
Example: Counting words ― 4
words = ['the','cat','sat','on','the','mat']
counts = {}
if word in counts:
counts[word] += 1
else:
403
Example: Counting words ― 5
words = ['the','cat','sat','on','the','mat']
counts = {}
if word in counts:
counts[word] += 1
else:
counts[word] = 1 counter2.py
404
print(counts)
404
Example: Counting words ― 6
$ python3 counter2.py
Dictionaries are unordered entities. You cannot predict the order that the
keys will appear when you print a dictionary or step through its keys.
405
Example: Counting words ― 7
✗
print(counts) Too ugly
items.sort()
406
Example: Counting words ― 8
$ python3 counter3.py
cat 1
mat 1
on 1
sat 1
the 2
407
407
Progress
408
408
Exercise 23
10 minutes
409
409
Formatted output
$ python3 counter3.py
cat 1
mat 1
on 1 Ugly!
sat 1
the 2
cat 1
mat 1
on 1 We want data
sat 1 nicely aligned
the 2
410
We have one last topic to cover. The output from our word counter is not as
pretty as it might be. The last topic we will cover is Python text formatting.
Full details of the formatting system can be found online at
docs.python.org/py3k/library/string.html#formatspec
410
The format() method
'xxxAyyy100zzz'
'xxx{}yyy{}zzz'
'xxxAyyy100zzz'
411
In Python 3 the string type has a method called format() which takes
arguments and returns another string which is the original with the method’s
arguments inserted into it in certain places. Those places are marked with
curly brackets in the string.
Curly brackets are otherwise quite normal characters. It’s only the
format() method that cares about them.
In its simplest form, the format() method replaces each pair of curly
brackets with the corresponding argument.
411
String formatting ― 1
>>> 'xxx{:5s}yyy'.format('A')
'xxxA␣␣␣␣yyy'
s ― substitute a string
'xxxA␣␣␣␣yyy '
5 ― pad to 5 spaces
(left aligns by default) 412
The real fun starts when we put something inside those curly brackets.
These are the formatting instructions.
The simplest examples start with a colon followed by some layout
instructions. (We will see what comes in front of the colon in a few slides
time.) The number indicates how many spaces to allocate for the insertion
and the letter that follows tells it what type ob object to expect. “s” stands for
string.
412
String formatting ― 2
>>> 'xxx{:<5s}yyy'.format('A')
'xxxA␣␣␣␣yyy'
By default strings align to the left of their space. We can be explicit about
this by inserting a left angle bracket, which you can think of as an arrow
head pointing the direction of the alignment.
413
String formatting ― 3
>>> 'xxx{:>5s}yyy'.format('A')
'xxx␣␣␣␣Ayyy'
If we want right aligned strings then we have to use the alignment marker.
414
Integer formatting ― 1
>>> 'xxx{:5d}yyy'.format(123)
'xxx␣␣123yyy'
If we change the letter to a “d” we are telling the format() method to insert
an integer (“digits”). These align to the right by default.
415
Integer formatting ― 2
>>> 'xxx{:>5d}yyy'.format(123)
'xxx␣␣123yyy'
416
Integer formatting ― 3
>>> 'xxx{:>5d}yyy'.format(123)
'xxx␣␣123yyy'
417
Integer formatting ― 4
>>> 'xxx{:05d}yyy'.format(123)
'xxx00123yyy'
If we precede the width number with a zero then the number is padded with
zeroes rather than spaces and alignment is automatic.
418
Integer formatting ― 5
>>> 'xxx{:+5d}yyy'.format(123)
'xxx␣+123yyy'
If we put a plus sign in front of the number then its sign is always shown,
even if it is positive.
419
Integer formatting ― 6
>>> 'xxx{:+05d}yyy'.format(123)
'xxx␣+0123yyy'
420
420
Integer formatting ― 7
>>> 'xxx{:5,d}yyy'.format(1234)
'xxx1,234yyy'
Adding a comma between the width and the “d” adds comma breaks to
large numbers.
421
Floating point formatting ― 1
>>> 'xxx{:5.2f}yyy'.format(1.2)
'xxx 1.20yyy'
Floating point numbers are slightly more complicated. The width parameter
has two parts, separated by a decimal point. The first number is the width of
the entire number (just as it is for strings and integers). The number after the
decimal point is the number of decimal points of precision that should be
included in the formatted output.
422
Floating point formatting ― 2
>>> 'xxx{:f}yyy'.format(1.2)
'xxx1.200000yyy'
The default is to have six decimal points of precision and to make the field
as wide as it needs to be.
423
Ordering and repeats ― 1
0 1 2
>>> 'X{:s}X{:d}X{:f}X'.format('abc', 123, 1.23)
0 1 2
'XabcX123X1.230000X'
0 1 2
Equivalent
424
Ordering and repeats ― 2
We can also use them to change the order that items appear in or to have
them appear more than once (or not at all).
425
Formatting in practice
...
formatting = '{:3} {:1}'
$ python3 counter4.py
cat 1
mat 1
on 1
sat 1
the 2 426
The script counter4.py is the same as counter3.py but with the new
formatting for its output.
426
Progress
Formatting string.format(args)
Substitutions {:>6s}
{:+06d}
{:+012.7f}
427
427
Exercise 24
Complete exercise24.py
to format the output as shown:
Joe 9
Samantha 45
Methuselah 969
5 minutes
428
428
And that's it! (And “it” is a lot!)
Text “if” test Reading files
Prompting Indented blocks Writing files
Numbers Lists Functions
Arithmetic Indices “Structured programming”
Comparisons Object methods Tuples
Booleans Built-in help “for” loops
Variables “for” loops Modules
Deleting names “Treat it like a list…” Dictionaries
“while” loop Values direct/via index Formatting
429
And congratulations!
You have completed an introductory course on Python. Well done.
It is only an introductory course and there is more. But do not let that
dishearten you; just take a look at what you have accomplished. You now
have a firm grounding to go further with Python or to start learning other
programming languages. (But the author would like you to stick with
Python.)
429
But wait! There’s more…
430
430