Python Handout PDF
Python Handout PDF
Bob Dowling
University Computing Service
[email protected]
http://www.ucs.cam.ac.uk/docs/course-notes/unix-courses/PythonAB 1
1
Course outline ― 1
Who uses Python & what for
What sort of language it is
Text
Names for values
Reading in user data
Numbers
Conversions
Comparisons
Truth & Falsehood
2
2
Course outline ― 2
Assignment
Names
Loops
if… else…
Indentation
Comments
3
Course outline ― 3
Lists
Indices
Lengths
Changing items
Extending lists
Methods
Creating lists
Testing lists
Removing from lists
for… loop
Iterables
Slices
4
4
Course outline ― 4
Files
Reading & writing
Tuples
Modules
System modules
External modules
Dictionaries
Formatted text
5
5
Who uses Python?
On-line games
Web services
Applications
Science
Instrument control
Embedded systems
en.wikipedia.org/wiki/List_of_Python_software
6
6
What sort of language is Python?
Compiled Interpreted
7
Running Python ― 1
We are going to use Python from the command line either directly or
indirectly.
So, first I need a Unix command line. I will get that from the GUI by clicking
on the terminal icon in the desktop application bar.
8
Running Python ― 2
Unix prompt
Unix command
Introductory blurb
$ python3
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Python prompt
Now, the Unix interpreter prompts you to give it a Unix command with a
short bit of text that ends with a dollar. In the slides this will be represented
simply as a dollar.
This is a Unix prompt asking for a Unix command.
The Unix command we are going to give is “python3”. Please note that
trailing “3”. The command “python” gives you either Python 2 or Python 3
depending on what system you are on. With this command we are insisting
on getting a version of Python 3.
The Python interpreter then runs, starting with a couple of lines of blurb. In
particular it identifies the specific version of Python it is running. (3.2.3 in this
slide.)
Then it gives a prompt of its own, three “greater than” characters. The
Python 3 program is now running and it is prompting us to give a Python
command.
You cannot give a Unix command at a Python prompt (or vice versa).
9
Quitting Python
>>> exit()
Any one
>>> quit()
of these
>>> Ctrl + D
10
There are various ways to quit interactive Python. There are two commands
which are equivalent for our purposes: quit() and exit(), but the
simplest is the key sequence [Ctrl]+[D].
10
A first Python command
Python prompt
Python command
11
There is a tradition that the first program you ever run in any language
generates the output “Hello, world!”.
I see no reason to buck tradition. Welcome to your first Python command;
we are going to output “Hello, world!”.
We type this command at the Python prompt. The convention in these slides
is that the typewriter text in bold face is what you type and the text in regular
face is what the computer prints.
We type “print” followed by an opening round brackets and the text
“Hello, world!” surrounded by single quotes, ending with a closing
round bracket and hitting the Return key, [ ↲], to indicate that we are done
with that line of instruction.
The computer responds by outputting “Hello, world!” without the
quotes.
Once it has done that it prompts us again asking for another Python
command with another Python prompt, “>>>”.
11
Python commands
Python “function”
Round brackets
― “parentheses”
print('Hello, world!')
Function’s “argument”
12
This is our first Python “function”. A function takes some input, does
something with it and (optionally) returns a value. The nomenclature derives
from the mathematics of functions, but we don’t need to fixate on the
mathematical underpinnings of computer science in this course.
Our function in this case is “print” and the command necessarily starts
with the name of the function.
The inputs to the function are called its “arguments” and follow the function
inside round brackets (“parentheses”).
In this case there is a single argument, the text to print.
Note that Python, as with many but not all programming languages, is “case
sensitive”. The word “print” is not the same as “Print” or “PRINT”.
12
Python text
Quotation marks
'Hello, world!'
The body
of the text
!
part of the text itself.
13
The text itself is presented within single quotation marks. (We will discuss
the choice of quotation marks later.)
The body of the text comes within the quotes.
The quotes are not part of the text; they merely indicate to the Python
interpreter that “hey, this is text!”
Recall that the the printed output does not have quotes.
13
Quotes?
print Command
'print' Text
14
14
Python scripts
File in home directory print('Hello, world!')
Unix prompt
Unix command
to run Python
$ Unix prompt 15
15
Editing Python scripts ― 1
16
To edit scripts we will need a plain text editor. For the purposes of this
course we will use an editor called “gedit”. You are welcome to use any
text editor you are comfortable with (e.g. vi or emacs).
Unfortunately the route to launch the editor the first time is a bit clunky.
Actually, it’s a lot clunky.
1. Click on the “Dash Home” icon at the top of the icon list.
This launches a selection tool that starts blank. If you have been using some
other files then these may show as “recent files”.
2. At the bottom of the widget you will see the “house” icon highlighted.
Click on the “three library books” icon next to it.
This switches the selector to the library of applications.
16
Editing Python scripts ― 2
17
3. Click on the “see more results” text to expose the complete set of
supported applications.
4. Scroll down until you see the “Text Editor” application. (The scroll
mouse tends to work better than dragging the rather thin scroll bar.)
5. Click the “Text Editor” icon.
17
Editing Python scripts ― 3
18
18
Editing Python scripts ― 4
19
Future launches won’t be anything like as painful. In future the text editor will
be immediately available in “Recent Apps”.
19
Progress
Interactive Python
Python scripts
print() command
20
20
Exercise 1
2 minutes
21
During this course there will be some “lightning exercises”. These are very
quick exercises just to check that you have understood what’s been covered
in the course up to that point.
Here is your first.
First, make sure you can print text from interactive Python and quit it
afterwards.
Second, edit the exercise1.py script and run the edited version with the
different output.
This is really a test of whether you can get the basic tools running. Please
ask if you have any problems!
21
A little more text
www.unicode.org/charts/ hello2.py
22
Now let’s look at a slightly different script just to see what Python can do.
Python 3 has excellent support for fully international text. (So did Python 2
but it was concealed.)
Python 3 supports what is called the “Unicode” standard, a standard
designed to allow for characters from almost every language in the world. If
you are interested in international text you need to know about the Unicode
standard. The URL shown will introduce you to the wide range of characters
supported.
The example in the slide contains the following characters:
ℏ PLANCK’S CONSTANT DIVIDED BY TWO PI
э CYRILLIC SMALL LETTER E
ł LATIN SMALL LETTER L WITH BAR
Ꮣ CHEROKEE LETTER DA
ዐ ETHIOPIC SYLLABLE PHARYNGEAL A
ω GREEK SMALL LETTER OMEGA
☺ WHITE SMILING FACE
ր ARMENIAN SMALL LETTER REH
ⲗ COPTIC SMALL LETTER LAUDA
∂ PARTIAL DIFFERENTIAL
‼ DOUBLE EXCLAMATION MARK
22
Getting characters
˘
ğ Character Selector
“LATIN SMALL
LETTER G \u011f
WITH BREVE”
23
23
Text: a “string” of characters
Class: string
Length: 13
Letters
str 13 H e l l o , ␣ w o r l d !
24
We will quickly look at how Python stores text, because it will give us an
introduction to how Python stores everything.
Every object in Python has a “type” (also known as a “class”).
The type for text is called “str”. This is short for “string of characters” and is
the conventional computing name for text. We typically call them “strings”.
Internally, Python allocates a chunk of computer memory to store our text. It
stores certain items together to do this. First it records that the object is a
string, because that will determine how memory is allocated subsequently.
Then it records how long the string is. Then it records the text itself.
24
Text: “behind the scenes”
str 13 72 101 108 108 111 44 32 … 100 33
>>> ord('ğ')
287
28710
>>> chr(287)
'ğ'
ğ 25
In these slides I’m going to represent the stored text as characters because
that’s easier to read. In reality, all computers can store are numbers. Every
character has a number associated with it. You can get the number
corresponding to any character by using the ord() function and you can
get the character corresponding to any number with the chr() function.
Mathematical note:
The subscript 10 and 16 indicate the “base” of the numbers.
25
Adding strings together: +
hello3.py
>>> 'Hello, ' + 'world!'
'Hello, world!'
>>>
26
26
Pure concatenation
>>> 'Hello,␣' + 'world!'
'Hello, world!'
This joining together is very simple. If you want words split by a space you
have to put the space in.
27
Single & double quotes
28
It doesn’t matter whether we write our strings with single or double quotes
(so long as they match at the two ends). Python simply notes that we are
defining a string.
28
Python strings: input & output
'Hello, world!'
Single or double
quotes on input.
"Hello, world!"
Create same
string object.
29
Internally there are no quotes, just a record that the object is text.
When Python comes to display the string and declares “this is text” itself it
uses single quotes.
29
Uses of single & double quotes
30
30
Why we need different quotes
✘
File "<stdin>", line 1
print('He said 'hello' to her.')
^
SyntaxError: invalid syntax
31
You must mix the quotes like that. If you do not then Python will be unable to
make sense of the command.
We will look at Python’s error messages in more detail later.
31
Adding arbitrary quotes
32
32
Putting line breaks in text
Hello,
world! What we want
>>> print('Hello, ↵
✘
File "<stdin>", line 1
print('Hello,
^
SyntaxError: EOL while
scanning string literal “EOL”: End Of Line
33
33
Inserting “special” characters
>>> print('Hello,\nworld!')
Hello, Treated as
world! a new line.
\n Converted into a
single character.
str 13 H e l l o , ↵ w o r l d !
>>> len('Hello,\nworld!')
13 len() function: gives
the length of the object
34
34
The backslash
Special Ordinary \' '
\" "
Ordinary Special \n ↵
\t ⇥
35
We have used backslash again, this time for a slightly different result.
Backslash before a character with special significance, such as the quote
character, makes the character “ordinary”. Used before an ordinary
character, such as “n”, it produces something “special”.
Only a few ordinary characters have special characters associated with
them but the two most commonly useful are these:
\n ↵ new line
\t ⇥ tab stop
35
\n: unwieldy for long text
'SQUIRE TRELAWNEY, Dr. Livesey, and the\n
rest of these gentlemen having asked me\n
to write down the whole particulars\nabou
t Treasure Island, from the\nbeginning to
the end, keeping nothing\nback but the b
earings of the island,\nand that only bec
ause there is still\ntreasure not yet lif
ted, I take up my\npen in the year of gra
ce 17__ and go\nback to the time when my
father kept\nthe Admiral Benbow inn and t
he brown\nold seaman with the sabre cut f
irst\ntook up his lodging under our roof.'
Single
line 36
The “\n” trick is useful for the occasional new line. It is no use for long texts
where we want to control the formatting ourselves.
36
Special input method for long text
'''SQUIRE TRELAWNEY, Dr. Livesey, and the
rest of these gentlemen having asked me
to write down the whole particulars
about Treasure Island, from the
beginning to the end, keeping nothing
back but the bearings of the island,
and that only because there is still
treasure not yet lifted, I take up my
pen in the year of grace 17__ and go
back to the time when my father kept
the Admiral Benbow inn and the brown
old seaman with the sabre cut first
took up his lodging under our roof. '''
Triple Multiple
quotes lines 37
Python has a special trick precisely for convenient definition of long, multi-
line text.
If you start the text with a “triple quote” then the special treatment of hitting
the [↵] key is turned off. This lets you enter text “free form” with natural line
breaks.
The triple quote is three quote characters with no spaces between them.
The quote character used can be either one but the triple use at one end
must match the one used at the other end.
37
Python’s “secondary” prompt
>>> '''Hello,
... world'''
Python asking for more
of the same command.
38
The triple quote lets us see another Python feature. If we type a long string
raw then after we hit ↵ we see Python’s “secondary prompt”. The three dots
indicate that Python is expecting more input before it will process what it has
in hand.
38
It’s still just text!
>>> 'Hello,\nworld!'
'Hello\nworld'
Python uses \n to represent
line breaks in strings.
>>> '''Hello,
... world!'''
39
It is also important to note that triple quotes are just a trick for input. The text
object created is still a standard Python string. It has no memory of how it
was created.
Also note that when Python is representing the content of a string object (as
opposed to printing it) it displays new lines as “\n”.
39
Your choice of input quotes:
Four inputs:
'Hello,\nworld!' "Hello,\nworld!"
'''Hello, """Hello,
world!''' world!"""
Same result:
str 13 H e l l o , ↵ w o r l d !
40
We have now seen four different ways to create a string with an embedded
new line. They all produce the same string object.
40
Progress
International text
print()
Concatenation of strings
Special characters
Long strings
41
41
Exercise 2
coffee
café
caffè
Kaffee
è \u00e8 AltGr + ; e
42
Attaching names to values
“variables” message = 'Hello, world!'
print(message)
>>> message='Hello, world!'
'Hello, world!'
>>> type(message)
<class 'str'>
message str 13 H e l l o , ␣ w o r l d !
43
43
Attaching names to values
message = 'Hello, world!'
print(message)
>>> type(print)
print function
message str 13 H e l l o , ␣ w o r l d !
44
Both “print” and “message” are the same this way. Both are names
attached to Python objects. “print” is attached to a chunk of memory
containing the definition of a function and “message” is attached to a chunk
of memory containing the text.
44
Reading some text into a script
message = input('Yes?␣')
print(message)
input('Yes?␣')
Boo! print(message)
45
Now that we know how to attach names to values we can start receiving
input from the user of our script.
For this we will use the cunningly named “input()” function.
This function takes some (typically short) text as its argument. It prints this
text as a prompt and then waits for the user to type something back (and
press [↵]. It then returns whatever the user typed (without the [ ↵]) as its
value.
We can use this function on the right hand side of an assignment.
Recall that the assignment completely evaluates the right hand side first.
This means that it has to evaluate the input() function, so it prompts the
user for input and evaluates to whatever it was that the user typed.
Then the left hand side is processed and the name “message” is attached to
this value.
We can then print this input text by using the attached name.
45
Can't read numbers directly!
$ python3 input2.py number = input('N?␣')
print(number + 1)
✘
N? 10
input2.py
string integer 46
46
input(): strings only
$ python3 input2.py number = input('N?␣')
print(number + 1)
✘
N? 10
input2.py
input('N?␣') str 2 1 0
≠ int 10
47
The problem is that the input() function always returns a string and the
string “character 1 followed by character 0” is not the same as the integer
ten.
We will need to convert from the string to the integer explicitly.
47
Some more types
>>> type(42)
>>> type(3.14159)
48
Converting text to integers
>>> int('10')
str 2 1 0 int 10
10
>>> int('␣-100␣')
str 6 ␣ - 1 0 0 ␣
-100
int -100
>>> int('100-10')
✘
ValueError:
invalid literal for int() with base 10: '100-10'
49
49
Converting text to floats
>>> float('␣10.␣')
10.0
50
50
Converting between ints and floats
>>> float(10)
10.0
>>> int(10.9)
10 Truncates
fractional part
>>> int(-10.9)
-10
51
The functions can take more than just strings, though. They can take other
numbers, for example. Note that the int() function truncates floating point
numbers.
51
Converting into text
'10'
'10.0'
52
52
Converting between types
53
In general there is a function for each type that converts whatever it can into
that type.
53
Reading numbers into a script
text = input('N?␣')
number = int(text)
print(number + 1)
N? 10
11
54
So finally we can see what we have to do to make our failing script work: we
need to add a type conversion line.
54
Progress
Names Values name = value
Types strings
integers
55
Exercise 3
3 minutes
56
56
Integers
ℤ {… -2, -1, 0,
1, 2, 3, 4 …}
57
57
Integer addition & subtraction
>>> 20+5
25
“No surprises”
58
We can start our handling of integers with some very basic arithmetic.
Note that spaces around the plus and minus character are ignored.
Adding or subtracting two integers simply gives a third integer.
58
Integer multiplication
There is no “×” on the keyboard. Linux:
AltGr + Shift + ,
Use “*” instead
>>> 20␣*␣5
100
Still no surprises
59
59
Integer division
There is no “÷” on the keyboard. Linux:
AltGr + Shift + .
Use “/” instead
>>> 20␣/␣5
4.0 This is a floating point number!
Surprise!
60
60
Integer division gives floats !
Fractions Floats sometimes
!
Consistency Floats always
>>> 20␣/␣40
0.5
>>> 20␣/␣30
0.6666666666666666
61
61
Integer powers
There is no “42” on the keyboard.
62
62
Integer remainders
e.g. Is a number even or odd?
Use “%”
>>> 4␣%␣2
0
>>> 5␣%␣2
1
>>> -5␣%␣2
1 Remainder is always non-negative
63
There’s one last integer arithmetic operator we will use once in a while.
Another way to look at division is to ask what the remainder is after a
division. Python represents this concept by using the percent sign between
to numbers to represent the remainder when the first number is divided by
the second.
We will use it for one purpose only in this course: to determine if a number is
even or odd. If a number’s remainder when divided by 2 is 0 then it’s even
and if the remainder is 1 then it’s odd.
63
How big can a Python integer be?
>>> 2**2
4
>>> 4**2
16
>>> 16**2
256
>>> 256**2
65536
>>> 65536**2
4294967296
64
Now we will look at the numbers themselves. We can ask the question “how
big can an integer be?” Mathematically, of course, there is no limit. In a
computer there are always limits. Each computer has only a finite amount of
memory to store information so there has to be a limit. We will see that
Python has no limits in principle and it is only the technical limit of the
computer that can restrict us. In practice this is never an issue for the size of
integers.
We will experiment with large integers by repeated squaring. We start with a
2 and keep squaring.
64
How big can a Python integer be?
>>> 4294967296**2
18446744073709551616
>>> 18446744073709551616**2
340282366920938463463374607431768211456
>>> 340282366920938463463374607431768211456**2
1157920892373161954235709850086879078532699846
65640564039457584007913129639936
>>> 115792089237316195423570985008687907853269
984665640564039457584007913129639936**2
1340780792994259709957402499820584612747936582
0592393377723561443721764030073546976801874298
1669034276900318581864860508537538828119465699
65
46433649006084096
65
How big can a Python integer be?
10443888814131525066917527107166243825799642490473837803842334832839
53907971557456848826811934997558340890106714439262837987573438185793
60726323608785136527794595697654370999834036159013438371831442807001
18559462263763188393977127456723346843445866174968079087058037040712
84048740118609114467977783598029006686938976881787785946905630190260
94059957945343282346930302669644305902501597239986771421554169383555
98852914863182379144344967340878118726394964751001890413490084170616
There is no limit!
75093668333850551032972088269550769983616369411933015213796825837188
09183365675122131849284636812555022599830041234478486259567449219461
70238065059132456108257318353800876086221028342701976982023131690176
78006675195485079921636419370285375124784014907159135459982790513399
61155179427110683113409058427288427979155484978295432353451706522326
Except for
90613949059876930021229633956877828789484406160074129456749198230505
71642377154816321380631045902916136926708342856440730447899971901781
machine
46576347322385026725305989979599609079946920177462481771844986745565
memory
92501783290704731194331655508075682218465717463732968849128195203174
57002440926616910874148385078411929804522981857338977648103126085903
00130241346718972667321649151113160292078173803343609024380470834040
3154190336
66
66
Big integers
2
C / C++
Fortran
4
16
int
INTEGER*4 256
long 65536
INTEGER*8
4294967296
long long
INTEGER*16 18446744073709551616
This may sound rather trivial but, in fact, Python is quite exceptional in this
regard. The compiled languages have to allocate space for their integers in
advance and so place limits on how large they can grow.
67
Floating point numbers
ℝ
✗ 1.0
0.33333333
3.14159265
2.71828182 68
And that’s it for whole numbers. Now we will look at floating point numbers,
a computer’s way of storing fractional values. This is a computer’s
approximation to the real numbers. As we will see it is a problematic
approximation.
The fancy ℝ is the mathematical symbol for the real numbers, from the
English word Real.
68
Basic operations
>>> 20.0 + 5.0 >>> 20.0 - 5.0
25.0 15.0
69
For our basic operations, floating point numbers behave just the same as
integers, using the same operators to achieve the same results. Floating
point division creates a floating point number.
69
Floating point imprecision
>>> 1.0 / 3.0
0.3333333333333333
≈ 17 significant figures
70
70
Hidden imprecision
>>> 0.1
!
0.1
71
How big can a Python float be? ― 1
>>> 65536.0**2 So far, so good.
4294967296.0
1.8446744073709552 e+19
1.8446744073709552 ×1019
72
Let’s ask the same question about floats as we asked about integers: how
large can they be?
We will repeat our approach of repeated squaring. We fast-forward to start
at 65536.0 squared and notice that we soon get anomolous responses.
When we square 4,294,967,296 we get a number with the letter “e” in it.
User’s of pocket calculators at school may recognise this representation: it
indicates a number between 1.0 and 9.999… multiplied by a power of 10.
Floating point numbers can only hold roughly 17 significant figures of
accuracy. This means that when the integer needs more than 17 digits
something has to give.
72
Floats are not exact
>>> 4294967296.0**2 Floating point
1.8446744073709552e+19
1.8446744073709552×1019 18446744073709552000
- 18446744073709551616
384
73
73
How big can a Python float be? ― 2
>>> 1.8446744073709552e+19**2
3.402823669209385e+38
>>> 3.402823669209385e+38**2
1.157920892373162e+77
74
If we accept that our answers are now only approximate we can keep
squaring. The “e-number” representation of scientific notation is accepted on
input by Python.
When we come to square 1.3407807929942597×10 154, though, we hit
another issue, this one fatal.
We get an “overflow error”. This means we have tried to create a floating
point number larger than Python can cope with. Under some circumstances
the “too big” problem gives rise to a sort-of-number called “inf” (standing
for “infinity”).
74
Floating point limits
1.2345678901234567 × 10N
17 significant figures
Positive values:
4.94065645841×10-324 < N < 8.98846567431×10307
75
Just for the record, floating point numbers have limits both in terms of the
largest and smallest numbers they can contain.
75
Complex numbers
ℑ
ℂ z
z2
>>> (1.25+0.5j)**2
(1.3125+1.25j)
76
Python also supports complex numbers, using j for the square root of -1.
We will not use them in this course, but you ought to know they exist.
76
Progress
Arithmetic + - * / ** %
Integers No limits!
Limited precision
Complex numbers
77
77
Exercise 4
1. 223 ÷ 71
2. (1 + 1/10)10
3. (1 + 1/100)100
4. (1 + 1/1000)1000
3 minutes
78
78
Comparisons
5 < 10 ✔
5 > 10 ✘
79
79
Comparisons
80
80
True & False
>>> type(True)
<class 'bool'> “Booleans”
5 + 10 15 int
int int
The important thing to understand is that this is not just Python reporting on
a test but rather the value generated by the test. True and False are (the
only) two values of a special Python type called a “Boolean” used for
recording whether something is true or not.
Just as the “+” operator takes two integers and returns an integer value, the
“<” operator takes two integers and returns a Boolean.
Booleans are named after George Boole, whose work laid the ground for
modern algebraic logic. (His classic book’s full title is “An Investigation of the
Laws of Thought on Which are Founded the Mathematical Theories of Logic
and Probabilities”, in true Victorian style.)
81
True & False
bool ✓ True
Only two values
bool ✗ False
82
82
Six comparisons
Maths Python
≠ !=
< <
> >
≤ <=
≥ >=
83
83
Equality comparison & assignment
= name = value
== value1 == value2
84
84
Textual comparisons
True
True
True
85
85
Ordering text is complicated
Python inequalities use Unicode character numbers.
86
“Syntactic sugar”
0 < number
number < 10
>>> number = 5
True
87
87
Converting to booleans
float() Converts to floating point numbers
<class 'float'>
int() Converts to integers
<class 'int'>
str() Converts to strings
<class 'str'>
As with all Python types there is a function named after the type that tries to
convert arbitrary inputs into Booleans. Given that there are only two Boolean
values this tends to be a very simple function.
88
Useful conversions
0 False Zero
1 True Non-zero
12 True
89
-1 True
89
Boolean operations
bool
? bool
bool
90
Boolean types have their own arithmetic just like ordinary numbers. It was
the algebra of these that George Boole developed.
90
Boolean operations ― “and”
bool
and bool
bool
91
Boolean operations ― “and”
92
We are much more likely to encounter the input booleans as the results of
comparisons that as literal values.
92
Boolean operations ― “or”
bool
or bool
bool
The next boolean operation to look at is “or”. The results of this operation is
True if either of its inputs are True and False only if both its inputs are
False.
93
Boolean operations ― “or”
94
Again, we tend to encounter it more often with other tests than with literal
booleans.
94
Boolean operations ― “not”
95
The final operation is “not”. This takes only one input and “flips” it. True
becomes False and vice versa.
95
Boolean operations ― “not”
False
True
96
96
Ambiguity in expressions
3+6/3
✘ ✔
(3 + 6) / 3 3 + (6 / 3)
3 5
97
97
Division before addition
3+6/3
Division first
3+ 2
Addition second
5
98
98
“Order of precedence”
First
not x x and y x or y
99
Last
99
Progress
Comparisons == != < > <= >=
Order of precedence
100
100
Exercise 5
Predict whether these expressions will evaluate to True or False.
Then try them.
3. 60 - 45 / 5 + 10 == 1
3 minutes
101
101
Names and values: “assignment”
Now let’s go back to the attaching of names to values that we saw with our
hello3.py script.
Consider the simple Python instruction shown.
Python does two things, strictly in this order:
First, it notices the literal value 100 (an integer). So Python allocates a
chunk of memory large enough and creates a Python object in it that
contains a Python integer with value 100.
Second, it creates the name “alpha” and attaches it to the integer.
102
Assignment: right to left
alpha = 100
103
The key thing to note is that the processing happens right to left. Everything
to the right hand side is processed first. Only after that processing is done is
the left hand side considered.
In this example it’s trivial. It will become less trivial very soon so remember
that the right hand side is evaluated before the left hand side is even looked
at.
ps: Computing uses the phrases “left hand side” and “right hand side” so
often that they are typically written as “LHS” and “RHS”.
103
Simple evaluations
>>> beta = 100 + 20
1. 100 + 20 RHS
2. 120
int
3. LHS
beta int 120
104
104
Names on the RHS — 1
>>> gamma = alpha + 40
alpha + 40 RHS
1.
alpha
2.
3.
int 140
105
105
Names on the RHS — 2
>>> gamma = alpha + 40
LHS
4. gamma 140
int
106
Only after all that is the LHS considered, and the name “gamma” is created
and attached to the newly minted integer.
106
Same name on both sides — 0
Starting
gamma int 140 position
>>> print(gamma)
140
107
107
Same name on both sides — 1
RHS
>>> gamma = gamma + 10
1. gamma + 10
2. gamma
3. 140
int function + int 10
4. 150
int
108
Then we run an assignment that has the name gamma on both the left and
right hand sides.
Again, first of all Python focuses exclusively on the RHS.
The expression “gamma + 10” is evaluated to give rise to an integer 150 in
Python memory.
108
Same name on both sides — 2
LHS
>>> gamma = gamma + 10
Only once that evaluation is complete does Python turn its attention to the
LHS.
The name gamma is going to be attached to the integer 150 in Python
memory. No attention is paid to where the integer 150 came from.
The name gamma is already in use and is attached to the integer 140. Its
attachment is changed to the new integer 150.
109
Same name on both sides — 3
LHS
>>> gamma = gamma + 10
int 150
✗
7.
gamma 140 No longer
int
used.
110
Once that is done there are no remaining references to the old integer 140.
Python automatically cleans it up, freeing the space for re-use.
This is a process called “garbage collection”. In some languages you have
to free up unused space yourself; in Python the system does it for you
automatically.
110
“Syntactic sugar”
111
111
Deleting a name ― 1
>>> print(thing)
>>> print(thing)
1
112
112
Deleting a name ― 2
>>> print(thing)
1 Known
variable
>>> del thing
>>> print(thing)
To delete the attachment we use the Python command “del”. The command
del thing
returns us to the state where the name is no longer known.
You can delete multiple names with the slightly extended syntax
del thing1, thing2, thing3
This is equivalent to
del thing1
del thing2
del thing3
but slightly shorter.
113
Common mistake
a = 10
!
b = 7
b = a - b b = a - b b ≠ 10 - 7 = 3
= 17 - 7
= 10
(ab)→( a−b
a+b
)
we need to be careful not to use a “half-transformed” state in the second
half of the transformation. If we calculate the new value for one coordinate
we can’t (trivially) use it in the calculation of the new value of the second
coordinate.
Later in this course when we look at “tuples” we will see a slick Python way
to fix this problem.
114
Progress
115
115
Our first “real” program
116
116
Square root of 2.0 by “bisection”
“Interval of uncertainty”
The technique we are going to use is called “bisection”. If you know this
technique you can relax for the next few slides. Please don’t snore. ☺
We are going to go through it by hand for a few iterations because when we
come to implement it in Python it is important that any confusion is due to
the Python, and not the maths the Python is implementing.
The trick is to identify a range of values that must contain the actual value
of √2. That is, we identify a lower bound that is less than √2 and an upper
bound that is greater than √2.
We then have some way (which we will explain in the following slides) to
improve that estimate by reducing the length of that interval of uncertainty.
To be precise, we will cut the uncertainty in half which is why the process is
called “bisection”.
We start by taking a lower bound of x=0, which is definitely lower than x=√2
because y=02=0<2, and an upper bound of x=2, which is definitely higher
than x=√2 because y=22=4>2.
117
Square root of 2.0 by bisection — 1
1.0**2
1.0
Mid-point: 1.0
118
118
Square root of 2.0 by bisection — 2
So what?
Well, y=1 is less than y=2 so the corresponding x-value, x=1 makes an
acceptable lower bound for the interval of uncertainty. And if we change our
lower bound to this value then our interval only runs from x=1 to x=2 with
total length 1, rather than its original length 2.
We have halved our uncertainty.
If we can do this trick multiple times then we will reduce the interval of
uncertainty very quickly to a length so small as to be irrelevant.
119
Square root of 2.0 by bisection — 3
1.5**2
2.25
Mid-point: 1.5
120
120
Square root of 2.0 by bisection — 4
121
Square root of 2.0 by bisection — 5
1.25**2
1.5625
Mid-point: 1.25
122
We find the new mid-point again, x=1.25. Squaring this gives the
corresponding y-value y=1.5625.
122
Square root of 2.0 by bisection — 6
y=1.5625 is less than y=2 so we change the lower bound. Our interval of
uncertainty now has length ¼.
123
Square root of 2.0 by bisection — 7
1.375**2
1.890625
Mid-point: 1.375
124
And again…
124
Square root of 2.0 by bisection — 8
125
Exercise 6
2 minutes
126
1.375 < √2 < 1.5
Please make sure that you understand the principle and do one more
iteration by hand.
126
Understanding before Programming
127
Apologies for spending so long on the maths but this is a general situation.
You must understand the situation before you can program it.
127
And now using Python!
lower = 0.0
upper = 2.0
middle = (lower+upper)/2
128
128
And now using Python — 2
True
lower = middle
print(lower, upper)
1.0 2.0
129
Next, we find the y‑value corresponding to the mid-point (by squaring the
x‑value 1.0) and ask if it is less than 2.0, the number whose square root we
are looking for.
middle**2 < 2.0
Recall that this will return a Python boolean value: True or False.
The squared value is 1.0 which is less than 2.0 (i.e. we get True) so we
raise the lower limit of the interval to the mid-point.
lower = middle
In this example we print the x‑value at each end of the interval to track our
progress.
129
And now using Python — 3
middle = (lower+upper)/2
print(middle, middle**2)
1.5 2.25
130
So we do it again.
We re-calculate the x‑value for the mid-point. Note that because we
changed the value the name lower was attached to the Python instruction is
identical to the one we gave first time round:
middle = (lower+upper)/2
We do some additional printing to track progress.
130
And now using Python — 4
False
upper = middle
print(lower, upper)
1.0 1.5
131
Again, we ask if the mid-point’s y‑value (i.e. its x‑value squared) is above or
below our target of 2.0:
middle**2 < 2.0
and this time get a boolean False. Because the value is greater than 2.0
(our test evaluates to False) we change the value of the upper bound of the
interval by attaching the name upper to the x‑value of the mid-point:
upper = middle
The values being handled are exactly the same as they were when we did it
as “raw maths” but this time they have names.
131
And now using Python — 5
middle = (lower+upper)/2
print(middle, middle**2)
1.25 1.5625
132
132
And now using Python — 6
True
lower = middle
print(lower, upper)
1.25 1.5
133
133
And now using Python — 7
middle = (lower+upper)/2
print(middle, middle**2)
1.375 1.890625
134
Fourth iteration.
134
And now using Python — 8
True
lower = middle
print(lower, upper)
1.375 1.5
135
135
Looking at the Python code
lower = 0.0
upper = 2.0
middle = (lower+upper)/2
print(middle, middle**2)
✔ ? ✘
lower = middle upper = middle
136
Looking at the Python structures
lower = 0.0 Set up
upper = 2.0
Loop
middle = (lower+upper)/2
print(middle, middle**2)
Choice
middle**2 < 2.0
✔ ? ✘
lower = middle upper = middle
137
Looping
Before
Should the
Loop test
loop run
✘ ✔ (again)?
What is
Loop body run each
loop?
After
138
138
Loop example: Count from 1 to 10
Before number = 1
✘ ✔ ✘ ✔
print(number)
Loop body number += 1
After print('Done!')
139
Let’s consider an example that’s simpler than our square root loop: counting
from 1 to 10.
Our “before” block initializes the attachment of a name number to a value 1:
number = 1
Our test sees if number is attached to a value less than or equal to 10 (our
final value):
number <= 10
Recall that this evaluates to a boolean value.
If the test evaluates to True then we run the loop body. This has two lines,
the first to print the value of number and the second to increase it by one:
print(number)
number += 1
If the test evaluates to False then we don’t loop and exit the structure. We
have a pointless print statement as a place-holder for more substantive
code in serious scripts:
print('Done!')
This is what we want to encode in Python.
139
Loop example: Count from 1 to 10
number = 1 number = 1
✘ ✔
print('Done!') print('Done!')
140
140
Loop test: Count from 1 to 10
number = 1
“while” keyword
loop test
while number <= 10 : colon
␣␣␣␣ print(number)
␣␣␣␣ number += 1
print('Done!')
141
We will start by looking at what we have done to the test. The test itself is
number <= 1
which is a Python expression that evaluates to a boolean, True or False.
We precede the test expression with the Python keyword “while”. This is
what tells Python that there’s a loop coming. It must be directly followed by
an expression that evaluates to a Boolean.
We follow the test expression with a colon. This is the marker that the
expression is over and must be the last element on the line.
Note that the test evaluates to True for the loop to be run and False for the
loop to quit. We are testing for “shall the loop keep going” not “shall the loop
stop”. Python tests for while, not until.
141
Loop body: Count from 1 to 10
number = 1
␣␣␣␣ print(number)
␣␣␣␣ number += 1 loop body
indentation
print('Done!')
142
The loop body, the code that is repeated, appears on the lines following the
“while line”. Both its lines are indented by four spaces each.
Note that the “after” section is not indented.
142
Loop example: Count from 1 to 10
$ python3 while1.py
number = 1
1
while number <= 10 : 2
3
print(number)
4
number += 1
5
6
print('Done!') 7
8
9
while1.py 10
Done!
$
143
First let’s check that this really works. In the file while1.py in your home
directories you will find exactly the code shown in the slide. Run it and watch
Python count from 1 to 10.
143
Python’s use of indentation
number = 1
The four spaces of indentation are not cosmetic. A sequence of lines that
have the same indentation form blocks in Python and can be thought of as a
single unit of code. In this case both lines get run (again) or neither of them
do.
The indented block is ended by the first line that follows it with no
indentation.
144
c.f. “legalese”
1
1(a)
1(b)
1(b)(i)
1(b)(ii)
1(b)(iii)
1(c)
2
3
145
145
Other languages
C while ...
{ { ... } Syntax
␣␣␣␣...
␣␣␣␣... ␣␣␣␣... Clarity
}
146
146
Progress
while ... : before
while test :
test to keep looping ␣␣␣␣action1
␣␣␣␣action2
␣␣␣␣action3
code blocks
afterwards
␣␣␣␣indentation
147
147
Exercise 7
while6.py
148
Back to our square root example
uncertainty tolerance
0.0 2.0
2.0 1.0×10–15
×½
1.0 2.0
1.0
What we want
×½
1.0 1.5
0.5
×½
1.25 1.5
0.25
×½
1.375 1.5
0.125 What we get 149
Now let’s return to our square root example. We have a loop the body of
which halves the length of the interval of uncertainty. We need to put this
into a Python loop so we need a corresponding loop test.
One typical approach is to test to see if the interval is longer than some
acceptable value. In this case we will demand that the interval have length
no longer than 10-15. (It will take 51 halvings to get from an initial length of
2.0 to something less than 10-15.)
A common name for an “acceptable uncertainty” is a “tolerance”: the amount
of uncertainty we are prepared to tolerate.
149
Keep looping while … ?
uncertainty > tolerance
150
We need a Python test for this. Recall that Python needs a test that
evaluates to True for the loop body to run. Our test then is ”is the current
uncertainty larger than the acceptable tolerance?”
We will set a name, tolerance, to have the value 1.0e-15, calculate an
uncertainty each loop and perform the test
uncertainty > tolerance
If this is True then we need to keep going.
If it is False then we can stop.
150
Square root: the loop
tolerance = 1.0e-15 Set up
lower = 0.0
upper = 2.0
uncertainty = upper - lower
Loop
while uncertainty > tolerance :
print(lower, upper)
151
uncertainty = upper - lower
So, if we return to our basic structure we can now see how Python’s while
syntax fits in.
We establish a tolerance.
We establish an initial uncertainty.
We test for
uncertainty > tolerance
as the loop test.
We recalculate the uncertainty at the end of the loop block for use in the
next round of the test.
151
Choosing
Choice
middle**2 < 2.0
✔ ? ✘
lower = middle upper = middle
Once again we have a test followed by some actions. This time, however,
the test doesn’t decide whether or not to run a block of code again, but
rather which of two blocks of code to run once.
Our test ― a Python expression that evaluates to a boolean ― is simply:
middle**2 < 2.0
and if this evaluates to True then we change the lower bound:
lower = middle
and if it evaluates to False then we change the upper bound:
upper = middle
Either way, once one or the other has run we move on and do not return to
the test.
152
Simple example
text = input('Number? ') $ python3 ifthenelse1.py
number = int(text)
Number? 8
if number % 2 == 0: Even number
print('Even number') That was fun
else:
print('Odd number')
153
153
if…then… else… ― 1
if keyword
Test
if number % 2 == 0 : Colon
else :
154
The first line of the test looks very similar to the while syntax we have
already seen. In this case, however, it uses a new keyword: “if”.
The if keyword is followed by the test: a Python expression that evaluates
to a boolean.
The line ends with a colon.
154
if…then… else… ― 2
if number % 2 == 0 :
155
The test line is immediately followed by the block of code that is run if the
test evaluates as True.
Because it is a block of code it is indented by four spaces to mark it as a
block. This example has a single line, but the block can be as long as you
want.
This block is sometimes called the “then-block” because “if the test is True
then run this block”.
155
if…then… else… ― 3
if number % 2 == 0 :
156
After the then-block comes another new keyword, “else:”. This is not
indented and is level with the “if” to indicate that it is not part of the then-
block.
It is then followed by a second block of code, know as the “else-block”. This
is the code that is run if the test evaluates as False.
Again, because it is a block of code it is indented.
The else keyword and its corresponding block are optional. You can do
nothing if the test returns False. The then-block is compulsory.
156
if…then… else… ― 4
if number % 2 == 0 :
else :
157
After the else-block the script continues. The print line is unindented so is
not part of the else-block. This line is run regardless of the result of the test.
157
Our square root example
middle = (lower + upper)/2 Before
158
Progress
if ... : before
else: if test :
␣␣␣␣action1
␣␣␣␣action2
choice of two else:
code blocks ␣␣␣␣action3
afterwards
␣␣␣␣indentation
159
159
Exercise 8
5 minutes
160
160
Back to our example
tolerance = 1.0e-15
lower = 0.0
upper = 2.0
uncertainty = upper - lower
So how do we embed an if-test with its two code blocks inside a while-loop
as the loop’s body?
The body of the while-loop is indented four spaces. So we start the if-test
indented four spaces and make its indented blocks doubly indented.
161
Levels of indentation
tolerance = 1.0e-15
lower = 0.0
upper = 2.0
uncertainty = upper - lower
162
Trying it out
tolerance = 1.0e-15 $ python3 sqrt1.py
lower = 0.0
upper = 2.0 1.0 2.0
uncertainty = upper - lower 1.0 1.5
1.25 1.5
while uncertainty > tolerance :
1.375 1.5
middle = (lower + upper)/2
1.375 1.4375
if middle**2 < 2.0: 1.40625 1.4375
lower = middle 1.40625 1.421875
else:
upper = middle
...
print(lower, upper)
uncertainty = upper - lower 1.414213... 1.414213...
sqrt1.py
☺ 163
The file sqrt1.py in your home directories contains the code as described
in the slide. It produces a very nice approximation to the square root of 2.
163
Script for the square root of 2.0
tolerance = 1.0e-15
lower = 0.0
upper = 2.0 √2.0
uncertainty = upper - lower
So now we have the script for the square root of 2. The next thing to do is to
generalize it to produce square roots of any number.
164
Input target
165
165
Initial bounds?
lower = ?
upper = ?
if...then...else...
166
166
Initial bounds
167
167
Generic square root script?
text = input('Number?␣')
number = float(text)
User input
tolerance = 1.0e-15
uncertainty = upper - lower
168
Negative numbers?
"else" is optional
169
We can improve our code. A step missing from the previous script is “input
validation” where we check that the input makes sense. We ought to check
that we have not been asked to generate the square root of a negative
number.
169
“Chained” tests
...
170
The input validation phase comes straight after the input itself.
170
“Chained” tests ― syntactic sugar
text = input('Number?␣')
number = float(text)
...
171
sqrt3.py
However, it can be integrated with the initialization phase, and often is. After
all, if you can’t initialize from the input then the input isn’t valid.
This leads us to a multi-stage test of the number whose square root we
want:
Is it less than 0?
If not, is it less than 1?
If not then…
Python has an extension to the simple if…else… test to allow for the “if
not then is it…” situation.
“elif” introduces a test and a corresponding block of code. The code is
called only if the previous if… test failed and its own test passes.
171
Without elif…
text = input('Number?␣')
number = float(text)
172
With elif…
text = input('Number?␣')
number = float(text)
173
173
Progress
Nested structures while … :
if … :
Chained tests if … :
…
elif … :
…
Testing inputs to scripts elif … :
…
else:
…
exit() 174
174
Exercise 9
Only do the second part after exercise9.py
you have the first part working!
5 minutes
175
175
Comments
176
176
Python comment character
#
a.k.a. “pound”, “number”, “sharp”
177
Python, in common with most other scripting languages, uses the hash
character to introduce comments. The hash character and everything
beyond it on the line is ignored.
(Strictly speaking the musical sharp character “ ♯” is not the same as “#” but
people get very sloppy with similar characters these days. This isn’t at all
relevant to Python but the author is an annoying pedant on the correct use
of characters. And don’t get him started on people who use a hyphen when
they should use an en-dash or em-dash.)
177
Python commenting example
178
On a real Unix system…
#!/usr/bin/python3
$ fubar.py
instead of
$ python3 fubar.py
179
You may encounter a “hash pling“ first line in many imported Python scripts.
This is part of some “Unix magic” that lets us simplify our command lines.
We can’t demonstrate it here because the MCS file server doesn’t support
Unix semantics.
179
Progress
Comments
“#” character
#
180
180
Exercise 10
2 minutes
181
181
Recap: Python types so far
182
Lists
[ -3.141592653589793, -1.5707963267948966,
0.0, 1.5707963267948966, 3.141592653589793 ]
183
183
What is a list?
hydrogen, helium, lithium, beryllium, …, protactinium, uranium
So what is a list?
A list is simply a sequence of values stored in a specific order with each
value identified by its position in that order.
So for an example consider the list of names of the elements up to uranium.
184
What is a list?
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59
185
Creating a list in Python
A literal list
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19] The whole list
>>> type(primes)
<class 'list'> A Python type
186
186
How Python presents lists
Square brackets
at the ends
187
187
Square brackets
188
We are going to meet square brackets used fr a lot of things so I will build
up a summary slide of their various uses. Here is use 1.
188
Python counts from zero
“index” 0 1 2 3 4 5 6 7
189
We still need to get at individual items in the list. Each is identified by its
position in the list.
Python, in common with many programming languages (but not all) starts its
count from zero. The leading element in the list is “item number zero”. The
one that follows it is “item number one” and so on. This number, the position
in the list counting from zero, is called the “index” into the list. The plural of
“index” is “indices”.
To keep yourself sane, we strongly recommend the language “item
number 3” instead of “the fourth item”.
189
Looking things up in a list
>>> primes = [ 2, 3, 5, 7, 11, 13, 17, 19]
0 1 2 3 4 5 6 7
190
Square brackets
191
191
Counting from the end
>>> primes = [ 2, 3, 5, 7, 11, 13, 17, 19]
0 1 2 3 4 5 6 7
-8 -7 -6 -5 -4 -3 -2 -1
Python has a trick for getting at the last element of the list. Negative indices
are also valid and count backwards from the end of the list. Typically the
only case of this that is used in paractice is that the index -1 gets the last
element of the list.
192
Inside view of a list
list
8 int 2 primes[0]
int 3 primes[1]
primes
…
int 17 primes[6]
int 19 primes[7]
193
We’ve seen these box diagrams for simple Python types already. The
structures for lists are a little more complicated but only a little. The list type
records how long it is and an ordered set of references to the actual objects
it contains.
193
Length of a list
list
>>> len(primes)
8 8
0 len() function:
length of list
primes
Maximum
7
index is 7
194
Note that the length of a list is the number of items it contains. The largest
legitimate index is one less than that because indices count from zero.
194
Changing a value in a list
>>> data = ['alpha', 'beta', 'gamma'] The list
So far we have created lists all in one go by quoting a literal list. We can use
the indexing notation (square brackets) to change items in a list too.
195
Changing a value in a list ― 1
Right to left
>>> data = ['alpha', 'beta', 'gamma']
list
3 str 5 a l p h a
str 4 b e t a
str 5 g a m m a
196
We can track what happens in that example in some detail. We will start with
the first line, defining the initial list.
As ever, Python assignment is done right to left. The right hand side is
evaluated as a list of three items, all of themstrings.
196
Changing a value in a list ― 2
Right to left
>>> data = ['alpha', 'beta', 'gamma']
list
3 str 5 a l p h a
data
str 4 b e t a
str 5 g a m m a
197
197
Changing a value in a list ― 3
Right to left
>>> data[2] = 'G'
list
3 str 5 a l p h a
data
str 4 b e t a
str 5 g a m m a
Now we come to the second line which changes one of these list items.
The right hand side is evaluated as a string containing a single characters.
That object gets created.
198
Changing a value in a list ― 4
Right to left
>>> data[2] = 'G'
list
3 str 5 a l p h a
data
str 4 b e t a
str 5 g a m m a
No longer
str 1 G referenced
199
199
Changing a value in a list ― 5
Right to left
>>> data[2] = 'G'
list
3 str 5 a l p h a
data
str 4 b e t a
str 1 G
200
Python then clears out the memory used for that old string so that it can
reuse it for something else. This process is called “garbage collection” in
computing.
200
Removing an entry from a list ― 1
>>> del data[1]
list
3 str 5 a l p h a data[0]
data
✗ str 4 b e t a data[1]
str 5 g a m m a data[2]
201
We can remove entries from the list too with the “del” keyword, just as we
removed names. The del keyword removes the reference from the list.
201
Removing an entry from a list ― 2
>>> del data[1]
list
2 str 5 a l p h a data[0]
data
No longer
str 4 b e t a
referenced
str 5 g a m m a data[1]
202
202
Removing an entry from a list ― 3
>>> del data[1]
list
2 str 5 a l p h a data[0]
data
str 5 g a m m a data[1]
203
203
Running off the end
list
8 int 2
int 3
primes
…
int 17
int 19
204
primes[8]
204
Running off the end
>>> len(primes)
8
>>> primes[7]
19
>>> primes[8]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
205
Type of error Description of error
205
Running off the end
>>> primes[8] = 23
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
206
Note that we can’t use indicies beyond the limit to extend a list either.
206
Progress
index primes[4]
Length len(primes)
Over-running primes[8]
207
207
Exercise 11
>>> numbers[1] = 3
>>> numbers[3] = 37
Do this yb hand. The script exercise11.py will tell you if you were right.
208
How can we add to a list?
list Same list list
8 New length 9
int 2 int 2
… ? …
int 17 int 17
int 19 int 19
209
Appending to a list
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19]
This is the Python syntax for appending an item to the end of a list. You
won’t recognise the syntax; it is something new.
210
primes.append() ?
The list
A connecting dot
211
211
“Methods”
Behaves just
like a function
These built in functions are called “methods” or, more precisely, “methods of
the object” are used all over Python and are a general concept across an
entire type of programming called “object oriented programming”.
212
Using the append() method
>>> print(primes)
[2, 3, 5, 7, 11, 13, 17, 19]
>>> primes.append(23)
The function doesn’t
return any value.
>>> primes.append(29)
>>> primes.append(31)
It modifies
>>> primes.append(37)
the list itself.
>>> print(primes)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37] 213
We can use the append() method repeatedly to extend the list as far as we
want.
213
Other methods on lists: reverse()
>>> numbers.reverse()
The function doesn’t
return any value.
>>> print(numbers)
It modifies
[1, 5, 7, 4]
the list itself.
214
214
Other methods on lists: sort()
>>> 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
!
Much better
>>> sqrt(2.0) to track the
module.
1.4142135623730951
>>> 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
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']
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']
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
Don’t be afraid to convert it explicitly into a list. Unless you dictionary is huge
you won’t see any problem with this.
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)
That something else is to create it with its initial value of 1 (because we have
met the word once now).
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'
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'
413
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'
414
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
Congratulations!
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
431
431
Python 3 formatting codes
Use of the format() method:
>>> '{:4s}␣{:3d}'.format('Dave', 27)
'Dave␣␣27'
>>>
The symbol “␣” is used to represent a space.
Strings
hello
{:s} hello
{:10s} hello␣␣␣␣␣
{:<10s} hello␣␣␣␣␣
{:>10s} ␣␣␣␣␣hello
Integers
1,234 -1,234
{:d} 1234 -1234
{:10d} ␣␣␣␣␣␣1234 ␣␣␣␣␣-1234
{:<10d} 1234␣␣␣␣␣␣ -1234␣␣␣␣␣
{:>10d} ␣␣␣␣␣␣1234 ␣␣␣␣␣-1234
{:+10d} ␣␣␣␣␣+1234 ␣␣␣␣␣-1234
{:010d} 0000001234 -000001234
{:+010d} +000001234 -000001234
{:10,d} ␣␣␣␣␣1,234 ␣␣␣␣-1,234
{:+10,d} ␣␣␣␣+1,234 ␣␣␣␣-1,234
Floating point
3.141592653589793 -1.2
{:f} 3.141593 -1.200000
{:10f} ␣␣3.141593 ␣-1.200000
{:10.5f} ␣␣␣3.14159 ␣␣-1.20000
{:<10.5f} 3.14159␣␣␣ -1.20000␣␣
{:>10.5f} ␣␣␣3.14159 ␣␣-1.20000
{:+10.5f} ␣␣+3.14159 ␣␣-1.20000
{:010.5f} 0003.14159 -001.20000
{:+010.5f} +003.14159 -001.20000