0% found this document useful (0 votes)
13 views

Python3 Notes

Uploaded by

khmfbbnc
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

Python3 Notes

Uploaded by

khmfbbnc
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 215

An introduction to Python

for absolute beginners

Bob Dowling
University Computing Service
scientific-computing@ucs.cam.ac.uk

http://www.ucs.cam.ac.uk/docs/course-notes/unix-courses/PythonAB 1

Welcome to the Computing Service's course “Introduction to Python”.


This course is designed for people with absolutely no experience of programming.
If you have any experience in programming other languages you are going to find
this course extremely boring and you would be better off attending our course
"Python for Programmers" where we teach you how to convert what you know
from other programming languages to Python.
This course is based around Python version 3. Python has recently undergone a
change from Python 2 to Python 3 and there are some incompatibilities between
the two versions. The older versions of this course were based around Python 2
but this course is built on Python 3.
Python is named after Monty Python and its famous flying circus, not the snake. It
is a trademark of the Python Software Foundation.

1
Course outline ― 1
Who uses Python & what for
What sort of language it is

How to launch Python


Python scripts

Text
Names for values
Reading in user data
Numbers
Conversions
Comparisons
Truth & Falsehood
2

2
Course outline ― 2
Assignment
Names

Our first “real” program

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

Writing our own functions

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

So who uses Python and what for?


Python is used for everything! For example:
“massively multiplayer online role-playing games” like Eve Online, science
fiction’s answer to World of Warcraft,
web applications written in a framework built on Python called “Django”,
desktop applications like Blender, the 3-d animation suite which makes
considerable use of Python scripts,
the Scientific Python libraries (“SciPy”),
instrument control and
embedded systems.

6
What sort of language is Python?

Compiled Interpreted

Explicitly Explicitly Implicitly Purely


compiled compiled compiled interpreted
to machine to byte to byte
code code code

C, C++, Java, C# Python Shell,


Fortran Perl

What sort of language is Python? The naïve view of computer languages is


that they come as either compiled languages or interpreted languages.
At the strictly compiled end languages like C, C++ or Fortran are "compiled"
(converted) into raw machine code for your computer. You point your CPU at
that code and it runs.
Slightly separate from the strictly compiled languages are languages like
Java and C# (or anything running in the .net framework). You do need to
explicitly compile these programming languages but they are compiled to
machine code for a fake CPU which is then emulated on whichever system
you run on.
Then there is Python. Python does not have to be explicitly compiled but
behind the scenes there is a system that compiles Python into an
intermediate code which is stashed away to make things faster in future.
But it does this without you having to do anything explicit yourself. So from
the point of view of how you use it you can treat it as a purely interpreted
language like the shell or Perl.

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 version

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

>>> print('Hello, world!')

Hello, world! Output

>>> Python prompt

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”

print ≠ PRINT “Case sensitive”

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

The quotes are not


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

So what do the quotes “do”?


If there are no quotes then Python will try to interpret the letters as
something it should know about. With the quotes Python simply interprets it
as literal text.
For example, without quotes the string of characters p-r-i-n-t are a
command; with quotes they are the text to be printed.

14
Python scripts
File in home directory print('Hello, world!')

Run from Unix prompt


hello1.py

Unix prompt

Unix command
to run Python

$ python3 hello1.py Python script

Hello, world! Python script’s output

$ Unix prompt 15

So we understand the “hello, world” command and how to run it from an


interactive Python. But serious Python programs can’t be typed in live; they
need to be kept in a file and Python needs to be directed to run the
commands from that file.
These files are called “scripts” and we are now going to look at the Python
script version of “hello, world”.
In your home directories we have put a file called “hello1.py”. It is
conventional that Python scripts have file names ending with a “.py” suffix.
Some tools actually require it. We will follow this convention and you should
too.
This contains exactly the same as we were typing manually: a single line
with the print command on it.
We are going to make Python run the instructions out of the script. We call
this “running the script”.
Scripts are run from the Unix command line. We issue the Unix command
“python3” to execute Python again, but this time we add an extra word: the
name of the script, “hello1.py”.
When it runs commands from a script, python doesn’t bother with the lines
of blurb and as soon as it has run the commands (hence the output) it exists
immediately, returning control to the Unix environment, so we get a Unix
prompt back.

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

This will launch the text editor, gedit.

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

Simple Python text

20

20
Exercise 1

1. Print “Goodbye, cruel world!” from interactive Python.

2. Edit exercise1.py to print the same text.

3. Run the modified exercise1.py script.

❢ Please ask if you have questions.

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

Full “Unicode” support

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
˘

AltGr + Shift + # g Linux

ğ Character Selector

“LATIN SMALL
LETTER G \u011f
WITH BREVE”

23

I don’t want to get too distracted by international characters, but I ought to


mention that the hardest part of using them in Python is typically getting
them into Python in the first place.
There are three “easy” ways.
There are key combinations that generate special characters. On Linux, for
example, the combination of the three keys [AltGr], [Shift], and [#] set up the
breve accent to be applied to the next key pressed.
Perhaps easier is the “Character Selector” application. This runs like a free-
standing “insert special character” function from a word processor. You can
select a character from it, copy it to the clipboard and paste it into any
document you want.
Finally, Python supports the idea of “Unicode codes”. The two characters
“\u” followed by the hexadecimal (base 16) code for the character in the
Unicode tables will represent that character. You have all memorized your
code tables, haven’t you?

23
Text: a “string” of characters

>>> type('Hello, world!')

<class 'str'> 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

>>> '\u011f' 011f16


'ğ'

>>> 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: +

“Concatenation” print('Hello, ' + 'world!')

hello3.py
>>> 'Hello, ' + 'world!'

'Hello, world!'

>>>

26

Now let’s do something with strings.


If we ‘add’ two strings together Python joins them together to form a longer
string.
Python actually permits you to omit the “+”. Don’t do this.

26
Pure concatenation
>>> 'Hello,␣' + 'world!'

'Hello, world!'

>>> 'Hello,' + '␣world!' Only simple


concatenation
'Hello, world!'

>>> 'Hello,' + 'world!' No spaces added


automatically.
'Hello,world!'
27

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

>>> 'Hello, world!' Single quotes

'Hello, world!' Single quotes

>>> "Hello, world!" Double quotes

'Hello, world!' Single 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.

'Hello, world!' Single quotes on output.

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

>>> print('He said "hello" to her.')

He said "hello" to her.

>>> print("He said 'hello' to her.")

He said 'hello' to her.

30

Having two sorts of quotes can be useful in certain circumstances. If you


want the text itself to include quotes of one type you can define it
surrounded by the other type.

30
Why we need different quotes

>>> print('He said 'hello' to her.')

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

>>> print('He said \'hello\' to her.')

He said 'hello' to her.

\' ' Just an ordinary


character.

\" " “Escaping”

32

There is a more general solution to the “quotes within quotes” problem.


Preceding each quote within the body of the text signals to Python that this
is just an ordinary quote character and should not be treated specially.
Note that what is encoded in the string is a single character. The backslash
is a signal to the Python interpreter as its constructs the string. Once the
string is constructed, with quotes in it, the backslash’s work is done.
This process of flagging a character to be treated differently than normal is
called “escaping” the character.

32
Putting line breaks in text
Hello,
world! What we want

>>> print('Hello, ↵ Try this


world')

>>> print('Hello, ↵
File "<stdin>", line 1
print('Hello,
^
SyntaxError: EOL while
scanning string literal
✘ “EOL”: End Of Line
33

We will follow the theme of “inserting awkward characters into strings” by


looking at line breaks.
We cannot insert a line break by hitting the [ ↵] key. This signals to Python
that it should process the line so far and Python cannot; it is incomplete.

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

Again, the backslash character comes to our rescue.


If we create a string with the sequence “\n” then Python interprets this as
the single character ↵.
Python can tell us exactly how many characters there are in a string. The
len() function tells us the length of the string in characters. There are 13
characters in the string created by 'Hello,\nworld!'. The quotes are
not part of the text and the \n becomes a single character.

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!'''

'Hello\nworld' Exactly the same!

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

1. Replace XXXX in exercise2.py so it prints the following


text (with the line breaks) and then run the script.

coffee
café
caffè
Kaffee

è \u00e8 AltGr + ; e

é \u00e9 AltGr + # e 3 minutes


42

There is more than one way to do this.


You can get the line breaks with \n in a single-quoted string or with literal
line breaks in a triple-quoted string. An alternative, but not in keeping with
the exercise, is to have four print() statements.
You can get the accented characters by using the \u sequences or you can
type them in literally with the keyboard combinations shown. (Linux only)

42
Attaching names to values
“variables” message = 'Hello, world!'
print(message)
>>> message='Hello, world!'

>>> message hello4.py

'Hello, world!'

>>> type(message)

<class 'str'>

message str 13 H e l l o , ␣ w o r l d !
43

Now we will move on to a serious issue in learning any computing language:


how to handle names for values.
Compare the two scripts hello1.py and hello4.py. They both do exactly
the same thing.
We can enter the text of hello4.py manually if we want using interactive
Python, it will work equally well there.
The first line of hello4.py creates the string ‘Hello, world!’ but instead of
printing it out directly the way that hello1.py does, it attaches a name,
“message”, to it.
The second line runs the print() function, but instead of a literal string as
its argument it has this name instead. Now the name has no quotes around
it, and as I said earlier this means that Python tries to interpret it as
something it should do something with. What it does is to look up the name
and substitute in the attached value.
Whenever the name is used, Python will look it up and substitute in the
attached value.

43
Attaching names to values
message = 'Hello, world!'
print(message)
>>> type(print)

<class 'builtin_function_or_method'> hello4.py

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)

$ python3 input1.py input1.py

input('Yes?␣')

Yes? Boo! message = …

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

Traceback (most recent call last):


File "input2.py", line 2, in <module>
print(number + 1 )
TypeError:
Can't convert 'int' object
to str implicitly

string integer 46

In the previous example script input1.py we simply took what we were


given by input() and printed it. The print() function is a flexible beast; it
can cope with almost anything.
The script hello2.py attempts to take what is given and do arithmetic with
it, namely add 1 to it. It fails, even though we type a number at input()’s
prompt.
This also gives us an error message and it’s time to investigate Python’s
error messages in more detail.
The first (the “trace back”) tells us where the error was. It was on line 2 of
the file input2.py. It also tells us what was on the line. Recall that with
syntax errors it also pointed out where in the line it realized something was
going wrong.
The second part tells us what the error was: we tried to add a string (text)
and an integer (a number). More precisely, Python couldn’t convert the
things we were adding together into things that we could add.

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('Hello, world!')

<class 'str'> string of characters

>>> type(42)

<class 'int'> integer

>>> type(3.14159)

<class 'float'> floating point number


48

To date we have seen only two types: “str” and


“builtin_function_or_method”. Here are some more.
Integers (whole numbers) are a type called “int”.
Floating point numbers (how computers approximate real numbers) are a
type called “float”.
The input() function gave is a “str”. We want an “int”.

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

There is a function — also called “int()” ― that converts the textual


representation of an integer into a genuine integer.
It copes with extraneous spaces and other junk around the integer but it
does not parse general expressions. It will take the textual form of a number,
but that's it.

49
Converting text to floats

>>> float('10.0') '10.0' is a string

10.0 10.0 is a floating


point number

>>> float('␣10.␣')

10.0

50

There is a similar function called float() which creates floating point


numbers.

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

>>> str(10) integer string

'10'

>>> str(10.000) float string

'10.0'

52

There is also a str() function for turning things into strings.

52
Converting between types

int() anything integer

float() anything float

str() anything string

Functions named after the type they convert into.

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)

$ python3 input3.py input3.py

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

floating point numbers

Reading in text input(prompt)

Type conversions str() int() float()


55

55
Exercise 3

Replace the two XXXX in exercise3.py to do the following:

1. Prompt the user with the text “How much?␣”.

2. Convert the user’s answer to a floating point number.

3. Print 2.5 plus that number.

3 minutes
56

56
Integers

ℤ {… -2, -1, 0,
1, 2, 3, 4 …}
57

Now that we have some rudimentary understanding of Python it’s time to


dive in a little deeper to the three types we have met so far.
We are going to start with the whole numbers, “integers” in technical
language.
Mathematical note:
The fancy Z is the mathematical symbol for the integers based on the
German word Zahlen.

57
Integer addition & subtraction
>>> 20+5
25

>>> 20␣-␣5 Spaces around the


operator don’t matter.
15

“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

The arithmetical operations addition and subtraction have their usual


mathematical symbols reflected on the standard keyboard. We have a plus
sign and a minus sign (actually a “hyphen”) character and we use them.
There is no multiplication symbol on the standard keyboard. You can
generate it as one of the octopus-friendly key combinations, but it’s not a
simple key.
Instead, the computing profession has settled on using the asterisk (“*”) to
represent multiplication. On your keyboards this is [Shift]+[8].
Multiplying two integers gives a third integer.

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

There is no division symbol on the keyboard without holding three keys


down at the same time. Again a convention has arisen to use the forward
slash character (strictly called a “solidus”) for division.
So far there have been no surprises in Python’s integer arithmetic. That
changes with division.
Not all integer division can be achieved precisely. You cannot divide 3 into 5
exactly. Because of this Python 3 always returns a type of number capable
of representing fractional values (a floating point number) even when the
division would have been exact.

60
Integer division gives floats !
Fractions Floats sometimes
!
Consistency Floats always

>>> 20␣/␣40
0.5

>>> 20␣/␣30
0.6666666666666666

61

The designers of Python decided that consistency of output was important


and therefore because it might sometimes need to use a float it should
always use a float.
Note that even floating point numbers cannot exactly represent all fractions.
½ can be precisely represented but ⅔ cannot. We will return to the
imprecision of floating point numbers when we look at them in detail.
(If you really want to stick to integers then Python 3 offers the “//“ operator
which returns an integer answer, rounded strictly down in case of fractional
answers.)

61
Integer powers
There is no “42” on the keyboard.

Use “**” instead

>>> 4␣**␣2 Spaces around the


operator don’t matter.
16

>>> 4*␣*2 Spaces in the


operator do!
SyntaxError: invalid syntax

62

Just as there is no mathematical symbol on the keyboard for multiplication


and division, there is no symbol at all for raising to powers. Mathematically
we represent it by superscripting the power after the number being raised.
We can’t do this on the keyboard so instead we cheat and invent our own
symbol for the operation.
Computing has split for this operation. Some languages use the circumflex
accent (“^”) and others, including Python, use a double asterisk, “**”.
Note that while spaces around the operator are ignored you can’t split the
two asterisks.

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

Python takes it in its stride and happily carries on.

65
How big can a Python integer be?
10443888814131525066917527107166243825799642490473837803842334832839
53907971557456848826811934997558340890106714439262837987573438185793
60726323608785136527794595697654370999834036159013438371831442807001
18559462263763188393977127456723346843445866174968079087058037040712
84048740118609114467977783598029006686938976881787785946905630190260
94059957945343282346930302669644305902501597239986771421554169383555
98852914863182379144344967340878118726394964751001890413490084170616
There is no limit!
75093668333850551032972088269550769983616369411933015213796825837188
09183365675122131849284636812555022599830041234478486259567449219461
70238065059132456108257318353800876086221028342701976982023131690176
78006675195485079921636419370285375124784014907159135459982790513399
61155179427110683113409058427288427979155484978295432353451706522326
90613949059876930021229633956877828789484406160074129456749198230505
Except for
71642377154816321380631045902916136926708342856440730447899971901781
machine
46576347322385026725305989979599609079946920177462481771844986745565
memory
92501783290704731194331655508075682218465717463732968849128195203174
57002440926616910874148385078411929804522981857338977648103126085903
00130241346718972667321649151113160292078173803343609024380470834040
3154190336
66

The Python language has no limit on the size of integer.

66
Big integers
2
C / C++
Fortran
4

16
int
INTEGER*4 256

long 65536
INTEGER*8
4294967296
long long
INTEGER*16 18446744073709551616

Out of the reach 3402823669209384634…


67
of C or Fortran! 63374607431768211456

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

>>> 20.0 * 5.0 >>> 20.0 / 5.0


100.0 4.0

>>> 20.0 ** 5.0 Equivalent to integer arithmetic


3200000.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

>>> 10.0 / 3.0


If you are relying on
3.3333333333333335 this last decimal place,
you are doing it wrong!

≈ 17 significant figures

70

So let’s see our first problem.


Floating point arithmetic is not exact, and cannot be.
Floating point numbers on modern hardware tends to give a precision of
17 significant figures. You do see the occasional issue as shown on the slide
but, frankly, if you are relying on the exact value of the final decimal place
you are doing it wroing.

70
Hidden imprecision
>>> 0.1
!
0.1

>>> 0.1 + 0.1


0.2

>>> 0.1 + 0.1 + 0.1


Really: if you are relying on
0.30000000000000004 this last decimal place,
you are doing it wrong!
71

Not all imprecision is overt. Some of it can creep up on you.


Computers work in base 2. They can store numbers like ½ and ⅞ exactly.
But they cannot store numbers like 1/10 exactly, just like we can’t represent
⅓ exactly in a decimal expansion.
The errors in storing 1/10 are small enough, though, that they are invisible at
first. However, if they accumulate they become large enough to show
through.
Really: don’t depend on precise values.

71
How big can a Python float be? ― 1
>>> 65536.0**2 So far, so good.
4294967296.0

>>> 4294967296.0**2 Switch to


1.8446744073709552e+19 “scientific notation”

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

>>> 4294967296**2 Integer


18446744073709551616

1.8446744073709552×1019 18446744073709552000

- 18446744073709551616

384
73

The approximation isn’t bad. The error is 384 in 18446744073709551616, or


approximately 2×10-17.

73
How big can a Python float be? ― 2
>>> 1.8446744073709552e+19**2
3.402823669209385e+38

>>> 3.402823669209385e+38**2
1.157920892373162e+77

>>> 1.157920892373162e+77**2 So far, so good.


1.3407807929942597e+154

>>> 1.3407807929942597e+154**2 Too big!


OverflowError: (34,
'Numerical result out of range')

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

-325 < N < 308

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!

Floating point numbers Limited size

Limited precision

Complex numbers

77

77
Exercise 4

Replace the XXXX in exercise4.py to evaluate


and print out the following calculations:

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

We can do arithmetic on numbers. What else?


We need to be able to compare numbers.
Is 5 less than 10? Yes it is.
Is 5 greater than 10? No it isn’t.

79
Comparisons

>>> 5 < 10 Asking the question


True

>>> 5 > 10 Asking the question
False

80

Now let’s see that in Python.


The “less than” character appears on the keyboard so we don’t need
anything special to express the concept like “**” for powers.
Python seems to answer the questions with “True” and “False”.

80
True & False
>>> type(True)
<class 'bool'> “Booleans”

5 + 10 15 int

int int

5 < 10 True bool


81

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

The boolean type has precisely two values.

82
Six comparisons
Maths Python

= == Double equals sign

≠ !=
< <
> >
≤ <=
≥ >=
83

There are six comparison operations in Python.


The equality comparison is defined in Python with a double equals sign,
“==”. The sign is doubled to distinguish comparison from assignment.
There is no “not equals” symbol on the standard keyboard. Instead, Python
uses the “!=” pair of characters. (As with “**” there must be no space
between the two characters.)
“Less than” and “greater than” we have already covered. These are
implemented directly by the “<” and “>” characters.
There are no “less than or equal to” or “greater than or equal to” keys,
though, so Python resorts to double character sequences again.

83
Equality comparison & assignment

name = value
= Attach a name to a value.

value1 == value2
== Compare two values

84

If ever there was a “classic typo” in programming it is the confusion of “=”


and “==”. Be careful.

84
Textual comparisons

>>> 'cat' < 'dog' Alphabetic ordering

True

>>> 'Cat' < 'cat' Uppercase before lowercase

True

>>> 'Dog' < 'cat' All uppercase before lowercase

True
85

Booleans typically arise from comparisons. We can compare more than


numbers (integers or floating point). We can also compare strings.
Text comparisons are based around the ordering of characters in the
Unicode character set. Note that all the uppercase letters in the Latin
alphabet precede all the lowercase letters. So any text that starts with an
uppercase letter counts as “less than“ any text that starts with a lowercase
letter.

85
Ordering text is complicated
Python inequalities use Unicode character numbers.

This is over-simplistic for “real” use.

“Collation” is a whole field of computing in itself

Alphabetical order? Traditional German usage?

German: z<ö Dictionary: of < öf

Swedish: ö<z Phone book: öf < of


86

Please note, however, that this is just a comparison of strings. It is not a


general comparison of text. Ordering text is called “collation” and is a very
compicated field.
For example, different languages order characters differently. Some
countries have different orderings for different purposes.
If you want to learn more about this field, start with the Unicode page on
collation: http://www.unicode.org/reports/tr10/

86
“Syntactic sugar”
0 < number

0 < number < 10 and

number < 10

>>> number = 5

>>> 0 < number < 10

True
87

A common requirement is to determine if a number lies in a particular range.


For this purpose, Python supports the mathematical notation a < b < c. The
inequalities can be any combination that make sense.

87
Converting to booleans
float() Converts to floating point numbers
<class 'float'>
int() Converts to integers
<class 'int'>
str() Converts to strings
<class 'str'>

bool() Converts to booleans


<class 'bool'>
88

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

'' False Empty string

'Fred' True Non-empty string

0 False Zero

1 True Non-zero

12 True
89
-1 True

The empty string is mapped to False. Every other string is mapped to


True.
For integers, 0 is mapped to False and every other value to True.
For floating point numbers, 0.0 is mapped to False and every other value
to True.

89
Boolean operations
bool
? bool
bool

Numbers have +, –, * … bool ✓

What do booleans have? 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

True and True True Both have


to be True
True and False False

False and True False

False and False False


91

The first operation on Booleans is the “and” operator.


The and of two booleans values is True if (and only if) both its inputs are
True. If either is False then its output is False.
>>> True and False
False
>>> True and True
True

91
Boolean operations ― “and”

>>> 4 < 5 and 6 < 7 4 < 5 True


and True
True 6 < 7 True

>>> 4 < 5 and 6 > 7 4 < 5 True


and False
False 6 > 7 False

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

True or True True At least


one has
True or False True to be True

False or True True

False or False False


93

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”

>>> 4 < 5 or 6 < 7 4 < 5 True


or True
True 6 < 7 True

>>> 4 < 5 or 6 > 7 4 < 5 True


or True
True 6 > 7 False

94

Again, we tend to encounter it more often with other tests than with literal
booleans.

94
Boolean operations ― “not”

bool not bool

not True False

not False True

95

The final operation is “not”. This takes only one input and “flips” it. True
becomes False and vice versa.

95
Boolean operations ― “not”

>>> not 6 < 7 6 < 7 True not False

False

>>> not 6 > 7 6 > 7 False not True

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

x**y -x +x x%y x/y x*y x-y x+y

x==y x!=y x>=y x>y x<=y x<y

not x x and y x or y
99
Last

99
Progress
Comparisons == != < > <= >=

Numerical comparison 5 < 7

Alphabetical ordering 'dig' < 'dug'

Booleans True False

Boolean operators and or not

Order of precedence

100

100
Exercise 5
Predict whether these expressions will evaluate to True or False.
Then try them.

1. 'sparrow' > 'eagle'

2. 'dog' < 'Cat' or 45 % 3 == 15

3. 60 - 45 / 5 + 10 == 1

3 minutes
101

101
Names and values: “assignment”

>>> alpha = 100

1. alpha = 100 Python creates


int 100 an “integer 100”
in memory.

2. alpha = 100 Python attaches


the name “alpha”
to the value.
alpha int 100
102

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

“RHS”: right hand side


Evaluated first

“LHS”: left hand side


Processed second

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

int 100 function + int 20

2. 120
int

3. LHS
beta int 120
104

We can see a slightly more involved example if we put some arithmetic on


the RHS.
Again, the RHS is evaluated first.
First, Python notices three “tokens”: the 100, the name “+” and the 20. It
creates two integer objects just as it did with the previous example and it
looks up a pre-existing function object that does addition of integers.
Second, Python triggers the addition function to generate a third integer with
the value 120.
This completes the evaluation of the RHS.
Third, Python creates a name “beta” and attaches it to the freshly created
integer 120.

104
Names on the RHS — 1
>>> gamma = alpha + 40

alpha + 40 RHS
1.

alpha
2.

int 100 function + int 40

3.
int 140
105

Now we will consider a more significantly involved example, one with a


name on the RHS.
First, Python recognizes the three tokens on the RHS. These are the name
“alpha” the “+” and the literal integer 40.
Second, it looks up the names. The “alpha” is replaced by the integer 100
and the name “+” is replaced by the actual function that does addition. The
token 40 is replaced by the actual integer 40 in memory.
Third, it runs the function to give an integer 140 object in memory.

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

Now (finally!) we get to the interesting case.


We start with the name gamma being attached to the value 140.

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

int 150 RHS


5.
gamma int 140

int 150 RHS

6. gamma int 140


109

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 int
✗ 140 No longer
used.

8. gamma int 150

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”

thing += 10 thing = thing + 10

thing -= 10 thing = thing - 10

thing *= 10 thing = thing * 10

thing /= 10 thing = thing / 10

thing **= 10 thing = thing ** 10

thing %= 10 thing = thing % 10

111

The operation of modifying a value is so common that Python, and some


other languages, have short-cuts in their syntax to make the operations
shorter to write. These operations are called “augmented assignments”.
This sort of short-cut for an operation which could already be written in the
language is sometimes called “syntactic sugar”.

111
Deleting a name ― 1

>>> print(thing)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
NameError: name 'thing' is not defined
Unknown
variable
>>> thing = 1

>>> print(thing)

1
112

There’s one last aspect of attaching names to values hat we need to


consider. How do we delete the attachment?
First of all, let’s see what it looks like when we refer to a name that isn’t
known to the system. The error message is quite straightforward:
name 'thing' is not defined
If we then create the name and attach it to a value, the integer 1 in this
example, we can then use the name without error message.

112
Deleting a name ― 2

>>> print(thing)

1 Known
variable
>>> del thing

>>> print(thing)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
NameError: name 'thing' is not defined
Unknown
113
variable

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

a = a + b a = 17 a has now changed!

b = a - b b = a - b b ≠ 10 - 7 = 3
= 17 - 7
= 10

Later in the course: “tuples”


(a,b) = (a+b, a-b)
114

While we are looking at attaching names to values and changing those


values, we will take the time to review a common “rookie mistake” especially
among people who do linear transformations.
Suppose we want to encode the mapping

(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

Assignment thing = thing + 10

Deletion del thing

Strictly right to left thing = thing + 10


2nd 1st

+= etc. “syntactic sugar” thing += 10

115

115
Our first “real” program

$ python3 sqrt.py We have to write sqrt.py


Number? 2.0
1.414213562373095

First, the maths.


Then, the Python.

116

We now have enough to make a start on “real programming”. We will need


some more Python elements but we can meet them as we need them rather
than up front.
We are going to write a program that prompts for a number and then
calculates and prints out its square root.
First we will review the maths of calculating square roots so that we know
what we are coding. Then we will do it in Python.

116
Square root of 2.0 by “bisection”

0.0 too small for √2

2.0 too large for √2

“Interval of uncertainty”

0.0 < √2 < 2.0


117

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

(0.0 + 2.0) / 2.0


1.0

1.0**2
1.0

Mid-point: 1.0
118

So, what's the trick for halving the interval of uncertainty?


We find the midpoint of the interval. In this case it’s obvious: the half-way
point between x=0 and x=2 is x=1.
Then we square it to find its corresponding value of y. In this case y=12=1.

118
Square root of 2.0 by bisection — 2

1.0**2 < 2.0

so change lower bound

1.0 < √2 < 2.0


119

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.0 + 2.0) / 2.0


1.5

1.5**2
2.25

Mid-point: 1.5
120

So we do it again. The new mid-point lies at x=1.5. This has a


corresponding y-value of y=2.25.

120
Square root of 2.0 by bisection — 4

1.5**2 > 2.0

so change upper bound

1.0 < √2 < 1.5


121

y=2.25 is greater than y=2 so we can use the corresponding x-value of


x=1.5 as our new upper bound. Now the interval of uncertainty is halved in
length again to be ½.

121
Square root of 2.0 by bisection — 5

(1.0 + 1.5) / 2.0


1.25

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

1.25**2 < 2.0

so change lower bound

1.25 < √2 < 1.5


123

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.25 + 1.5) / 2.0


1.375

1.375**2
1.890625

Mid-point: 1.375
124

And again…

124
Square root of 2.0 by bisection — 8

1.375**2 < 2.0

so change lower bound

1.375 < √2 < 1.5


125

…to give an interval of length ⅛.

125
Exercise 6

One more iteration.

Find the mid-point.


Square it.
Compare the square to 2.0.

Do you change the


lower or upper bound?

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

So now let's start the implementation of this process in Python.


We will do exactly the same maths, but this time with Python syntax.
First we set the end points for the interval of uncertainty and attach names
to the two x-values.
The names lower and upper are attached to the end points:
lower = 0.0
upper = 2.0
We establish the x-value of the mid-point and attach the name middle to it:
middle = (lower+upper)/2
This is exactly where we started last time, but we have attached Python
names to the values.

128
And now using Python — 2

middle**2 < 2.0

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

middle**2 < 2.0

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

We now do a third iteration.

132
And now using Python — 6

middle**2 < 2.0

True

lower = middle

print(lower, upper)

1.25 1.5

133

This time the test evaluates to True so we change lower.

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

middle**2 < 2.0

True

lower = middle

print(lower, upper)

1.375 1.5

135

And another True so we change lower again.


And that's enough of stepping through it manually.

135
Looking at the Python code
lower = 0.0
upper = 2.0

middle = (lower+upper)/2
print(middle, middle**2)

middle**2 < 2.0

✔ ? ✘
lower = middle upper = middle

print(lower, upper) 136

Let’s look at the Python code we have used.


We started by initializing our interval of uncertainty:
lower = 0.0
upper = 2.0
Then we started the operations we would repeat by calculating the x‑value
of the mid-point:
middle = (lower+upper)/2
We squared this and compared the squared y‑value with 2.0, our target
value:
middle**2 < 2.0
and, based on whether this evaluated to True or False we ran either:
lower = middle
or:
upper = middle
Then we ran the iteration again.

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

print(lower, upper) 137

Structurally, we need to be able to do two things beyond our current


knowledge of Python. We need to be able to run certain instructions time
and time again (“looping”) and we need to be able to choose one of two
different actions depending on whether a boolean value is True or False.

137
Looping

Before

Should the
Loop test
loop run
✘ ✔ (again)?

What is
Loop body run each
loop?

After
138

We will address looping first.


A loop has a number of components.
Strictly not part of the loop are the “before” and “after” sections but these
give context and may use values needed by the loop.
The loop itself must have some sort of test to indicate whether the loop
should run again or whether the looping can stop and control can pass to
the “after” code.
Then there must be the set of instructions that will be run each time the loop
repeats. We call this the “body” of the loop.

138
Loop example: Count from 1 to 10

Before number = 1

Loop test number <= 10

✘ ✔ ✘ ✔

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

while number <= 10 : number <= 10

✘ ✔

␣␣␣␣ print(number) print(number)


␣␣␣␣ number += 1 number += 1

print('Done!') print('Done!')
140

This is how we encode the structure in Python. We will examine it element


by element, but at first glance we observe a “while” keyword and a colon
on either wise of the test and the loop body being indented four spaces.

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

while number <= 10 :

␣␣␣␣ 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

while number <= 10 :


Four spaces’ indentation
indicate a “block” of code.
␣␣␣␣ print(number)
␣␣␣␣ number += 1
The block forms
print('Done!') the repeated lines.

The first unindented line


marks the end of the block.
144

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

If this seems a little alien consider the “legalese” of complex documents.


They have paragraphs, sub-paragraphs and sub-sub-paragraphs etc., each
indented relative to the one containing them.

145
Other languages

Shell while ...


do do ... done Syntax
␣␣␣␣...
␣␣␣␣... ␣␣␣␣... Clarity
done

C while ...
{ { ... } Syntax
␣␣␣␣...
␣␣␣␣... ␣␣␣␣... Clarity
}
146

Marking blocks of code is one of the places where computing languages


differ from one another.
Some have special words that appear at the start and end of blocks like “do”
and “done”. Others use various forms of brackets like “{” and “}”.
Interestingly, programmers in these languages typically also indent code
within the blocks for visual clarity. Python simply uses the indentation for its
core syntax rather than just for ease of reading.
Purely for interest, the Shell and C versions of while1.py are also in your
home directory as while1.sh and while1.c.

146
Progress
while ... : before

while test :
test to keep looping ␣␣␣␣action1
␣␣␣␣action2
␣␣␣␣action3
code blocks
afterwards
␣␣␣␣indentation

147

147
Exercise 7

For each script: while2.py

␣␣␣␣ Predict what it will do. while3.py

␣␣␣␣ Run the script. while4.py

␣␣␣␣ Were you right? while5.py

while6.py

To kill a running script: Ctrl + C


5 minutes
148

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

while uncertainty > tolerance :


␣␣␣␣
Do stuff.
␣␣␣␣
␣␣␣␣
␣␣␣␣

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 :

middle = (lower + upper)/2


Choice

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.

All we have to do now is to add in the choice block.

151
Choosing
Choice
middle**2 < 2.0

✔ ? ✘
lower = middle upper = middle

middle**2 < 2.0 True or False

True lower = middle

False upper = middle 152

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')

print('That was fun!')


$ python3 ifthenelse1.py
Number? 7
Odd number
ifthenelse1.py That was fun

153

Again, we will look at an example that demonstrates just the structure.


There is a script in your home directories called ifthenelse1.py which
illustrates the structure on its own.
Mathematical note:
The script tests for a number being even by using the “remainder” operator
“%” to calculate the remainder if we divide by 2 and testing for that remainder
being 0.

153
if…then… else… ― 1
if keyword

Test

if number % 2 == 0 : Colon

␣␣␣␣ print('Even number')

else :

␣␣␣␣ upper = middle

print('That was fun!')

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 :

␣␣␣␣ print('Even number') Run if test is True


Indentation
else :

␣␣␣␣ upper = middle

print('That was fun!')

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 :

␣␣␣␣ print('Even number')

else : else: keyword

␣␣␣␣ upper = middle Run if test is False


Indentation
print('That was fun!')

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 :

␣␣␣␣ print('Even number')

else :

␣␣␣␣ upper = middle


Run afterwards
print('That was fun!')
regardless of test

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

if middle**2 < 2.0 :

␣␣␣␣ lower = middle


if… block
else :

␣␣␣␣ upper = middle

print(lower, upper) After


158

Let’s return to our square root example.


Here we have the creation of a mid-point x-value followed by an if-test on it:
middle = (lower+upper)/2
if middle**2 < 2.0:
This switches between two single-line code blocks. If the test evaluates to
True then the then-block is run:
lower = middle
and if it evaluates to False then the else-block is run:
else:
upper = middle
After one or other is run the print statement is always run:
print(lower, upper)
All we have to do now is to fit it inside our while loop.

158
Progress
if ... : before

else: if test :
␣␣␣␣action1
␣␣␣␣action2
choice of two else:
code blocks ␣␣␣␣action3

afterwards
␣␣␣␣indentation

159

159
Exercise 8

For each script: ifthenelse2.py

␣␣␣␣ Predict what it will do. ifthenelse3.py

␣␣␣␣ Run the script. ifthenelse4.py

␣␣␣␣ Were you right? ifthenelse5.py

5 minutes
160

160
Back to our example
tolerance = 1.0e-15
lower = 0.0
upper = 2.0
uncertainty = upper - lower

while uncertainty > tolerance :


middle = (lower + upper)/2
if starts
if middle**2 < 2.0 :
indented
lower = middle
else : Doubly
indented
upper = middle
print(lower, upper)
161
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

while uncertainty > tolerance :


␣␣␣␣middle = (lower + upper)/2 4 spaces
␣␣␣␣if middle**2 < 2.0 :
␣␣␣␣␣␣␣␣lower = middle 8 spaces
␣␣␣␣else :
␣␣␣␣␣␣␣␣upper = middle
␣␣␣␣print(lower, upper)
162
␣␣␣␣uncertainty = upper - lower

So if our standard indentation is four spaces then the doubly indented


sections are indented eight spaces.
This is a simple example with only two levels of indentation. Python can
‘nest’ blocks much further than this.

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

while uncertainty > tolerance :


␣␣␣␣middle = (lower + upper)/2
␣␣␣␣if middle**2 < 2.0 : √2.0
␣␣␣␣␣␣␣␣lower = middle
␣␣␣␣else :
␣␣␣␣␣␣␣␣upper = middle
␣␣␣␣print(lower, upper)
164
␣␣␣␣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

text = input('Number? ')


number = float(text)

if middle**2 < number :

165

Obviously we have to input the number whose square root we want. We


have already seen how to do this and to convert it from a string into a
floating point number:
text = input('Number? ')
number = float(text)
Once we have the number the test
middle**2 < 2.0
is straightforwardly extended to
middle**2 < number

165
Initial bounds?

lower = ?
upper = ?

x > 1.0 1.0 < √x < x

1.0 > x 1.0 > √x > x

if...then...else...

166

We have to set initial bounds for our interval of uncertainty.


This is where it is important that you think about the problem before coding.
If the number whose square root is sought is less than 1 then the square
root is bigger than the number and less than 1. If it is larger than 1 then its
square root is less than the number and bigger than 1.
In Python terms this means we can test for the number being less than 1
and set the bounds accordingly.

166
Initial bounds

if number < 1.0 :


␣␣␣␣lower = number
␣␣␣␣upper = 1.0
else :
␣␣␣␣lower = 1.0
␣␣␣␣upper = number

167

It looks like this.

167
Generic square root script?
text = input('Number?␣')
number = float(text)
User input

if number < 1.0:


␣␣␣␣lower = number Initialization
␣␣␣␣upper = 1.0
else:
␣␣␣␣lower = 1.0
␣␣␣␣upper = number

tolerance = 1.0e-15
uncertainty = upper - lower

while uncertainty > tolerance:


␣␣␣␣middle = (lower+upper)/2.0
␣␣␣␣if middle**2 < number: Processing
␣␣␣␣␣␣␣␣lower = middle
␣␣␣␣else:
␣␣␣␣␣␣␣␣upper = middle

␣␣␣␣uncertainty = upper - lower


168
print(lower, upper) sqrt2.py
Output

This gives us enough of a script to see the overarching structure of a script:


We start with getting the data we need from the outside world. (“input”)
Then we set up any initial state we need based on that. (“initialization”)
Then we do our processing.
Finally we reveal our results. (“output”)
Typically the processing phase takes longest to run, but note that, as here, it
is often not the majority of the lines of code.

168
Negative numbers?

Need to catch negative numbers

if number < 0.0:


␣␣␣␣print('Number must be positive!')
␣␣␣␣exit() Quit immediately

"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

text = input('Number?␣') User input


number = float(text)

if number < 0.0: Input validation


␣␣␣␣print('Number must be positive!')
␣␣␣␣exit()

if number < 1.0: Initialization


␣␣␣␣lower = number
␣␣␣␣upper = 1.0
else:
␣␣␣␣lower = 1.0
␣␣␣␣upper = number

...

170

The input validation phase comes straight after the input itself.

170
“Chained” tests ― syntactic sugar

text = input('Number?␣')
number = float(text)

if number < 0.0:


␣␣␣␣print('Number must be positive!')
␣␣␣␣exit()

elif number < 1.0: elif: “else if”


␣␣␣␣lower = number
␣␣␣␣upper = 1.0
else:
␣␣␣␣lower = 1.0
␣␣␣␣upper = number

...

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)

if number < 0.0:


␣␣␣␣print('Number is negative.')
else:
␣␣␣␣if number < 1.0:
␣␣␣␣␣␣␣␣print('Number is between zero and one.')
␣␣␣␣else:
␣␣␣␣␣␣␣␣if number < 2.0:
␣␣␣␣␣␣␣␣␣␣␣␣print('Number is between one and two.')
␣␣␣␣␣␣␣␣else:
␣␣␣␣␣␣␣␣␣␣␣␣if number < 3.0:
␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣print('Number is between two and three.')
␣␣␣␣␣␣␣␣␣␣␣␣else:
␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣print('Number is three or more.')
172
Stacked clauses get unwieldy

To take an extreme example, consider this multi-level test. The continual


nesting inside the else clauses causes the whole script to drift to the right.

172
With elif…

text = input('Number?␣')
number = float(text)

if number < 0.0:


␣␣␣␣print('Number is negative.')
elif number < 1.0:
␣␣␣␣print('Number is between zero and one.')
elif number < 2.0:
␣␣␣␣print('Number is between one and two.')
elif number < 3.0:
␣␣␣␣print('Number is between two and three.')
else:
␣␣␣␣print('Number is three or more.')

173

Applying elif causes everything to slide back into place.

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!

1. Edit the square root script to catch negative numbers.

2. Edit the square root script to ask for the tolerance.


The tolerance must be bigger than 5×10–16.
Test for that.

5 minutes
175

175
Comments

We have written our first real Python script

What did it do?

Why did it do it?

Need to annotate the script

176

sqrt3.py is a real program.


Now imagine you pass it to someone else or put it away for twelve months
and come back to it forgetting how you wrote it in the first place.
Chances are that the reader of your script might like some hints as to what it
is doing and why.
“Comments” in computer programs are pieces of text that describe what ios
going on without getting in the way of the lines of code that are executed.

176
Python comment character

The “hash” character

#
a.k.a. “pound”, “number”, “sharp”

Lines starting with “#” are ignored

Partial lines starting “#” are ignored

Used for annotating scripts

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

# Script to calculate square roots by bisection


# (c) Bob Dowling 2012. Licensed under GPL v3.0
text = input('Number?␣')
number = float(text) # Need a real number

# Test number for validity,


# set initial bounds if OK.
if number < 0.0:
␣␣␣␣print('Number must be non-negative!')
␣␣␣␣exit()
elif number < 1.0:
␣␣␣␣lower = number
␣␣␣␣upper = 1.0
else:
␣␣␣␣lower = 1.0
␣␣␣␣upper = number
178

This is what a commented script looks like.

178
On a real Unix system…

#!/usr/bin/python3

# Script to calculate square roots by bisection


# (c) Bob Dowling 2012. Licensed under GPL v3.0
text = input('Number?␣')
number = float(text) # Need a real number

Magic line for executable files

$ 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

Comment your square root script from exercise 9.

2 minutes
181

181
Recap: Python types so far

Whole numbers -127

Floating point numbers 3.141592653589793

Complex numbers (1.0 + 2.0j)

Text 'The cat sat on the mat.'

Booleans True False


182

We are about to introduce a new Python type, so we will take a moment to


remind ourseoves of the various Python types we have met already.

182
Lists

[ 'hydrogen', 'helium', 'lithium', 'beryllium',


'boron', …, 'thorium', 'protactinium', 'uranium' ]

[ -3.141592653589793, -1.5707963267948966,
0.0, 1.5707963267948966, 3.141592653589793 ]

[ 2, 3, 5, 7, 11, 13, 17, 19 ]

183

The new Python type we are going to meet is called a “list”.

183
What is a list?
hydrogen, helium, lithium, beryllium, …, protactinium, uranium

A sequence of values The names of the elements

Values stored in order Atomic number order

Individual value identified “helium” is the name of the


by position in the sequence second element
184

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

A sequence of values The prime numbers


less than sixty

Values stored in order Numerical order

Individual value identified 7 is the fourth prime


by position in the sequence
185

Or the list of primes up to 60.


Note that a list must be finite.

185
Creating a list in Python

>>> primes = [ 2, 3, 5, 7, 11, 13, 17, 19]

A literal list

>>> primes
[2, 3, 5, 7, 11, 13, 17, 19] The whole list

>>> type(primes)
<class 'list'> A Python type

186

So how might we do this in Python?


We will create a list in Python of the primes less than 20. We can do this in a
single line as shown.
A list in Python is a single Python object, albeit with multiple contents, and
has its own type, unsurprisingly called “list”.

186
How Python presents lists

Square brackets
at the ends

[2, 3, 5, 7, 11, 13, 17, 19]

Commas between items

187

Python presents (and accepts) lists as a series of values separated by


commas, surrounded by square brackets.

187
Square brackets

primes = [2, 3, 5, 7, 11] Literal list

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

“value” [2, 3, 5, 7, 11, 13, 17, 19]

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

[2, 3, 5, 7, 11, 13, 17, 19]


index
>>> primes[0]
2
square brackets
>>> primes[6]
17 190

So, how do we get “item number 5” from a list?


We can follow the list (or, more usually, a name attached to the list) with the
index in square brackets.

190
Square brackets

primes = [2, 3, 5, 7, 11] Literal list

primes[3] Index into list

191

And this is the second use of square brackets.

191
Counting from the end
>>> primes = [ 2, 3, 5, 7, 11, 13, 17, 19]

0 1 2 3 4 5 6 7

[2, 3, 5, 7, 11, 13, 17, 19]

-8 -7 -6 -5 -4 -3 -2 -1

getting at the last item


>>> primes[-1]
19 192

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

>>> data[2] Initial value


'gamma'

>>> data[2] = 'G' Change value

>>> data[2] Check change


'G'
>>> data Changed list
['alpha', 'beta', 'G']
195

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

This then has the name “data” attached to it.

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

str 1 G New value


198

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

The assignment causes the reference within the string to be changed to


refer to the new string and to stop referring to the previous one, “gamma”.
In this case there are now no references to the “gamma” string.

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

This leaves the string “beta” no longer referenced by anything.

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

And garbage collection kicks in again.

203
Running off the end
list
8 int 2

int 3
primes

int 17

int 19
204
primes[8]

We have remarked on a couple of occasions that the largest valid index is a


number one less than the length of the list.
So what happens if you ask for an index greater than the largest legal
value?

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

You get an error unsurprisingly.


The type of the error is an “IndexError” ― something went wrong with an
index.
The error message specifies that the index asked for was outside the valid
range.

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

Same type Similar description of error


of error but with “assignment”

206

Note that we can’t use indicies beyond the limit to extend a list either.

206
Progress

Lists [2, 3, 5, 7, 11, 13, 17, 19]

index primes[4]

Count from zero primes[0]

Deletion del primes[6]

Length len(primes)

Over-running primes[8]
207

207
Exercise 11

Track what is happening to this list at each stage.

>>> numbers = [5, 7, 11, 13, 17, 19, 29, 31]

>>> numbers[1] = 3

>>> del numbers[3]

>>> numbers[3] = 37

>>> numbers[4] = numbers[5]


5 minutes
208

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

Extra item int 23 209

So, how can we extend a list?

209
Appending to a list
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19]

A function built into a list


>>> primes.append(23)

>>> primes The list is now updated


[2, 3, 5, 7, 11, 13, 17, 19, 23] 210

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

>>> primes.append(23) append()

The value to append

All lists have this


function built in.

211

So we need to look at this new construction.


We have the list, “primes”, followed by a dot which acts as a connector.
This is followed by the name of a function, “append”. This function is not a
standard Python function like print() or len(). Instead it is a function
that is “built in” to the list itself. The list has its own function which appends
to that list.
Alternatively, think of “primes.append()” as a function that appends to
primes.

211
“Methods”
Behaves just
like a function

object . function (arguments)

a function that has


special access to
the object’s data.
212

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 = [4, 7, 5, 1]

>>> numbers.reverse()
The function doesn’t
return any value.
>>> print(numbers)
It modifies
[1, 5, 7, 4]
the list itself.

214

append() is not the only method built into lists.


For example reverse() takes the list and reverses its contents.
Note that it doesn’t return a reversed list as a value; t doesn’t return
anything at all.
It silently reverses the content of the list itself.
Also note that it takes no argument; the brackets on the end of the function
are empty.

214
Other methods on lists: sort()

>>> numbers = [4, 7, 5, 1]

>>> 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

You might also like