Sigcse Slides PDF
Sigcse Slides PDF
John M. Zelle
Wartburg College
Outline
Why Python? Educational Apps
Functional Programming
Basic Structures GUIs
I/O Graphics
Assignment Internet Programming
Numbers Databases
Strings Op Systems
Functions Others
Decisions
Loops Python Resources
Collections
Software Engineering
Modules/Packages
Classes
Exceptions
Library
What is Python?
Or...
def main():
print "Hello SIGCSE"
main()
Running Python Programs
Options:
Start Interpreter from command line (>>> )
Type program statements
Import script file
#File: chaos.py
# A simple program illustrating chaotic behavior.
def main():
print "This program illustrates a chaotic function"
x = input("Enter a number between 0 and 1: ")
for i in range(10):
x = 3.9 * x * (1 - x)
print x
main()
Python Features
No variable declarations
$ python chaos.py
This program illustrates a chaotic function
Enter a number between 0 and 1: .5
0.975
0.0950625
0.335499922266
0.869464925259
0.442633109113
0.962165255337
0.141972779362
0.4750843862
0.972578927537
0.104009713267
$
Basic Output Statement
Notes:
Simple Assignment
<var> = <expr>
myVar = oldValue * foo + skip
Simultaneous Assignment
<var1>, <var2>, ... = <expr1>, <expr2>, ...
a,b = b,a
Assigning Input
input(<prompt>)
myVar = input("Enter a number: ")
x,y = input("Enter the coordinates (x,y): ")
Example Program: Fibonacci
# fibonacci.py
# This program computes the nth Fibonacci number
cur,prev = 1,1
for i in range(n-2):
cur,prev = prev+cur,cur
Pluses
less code
less upfront explanation
eliminates "redeclaration" errors
Minuses
typo on LHS of = creates new variable
allows variables to change type
Pluses
less code clutter (; and {})
eliminates most common syntax errors
promotes and teaches proper code layout
Minuses
occasional subtle error from inconsistent spacing
will want an indentation-aware editor
Builtins
+, -, *, /, %, **, abs(), round()
Math Library
pi, e, sin(), cos(), tan(), log(),
log10(), ceil(), ...
Example Numeric Program: quadratic.py
# quadratic.py
# Program to calculate real roots
# of a quadratic equation
import math
discRoot = math.sqrt(b * b - 4 * a * c)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
import math as m
discRt = m.sqrt(b * b - 4 * a * c)
factorial = 1
for factor in range(2,n+1):
factorial *= factor
>>> "Hello" * 3
HelloHelloHello
>>> greet[4:9]
o Joh
>>> greet[:5]
Hello
>>> greet[6:]
John
>>> len(greet)
10
Example Program: Month Abbreviation
# month.py
# prints the abbreviation for a month
months = "JanFebMarAprMayJunJulAugSepOctNovDec"
Interactive input
s = raw_input("Enter your name: ")
Type conversion
to string
>>> str(10)
10
from string
>>> eval(10)
10
>>> eval(3 + 4 * 7)
31
Standard String Library (string)
capitalize(s) -- upper case first letter
capwords(s) -- upper case each word
upper(s) -- upper case every letter
lower(s) -- lower case every letter
message = ""
for numStr in string.split(inString):
message += chr(eval(numStr))
Examples
>>> "Hello %s %s, you owe %d" % ("Mr.", "X", 10000)
Hello Mr. X, you owe 10000
Opening a file
syntax: <filevar> = open(<name>, <mode>)
example: infile = open("numbers.dat", "r")
Writing to file
syntax: <filevar>.write(<string>)
example: outfile.write(data)
Example Program: Username Creation
inf.close()
outf.close()
Example:
def distance(x1, y1, x2, y2):
# Returns dist from pt (x1,y1) to pt (x2, y2)
dx = x2 - x1
dy = y2 - y1
return math.sqrt(dx*dx + dy*dy)
Notes:
Parameters are passed by value
Can return multiple values
Function with no return statement returns None
Allows Default values
Allows Keyword arguments
Allows variable number of arguments
Teaching Tip: Uniform Memory Model
Pluses
All assignments are exactly the same
Parameter passing is just assignment
Minuses
Need to be aware of aliasing when objects are mutable
Variable Scope
Classic Python has only two scope levels: local and global
(module level)
def myFunc():
global callCount
...
callCount = callCount + 1
Decisions
if temp > 90:
print "Its hot!"
if x <= 0:
print "negative"
else:
print "nonnegative"
if x > 8:
print "Excellent"
elif x >= 6:
print "Good"
elif x >= 4:
print "Fair"
elif x >= 2:
print "OK"
else:
print "Poor"
Booleans in Python
No Boolean type
Example:
for n in names:
if n == target: break
else:
print "Error:", target, "is not in list"
>>> x[3]
U
>>> x[1:3]
[Spam, 4]
>>> x + x
[1, Spam, 4, U, 1, Spam, 4, U]
>>> x * 2
[1, Spam, 4, U, 1, Spam, 4, U]
>>> x[1] = 5
>>> x
[1, 5, 3, 4]
def getNums():
nums = []
while 1:
xStr = raw_input("Enter a number: ")
if not xStr:
break
nums.append(eval(xStr))
return nums
def average(lst):
sum = 0.0
for num in lst:
sum += num
return sum / len(lst)
data = getNums()
print "Average =", average(data)
Tuples: Immutable Sequences
>>> dict[Python]
Van Rossum
>>> dict.keys()
[Python, Pascal, Java, C++]
>>> dict.values()
[Van Rossum, Wirth, Gosling, Stroustrup]
>>> dict.items()
[(Python, Van Rossum), (Pascal, Wirth), (Java,
Gosling), (C++, Stroustrup)]
More Dictionary Operations
k in dict -- Ditto
text = open(sys.argv[1],r).read()
text = text.lower()
for ch in string.punctuation:
text = text.replace(ch, )
counts = {}
for w in text.split():
counts[w] = counts.get(w,0) + 1
items = []
for w,c in counts.items():
items.append((c,w))
items.sort()
items.reverse()
for i in range(10):
c,w = items[i]
print w, c
Python Modules
Pluses
Makes independent testing of modules easier
Eliminates visibility constraints (public, private, static, etc.)
Minuses
Language does not enforce the discipline
class MSDie:
def roll(self):
self.value = randrange(1, self.sides+1)
def getValue(self):
return self.value
Using a Class
class SettableDie(MSDie):
"""Implementation of a classic
stack data structure: class Stack"""
class Stack:
FP features
First class functions
Recursion
Reliance on lists
Closures
def reverse(lst):
if lst==[]:
return []
else:
return reverse(tail(lst)) + [head(lst)]
FP Example: QuickSort
Pluses
Cross-platform
Very easy to learn and use
Comes with Python
Event loop integrated into interpreter
Excellent text and canvas widgets
Minuses
Small widget set
Relies on TCL layer
can be sluggish
more layers to understand
Example Program: Hello World, GUI-style
from Tkinter import *
root = Tk()
root.title("Hello GUI")
Label(root, text=Hello SIGCSE,
font=times 32 bold).pack()
root.mainloop()
Example Program: Quitter
def quit():
ans = askokcancel(Verify exit, "Really quit?")
if ans:
sys.exit()
root = Tk()
root.title("Quitter")
b = Button(root, text="Dont do it",
font="times 24 normal",
command = quit)
b.pack()
root.mainloop()
Example Program: Quitter (Screenshots)
Example Program: OO Quitter
class Quitter:
def quit(self):
ans = askokcancel("Verify exit",
"Really quit?")
if ans: sys.exit()
root = Tk()
root.title("Quitter 2")
Quitter(root).mainloop()
Example Program: Simple Editor
class Editor(Frame):
def buildMenus(self):..
def onSave(self):...
def onExit(self):...
Example Program: Simple Editor(contd)
def buildMenus(self):
menubar = Menu(self.root)
self.root.config(menu=menubar)
filemenu = Menu(menubar,tearoff=0)
filemenu.add_command(label="New...", command=None)
filemenu.add_command(label="Open...", command=None)
filemenu.add_separator()
filemenu.add_command(label = "Save",
command=self.onSave)
filemenu.add_command(label="Save as...",
command=None)
filemenu.add_separator()
filemenu.add_command(label="Exit",
command=self.onExit)
menubar.add_cascade(label="File", menu=filemenu)
Example Program: Simple Editor (contd)
def onSave(self):
if not self.filename:
filename = asksaveasfilename()
if not filename:
return
self.filename=filename
file = open(filename, w)
file.write(self.text.get("1.0",END))
file.close()
def onExit(self):
ans = askokcancel(Verify exit,
Really quit?)
if ans: sys.exit()
root = Tk()
root.title("Simple Editor")
Editor(root).mainloop()
Example Program: Simple Editor (screen)
Real Tkinter Application: PySol
Computer Graphics
scene.autoscale=0
dt = 0.01
while 1:
rate(100)
ball.pos = ball.pos + ball.velocity*dt
if ball.y < 1:
ball.velocity.y = -ball.velocity.y
else:
ball.velocity.y = ball.velocity.y - 9.8*dt
VPython Example: Screenshot
PyOpenGL Example: GLUT Cone
def init():
glMaterialfv(GL_FRONT, GL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
...
glMaterialfv(GL_FRONT, GL_SHININESS, 50.0)
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.0, 1.0, 0.0, 1.0])
...
glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0]);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
def redraw(o):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glPushMatrix()
glTranslatef(0, -1, 0)
glRotatef(250, 1, 0, 0)
glutSolidCone(1, 2, 50, 10)
glPopMatrix()
def main():
o = Opengl(width = 400, height = 400, double = 1, depth = 1)
o.redraw = redraw
o.pack(side = TOP, expand = YES, fill = BOTH)
init()
o.mainloop()
main()
PyOpenGL Example: GLUT Cone (Screen)
Internet Programming
Client-Server GUI
Example Project: Chat Server
Three modules
chat server
talk client
listen client
def server(port=2001):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", port))
s.listen(10)
listeners = [] # list of listener sockets
print "SCServer started on port", port
while 1:
conn, address = s.accept()
message = ""
while "\n" not in message:
message = message + conn.recv(1)
if message[0] in "lL":
listeners.append(conn)
elif message[0] in "tT":
for lsock in listeners:
lsock.send(message[1:])
---------------------------------------------------------------
def listen(machine, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((machine, port))
s.send("listen\n")
try:
while 1:
mess = ""
while not "\n" in mess:
mess = mess + s.recv(1)
print mess[:-1]
finally:
s.close()
<HTML>
<PRE>
%s
</PRE>
</HTML>"""
class EchoHandler(StreamRequestHandler):
def handle(self):
lines = []
while 1:
line = self.rfile.readline()
if line == "\r\n": break #empty line at end of header
lines.append(line)
self.wfile.write(RESPONSE % "".join(lines))
def start(port):
server = TCPServer(("",port), EchoHandler)
server.serve_forever()
Python Provides
Standard module (cgi) to parse form input
Add-ons to produce nice HTML
Simple CGI Script
import cgi
RESPONSE="""Content-type: text/html
<HTML>
<HEAD>
<TITLE>%s</TITLE>
</HEAD>
<PRE>
<BODY>
%s
</PRE>
</BODY>"""
form = cgi.FieldStorage()
content = []
for name in form.keys():
content.append("Name: %s value: %s" % (name, form[name].value))
content.append("Done")
Uses
Backend for web applications
Interactive query engine
DB Application Development
Datbase Example: PostgreSQL
import pg # PostgreSQL database module
from pprint import pprint # pretty printing
----------------------------------------------------------------
4
[(Johnson, 900.0), (Jones, 750.0), (Lindsay, 700.0)]
[{customer_name: Johnson, balance: 900.0},
{customer_name: Jones, balance: 750.0},
{customer_name: Lindsay, balance: 700.0}]
(customer_name, balance)
Operating Systems
--------------------------------------------------------------
import signal
for i in range(1,31):
if i != 9 and i != 19:
signal.signal(i, handler)
def spawnNode():
readEnd, writeEnd = os.pipe()
if os.fork() == 0: # Code for newly created node
os.close(writeEnd); sieveNode(readEnd); sys.exit(0)
return writeEnd
def sieveNode(pipeIn):
myIn = os.fdopen(pipeIn) # Turn pipe into regular file
myNum = eval(myIn.readline())
print "[%d]: %d" % (os.getpid(),myNum)
myOut = None
while 1:
candidate = eval(myIn.readline())
if candidate == -1: break
if candidate % myNum != 0: # not divisible, send down pipe
if not myOut: myOut = spawnNode()
os.write(myOut, str(candidate)+\n)
if myOut:
os.write(myOut,-1\n)
os.wait()
Threads
Assignments:
Create more sophisticated structures
Concurrency/Synchronization problems
Example Assignment: Counting
Semaphores
class Semaphore:
def __init__(self, value = 0):
self.count = value
self.queue = []
self.mutex = thread.allocate_lock()
def wait(self):
self.mutex.acquire()
self.count = self.count - 1
if self.count < 0:
wlock = thread.allocate_lock()
wlock.acquire()
self.queue.append(wlock)
self.mutex.release()
wlock.acquire() # suspend on new lock
else:
self.mutex.release()
def signal(self):
self.mutex.acquire()
self.count = self.count + 1
if self.count <= 0:
wlock = self.queue[0]
del self.queue[0]
wlock.release() # let the waiting thread go
self.mutex.release()
Example Program: Dining Philosophers
NUM_PHILOSOPHERS = 5; THINKMAX = 6; EATMAX = 2
d = DPDisplay(NUM_PHILOSOPHERS)
forks = []
for i in range(NUM_PHILOSOPHERS):
forks.append(Semaphore(1)); d.setFork(i,"free")
for i in range(NUM_PHILOSOPHERS):
thread.start_new_thread(philosopher, (i,forks, d))
d.pause()
Dining Philosophers (Screenshot)
Student Project: Hungry Monkeys
Python in Other Classes
Python Rocks!