Python program structure
¨ Programs are composed of modules
¨ Modules contain statements
¨ Statements contain expressions: logic
¨ Expressions create and process objects
Statement |
Examples |
Assignment |
curly,
moe, larry = 'good', 'bad', 'ugly' |
Calls |
stdout.write("spam,
ham, toast\n") |
Print |
print
1, "spam", 4, 'u', |
If/elif/else |
if
"python" in text: mail(poster, spam) |
For/else |
for
peteSake in spam: print peteSake |
While/else |
while
1: print 'spam',i; i=i+1 |
Pass |
while
1: pass |
Break,
Continue |
while
1: break |
Try/except/finally |
try:
spam() except: print 'spam error' |
Raise |
raise
overWorked, cause |
Import,
From |
import
chips; from refrigerator import beer |
Def,
Return,Yield |
def
f(a, b, c=1, *d): return a+b+c+d[0] |
Class |
class
subclass(superclass): staticData = [] |
Global |
def
function(): global x, y; x = 'new' |
|
|
Exec |
exec
"import " + moduleName in gdict, ldict |
Assert |
assert
name != "", "empty name field" |
With/As |
with
open('text.dat'):… # in python 2.6+ |
Python syntax
¨ No variable/type declarations
¨ No braces or semicolons
¨ The “what you see is what you get” of languages
Python assignment
¨ Assignments create object references
¨ Names are created when first assigned
¨ Names must be assigned before being referenced
A Tale of Two Ifs…
C++/Java:
if (x) {
x = y + z; // braces, semicolons, parens
}
Python:
if x:
x = y + z # indented blocks, end of line, colon
¨ ‘=’ assigns object references to names or components
¨ Implicit assignments: import, from, def, class, for, calls
Operation |
Interpretation |
spam
= 'SPAM' |
basic
form |
spam,
ham = 'yum', ' |
tuple
assignment |
[spam,
ham] = ['yum', ' |
list
assignment |
a,
b, c, d = 'spam' |
sequence
assign |
spam
= ham = 'lunch' |
multiple-target |
spam
+= 42; ham *= 12 |
Augmented
(2.0) |
Variable name rules
¨ (‘_’ or letter) + (any number of letters, digits, ‘_’s)
¨ Case matters: ‘SPAM’ is not ‘spam’
¨ But can’t use reserved words:
¨ + “yield”,
for generators (2.3 and later)
¨ + “with”
and “as” for context managers (2.6, optional
in 2.5 though not in 2.5 IDLE!)
and |
assert |
break |
class |
continue |
def |
del |
elif |
else |
except |
exec |
finally |
for |
from |
global |
if |
import |
in |
is |
lambda |
not |
or |
pass |
print |
raise |
return |
try |
while |
· Also applies to module file names:
‘my-code.py’ can be run, but not
imported!
¨ Useful for calls, and interactive prints
¨ Expressions can be used as statements
¨ Statements cannot be used as expressions (‘=’)
Operation |
Interpretation |
spam(eggs,
ham) |
function
calls |
spam.ham(eggs) |
method
calls |
spam |
interactive
print |
spam
< ham and ham != eggs |
compound
expr's |
spam
< ham < eggs |
range
tests |
¨ Python 2.0 “list comprehension” expressions (covered in Functions)
¨ Similar to map/lambda combination (result=[0,1,4,9])
[i**2 for i in range(4)] …like… map((lamba x: x**2), range(4))
¨ ‘print’ statement writes objects to the ‘stdout’ stream
¨ File object ‘write’ methods write strings to files
¨ Adding a trailing comma suppresses line-feed
¨ Reset ‘sys.stdout’ to catch print output
Operation |
Interpretation |
print
spam, ham |
print
objects to sys.stdout |
print
spam, ham, |
don’t add
linefeed at end |
print>>file,
spam |
Python
2.0: not to stdout |
The Python ‘Hello world’ program
· Expression results don’t need to be printed at top-level
>>> print 'hello world'
hello world
>>> 'hello world'
'hello world'
· The hard way
>>> x = 'hello world'
>>> import sys
>>> sys.stdout.write(str(x) + '\n')
· sys.stdout can be assigned
>>> sys.stdout = open('log', 'a') # or a class with .write
>>> print x
¨ Python’s main selection construct
¨ No ‘switch’: via if/elif/else, dictionaries, or lists
General format
if <test1>:
<statements1>
elif <test2>: # optional elif’s
<statements2>
else: # optional else
<statements3>
Examples
>>> if 3 > 2:
... print 'yep'
...
yep
>>> x = 'killer rabbit'
>>> if x == 'bunny':
... print 'hello little bunny'
... elif x == 'bugs':
... print "what's up doc?"
... else:
... print 'Run away!... Run away!...'
...
Run away!... Run away!...
>>> choice = 'ham'
>>> print {'spam': 1.25, # dictionary switch
... 'ham': 1.99,
... 'eggs': 0.99,
... 'bacon': 1.10}[choice]
1.99
# with
actions
{'spam': (lambda: …),
'ham':
(lambda: …),
…}[choice]()
¨ Compound statements = header, ‘:’, indented statements
¨ Block and statement boundaries detected automatically
¨ Comments run from “#” through end of line
¨ Documentation strings at top of file, class, function
Block delimiters
¨
Block boundaries detected by line indentation
¨
Indentation is any combination of spaces and tabs
¨
Tabs = N spaces up to multiple of 8 (but don’t mix)
Statement delimiters
¨
Statement normally end at end-of-line, or ';'
¨
Statements may span lines if open syntactic pair: ( ), { }, [ ]
¨
Statements may span lines if end in backslash (outdated feature)
¨
Some string constants span lines too (triple-quotes)
Special cases
L = ["Good",
"Bad",
"Ugly"] # open pairs may span lines
x = 1; y = 2; print x # more than 1 simple statement
if 1: print 'hello' # simple statement on header line
Nesting code blocks
x = 1 # block0
if x:
y = 2 # block1
if y:
print 'block2'
print 'block1'
print 'block0'
Form |
Role |
# comments |
In-file
documentation |
The
dir function |
Lists
of attributes available on objects |
Docstrings: __doc__ |
In-file
documentation attached to objects |
PyDoc: The help function |
Interactive
help for objects |
PyDoc: HTML reports |
Module
documentation in a browser |
Standard
manual set |
Official
language and library descriptions |
Web
resources |
Online
tutorial, examples, and so on |
Published
books |
Commercially-available
texts (see Resources) |
>>> import sys
>>> dir(sys) # also works on types, objects, etc.
['__displayhook__', '__doc__', '__excepthook__', '__name__', …
>>> print sys.__doc__
This module provides access to some objects …
>>> help(sys)
Help on built-in module sys: …
Start/Python24/ModuleDocs (or pydocgui.pyw):
# File: docstrings.py
"""
Module documentation
Words Go Here
"""
spam = 40
def square(x):
"""
function documentation
can we have your liver then?
"""
return x **2
¨ True = non-zero number, or non-empty object
¨ Comparisons operators return “True” (1) or “False” (0)
¨ Boolean operators short-circuit
¨ Boolean operators return an operand object
Object |
Value |
"spam" |
true |
"" |
false |
[] |
false |
{} |
false |
1 |
true |
0.0 |
false |
None |
false |
Examples
>>> 2 < 3, 3 < 2 # return True (1) or False (0)
(True, False)
>>> 2 or 3, 3 or 2 # return left operand if true
(2, 3) # else return right operand (T|F)
>>> [] or 3
3
>>> [] or {}
{}
>>> 2 and 3, 3 and 2 # return left operand if false
(3, 2) # else return right operand (T|F)
>>> [] and {}
[]
>>> 3 and []
[]
C’s ternary operator in Python
·
Prior to
2.5: X = (A and B) or C
·
New in
2.5: X = B if A else C
Boolean type (2.3+)
bool is a subclass of int
bool has two instances: True and False
True,False are 1,0 but print differently
>>> 1 > 0
True
>>> True == 1, True is 1
(True, False)
>>> True + 1
2
¨ Python’s most general iteration construct
¨ One of two looping statements: while, for
¨ Implicit looping tools: map, reduce, filter, in, list comprehensions
General format
while <test>:
<statements>
else: # optional else
<statements2> # run if didn’t exit with break
Examples
>>> while True:
... print 'Type Ctrl-C to stop me!'
>>> count = 5
>>> while count:
... print count,
... count -= 1
...
5 4 3 2 1
>>> x = 'spam'
>>> while x:
... print x,
... x = x[1:] # strip first char off x
...
spam pam am m
>>> a=0; b=10
>>> while a < b: # one way to code counter loops
... print a,
... a = a+1
...
0 1 2 3 4 5 6 7 8 9
¨ break jumps out of the closest enclosing loop
¨ continue jumps to the top of the closest enclosing loop
¨ pass does nothing: an empty statement placeholder
¨ loop else run if loop exits normally: without a ‘break’
General loop format
while <test>:
<statements>
if <test>: break # exit loop now, skip else
if <test>: continue # go to top of loop now
else:
<statements> # if we didn’t hit a ‘break’
Examples
¨ Pass: an infinite loop
while True: pass # ctrl-C to stop!
¨ Continue: print even numbers
· Avoids statement nesting (but use sparingly!)
x = 10
while x:
x = x-1
if x % 2 != 0: continue # odd?--skip
print x,
¨ Break: find factors
· Avoids search status flags
x = y / 2
while x > 1:
if y % x == 0: # remainder
print y, 'has factor', x
break # skip else
x = x-1
else: # normal exit
print y, 'is prime'
¨ A general sequence iterator
¨ Works on strings, lists, tuples
¨ Replaces most ‘counter’ style loops
¨ Repeatedly indexes object until IndexError detected
¨ Preview: also works on Python classes and C types
General format
for <target> in <object>: # assign object items to target
<statements>
if <test>: break # exit loop now, skip else
if <test>: continue # go to top of loop now
else:
<statements> # if we didn’t hit a ‘break’
Examples
>>> for x in ["spam", "eggs", "spam"]:
... print x,
...
spam eggs spam
>>> prod = 1
>>> for i in (1, 2, 3, 4): prod *= i # tuples
...
>>> prod
24
>>> S = 'spam'
>>> for c in S: print c # strings
...
s
p
a
m
Works on any iterable object: files, dicts
>>> for line in open('data.txt'):
print line.upper() # calls .next(), catches exc
>>> for key in D:
print key, D[key]
¨ for subsumes most counter loops
¨ range generates a list of integers to iterate over
¨ xrange similar, but doesn’t create a real list
¨ avoid range, and the temptation to count things!
# The easy (and fast) way
>>> X = 'spam'
>>> for item in X: print item, # step through items
...
s p a m
# The hard way: a C-style for loop
>>> i = 0
>>> while i < len(X): # manual while indexing
... print X[i],; i += 1
...
s p a m
# Range and fixed repitions
>>> range(5), range(2, 5)
([0, 1, 2, 3, 4], [2, 3, 4])
>>> for i in range(4): print 'A shrubbery!'
...
A shrubbery!
A shrubbery!
A shrubbery!
A shrubbery!
# Using range to generate offsets (not items!)
>>> X
'spam'
>>> len(X)
4
>>> range(len(X))
[0, 1, 2, 3]
>>> for i in range(len(X)): print X[i], # step through offsets
...
s p a m
# Using range and slicing for non-exhaustive traversals
>>> range(2,10,2)
[2, 4, 6, 8]
>>> S = 'abcdefghijk'
>>> for i in range(0,len(S),2): print S[i],
...
a c e g i k
in recent releases…
>>> for c in S[::2]: print c, # S[::-1] reverses
...
a c e g i k
# Using range and enumerate to change a list in-place
>>> L = [1, 2, 3, 4]
>>> for x in L: x += 10
>>> L
[1, 2, 3, 4]
>>> for i in range(len(L)): L[i] += 10
>>> L
[11, 12, 13, 14]
List comprehensions
>>> M = [x + 10 for x in L]
>> M
21, 22, 23, 24]
>>> lines = [line.rstrip() for line in open('README.txt')]
>>> [row[1] for row in matrix]
… more in functions section
Enumerate in 2.3+
>>> for (i, x) in enumerate(L):
L[i] = x * 2
>>> L
[22, 24, 26, 28]
>>> enumerate(L)
<enumerate object at 0x00B48440>
>>> list(enumerate(L))
[(0, 22), (1, 24), (2, 26), (3, 28)]
>>> E = enumerate(L)
>>> E.next()
(0, 22)
>>> E.next() # see generators in next section
(1, 24)
# Traversing sequences in parallel with zip
>>> L1 = [1,2,3,4]
>>> L2 = [5,6,7,8]
>>>
>>> zip(L1,L2)
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>>
>>> for (x,y) in zip(L1, L2):
... print x, y, '--', x+y
...
1 5 -- 6
2 6 -- 8
3 7 -- 10
4 8 -- 12
# Traversing dictionaries by sorted keys
>>> D = {'a':1, 'b':2, 'c':3}
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> Ks = D.keys()
>>> Ks.sort()
>>> for k in Ks: print D[k],
1 2 3
Sorted in 2.4+
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> for k in sorted(D): print D[k],
1 2 3
# Common ways to read from files
# file creation
>>> myfile = open('myfile.txt', 'w')
>>> for i in range(3):
myfile.write(('spam' * (i+1)) + '\n')
>>> myfile.close()
# all at once
>>> print open('myfile.txt').read()
spam
spamspam
spamspamspam
# line by line
>>> myfile = open('myfile.txt')
>>> while True:
line = myfile.readline()
if not line: break
print line,
spam
spamspam
spamspamspam
# all lines at once
>>> for line in open('myfile.txt').readlines():
print line,
spam
spamspam
spamspamspam
# file iterators:
line by line
>>> for line in open('myfile.txt'):
print line,
spam
spamspam
spamspamspam
# by byte counts
>>> myfile = open('myfile.txt')
>>> while True:
line = myfile.read(10)
if not line: break
print '[' + line + ']',
[spam
spams] [pam
spamsp] [amspam
]
# Summing data file columns
>>> print open('data.txt').read()
001.1 002.2 003.3
010.1 020.2 030.3 040.4
100.1 200.2 300.3
>>> sums = {}
>>> for line in open('data.txt'):
cols = [float(col) for col in line.split()] # next!
for pos, val in enumerate(cols):
sums[pos] = sums.get(pos, 0.0) + val
>>> for key in sorted(sums):
print key, '=', sums[key]
0 = 111.3
1 = 222.6
2 = 333.9
3 = 40.4
>>> sums
{0: 111.3, 1: 222.59999999999999, 2: 333.90000000000003,
3: 40.399999999999999}
¨ Don’t forget to type a “:” at the end of compound statement headers
¨ Be sure to start top-level (unnested) code in column 1
¨ Blank lines in compound statements are ignored in files, but end the statement at the interactive prompt
¨ Avoid mixing tabs and spaces in indentation, unless you’re sure what your editor does with tabs
¨ C programmers: you don’t need “( )” around tests in “if” and “while”; you can’t use “{ }” around blocks
¨ In-place change operations like list.append() and list.sort() don’t return a value (really, they return “None”); call them without assigning the result.
¨ Add parens to call a function: “file.close()” is a call, “file.close” is a reference only
¨ Create and process higher-level program components
Unit |
Role |
Functions |
procedural units |
Modules |
code/data packages |
Exceptions |
errors and special cases |
Classes |
new objects |
C modules |
optimization, customization,
integration |
Click here to go to
lab exercises
Click here to go to
exercise solutions
Click here to go to solution source files
Click here to go to
lecture example files