Download Python Fundamentals (Powerpoint)

Document related concepts
no text concepts found
Transcript
Python Fundamentals
by
Chris Seddon
Copyright ©2000-14 CRS Enterprises Ltd
1
Python Fundamentals
.
1 Introduction to Python
2.Control Structures
3.Basic Data Types
4.Advanced Data Types
5.Dictionaries
6.Functions
7.Exception Handling
8.Classes and Objects
9. Files
10.Larger Programs
11.Inheritance
12.Further Topics
13.Pattern Matching
14.Unit Test
Copyright ©2000-14 CRS Enterprises Ltd
3
Chapter 1
1
Copyright ©2000-14 CRS Enterprises Ltd
5
Introduction to Python
IronPython
Copyright ©2000-14 CRS Enterprises Ltd
6
What is Python?
Python is a scripting language
unlike C++, C# and Java
easy to learn
no compile step
can be run a line at a time inside an interpreter
supports dynamic execution of source (you can type in code at run
time)
Supports both Object Oriented and functional styles of
programming
often described as an agile language
capable of performing a wide variety of tasks
ideal for rapid prototyping
often used as a plug-in to a C++ or Java system
Copyright ©2000-14 CRS Enterprises Ltd
7
Advantages of Python
Python is best used
to develop small programs and scripts
simple programs can be created very quickly
Python can be used for large-scale programming
projects
sophisticated module and packaging scheme
extensive object oriented support
Jython has access to all Java libraries
Python was designed to be an object oriented language
from the start
more simplified and natural coding style than Perl, Rexx and VBScript
highly portable
Copyright ©2000-14 CRS Enterprises Ltd
8
What is Jython?
An implementation of Python
fully integrated with the Java Virtual Machine
runs on any JVM
unlike a Python program
including Windows, Mac OS, most UNIX, all Linux systems, and all
IBM systems
highly portable
because of the connection with Java
Jython currently supports the Python syntax at level 2.5
Jython Libraries
uses Java libraries because of the JVM
NOT standard Python libraries
can be a problem sometimes
Copyright ©2000-14 CRS Enterprises Ltd
9
Everything is Interpreted
Python is an interpreted language
no pre-compile step as in Java and C++
each time Python code is run it is interpreted afresh
code changes can be very quickly made and tested
code can also be entered interactively
can dynamically construct Python code, in the form of a string and execute
it directly
myPython.py
myJava.java
myJava.class
Target
Hardware
Copyright ©2000-14 CRS Enterprises Ltd
JVM
10
Performance
Python is interpreted
much slower than a compiled language such as C/C++
increased design and coding flexibility more than makes up for
performance loss
Python libraries usually written in C/C++
a large proportion of the Python library is written in C/C++
as is the interpreter itself
hence high performance
Python has modules to measure performance
profile, cProfile
Copyright ©2000-14 CRS Enterprises Ltd
11
Invoking Python
Use the Command-Line Interpreter
code is entered one line at a time
see the results immediately
ideal way to learn Python
Use Python source files
complied by the Python interpreter
source files can be combined using modules for larger applications
Python plug-in for Eclipse is often a good choice
PyDev is very mature
Copyright ©2000-14 CRS Enterprises Ltd
12
A "Hello World" Example
The Hello World example is a trivial one liner in Python;
you don’t even require a semi-colon!
print "Hello World!"
Copyright ©2000-14 CRS Enterprises Ltd
13
Further Example
The Hello World example is a trivial one liner in Python;
you don’t even require a semi-colon!
# this is a comment
x = 100
y = 200
if x + y < 500:
print "sum is less than 500"
colon
indent
Copyright ©2000-14 CRS Enterprises Ltd
14
Chapter 2
2
Copyright ©2000-14 CRS Enterprises Ltd
17
Control Structures
Statements
if
for
while
Copyright ©2000-14 CRS Enterprises Ltd
18
if Statements
x = int(raw_input("Please enter an integer: "))
if x < 0:
print 'Negative'
Please enter an integer: -5
Negative
Copyright ©2000-14 CRS Enterprises Ltd
19
if Statements
x = int(raw_input("Please enter a positive integer: "))
if x > 0:
print 'x is positive'
print 'the square of x is', x * x
print 'the cube of x is', x * x * x
print 'End of if-statement'
Please enter a positive integer: 66
x is positive
the square of x is 4356
the cube of x is 287496
End of if-statement
Copyright ©2000-14 CRS Enterprises Ltd
20
if-else Statements
x = int(raw_input("Please enter an integer: "))
if x < 0:
print 'Negative'
else:
print 'Not negative'
Please enter an integer: 5
Not negative
Please enter an integer: -5
Negative
Copyright ©2000-14 CRS Enterprises Ltd
21
if-elif-else Statements
x = int(raw_input("Please enter an integer: "))
if x < 0:
print 'Negative'
elif x == 0:
print 'Zero'
elif x == 1:
print 'One'
else:
print 'Greater than one'
Copyright ©2000-14 CRS Enterprises Ltd
Please enter an integer: -3
Negative
Please enter an integer: 0
Zero
Please enter an integer: 1
One
Please enter an integer: 7
Greater than one
22
Conditional if Statements
x = 100
result = (-1 if x < 0 else 1)
print result
x = -200
result = (-1 if x < 0 else 1)
print result
1
-1
Copyright ©2000-14 CRS Enterprises Ltd
23
for Statements
for x in (10,17,24,31,38,45,52,59,66,73,80,87,94):
print x,
print
for x in range(10,100,7):
print x,
10 17 24 31 38 45 52 59 66 73 80 87 94
10 17 24 31 38 45 52 59 66 73 80 87 94
Copyright ©2000-14 CRS Enterprises Ltd
24
for-else Statements
for x in (1,2,3,4,5,6):
print x,
else:
print "only get here if all iterations succeed ..."
for x in (1,2,3,4,5,6):
print x,
if x > 3:
break
else:
print "only get here if all iterations succeed ..."
1 2 3 4 5 6 only get here if all iterations succeed ...
1234
Copyright ©2000-14 CRS Enterprises Ltd
25
Using range
use range to iterate a fixed number of times
for x in range(1,10):
print x,
123456789
Copyright ©2000-14 CRS Enterprises Ltd
26
while Statements
formula = 0
x=0
while formula < 1000:
x=x+1
formula = 2*x*(x + 1)
print x, formula
Copyright ©2000-14 CRS Enterprises Ltd
1 4
2 12
3 24
4 40
5 60
6 84
7 112
8 144
9 180
10 220
11 264
12 312
13 364
14 420
15 480
16 544
17 612
18 684
19 760
20 840
21 924
22 1012
27
Chapter 3
3
Copyright ©2000-14 CRS Enterprises Ltd
29
Basic Data Types
Basic Types
int
long
boolean
float
complex
string
Copyright ©2000-14 CRS Enterprises Ltd
30
Data Types
Everything is an object
including all types discussed in this chapter
full documentation for the Java types is online
Several types are immutable
strings, tuples
Sometimes objects behave as though immutable
if you attempt to modify a number, Python simply creates a new object
and marks the old object ready for garbage collection
could lead to excessive delays during the garbage collection cycle.
Copyright ©2000-14 CRS Enterprises Ltd
31
Built in Types
int
C long
includes Booleans
hex and octal numbers available
boolean
True, False, and, or
float
C double type (13 sig. fig.)
long
unlimited precision
e.g. 10000000000000000000000000
complex
real and imaginary parts are each implemented using Java double
e.g. (5.0+3.1j)
Copyright ©2000-14 CRS Enterprises Ltd
32
Integers
Limited precision
decimals, octal and hexadecimal
# integers
x = 100
x += 1
print type(x)
print x
x = 053
print x
<type 'int'>
101
43
255
x = 0xFF
print x
Copyright ©2000-14 CRS Enterprises Ltd
33
Booleans
Values
True, False
Operators
and, or
x = True
y = False
z = x or y
print z
True
z = x and y
print z
print type(z)
False
<type 'bool'>
Copyright ©2000-14 CRS Enterprises Ltd
34
Floating Point
13 significant figures on 64 bit implementation
no exact representation
# floating point
x = 1e4 + 0.1e-4
format = "%32.20g"
print type(x)
print (format % x)
<type 'float'>
10000.000009999999747
Copyright ©2000-14 CRS Enterprises Ltd
35
Complex Numbers
floating types
real and imaginary parts
can be extracted separately
x = (+2.5-3.4j) - (-1.4+1.0j)
print type(x)
print x
print x.real
print x.imag
Copyright ©2000-14 CRS Enterprises Ltd
<type 'complex'>
(3.9-4.4j)
3.9
-4.4
36
Integers are Immutable
x is really an object reference (pointer)
id(x)
refers to the object at the end of the pointer
x can change, but integer it points to is immutable
x just points to a different object
the original object gets garbage collected
x = 100
print id(x)
10053412
x=x+1
print id(x)
10053400
Copyright ©2000-14 CRS Enterprises Ltd
37
Strings ...
immutable
single or double quotes
triple quoting for multi-line strings
x = 'hello'
y = "from"
z = """the
planet
earth"""
print type(x)
print x, y, z
<type 'str'>
hello from the
planet
earth
HELLO FROM THE
PLANET
EARTH
phrase = x + " " + y + " " + z
print phrase.upper()
Copyright ©2000-14 CRS Enterprises Ltd
38
... Strings
Many string manipulation methods available
original string is unchanged
new string returned
s = "---abc:XYZ:123---"
t = s.lower()
t = s.lstrip("-")
t = s.replace(":","@")
t = s.rstrip("-")
t = s.split(":")
t = s.strip("-")
t = s.swapcase()
t = s.upper()
Copyright ©2000-14 CRS Enterprises Ltd
---abc:xyz:123--abc:XYZ:123-----abc@XYZ@123-----abc:XYZ:123
['---abc', 'XYZ', '123---']
abc:XYZ:123
---ABC:xyz:123-----ABC:XYZ:123---
39
... Strings
More string methods ...
count(sub)
find(sub)
number of occurrences of substring
index in the string where substring is found
isalnum()
isalpha()
true if string is alphanumeric
true if string is alphabetic
isdigit()
true if string is all digits
join(seq)
partition(sep)
concatenate all the strings in the sequence
split the string at the first occurrence of sep and return a 3tuple
split(sep)
return a list of the words in the string using sep as the delimiter
Copyright ©2000-14 CRS Enterprises Ltd
40
Chapter 4
4
Copyright ©2000-14 CRS Enterprises Ltd
43
Advanced Data Types
Sequence Types
list (mutable)
tuple (immutable)
set
use [ ]
use ( )
no duplicates
Dictionary Types
dict (mutable)
use { }
Copyright ©2000-14 CRS Enterprises Ltd
44
List ...
mutable
can be nested
x1 = [ ]
x2 = [1]
x3 = [1,2,3]
x4 = [1, 'mixed', 2, 'list']
x5 = [[1,2],[3,4]]
print type(x1)
print x1, "-----", len(x1)
print x2, "-----", len(x2)
print x3, "-----", len(x3)
print x4, "-----", len(x4)
print x5, "-----", len(x5)
Copyright ©2000-14 CRS Enterprises Ltd
<type 'list'>
[]
[1]
[1, 2, 3]
[1, 'mixed', 2, 'list']
[[1, 2], [3, 4]]
----- 0
----- 1
----- 3
----- 4
----- 2
45
... List
Lists can be extended with
extend or append
Elements can be modified
object reference gets changed
Can contain immutable items
such as tuples
list1 = [[1,2],[3,4]]
# notation for accessing lists
print list1
print list1[1]
print list1[1][0]
# append and extend are equivalent
list2 = [10, 20, 30]
list = [ ]
list.extend(list1)
list.append(list2)
print list
# modifying lists
list1[1][0] = 99
print list1[1][0]
# lists can contain tuples
list3 = [(1,2), (3,4), (5,6)]
print list3
Copyright ©2000-14 CRS Enterprises Ltd
46
Tuple
immutable
can be nested
note syntax for a single item tuple
x1 = ()
x2 = (1,)
x3 = (1,2,3)
x4 = (1, "mixed", 2, "tuple")
x5 = ((1,2),(3,4))
print type(x1)
print x1, "-----", len(x1)
print x2, "-----", len(x2)
print x3, "-----", len(x3)
print x4, "-----", len(x4)
print x5, "-----", len(x5)
Copyright ©2000-14 CRS Enterprises Ltd
<type 'tuple'>
()
(1,)
(1, 2, 3)
(1, 'mixed', 2, 'tuple')
((1, 2), (3, 4))
----- 0
----- 1
----- 3
----- 4
----- 2
47
Accessing Lists and Tuples
only lists can be modified
tuples are immutable
mylist = [10, 20, 30]
mytuple = (10, 20, 30)
y = mytuple[0]
y = mytuple[1]
y = mytuple[2]
x = mylist[0]
x = mylist[1]
x = mylist[2]
mylist[1] = 99
mylist.append(40)
print mylist
Copyright ©2000-14 CRS Enterprises Ltd
[10, 99, 30, 40]
48
Casting between Lists and Tuples
use a cast to convert
tuple( ... )
list( ...)
theList = [2, 3, 5, 7, 11, 13, 17]
myTuple = tuple(theList)
myList = list(myTuple)
print myTuple
print myList
Copyright ©2000-14 CRS Enterprises Ltd
(2, 3, 5, 7, 11, 13, 17)
[2, 3, 5, 7, 11, 13, 17]
49
Slices
Sequences support slicing
selects a range of elements (-1 represents the last element)
x[1:3] selects the second through third elements of x
the end index is always one past the selection
assignment slicing
replaces multiple elements
x[3:5] = (5,4)
colors = ["red", "blue", "green", "white", "black"]
print colors[1]
print colors[1:3]
print colors[1:]
print colors[-3:-1]
print colors[4:1:-1]
colors[2:4] = ("purple", "cyan")
print colors[0:];
Copyright ©2000-14 CRS Enterprises Ltd
blue
['blue', 'green']
['blue', 'green', 'white', 'black']
['green', 'white']
['black', 'white', 'green']
['red', 'blue', 'purple', 'cyan', 'black']
50
Set and FrozenSet
unordered collections of unique elements
Set (mutable)
FrozenSet (immutable)
myset = set(("Monday", "Tuesday"))
myset.add("Wednesday")
myset.add("Thursday")
myset.add("Friday")
print myset
if "Wednesday" in myset:
print "member"
myset.remove("Wednesday")
if "Wednesday" not in myset:
print "not a member"
Copyright ©2000-14 CRS Enterprises Ltd
set(['Friday', 'Tuesday', 'Thursday',
'Wednesday', 'Monday'])
member
not a member
51
Set and FrozenSet
Set supports mathematical operations
union, intersection and symmetric difference
sequence1 = 1, 3, 5, 7, 5, 4, 3, 2, 1
sequence2 = 2, 4, 6, 8, 6, 4, 3, 2, 1
set1 = set(sequence1)
set2 = set(sequence2)
print(set1)
set([1, 2, 3, 4, 5, 7])
print(set2)
set([1, 2, 3, 4, 6, 8])
unionSet = set1.union(set2)
intersectionSet = set1.intersection(set2)
differenceSet = set1.symmetric_difference(set2)
print(unionSet)
set([1, 2, 3, 4, 5, 6, 7, 8])
print(intersectionSet)
set([1, 2, 3, 4])
print(differenceSet)
set([5, 6, 7, 8])
Copyright ©2000-14 CRS Enterprises Ltd
52
Not Defined
special type
NoneType
x = 120
print type(x)
print x
x = None # not defined
print type(x)
print x
<type 'int'>
120
<type 'NoneType'>
None
240
if (x == None):
x = 240
print x
Copyright ©2000-14 CRS Enterprises Ltd
53
Chapter 5
5
Copyright ©2000-14 CRS Enterprises Ltd
55
Dictionaries
keys and values
inserting, updating and deleting
common methods
Copyright ©2000-14 CRS Enterprises Ltd
56
Dictionary
like a database table
also called hash, associative array
key:value pairs
keys usually a string
keys must be immutable
very efficient lookups
empty = { }
months = {"Jan":1, "Feb":2, "May":5, "Dec":12}
seasons = {"Spring":("Mar","Apr","May"), "Summer":("Jun","Jul","Aug")}
print type(empty)
print months["Dec"]
print seasons["Summer"]
Copyright ©2000-14 CRS Enterprises Ltd
<type 'dict'>
12
('Jun', 'Jul', 'Aug')
57
Working with Dictionaries
Dictionaries are mutable
modify existing entries
add new entries
Key Order is indeterminate
because of hashing algorithm
salary = {
"zak": 34000,
"sara": 27000,
"pedro": 52000,
"jo": 12500,
"zoe": 66000
}
print salary["pedro"]
salary["jo"] = 15000; # modify existing
salary["peter"] = 35000 # add new entry
Copyright ©2000-14 CRS Enterprises Ltd
58
Initialization
Use { } or constructor
salary1 = {
"zak": 34000,
"sara": 27000,
"pedro": 52000,
"kilas": 12500,
"zoe": 66000
}
salary2 = dict( zak
= 34000,
sara
= 27000,
pedro
= 52000,
kilas
= 12500,
zoe
= 66000)
Copyright ©2000-14 CRS Enterprises Ltd
59
Inserting or Updating
New elements ...
are added
salary["sara"] = 28000
Existing elements ...
are updated
salary["sara"] = 29000
Copyright ©2000-14 CRS Enterprises Ltd
60
Removing Keys
Use del statement
del salary["zak"]
or
Use pop
salary.pop("zak")
Copyright ©2000-14 CRS Enterprises Ltd
61
Removing Values
Assign key to None
previous value gets garbage collected
salary["sara"] = None
Copyright ©2000-14 CRS Enterprises Ltd
62
Common Functions ...
Extract all the keys, and all the values
# create list of keys
theKeys = salary.keys()
# create list of values
theValues = salary.values()
Copyright ©2000-14 CRS Enterprises Ltd
63
... Common Functions
Work with keys, values or both
# print all the keys
for key in salary.iterkeys():
print key,
print
# print all the values
for value in salary.itervalues():
print value,
print
# print all <key,value> pairs
for key, value in salary.iteritems():
print key, value
Copyright ©2000-14 CRS Enterprises Ltd
64
Chapter 6
6
Copyright ©2000-14 CRS Enterprises Ltd
67
Functions
Simple functions
Passing parameters
Returning multiple results
Pass by value
Working with lists
Pass by object reference
Object identity
Copyright ©2000-14 CRS Enterprises Ltd
68
Simple Functions
def square(n):
print n * n
square(5)
square(6)
square(7)
25
36
49
Copyright ©2000-14 CRS Enterprises Ltd
69
return Statements
def average(a, b):
return (a + b)/2.0
x = average(5, 8)
print x
x = average(5.5, 7.7)
print x
print average(10.5, 12.5)
6.5
6.6
11.5
Copyright ©2000-14 CRS Enterprises Ltd
70
A swap Function
def swap(a,b):
return b,a
x = 100
y = 200
[x,y] = swap(x,y)
print x, y
200 100
Copyright ©2000-14 CRS Enterprises Ltd
71
How not to Swap
def no_swap(a,b):
temp = a
a=b
b = temp
x = 100
y = 200
no_swap(x,y)
print x, y
100 200
Copyright ©2000-14 CRS Enterprises Ltd
72
Object Identity
def readIt(a):
print a,"id3 =",id(a)
def modifyIt(a):
a=a+1
print a,"id4 =",id(a)
100 id1 = 12160993
101 id2 = 9774375
101 id3 = 9774375
102 id4 = 28991818
x = 100
print x,"id1 =",id(x)
x=x+1
print x,"id2 =",id(x)
readIt(x)
modifyIt(x)
Copyright ©2000-14 CRS Enterprises Ltd
73
Object Identity with Lists
list1 = [2, 3, 5, 7, 11]
list2 = [2, 4, 6, 8, 10]
list3 = [2, 4, 6, 8, 10]
print "list1 id =", id(list1)
print "list2 id =", id(list2)
print "list3 id =", id(list3)
list1.append(13)
print "list1 id =", id(list1)
list1 id = 9774375
list2 id = 28991818
list3 id = 21579068
list1 id = 9774375
Copyright ©2000-14 CRS Enterprises Ltd
74
Pass by Object Reference
def modifyList(mylist):
del mylist[0]
print id(mylist),mylist
theList = [2, 3, 5, 7, 11]
print id(theList), theList
modifyList(theList)
print id(theList), theList
12160993 [2, 3, 5, 7, 11]
12160993 [3, 5, 7, 11]
12160993 [3, 5, 7, 11]
Copyright ©2000-14 CRS Enterprises Ltd
75
Swapping Lists
def swap(list):
list[0],list[1] = list[1],list[0]
mylist = [100,200]
swap(mylist)
print mylist
[200, 100]
Copyright ©2000-14 CRS Enterprises Ltd
76
Returning Lists
def makeList(start,end):
mylist = range(start, end)
mylist.insert(0, 10)
mylist.append(99)
return mylist
list1 = makeList(15, 25)
list2 = makeList(18, 21)
print list1
print list2
[10, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 99]
[10, 18, 19, 20, 99]
Copyright ©2000-14 CRS Enterprises Ltd
77
Function Aliases
def fib(n):
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
print
fib(15000)
f = fib
f(100)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
1 1 2 3 5 8 13 21 34 55 89
Copyright ©2000-14 CRS Enterprises Ltd
78
Default Parameter Values
def Display(a, b=10, c=100):
print ("a=%6.1f " % a), ("b=%6.1f " % b), ("c=%6.1f" % c)
Display(19, 6.2, 4.8)
Display(17)
Display(17, 21)
Display(17, c=0)
a=
a=
a=
a=
Copyright ©2000-14 CRS Enterprises Ltd
19.0
17.0
17.0
17.0
b=
b=
b=
b=
6.2
10.0
21.0
10.0
c= 4.8
c= 100.0
c= 100.0
c= 0.0
79
Lambda Functions
sum = lambda x, y: x + y
print sum(1,2)
print sum(5,9)
print sum(10,20)
3
14
30
Copyright ©2000-14 CRS Enterprises Ltd
80
Passing Tuples and Lists
def f(*args):
print 'args:', args
a = (3,4,7,8)
b = [3,4,7,8]
args: (1, 3, 4, 7, 8, 9)
args: (1, (3, 4, 7, 8), 9)
args: (1, [3, 4, 7, 8], 9)
args: (1, 3, 4, 7, 8)
args: (1, 3, 4, 7, 8)
f(1,3,4,7,8,9)
# pass multiple args
f(1,a,9)
# pass int, tuple, int
f(1,b,9)
# pass int, list, int
f(1,*a) # treat tuple as multiple args
f(1,*b) # treat list as multiple args
Copyright ©2000-14 CRS Enterprises Ltd
81
Passing Named Parameters
def f(x,y,**params):
print 'x,y:', x, y
print 'params:', params
f(13,7, Jan=1, Feb=2, May=5, Dec=12)
x,y: 13 7
params: {'Dec': 12, 'May': 5, 'Jan': 1, 'Feb': 2}
Copyright ©2000-14 CRS Enterprises Ltd
82
Stub Functions
def myStub(x, y):
pass
myStub(5,6)
myStub(1,10)
myStub(0,7)
Copyright ©2000-14 CRS Enterprises Ltd
83
Chapter 7
7
Copyright ©2000-14 CRS Enterprises Ltd
85
Exception Handling
Keywords
try
except
finally
raise
assert
Copyright ©2000-14 CRS Enterprises Ltd
86
try-except Statements
array = [1,2,3,4,5,6]
exception thrown here
try:
for x in array:
print x, array[x]
exception type
print "Exiting try block"
except IndexError,target:
print "... entering except block"
print target
this is never executed
object reference
23
34
45
56
6 ... entering except block
list index out of range
Copyright ©2000-14 CRS Enterprises Ltd
87
try-except-else Statements
from math import sqrt
x = int(raw_input("Enter positive integer: "))
try:
root = sqrt(x)
except:
print "... entering except block"
else:
print "... entering else block"
print root
exception occurs
no exception
Enter positive integer: 25
... entering else block
5.0
Enter positive integer: -25
... entering except block
Copyright ©2000-14 CRS Enterprises Ltd
88
try-finally Statements
array = [1,2,3,4,5,6]
1 2 3 4 5 6 ... entering finally block
3 5 ... entering finally block
IndexError: list index out of range
try:
for x in array:
print array[x - 1],
finally:
print "... entering finally block"
guaranteed to be called
even if exception occurs
try:
for x in array:
print array[x * 2],
finally:
print "... entering finally block"
Copyright ©2000-14 CRS Enterprises Ltd
89
raise Statements
array = [1,2,3,-4,5,6]
try:
exception type
for x in array:
if x < 0:
raise ValueError, "array index is negative!"
print x,
object reference
except ValueError, value:
print
print "... entering except block: " + str(value)
123
... entering except block: array
index is negative!
Copyright ©2000-14 CRS Enterprises Ltd
90
Unified try except finally
In Python 2.5+ you can combine finally and except
not allowed in previous versions
try:
block-1 ...
except Exception1:
handler-1 ...
except Exception2:
handler-2 ...
else:
else-block
finally:
final-block
Copyright ©2000-14 CRS Enterprises Ltd
91
Nested Exceptions
def f1():
print "Entering f1"
f2()
print "Leaving f1"
never
executed
def f2():
print "Entering f2"
f3()
print "Leaving f2"
regarded as part
of the try block
Entering f1
Entering f2
Entering f3
Some exception
def f3():
print "Entering f3"
raise Exception("Some exception")
print "Leaving f3"
try:
f1()
except Exception, reason:
print reason
Copyright ©2000-14 CRS Enterprises Ltd
92
Standard Exceptions
Exception
StopIteration
StandardError
BufferError
ArithmeticError
FloatingPointErro
OverflowError
ZeroDivisionError
AssertionError
AttributeError
EnvironmentError
IOError
OSError
EOFError
ImportError
LookupError
IndexError
KeyError
Copyright ©2000-14 CRS Enterprises Ltd
MemoryError
NameError
UnboundLocalError
ReferenceError
RuntimeError
NotImplementedError
SyntaxError
IndentationError
TabError
SystemError
TypeError
ValueError
UnicodeError
UnicodeDecodeError
UnicodeEncodeError
UnicodeTranslateError
93
User Defined Exceptions
Always subclass Exception
class MyError(Exception):
def __init__(self, value):
self.value = value
My exception occurred, value: 4
try:
raise MyError(2*2)
except MyError as e:
print 'My exception occurred, value:', e.value
Copyright ©2000-14 CRS Enterprises Ltd
94
assert Statements
def CalculateQuartile(percent):
assert type(percent).__name__ == 'int'
assert percent >= 0 and percent <= 100
quartile = 4
if percent > 25:
print CalculateQuartile(34)
quartile = 3
print CalculateQuartile(104)
if percent > 50:
quartile = 2
if percent > 75:
2
quartile = 1
assert percent >= 0 and percent <= 100
return quartile
AssertionError
Copyright ©2000-14 CRS Enterprises Ltd
95
Chapter 8
8
Copyright ©2000-14 CRS Enterprises Ltd
97
Classes and Objects
Classes
what is a class
what is an object
Methods
defining
calling
Attributes
for objects
for classes
Copyright ©2000-14 CRS Enterprises Ltd
98
The Object Model
Object-oriented programming
modelling real-world objects
model described by classes
model implemented by creating
objects
Copyright ©2000-14 CRS Enterprises Ltd
99
Classes
A class defines
a new data type
its operations
its state
Type
Yacht
{
Tack
Operations
DropAnchor
bearing
speed
Copyright ©2000-14 CRS Enterprises Ltd
}
Attributes
100
Classes
methods are functions
attributes are object references
reference to self
operations
methods
class Yacht:
def __init__(self, bearing, speed):
self.bearing = bearing
self.speed = speed
attributes
def Display(self):
print self.bearing, self.speed
Copyright ©2000-14 CRS Enterprises Ltd
101
Objects
A class is a blueprint for building objects
An object is an instance of a class
keyword self refers to this instance
class Yacht:
def __init__(self, bearing, speed):
self.bearing = bearing
self.speed = speed
def Display(self):
print self.bearing, self.speed
Object 1
Object 2
bearing = 40
speed = 1.7
bearing = 30
speed = 1.3
Copyright ©2000-14 CRS Enterprises Ltd
102
Creating Objects
Use the classname to create a new object
returns an object reference
the object is not directly accessible
Object destroyed by the VM
when no references exist
object reference
Copyright ©2000-14 CRS Enterprises Ltd
oceanis1 = Yacht()
oceanis2 = Yacht()
mirror1 = Yacht()
mirror2 = Yacht()
103
Initializing Objects
Classes can define an __init__ method
method often takes parameters
defines how object will be initialized
only 1 initializer allowed
mirror1 = Yacht(25, 1.2)
mirror1
Copyright ©2000-14 CRS Enterprises Ltd
def __init__(self, bearing, speed):
self.bearing = bearing
self.speed = speed
bearing = 25
speed = 1.2
104
Initializing Objects
class Yacht:
def __init__(self, bearing, speed):
self.bearing = bearing
self.speed = speed
def Display(self):
print self.bearing, self.speed
oceanis1 = Yacht(25, 1.2)
oceanis2 = Yacht(35, 6.0)
mirror1 = Yacht(90, 3.5)
mirror2 = Yacht(220, 1.6)
25 1.2
35 6.0
90 3.5
220 1.6
oceanis1.Display()
oceanis2.Display()
mirror1.Display()
mirror2.Display()
Copyright ©2000-14 CRS Enterprises Ltd
105
Assigning References
Assigning references
both point to the same object
mirror1
bearing = 25
speed = 1.2
mirror2
mirror1 = Yacht(25, 1.2)
mirror2 = mirror1
Copyright ©2000-14 CRS Enterprises Ltd
106
Attributes
Class Attributes
shared by all objects in a class
Object Attributes
unique to each object
Avoid name clashes
object attribute hides class attribute of the same name
Copyright ©2000-14 CRS Enterprises Ltd
107
Object Attributes
Object attributes can be
defined on the fly
can apply to different objects
Object b1 has
height
width
color
Object b2 has
height
width
Use pass to define a empty
class
useful for trying things out
Copyright ©2000-14 CRS Enterprises Ltd
class Box:
pass
b1 = Box( )
b2 = Box( )
b1.height = 100
b1.width = 50
b1.color = "red"
b2.height = 100
b2.width = 50
108
Class Attributes
Shared by all objects in
class
class attribute
class Point:
count = 0
object
attribute
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
Point.count = Point.count + 1
def WhereAmI(self):
print "Point(%i) is at %i,%i" % (id(self), self.x, self.y)
normal
method
static(class)
method
def MoveBy(self, dx, dy):
self.x += dx
self.y += dy
def HowManyPoints(self):
print "There are %i Point object(s)\n" % Point.count
Copyright ©2000-14 CRS Enterprises Ltd
109
Manipulating Objects
p1 = Point(5,7)
p1.WhereAmI()
p1.MoveBy(1,1)
p1.WhereAmI()
p1.HowManyPoints()
p2 = Point(15,17)
p2.WhereAmI()
p2.MoveBy(1,10)
p2.WhereAmI()
p1.HowManyPoints()
p3 = Point(25,27)
p3.WhereAmI()
p3.MoveBy(1,100)
p3.WhereAmI()
p1.HowManyPoints()
Copyright ©2000-14 CRS Enterprises Ltd
class Point:
count = 0
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
Point.count = Point.count + 1
def WhereAmI(self):
print "Point(%i) is at ...
def MoveBy(self, dx, dy):
self.x += dx
self.y += dy
def HowManyPoints(self):
print "There are ...
110
Output from Example
Note each object has a unique identifier
print id(p1)
print id(p2)
print id(p3)
Note the effect of calling p1.HowManyPoints()
Point(23107068) is at 5,7
Point(23107068) is at 6,8
There are 1 Point object(s)
Point(24318772) is at 15,17
Point(24318772) is at 16,27
There are 2 Point object(s)
Point(27787651) is at 25,27
Point(27787651) is at 26,127
There are 3 Point object(s)
Copyright ©2000-14 CRS Enterprises Ltd
111
Chapter 9
9
Copyright ©2000-14 CRS Enterprises Ltd
113
Files
Opening and closing
Reading and writing
Modes
read only
read-write
append
Iterating through
Random Access
seek
Copyright ©2000-14 CRS Enterprises Ltd
114
File Objects
open
creates a file object
close
destroys a file object
myFile = open('myfile.txt', 'w')
myFile.close()
Copyright ©2000-14 CRS Enterprises Ltd
115
Iterating through a File
Use for-in statement
to process every line
loop terminates on end of file
f = open("hello.txt")
for line in f:
print line
Copyright ©2000-14 CRS Enterprises Ltd
116
Using with Statement
with statement
automatic clean up
avoid forgetting to close a file
generated code
inner try block will always close
but might throw an IOError
generated code
try:
f = open("data/hello.txt", "r")
try:
for line in f:
print line,
finally:
f.close()
except IOError,e:
print e
try:
with open("data/hello.txt", "r") as f:
for line in f:
print line,
except IOError,e:
print e
Copyright ©2000-14 CRS Enterprises Ltd
117
Coping with Errors
If file I/O fails
Error obect thrown
belongs to IOError class
try:
f = open("data/unknown.txt", "r+t")
except IOError,error:
print "File open failed!"
error object
print error
error class
Copyright ©2000-14 CRS Enterprises Ltd
118
Read Methods
Simple to read from files
f = open('myfile.txt', 'w')
data = f.read()
f.close()
read entire file
f = open('myfile.txt', 'w')
data = f.read(100)
f.close()
f = open('myfile.txt', 'r')
f.readline()
f.readline()
f.readline()
f.close()
read a line at a time
(empty string returned on EOF)
read 100
bytes from file
Copyright ©2000-14 CRS Enterprises Ltd
119
Write Methods
Simple to write to files
f = open("data/out1.txt", "w")
f.write("line 1\nline 2\n")
f.close()
write a string
sequence = ("line 1\n", "line 2\n", "line 3\n", "line 4\n")
f = open("data/out2.txt", "w")
f.writelines(sequence)
f.close()
write a sequence of
lines
Copyright ©2000-14 CRS Enterprises Ltd
120
File Modes
read only
use "r"
read and write
use "r+"
or "w+" to empty file on opening
write only
use "w"
file will be empty on opening
appending
use "a"
binary
use "b" for binary and "t" for text (default)
random access
choose appropriate mode and then use seek()
Copyright ©2000-14 CRS Enterprises Ltd
121
Writing Binary Data
Open file with mode 'b'
myFile = open('data/myfile2.bin', 'wb')
myFile.write("\x5F\x9D\x3E");
myFile.close()
Copyright ©2000-14 CRS Enterprises Ltd
122
Reading Binary Data
Use ord() and hex(ord()) for conversions
myFile = open('data/myfile2.bin', 'rb')
# read bytes
ch1 = myFile.read(1) # read 1 byte
ch2 = myFile.read(1)
ch3 = myFile.read(1)
# convert to ascii (decimal)
d1 = ord(ch1)
d2 = ord(ch2)
d3 = ord(ch3)
# convert to ascii (hex)
h1 = hex(ord(ch1))
h2 = hex(ord(ch2))
h3 = hex(ord(ch3))
myFile.close()
Copyright ©2000-14 CRS Enterprises Ltd
123
Random Access
seek(offset, whence)
whence = 0
whence = 1
whence = 2
=> from start of file
=> from current position
=> from end of file
myFile = open('myfile.txt', 'w')
myFile.seek(40, 0)
myFile.write("ABCDEFGH");
myFile.seek(140, 0)
myFile.write("ABCDEFGH");
myFile.seek(240, 0)
myFile.write("ABCDEFGH");
myFile.close()
Copyright ©2000-14 CRS Enterprises Ltd
124
Reading a File into a Dictionary
You can read an entire file into a Dictionary
and then perform lookups
stdcodes = {}
f = open("codes.txt", "r+t")
read a file line by line, splitting each
line and then adding to dictionary
for line in f:
[code, place] = line.rstrip().split(' ', 1)
stdcodes[place] = code
now try searching the dictionary
placeRequested = raw_input("Enter place: ")
try:
print "The code for " + placeRequested + \
" is " + stdcodes[placeRequested]
Town: Washington
except KeyError:
The code for Washington is 0191
print "code not found"
Copyright ©2000-14 CRS Enterprises Ltd
125
Sorting a File
stdcodes = {}
f = open("codes.txt", "r+t")
read a file line by line, splitting each
line and then adding to dictionary
for line in f:
[code, place] = line.rstrip().split(' ', 1)
stdcodes[place] = code
list = [ ]
list = stdcodes.keys()
list.sort()
for place in list:
print place, stdcodes[place]
Copyright ©2000-14 CRS Enterprises Ltd
extract the keys into an
array then sort the array
now step through the sorted list looking
up each entry in the original dictionary
126
Chapter 10
10
Copyright ©2000-14 CRS Enterprises Ltd
129
Larger Programs
Modules and Packages
Importing
Symbol Tables
Installing Libraries
Copyright ©2000-14 CRS Enterprises Ltd
130
Modules and Packages
Programs can be organized into modules and packages
many modules are available in the Python and Java libraries
Modules
may be Python code files
but can be written in other languages such as C/C++
Packages
collection of modules grouped using a common package name
helps resolve namespace conflicts
A package is defined by creating a directory
with the same name as the package
place modules in this directory
can be extended to include sub-packages within sub-directories
Copyright ©2000-14 CRS Enterprises Ltd
131
What is a Module
Importing a file
executes all the code in that file
often just defines functions
import myfunctions
myfunctions.f1()
myfunctions.f2()
myfunctions.f3()
myfunctions.f4()
myfunctions.py
def f1():
pass
def f2():
pass
def f3():
pass
def f4():
pass
Copyright ©2000-14 CRS Enterprises Ltd
132
Module Test Code
Importing a file ...
causes all code to executed
but what about test code?
Wrap all test code ...
inside a __name__ test
__name__ is only set to
__main__
if we are the main program
code will not be executed via an import
Copyright ©2000-14 CRS Enterprises Ltd
def f1():
def f2():
def f3():
def f4():
pass
pass
pass
pass
if __name__ == "__main__":
f1()
f2()
f3()
f4()
133
Importing
4 ways to import
mypackage
mysubpackage
import mypackage.mysubpackage.MyClass
x1 = mypackage.mysubpackage.MyClass()
x1.f1()
from mypackage import mysubpackage
x2 = mysubpackage.MyClass()
x2.f2()
public class MyClass {
public MyClass() { ... }
public void f1() { ... }
public void f2() { ... }
public void f3() { ... }
public void f4() { ... }
}
import mypackage.mysubpackage.MyClass as theClass
x3 = theClass()
x3.f3()
from mypackage.mysubpackage import MyClass as theClass
x4 = theClass()
x4.f4()
Copyright ©2000-14 CRS Enterprises Ltd
134
Packages
Import
loads all modules together
executes __init__.py
for each package
import sys
sys.path.append("lib")
# load both packages together
import mypackage.mysubpackage
x = mypackage.mysubpackage.ModuleA.A()
x.f();
loading mypackage
x.g();
loading mysubpackage
x.h()
this is A.f() ...
this is A.g() ...
this is A.h() ...
Copyright ©2000-14 CRS Enterprises Ltd
mypackage/__init__.py
mysubpackage/__init__.py
ModuleA.py
135
Module Search Path
When loading modules
the interpreter searches the list of directories in sys.path
first entry in sys.path can be an empty string
refers to the current working directory
other entries in sys.path may consist of
directory names, .zip archive files, and .egg files
order determines which modules are loaded
import sys
sys.path.append('mylib')
Copyright ©2000-14 CRS Enterprises Ltd
136
Displaying Symbol Tables ...
To display symbol table of main program
use the global dictionary
Iterate through the dictionary using iteritems()
# use globals to get a list of symbols in main module
# Jython returns a StringMap which needs to be
# converted to a dictionary
symbols = dict(globals())
#print all the symbols in module
for key, value in symbols.iteritems():
print key, value
Copyright ©2000-14 CRS Enterprises Ltd
137
... Displaying Symbol Tables
To display symbol table of a module
use the module's dictionary
Iterate through the dictionary using iteritems()
#print all the symbols in myfunctions module
for key, value in myfunctions.__dict__.iteritems():
print key, value
Copyright ©2000-14 CRS Enterprises Ltd
138
Installing Third-Party Libraries
Definitive resource for locating third-party libraries and
extensions to Python is
the Python Package Index (PyPI)
http://pypi.python.org
Installing third-party modules is usually straightforward
use easy_install or pip
use platform-native installer
use a download a zip that comes with setup.py file
to install type
python setup.py install
Copyright ©2000-14 CRS Enterprises Ltd
139
Chapter 11
11
Copyright ©2000-14 CRS Enterprises Ltd
141
Inheritance and Polymorphism
Inheritance
new style classes and object
subtyping
Abstract Classes
interfaces
OO contracts
Polymorphism
the good
the bad (duck typing)
Copyright ©2000-14 CRS Enterprises Ltd
142
Subclassing
A class can inherit methods and state from another class
the new class is called the subclass or derived class
the original class is called the superclass or base class
The subclass
is a superset of the superclass
inherits all the methods and state of the superclass
can add extra methods and state of its own
cannot remove and methods and state of the superclass
methods in the superclass can be overridden by the
subclass
the subclass is defined in the terms of the differences from
the superclass
Copyright ©2000-14 CRS Enterprises Ltd
143
The Object Class
object
All classes have a single root
object
only for new style classes
Person
Object
defines methods inherited by all Python
classes
Employee
SalesPerson
Copyright ©2000-14 CRS Enterprises Ltd
144
Constructors
Subclass makes explicit call to CTORs in superclass
class Person(object):
def __init__(self, name):
self.name = name
class Employee(Person):
def __init__(self, name, id):
Person.__init__(self, name)
self.id = id
class SalesPerson(Employee):
def __init__(self, name, id, region):
Employee.__init__(self, name, id)
self.region = region
Employee IS A Person
SalesPerson IS A Employee
SalesPerson IS A Person
p = Person("Anne")
e = Employee("Beth", 7468)
s = SalesPerson("Carol", 4712, "NE")
Copyright ©2000-14 CRS Enterprises Ltd
145
The Substitution Rule
Employee class
extends the Person class
Person
SalesPerson class
extends the Employee class
Employee substitutes for
Person object
SalesPerson substitutes for
Employee object
Person object
Copyright ©2000-14 CRS Enterprises Ltd
Superclass
extends
Employee
Subclass
extends
SalesPerson
146
Inheriting Methods
class Person(object):
def Print( ):
...
class Employee(Person):
def GetBonus( ):
...
Person p
Print( )
Employee e
class Salesman(Employee):
def GetBonus( ):
...
Salesman s
Print()
Print( )
Employee.GetBonus( )
GetBonus( )
GetBonus( )
Copyright ©2000-14 CRS Enterprises Ltd
147
Overriding Superclass Methods
Subclass can override any method of the superclass
superclass method hidden from client code
e = Employee("Beth", 7468)
e.display()
class Employee(Person):
def display(self):
Person.display(self)
# alternatively search super classes for display method
# super(Employee, self).display() # only for new style classes
print "id=", self.id,
Copyright ©2000-14 CRS Enterprises Ltd
148
Concrete and Abstract Classes
Concrete class
all methods are fully implemented
may have instance variables
objects can be instantiated
Abstract class
some methods are not implemented
some methods are implemented
may have instance variables
objects cannot be instantiated
Hoisting
abstract classes used to hold "common" code from subclasses
A concrete subclass
must implement all abstract methods of its superclass
Copyright ©2000-14 CRS Enterprises Ltd
149
Abstract Classes ...
from abc import ABCMeta, abstractmethod, abstractproperty
class Shape:
__metaclass__ = ABCMeta
@abstractmethod
def display(self): pass
@abstractproperty
def name(self): pass
Copyright ©2000-14 CRS Enterprises Ltd
150
... Abstract Classes
class Circle(Shape):
def __init__(self, name):
self.theName = name
def display(self):
print "Circle", self.name
@property
def name(self):
return self.theName
non abstract
methods and
instance
variables
automatically
available
must implement
all abstract
methods
c = Circle("my-circle")
print c.name
c.display()
Copyright ©2000-14 CRS Enterprises Ltd
151
Interfaces
An interface
similar to an abstract class, but ...
all methods are abstract
no instance variables allowed
final class variables permitted (constants)
Can't be instantiated
A concrete class can
implemented multiple interfaces
multiple inheritance model
extend only one class
multiple inheritance model
Copyright ©2000-14 CRS Enterprises Ltd
152
Polymorphic Methods
An (optional) abstract method
defined in interfaces and abstract classes
not appropriate for the superclass to provide an implementation
implemented by a subclasses
Implementations
each implementing subclass can provide its own implementation
there can be 'many forms' of these implementations
each implementation is called a Polymorphic method
Copyright ©2000-14 CRS Enterprises Ltd
153
Polymorphism
Polymorphic collections
include objects of any subclass
can call any of the methods of the superclass
class Person(object):
def Eat(self): pass
def Drink(self): pass
def Sleep(self): pass
class Employee(Person):
def Eat(self): pass
def Drink(self): pass
def Sleep(self): pass
def NightOut(p):
p.Drink()
p.Drink()
p.Eat()
p.Drink()
p.Sleep()
class SalesPerson(Employee):
def Eat(self): pass
def Drink(self): pass
def Sleep(self): pass
Copyright ©2000-14 CRS Enterprises Ltd
154
Duck Typing
Python allows polymorphic methods from classes not in
the hierarchy
not really sensible
drawback of Python's weak (duck) typing
class Person(object):
def Eat(self): pass
def Drink(self): pass
def Sleep(self): pass
def NightOut(p):
p.Drink()
p.Drink()
p.Eat()
p.Drink()
p.Sleep()
class Employee(Person): ...
class SalesPerson(Employee): ...
p = Person()
e = Employee()
s = SalesPerson()
class Horse:
def Eat(self): pass
def Drink(self): pass
def Sleep(self): pass
NightOut(p)
NightOut(e)
NightOut(s)
h = Horse()
NightOut(h)
Copyright ©2000-14 CRS Enterprises Ltd
155
Interfaces as Contracts
Interfaces for the Class Implementor
the interface defines all the methods and signatures for which the class
designer must provide implementations
Interfaces for the Class User
the class user can write code assuming that implementations will be
provided for all the methods in the interface
The Contract
each interface defines a contract between the class user and class
implementor
separates interface from implementation
essential for good object oriented design
Copyright ©2000-14 CRS Enterprises Ltd
156
Chapter 12
12
Copyright ©2000-14 CRS Enterprises Ltd
159
Further Topics
Intrinsic Attributes
for classes and objects
Dynamic Statements
exec and eval
Operator Overloading
numeric types
list types
Copyright ©2000-14 CRS Enterprises Ltd
160
The 5 Intrinsic Class Attributes
__name__
__doc__
__module__
__dict__
__bases__
name of the class (read only)
class documentation string
module in which the class is defined
map of all class attributes
tuple of all base classes
class Derived(Base):
"This is the Derived class"
def Display(self):
pass
print Derived.__name__
print Derived.__doc__
print Derived.__module__
print Derived.__dict__
print Derived.__bases__
Copyright ©2000-14 CRS Enterprises Ltd
Derived
This is the Derived class
__main__
{'Display': <function Display at ...
(<class __main__.Base at ...
161
The 2 Intrinsic Object Attributes
__class__
the object's class
__dict__ map of all the object's attributes
class Derived(Base):
"This is the Derived class"
def Display(self):
pass
x = Derived()
x.color = "red"
x.width = 10
print x.__class__
print x.__dict__
__main__.Derived
{'color': 'red', 'width': 10}
Copyright ©2000-14 CRS Enterprises Ltd
162
exec and eval Statements
exec
x = 10
y = 20
codeFragment = raw_input("Please enter some code (e.g. 'print x + y'): ")
exec codeFragment
Please enter some code (e.g. 'print x + y'): print x * y + 1
201
eval
x = 10
y = 20
codeFragment = str(input("Please enter an expression (e.g. 'x + y'): "))
result = eval(codeFragment)
print "result is: ", result
Please enter an expression (e.g. 'x + y'): x * y
result is: 200
Copyright ©2000-14 CRS Enterprises Ltd
163
Operator Overloading Numeric Types
class Time:
def __init__(self, hrs, min):
self.hrs = hrs
self.min = min
def __add__(self, other):
hrs = self.hrs + other.hrs
min = self.min + other.min
if min >= 60:
hrs = hrs + 1
min = min - 60
return Time(hrs, min)
t3 = t1 + t2
def Display(self):
print "Time is", self.hrs, self.min
Copyright ©2000-14 CRS Enterprises Ltd
164
Operator Overloading Numeric Types
class Time:
def __init__(self, hrs, min):
self.hrs = hrs
self.min = min
def __iadd__(self, other):
self.hrs = self.hrs + other.hrs
self.min = self.min + other.min
if self.min >= 60:
self.hrs = self.hrs + 1
self.min = self.min - 60
return self
t1 += t3
def Display(self):
print "Time is", self.hrs, self.min
Copyright ©2000-14 CRS Enterprises Ltd
165
Operator Overloading Numeric Types
class Time:
def __init__(self, hrs, min):
self.hrs = hrs
self.min = min
def __add__(self, other):
hrs = self.hrs + other.hrs
min = self.min + other.min
if min >= 60:
hrs = hrs + 1
min = min - 60
return Time(hrs, min)
t1 = Time(5,30)
t2 = Time(3,30)
t3 = t1 + t2
t3.Display()
def __iadd__(self, other):
t1 += t3
self.hrs = self.hrs + other.hrs
t1.Display()
self.min = self.min + other.min
if self.min >= 60:
self.hrs = self.hrs + 1
self.min = self.min - 60
return self
Time is 9 0
Time is 14 30
def Display(self):
print "Time is", self.hrs, self.min
Copyright ©2000-14 CRS Enterprises Ltd
166
Operator Overloading other Types
Emulate other types
Built-In Objects
Sequences
Slices
Emulate Maps
Special Methods to be Written
e.g. for Maps
__len__(self)
__getitem__(self,key)
__setitem__(self,key,value)
__delitem__(self,key)
Copyright ©2000-14 CRS Enterprises Ltd
167
Operator Overloading List Types
class MyList:
def __init__(self, p1, p2):
self.theList = [ ]
self.theList.append(p1)
self.theList.append(p2)
t1 = MyList(1,2)
t2 = MyList(3,4)
t3 = t1 + t2
def __add__(self, other):
result = [ ]
for item in self.theList:
result.append(item)
for item in other.theList:
result.append(item)
return result
t1: [1,2]
t2: [3,4]
t3: [1,2,3,4]
Copyright ©2000-14 CRS Enterprises Ltd
168
Overloading [ ] using __getitem__
class mydata:
def __init__(self):
self.data = "ABCDEFG"
def __getitem__(self, i):
return self.data[i]
B
ABCDEFG
object = mydata()
theChar = object[1]
print theChar;
for item in object:
print item,
Copyright ©2000-14 CRS Enterprises Ltd
169
Chapter 13
13
Copyright ©2000-14 CRS Enterprises Ltd
171
Pattern Matching
Pattern Matching
Splitting
Substitution
Comments
Replacement
Capture Patterns
Greedy Matching
Look Ahead
Copyright ©2000-14 CRS Enterprises Ltd
172
Anchors and Selections
selection indicates which characters to match
[abc]
any one character from list (a OR b OR c)
[a-m]
any one character from range (a OR b OR ... OR m)
[^abc] any one character not in list (NOT a NOR b NOR c)
. any one character
\s any white space character
\S any NON white space character
\d any digit
\D any NON digit
\w any alphanumeric
\W any NON alphanumeric
anchors indicate context
^ start of string
$ end of string
\b on a word boundary
\B NOT on a word boundary
Copyright ©2000-14 CRS Enterprises Ltd
173
Repeat Counts
repeat counts apply to the previous expression
* 0 or more repeats
+ 1 or more repeats
? 0 or 1 repeats
{n,m}
n to m repeats
{n,}
at least n repeats
{n} exactly n repeats
Examples
[aeiou]*
[0-9]+
[0-9]{3,5}
\.?
0 or more vowels
1 or more digits (\d+)
3 to 5 digits
0 or 1 periods
\. matches a period
the backslash negates the special meaning of the pattern that follows
Copyright ©2000-14 CRS Enterprises Ltd
174
Pattern Matching Functions
match
match from the start of text
search
match anywhere in the text
import re
test = "-------ABC------------"
pattern = r"\w+"
pattern = re.compile(pattern)
match = pattern.match(test)
print match
None
match = pattern.search(test)
print match.group()
ABC
Copyright ©2000-14 CRS Enterprises Ltd
175
Splitting
Perhaps we want to split a string using a regular
expression as a delimiter
pattern.split(text)
import re
pattern = re.compile(r"\s*;\s*")
text = "aaa ; bbb ;ccc ;
ddd ; eee"
list = pattern.split(text)
print list
['aaa', 'bbb', 'ccc', 'ddd', 'eee']
Copyright ©2000-14 CRS Enterprises Ltd
176
Substitution
Perhaps we want to substitute something for the matched
pattern? Use
pattern.sub(replacement, text)
import re
pattern = re.compile(r"\s*;\s*")
text = "aaa ; bbb ;ccc ;
ddd ; eee"
newText = pattern.sub("---", text)
print newText
aaa---bbb---ccc---ddd---eee
Copyright ©2000-14 CRS Enterprises Ltd
177
Using Comments
Always a good idea to use comments
regular expressions are difficult to read at the best of times
import re
string = "AAAA1111BBBB2222CCCC3333DDDD";
pattern = r"""
^
# start of line
(.*?)
# 0 or more characters
# non greedy
(\d+) # 1 or more digits
(.*)
# 0 or more characters
$
# end of line
"""
compiledPattern = re.compile(pattern, re.VERBOSE)
result = compiledPattern.search(string)
Copyright ©2000-14 CRS Enterprises Ltd
178
More Advanced Searches
Use ( ) in pattern to capture data
import re
text = "---111122223333333333334444555566667777---"
pattern = "2+(3+)4+(5+)6+"
# search for pattern
pattern = re.compile(pattern)
result = pattern.search(text)
# print results
print "full match: ", result.group(0)
print "capture pattern 1: ", result.group(1)
print "capture pattern 2: ", result.group(2)
print "all captures: ", result.groups()
Copyright ©2000-14 CRS Enterprises Ltd
179
Repeating Patterns
Use findall() and finditer()
to repeat searches
import re
text = "AB12CD34EF56GH"
pattern = r"(\d+)"
# find all occurrences of pattern
matcher = re.findall(pattern, text)
print matcher
# iterate through finding the pattern
for matcher in re.finditer(pattern, text):
print matcher.groups(0)
Copyright ©2000-14 CRS Enterprises Ltd
['12', '34', '56']
('12',)
('34',)
('56',)
180
Greedy Patterns
Greedy Patterns are the default
Use ? to use non greedy matching
text = "AAAA1111BBBB2222CCCC3333DDDD"
greedyPattern = r"^(.+)(\d+)(.+)$"
nonGreedyPattern = r"^(.+?)(\d+)(.+)$"
^(.+)(\d+)(.+)$
Greedy:
<AAAA1111BBBB2222CCCC333><3><DDDD>
^(.+?)(\d+)(.+)$
Non-Greedy: <AAAA><1111><BBBB2222CCCC3333DDDD>
Copyright ©2000-14 CRS Enterprises Ltd
181
Look Ahead and Look Behind
(?= )
(?! )
(?<= )
(?<! )
peek ahead matching RE
peek ahead not matching RE
peek behind matching RE
peek behind not matching RE
\w+[.](?!bat)\w+$
?!bat
not "bat"
filename.ext
Copyright ©2000-14 CRS Enterprises Ltd
182
Building Patterns
Translation patterns can be built from hashes
e.g. translate all occurrences of mon to Monday, tue to Tuesday etc
import re
def replaceGroup(matcher):
key = matcher.group(1)
return days[key]
days = { 'mon' : 'Monday', 'tue' : 'Tuesday',
'wed' : 'Wednesday', 'thu' : 'Thursday',
'fri' : 'Friday' }
pattern = "(" + "|".join(days.keys()) + ")"
compiledPattern = re.compile(pattern)
print "pattern: ", pattern
text = '''The course starts on mon, continues on tue,
but wed is the last day'''
for matcher in re.finditer(compiledPattern, text):
text = compiledPattern.sub(replaceGroup, text, 1)
print text
Copyright ©2000-14 CRS Enterprises Ltd
183
Copyright ©2000-14 CRS Enterprises Ltd
184
Chapter 14
14
Copyright ©2000-14 CRS Enterprises Ltd
185
Unit Test
Unittest framework
DocTest
PyTest
Copyright ©2000-14 CRS Enterprises Ltd
186
Components of Unittest
test fixture
code run to prepare for one or more tests
e.g. start a server
any associate cleanup actions
test case
unit of testing
implemented as a method of test class
test suite
a collection of test cases
used to aggregate tests that should be executed together.
test runner
component which orchestrates the execution of tests
provides output relating to the success or failure of the tests
Copyright ©2000-14 CRS Enterprises Ltd
187
Structure of Test Class
derive from unittest.TestCase
setUp call before each test
tearDown called after each test
import unittest
execute tests by calling
unittest.main()
test names must begin with
test...
class testPoint(unittest.TestCase):
def setUp(self):
# called before each test executes
def testA(self): ...
def testB(self): ...
def testC(self): ...
def testD(self): ...
if __name__ == '__main__':
unittest.main()
Copyright ©2000-14 CRS Enterprises Ltd
188
Structure of a Test Case
Use assertEqual()
to check the output of a test is correct
other functions available
def testMoveBy2(self):
"""moveBy test(2)"""
self.point.moveBy(5, 2)
self.assertEqual(self.point.display(), "8,7")
FAIL: moveBy test(2)
---------------------------------------------------------------------Traceback (most recent call last):
File "C:\_Eclipse\Python\Unit Test\unit-testing-1.py", line 29, in testMoveBy2
self.assertEqual(self.point.display(), "8,7")
AssertionError: '8,6' != '8,7'
Copyright ©2000-14 CRS Enterprises Ltd
189
Test Functions
assertEqual()
check for an expected result
assert_()
verify a condition
assertRaises()
verify that an expected exception gets raised
Copyright ©2000-14 CRS Enterprises Ltd
190
Test Suites
Tests can be grouped into suites
def suite():
suite = unittest.TestSuite()
suite.addTest(testPoint('testConstructor'))
suite.addTest(testPoint('testMoveBy1'))
suite.addTest(testPoint('testDistance1'))
return suite
if __name__ == '__main__':
mySuite = suite()
unittest.TextTestRunner(verbosity=0).run(mySuite)
Copyright ©2000-14 CRS Enterprises Ltd
191
DocTest
DocTest module searches for text that look like
interactive Python sessions
executes those sessions to verify that they work exactly as shown
Tests are embedded in code
easy to define tests
can cause clutter
Copyright ©2000-14 CRS Enterprises Ltd
192
01 simple example
Use doctest.testmod(...)
many parameters, but usually just use verbose=True
def cube(x):
"""
The cube function returns x * x * x
>>> cube(3)
27
>>> cube(-1)
-1
"""
return x*x*x
if __name__ == '__main__':
import doctest
doctest.testmod(verbose = True)
Copyright ©2000-14 CRS Enterprises Ltd
193
02 formatting
Tests can be fuzzy
... used to omit some results
whitespace not relevant
if ELLIPIS and NORMALIZE_WHITESPACE specified
def squares(a, b):
"""
returns all the squares in range a..b
>>> squares(1,10) # doctest:+ELLIPSIS +NORMALIZE_WHITESPACE
[1, 4, ..., 100]
"""
answer=[]
for i in range(a,b+1):
answer.append(i*i)
return answer
Copyright ©2000-14 CRS Enterprises Ltd
194
03 failures
Failures reported
with line numbers
and erroneous result
def sumsquares(n):
"""
Trying:
1+4+9+16 = 30 (not 30457)
sumsquares( 4 )
>>> sumsquares( 4 )
Expecting:
30457
30457
"""
**********************************************************************
sum = 0
File "C:\_Eclipse\Advanced Python\src\Unit
Framework
forTest
i in range(n+1):
Failed example:
sum += square(i)
sumsquares( 4 )
return sum
Expected:
30457
Got:
30
Copyright ©2000-14 CRS Enterprises Ltd
195
04 exceptions
Exceptions can be catered for in the tests
use ... to suppress unnecessary information
def square(x):
"""
This function squares a number
>>> square(-3)
9
>>> square(16)
Traceback (most recent call last):
...
ValueError: input too large
"""
if x > 10:
raise ValueError('input too large')
else:
return x*x
Copyright ©2000-14 CRS Enterprises Ltd
196
PyTest
PyTest runs as a separate program
inspects code for methods beginning with test_ and runs them
If you need to install PyTest, use:
easy_install -U py
To run tests, go to a command prompt and type:
py.test myExample.py
Copyright ©2000-14 CRS Enterprises Ltd
197
01 simple example
Add tests as methods in your modules
use assert statements
def square(x):
return x * x
def test_squares():
assert square(6) == 36 # succeeds
assert square(10) == 99 # fails
Copyright ©2000-14 CRS Enterprises Ltd
198
02 multiple tests
Use iterators to create multiple tests
Use setup_class()
class TestSquare:
for initial test conditions
def setup_class(self):
self.m = maths.Maths()
def is_square(self, n, expected):
self.m.setX(n)
assert self.m.square() == expected
def test_squares(self):
# set up 5 tests (the last one fails!)
inputs = ( 4, 7, 10, 20, 25)
outputs = (16, 49, 100, 400, -1)
for i, o in zip(inputs, outputs):
yield self.is_square, i, o
Copyright ©2000-14 CRS Enterprises Ltd
199