lpython/ 000777 000000 000000 00000000000 06671372472 006237 lpython/lp-code-readme.txt 001777 000000 000000 00000006540 06713513276 011570 File: lp-code-readme.txt
Home: http://rmi.net/~lutz/examples-lp.html
Date: May 3, 1999
-------------------------------------------
About this file
This tar file contains source code for all the examples
and exercise solutions in the book _Learning Python_.
We're providing it as an additional resource, to help
you save typing time as you work through the book.
Using this file
To use this file, simply download it to your machine, and
untar to create the directory structure and files. To untar
on UNIX and UNIX-like platforms, put the downloaded file in
a directory that is easy for you to access (e.g., in your
home directory), and execute a command like:
tar xvf lp-code.tar
On other machines, other tools may have the same effect
(e.g., the winzip program for MS-Windows knows how to untar
tar files too). Untarring the file will generate a new
subdirectory structure that looks like this:
lpython/ --top level directory
lpython/lp-code-readme.txt --this file
lpython/unix --version with UNIX-style newlines
lpython/unix/examples --code for examples in the chapters
lpython/unix/solutions --code for exercise solutions
lpython/dos --version with MS-DOS newlines
lpython/dos/examples --code for examples in the chapters
lpython/dos/solutions --code for exercise solutions
This structure appears in the directory where you ran the
untar operation, and of course you should think "\" instead
of "/" if you're on a DOS or Windows machine.
Once you've untarred the files, you wind up with a set of
text files on your machine, which you can view with your
favorite text editor. To run the code, simply cut-and-paste
the program text into other text files (aka modules), or
Python's interactive command line; see chapter 1 for details.
Why unix and dos directories?
The "unix" and "dos" directories contain identical data, but
files on the "unix" branch have UNIX-style end-of-line, and
"dos" branch files have the MS-DOS end-of-line. Either form
can sometimes look odd when edited on the other kind of platform,
so we provided both as a convenience. If you don't know what the
difference is, just use the version that looks best on your
platform and text editor.
What's in the text files?
Within the "examples" and "solutions" subdirectories, you'll
find one text file per chapter. For example:
lpython/unix/examples/chapter1.txt
lpython/unix/examples/chapter2.txt
lpython/unix/examples/chapter3.txt
and so on. In the "solutions" directory, the per-chapter text
files contain code snippets labeled with exercise numbers, and
correspond to the items in appendix C. In "examples", the code
snippets are labeled with the page number they appear on or near.
Some code listings are from interactive sessions; to run them
yourself, cut and paste all but the ">>>" or "..." prompts.
Other hints
All of the above will make more sense once you start poking
around the source files. And remember, be sure to see the
resources listed in the Preface of the book for updates and
book-related contact points.
lpython/unix/ 000777 000000 000000 00000000000 06713575640 007221 lpython/unix/lp-code-readme.txt 001777 000000 000000 00000006420 06713575570 012555 File: lp-code-readme.txt
Home: http://rmi.net/~lutz/examples-lp.html
Date: May 3, 1999
-------------------------------------------
About this file
This tar file contains source code for all the examples
and exercise solutions in the book _Learning Python_.
We're providing it as an additional resource, to help
you save typing time as you work through the book.
Using this file
To use this file, simply download it to your machine, and
untar to create the directory structure and files. To untar
on UNIX and UNIX-like platforms, put the downloaded file in
a directory that is easy for you to access (e.g., in your
home directory), and execute a command like:
tar xvf lp-code.tar
On other machines, other tools may have the same effect
(e.g., the winzip program for MS-Windows knows how to untar
tar files too). Untarring the file will generate a new
subdirectory structure that looks like this:
lpython/ --top level directory
lpython/lp-code-readme.txt --this file
lpython/unix --version with UNIX-style newlines
lpython/unix/examples --code for examples in the chapters
lpython/unix/solutions --code for exercise solutions
lpython/dos --version with MS-DOS newlines
lpython/dos/examples --code for examples in the chapters
lpython/dos/solutions --code for exercise solutions
This structure appears in the directory where you ran the
untar operation, and of course you should think "\" instead
of "/" if you're on a DOS or Windows machine.
Once you've untarred the files, you wind up with a set of
text files on your machine, which you can view with your
favorite text editor. To run the code, simply cut-and-paste
the program text into other text files (aka modules), or
Python's interactive command line; see chapter 1 for details.
Why unix and dos directories?
The "unix" and "dos" directories contain identical data, but
files on the "unix" branch have UNIX-style end-of-line, and
"dos" branch files have the MS-DOS end-of-line. Either form
can sometimes look odd when edited on the other kind of platform,
so we provided both as a convenience. If you don't know what the
difference is, just use the version that looks best on your
platform and text editor.
What's in the text files?
Within the "examples" and "solutions" subdirectories, you'll
find one text file per chapter. For example:
lpython/unix/examples/chapter1.txt
lpython/unix/examples/chapter2.txt
lpython/unix/examples/chapter3.txt
and so on. In the "solutions" directory, the per-chapter text
files contain code snippets labeled with exercise numbers, and
correspond to the items in appendix C. In "examples", the code
snippets are labeled with the page number they appear on or near.
Some code listings are from interactive sessions; to run them
yourself, cut and paste all but the ">>>" or "..." prompts.
Other hints
All of the above will make more sense once you start poking
around the source files. And remember, be sure to see the
resources listed in the Preface of the book for updates and
book-related contact points.
lpython/unix/tounix.py 001777 000000 000000 00000000364 06713575640 011135 import string, sys, os
# os.mkdir("converted")
for f in sys.argv[1:]:
print f
i = open(f, 'r')
t = i.read()
i.close()
s = string.join(string.split(t, "\015\012"), "\012")
o = open(f, 'w')
o.write(s)
o.close()
lpython/unix/examples/ 000777 000000 000000 00000000000 06713575264 011041 lpython/unix/examples/chapter3.txt 001777 000000 000000 00000014251 06713575256 013330 *** Page 73-74 ****************************************************************
>>> nudge = 1
>>> wink = 2
>>> A, B = nudge, wink # tuples
>>> A, B
(1, 2)
>>> [C, D] = [nudge, wink] # lists
>>> C, D
(1, 2)
>>> nudge, wink = wink, nudge # tuples: swaps values
>>> nudge, wink # same as T=nudge; nudge=wink; wink=T
(2, 1)
>>> x = 0 # x bound to an integer object
>>> x = "Hello" # now it's a string
>>> x = [1, 2, 3] # and now it's a list
*** Page 76-77 ****************************************************************
>>> print "a", "b"
a b
>>> print "a" + "b"
ab
>>> print "%s...%s" % ("a", "b")
a...b
>>> print 'hello world' # print a string object
hello world
>>> 'hello world' # interactive prints
'hello world'
>>> import sys # printing the hard way
>>> sys.stdout.write('hello world\n')
hello world
class FileFaker:
def write(self, string):
# do something with the string
import sys
sys.stdout = FileFaker()
print someObjects # sends to the write method of the class
python script.py < inputfile > outputfile
python script.py | filter
*** Page 78-79 ****************************************************************
>>> if 1:
... print 'true'
...
true
>>> if not 1:
... print 'true'
... else:
... print 'false'
...
false
>>> x = 'killer rabbit'
>>> if x == 'roger':
... print "how's jessica?"
... elif x == 'bugs':
... print "what's up doc?"
... else:
... print 'Run away! Run away!'
...
Run away! Run away!
>>> choice = 'ham'
>>> print {'spam': 1.25, # a dictionary-based 'switch'
... 'ham': 1.99, # use has_key() test for default case
... 'eggs': 0.99,
... 'bacon': 1.10}[choice]
1.99
>>> if choice == 'spam':
... print 1.25
... elif choice == 'ham':
... print 1.99
... elif choice == 'eggs':
... print 0.99
... elif choice == 'bacon':
... print 1.10
... else:
... print 'Bad choice'
...
1.99
*** Page 80-82 ****************************************************************
x = 1
if x:
y = 2
if y:
print 'block2'
print 'block1'
print 'block0'
L = ["Good",
"Bad",
"Ugly"] # open pairs may span lines
if a == b and c == d and \
d == e and f == g:
print 'olde' # backslashes allow continuations
if (a == b and c == d and
d == e and e == f):
print 'new ' # but parentheses usually do too
x = 1; y = 2; print x # more than 1 simple statement
if 1: print 'hello' # simple statement on header line
*** Page 83 *******************************************************************
>>> 2 < 3, 3 < 2 # less-than: return 1 or 0
(1, 0)
>>> 2 or 3, 3 or 2 # return left operand if true
(2, 3) # else return right operand (whether true or false)
>>> [] or 3
3
>>> [] or {}
{}
>>> 2 and 3, 3 and 2 # return left operand if false
(3, 2) # else return right operand (whether true or false)
>>> [] and {}
[]
>>> 3 and []
[]
*** Page 85 *******************************************************************
>>> while 1:
... print 'Type Ctrl-C to stop me!'
>>> x = 'spam'
>>> while x:
... print x,
... x = x[1:] # strip first character 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
*** Page 86-87 ****************************************************************
while 1: pass # type ctrl-C to stop me!
x = 10
while x:
x = x-1
if x % 2 != 0: continue # odd?--skip print
print x,
# y = some value
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'
*** Page 88-91 ****************************************************************
>>> for x in ["spam", "eggs", "ham"]:
... print x,
...
spam eggs ham
>>> sum = 0
>>> for x in [1, 2, 3, 4]:
... sum = sum + x
...
>>> sum
10
>>> prod = 1
>>> for item in [1, 2, 3, 4]: prod = prod * item
...
>>> prod
24
>>> S, T = "lumberjack", ("and", "I'm", "okay")
>>> for x in S: print x,
...
l u m b e r j a c k
>>> for x in T: print x,
...
and I'm okay
>>> T = [(1, 2), (3, 4), (5, 6)]
>>> for (a, b) in T: # tuple assignment at work
... print a, b
...
1 2
3 4
5 6
>>> items = ["aaa", 111, (4, 5), 2.01] # a set of objects
>>> tests = [(4, 5), 3.14] # keys to search for
>>>
>>> for key in tests: # for all keys
... for item in items: # for all items
... if item == key: # check for match
... print key, "was found"
... break
... else:
... print key, "not found!"
...
(4, 5) was found
3.14 not found!
>>> for key in tests: # for all keys
... if key in items: # let Python check for a match
... print key, "was found"
... else:
... print key, "not found!"
...
(4, 5) was found
3.14 not found!
>>> seq1 = "spam"
>>> seq2 = "scam"
>>>
>>> res = [] # start empty
>>> for x in seq1: # scan first sequence
... if x in seq2: # common item?
... res.append(x) # add to result end
...
>>> res
['s', 'a', 'm']
file = open("name", "r")
while 1:
line = file.readline() # fetch next line, if any
if not line: break # exit loop on end-of-file (empty string)
Process line here...
file = open("name", "r")
for line in file.readlines(): # read into a lines list
Process line here...
*** Page 91-92 ****************************************************************
>>> range(5), range(2, 5), range(0, 10, 2)
([0, 1, 2, 3, 4], [2, 3, 4], [0, 2, 4, 6, 8])
>>> X = 'spam'
>>> for item in X: print item, # simple iteration
...
s p a m
>>> i = 0
>>> while i < len(X): # while iteration
... print X[i],; i = i+1
...
s p a m
>>> for i in range(len(X)): print X[i], # manual indexing
...
s p a m
>>> for i in range(3): print i, 'Pythons'
...
0 Pythons
1 Pythons
2 Pythons
*** see solutions file for exercises' source code ***
lpython/unix/examples/chapter10.txt 001777 000000 000000 00000040572 06713574764 013416 ** Page 276 *******************************************************************
# file feedback.py (CGI)
import cgi, os, sys, string
def gush(data):
print "Content-type: text/html\n"
print "
Thanks, %(name)s!
" % vars(data)
print "Our customer's comments are always appreciated."
print "They drive our business directions, as well as"
print "help us with our karma."
print "
Thanks again for the feedback!
"
print "And feel free to enter more comments if you wish."
print "
" % vars(data)
print "We're very sorry to read that you had a complaint"
print "regarding our product__We'll read your comments"
print "carefully and will be in touch with you."
print "
Nevertheless, thanks for the feedback.
"
print "
"+10*" "+"--Joe."
def bail():
print "
Error filling out form
"
print "Please fill in all the fields in the form.
"
print ''
print 'Go back to the form'
sys.exit()
class FormData:
""" A repository for information gleaned from a CGI form """
def __init__(self, formdict):
for fieldname in self.fieldnames:
if not form.has_key(fieldname) or form[fieldname].value == "":
bail()
else:
setattr(self, fieldname, form[fieldname].value)
class FeedbackData(FormData):
""" A FormData generated by the comment.html form. """
fieldnames = ('name', 'address', 'email', 'type', 'text')
def __repr__(self):
return "%(type)s from %(name)s on %(time)s" % vars(self)
DIRECTORY = r'C:\complaintdir'
if __name__ == '__main__':
sys.stderr = sys.stdout
form = cgi.FieldStorage()
data = FeedbackData(form)
if data.type == 'comment':
gush(data)
else:
whimper(data)
# save the data to file
import tempfile, pickle, time
tempfile.tempdir = DIRECTORY
data.time = time.asctime(time.localtime(time.time()))
pickle.dump(data, open(tempfile.mktemp(), 'w'))
# html file excerpt
# similar code snippet
form = cgi.FieldStorage()
form_ok = 1
if not form.has_key("name") or form["name"].value == "":
form_ok = 0
else:
data_name = form["name"].value
if not form.has_key("email") or form["email"].value == "":
form_ok = 0
else:
data_email = form["email"].value
...
** Page 283 *******************************************************************
# file formletter.py (COM)
from win32com.client import constants, Dispatch
WORD = 'Word.Application.8'
False, True = 0, -1
import string
class Word:
def __init__(self):
self.app = Dispatch(WORD)
def open(self, doc):
self.app.Documents.Open(FileName=doc)
def replace(self, source, target):
self.app.Selection.HomeKey(Unit=constants.wdLine)
find = self.app.Selection.Find
find.Text = "%"+source+"%"
self.app.Selection.Find.Execute()
self.app.Selection.TypeText(Text=target)
def printdoc(self):
self.app.Application.PrintOut()
def close(self):
self.app.ActiveDocument.Close(SaveChanges=False)
def print_formletter(data):
word.open(r"h:\David\Book\tofutemplate.doc")
word.replace("name", data.name)
word.replace("address", data.address)
word.replace("firstname", string.split(data.name)[0])
word.printdoc()
word.close()
if __name__ == '__main__':
import os, pickle
from feedback import DIRECTORY, FormData, FeedbackData
word = Word()
for filename in os.listdir(DIRECTORY):
data = pickle.load(open(os.path.join(DIRECTORY, filename)))
if data.type == 'complaint':
print "Printing letter for %(name)s." % vars(data)
print_formletter(data)
else:
print "Got comment from %(name)s, skipping printing." % vars(data)
# program run
C:\Programs> python formletter.py
Printing letter for John Doe.
Got comment from Your Mom, skipping printing.
Printing letter for Susan B. Anthony.
** Page 288 *******************************************************************
# file feedbackeditor.py (Tkinter)
from FormEditor import FormEditor
from feedback import FeedbackData, FormData
from Tkinter import mainloop
FormEditor("Feedback Editor", FeedbackData, r"c:\Complaintdir")
mainloop()
# file FormEditor
from Tkinter import *
import string, os, pickle
class FormEditor:
def __init__(self, name, dataclass, storagedir):
self.storagedir = storagedir # stash away some references
self.dataclass = dataclass
self.row = 0
self.current = None
self.root = root = Tk() # create window and size it
root.minsize(300,200)
root.rowconfigure(0, weight=1) # define how columns and rows scale
root.columnconfigure(0, weight=1) # when the window is resized
root.columnconfigure(1, weight=2)
# create the title Label
Label(root, text=name, font='bold').grid(columnspan=2)
self.row = self.row + 1
# create the main listbox and configure it
self.listbox = Listbox(root, selectmode=SINGLE)
self.listbox.grid(columnspan=2,sticky=E+W+N+S)
self.listbox.bind('', self.select)
self.row = self.row + 1
# call self.add_variable once per variable in the class's fieldnames var
for fieldname in dataclass.fieldnames:
setattr(self, fieldname, self.add_variable(root, fieldname))
# create a couple of buttons, with assigned commands
self.add_button(self.root, self.row, 0, 'Delete Entry', self.delentry)
self.add_button(self.root, self.row, 1, 'Reload', self.load_data)
self.load_data()
def add_variable(self, root, varname):
Label(root, text=varname).grid(row=self.row, column=0, sticky=E)
value = Label(root, text='', background='gray90',
relief=SUNKEN, anchor=W, justify=LEFT)
value.grid(row=self.row, column=1, sticky=E+W)
self.row = self.row + 1
return value
def add_button(self, root, row, column, text, command):
button = Button(root, text=text, command=command)
button.grid(row=row, column=column, sticky=E+W, padx=5, pady=5)
def load_data(self):
self.listbox.delete(0,END)
self.items = []
for filename in os.listdir(self.storagedir):
item = pickle.load(open(os.path.join(self.storagedir, filename)))
item._filename = filename
self.items.append(item)
self.listbox.insert('end', `item`)
self.listbox.select_set(0)
self.select(None)
def select(self, event):
selection = self.listbox.curselection()
self.selection = self.items[int(selection[0])]
for fieldname in self.dataclass.fieldnames:
label = getattr(self, fieldname) # GUI field
labelstr = getattr(self.selection, fieldname) # instance attribute
labelstr = string.replace(labelstr,'\r'), '')
label.config(text=labelstr)
def delentry(self):
os.remove(os.path.join(self.storagedir,self.selection._filename))
self.load_data()
** Page 295 *******************************************************************
~/book> jpython
JPython 1.0.3 on java1.2beta4
Copyright 1997-1998 Corporation for National Research Initiatives
>>> 2 + 3
5
# file jpythondemo.py
from pawt import swing
import java
def exit(e): java.lang.System.exit(0)
frame = swing.JFrame('Swing Example', visible=1)
button = swing.JButton(This is a Swinging button!', actionPerformed=exit)
frame.contentPane.add(button)
frame.pack()
** Page 298 *******************************************************************
# file grapher.py (JPython)
# note: this requires a JPython that supports the
# struct module, which is used by the pickle module
from pawt import swing, awt, colors, GridBag
RIGHT = swing.JLabel.RIGHT
APPROVE_OPTION = swing.JFileChooser.APPROVE_OPTION
import java.io
import pickle, os
default_setup = """from math import *
def squarewave(x,order):
total = 0.0
for i in range(1, order*2+1, 2):
total = total + sin(x*i/10.0)/(float(i))
return total
"""
default_expression = "squarewave(x, order=3)"
class Chart(awt.Canvas):
color = colors.darkturquoise
style = 'Filled'
def getPreferredSize(self):
return awt.Dimension(600,300)
def paint(self, graphics):
clip = self.bounds
graphics.color = colors.white
graphics.fillRect(0, 0, clip.width, clip.height)
width = int(clip.width * .8)
height = int(clip.height * .8)
x_offset = int(clip.width * .1)
y_offset = clip.height - int(clip.height * .1)
N = len(self.data); xs = [0]*N; ys = [0]*N
xmin, xmax = 0, N-1
ymax = max(self.data)
ymin = min(self.data)
zero_y = y_offset - int(-ymin/(ymax-ymin)*height)
zero_x = x_offset + int(-xmin/(xmax-xmin)*width)
for i in range(N):
xs[i] = int(float(i)*width/N) + x_offset
ys[i] = y_offset - int((self.data[i]-ymin)/(ymax-ymin)*height)
graphics.color = self.color
if self.style == "Line":
graphics.drawPolyline(xs, ys, len(xs))
else:
xs.insert(0, xs[0]); ys.insert(0, zero_y)
xs.append(xs[-1]); ys.append(zero_y)
graphics.fillPolygon(xs, ys, len(xs))
# draw axes
graphics.color = colors.black
graphics.drawLine(x_offset,zero_y, x_offset+width, zero_y)
graphics.drawLine(zero_x, y_offset, zero_x, y_offset-height)
# draw labels
leading = graphics.font.size
graphics.drawString("%.3f" % xmin, x_offset, zero_y+leading)
graphics.drawString("%.3f" % xmax, x_offset+width, zero_y+leading)
graphics.drawString("%.3f" % ymin, zero_x-50, y_offset)
graphics.drawString("%.3f" % ymax, zero_x-50, y_offset-height+leading)
class GUI:
def __init__(self):
self.numelements = 100
self.frame = swing.JFrame(windowClosing=self.do_quit)
# build menu bar
menubar = swing.JMenuBar()
file = swing.JMenu("File")
file.add(swing.JMenuItem("Load", actionPerformed = self.do_load))
file.add(swing.JMenuItem("Save", actionPerformed = self.do_save))
file.add(swing.JMenuItem("Quit", actionPerformed = self.do_quit))
menubar.add(file)
self.frame.JMenuBar = menubar
# create widgets
self.chart = Chart(visible=1)
self.execentry = swing.JTextArea(default_setup, 8, 60)
self.evalentry = swing.JTextField(default_expression,
actionPerformed = self.update)
# create options panel
optionsPanel = swing.JPanel(awt.FlowLayout(
alignment=awt.FlowLayout.LEFT))
# whether the plot is a line graph or a filled graph
self.filled = swing.JRadioButton("Filled",
actionPerformed=self.set_filled)
optionsPanel.add(self.filled)
self.line = swing.JRadioButton("Line",
actionPerformed=self.set_line)
optionsPanel.add(self.line)
styleGroup = swing.ButtonGroup()
styleGroup.add(self.filled)
styleGroup.add(self.line)
# color selection
optionsPanel.add(swing.JLabel("Color:", RIGHT))
colors = filter(lambda x: x[0] != '_', dir(colors))
self.colorname = swing.JComboBox(colors)
self.colorname.itemStateChanged = self.set_color
optionsPanel.add(self.colorname)
# number of points
optionsPanel.add(swing.JLabel("Number of Points:", RIGHT))
self.sizes = [50, 100, 200, 500]
self.numpoints = swing.JComboBox(self.sizes)
self.numpoints.selectedIndex = self.sizes.index(self.numelements)
self.numpoints.itemStateChanged = self.set_numpoints
optionsPanel.add(self.numpoints)
# do the rest of the layout in a GridBag
self.do_layout(optionsPanel)
def do_layout(self, optionsPanel):
bag = GridBag(self.frame.contentPane, fill='BOTH',
weightx=1.0, weighty=1.0)
bag.add(swing.JLabel("Setup Code: ", RIGHT))
bag.addRow(swing.JScrollPane(self.execentry), weighty=10.0)
bag.add(swing.JLabel("Expression: ", RIGHT))
bag.addRow(self.evalentry, weighty=2.0)
bag.add(swing.JLabel("Output: ", RIGHT))
bag.addRow(self.chart, weighty=20.0)
bag.add(swing.JLabel("Options: ", RIGHT))
bag.addRow(optionsPanel, weighty=2.0)
self.update(None)
self.frame.visible = 1
self.frame.size = self.frame.getPreferredSize()
self.chooser = swing.JFileChooser()
self.chooser.currentDirectory = java.io.File(os.getcwd())
def do_save(self, event=None):
self.chooser.rescanCurrentDirectory()
returnVal = self.chooser.showSaveDialog(self.frame)
if returnVal == APPROVE_OPTION:
object = (self.execentry.text, self.evalentry.text,
self.chart.style,
self.chart.color.RGB,
self.colorname.selectedIndex,
self.numelements)
file = open(os.path.join(self.chooser.currentDirectory.path,
self.chooser.selectedFile.name), 'w')
pickle.dump(object, file)
file.close()
def do_load(self, event=None):
self.chooser.rescanCurrentDirectory()
returnVal = self.chooser.showOpenDialog(self.frame)
if returnVal == APPROVE_OPTION:
file = open(os.path.join(self.chooser.currentDirectory.path,
self.chooser.selectedFile.name))
(setup, each, style, color,
colorname, self.numelements) = pickle.load(file)
file.close()
self.chart.color = java.awt.Color(color)
self.colorname.selectedIndex = colorname
self.chart.style = style
self.execentry.text = setup
self.numpoints.selectedIndex = self.sizes.index(self.numelements)
self.evalentry.text = each
self.update(None)
def do_quit(self, event=None):
import sys
sys.exit(0)
def set_color(self, event):
self.chart.color = getattr(colors, event.item)
self.chart.repaint()
def set_numpoints(self, event):
self.numelements = event.item
self.update(None)
def set_filled(self, event):
self.chart.style = 'Filled'
self.chart.repaint()
def set_line(self, event):
self.chart.style = 'Line'
self.chart.repaint()
def update(self, event):
context = {}
exec self.execentry.text in context
each = compile(self.evalentry.text, '', 'eval')
numbers = [0]*self.numelements
for x in range(self.numelements):
context['x'] = float(x)
numbers[x] = eval(each, context)
self.chart.data = numbers
if self.chart.style == 'Line':
self.line.setSelected(1)
else:
self.filled.setSelected(1)
self.chart.repaint()
GUI()
** Page 303 *******************************************************************
from Numeric import *
coords = arange(-6, 6, .02) # create a range of coordinates
xs = sin(coords) # take the sine of all of the x's
ys = cos(coords)*exp(-coords*coords/18.0) # take a complex function of the y's
zx = xs * ys[:,NewAxis] # multiply the x row with the y column
lpython/unix/examples/chapter2.txt 001777 000000 000000 00000021512 06713575250 013317 *** Page 28 *******************************************************************
Numbers 3.1415, 1234, 999L, 3+4j
Strings 'spam', "guido's"
Lists [1, [2, 'three'], 4]
Dictionaries {'food':'spam', 'taste':'yum'}
Tuples (1,'spam', 4, 'U')
Files text = open('eggs', 'r').read()
1234, -24, 0 Normal integers (C longs)
999999999999L Long integers (unlimited size)
1.23, 3.14e-10, 4E210, 4.0e+210 Floating-point (C doubles)
0177, 0x9ff Octal and hex constants
3+4j, 3.0+4.0j, 3J Complex number constants
*** Page 32-35 ****************************************************************
% python
>>> a = 3 # name created
>>> b = 4
>>> b / 2 + a # same as ((4 / 2) + 3)
5
>>> b / (2.0 + a) # same as (4 / (2.0 + 3))
0.8
>>> x = 1 # 0001
>>> x << 2 # shift left 2 bits: 0100
4
>>> x | 2 # bitwise OR: 0011
3
>>> x & 1 # bitwise AND: 0001
1
>>> 9999999999999999999999999999 + 1
OverflowError: integer literal too large
>>> 9999999999999999999999999999L + 1
10000000000000000000000000000L
>>> 1j * 1J
(-1+0j)
>>> 2 + 1j * 3
(2+3j)
>>> (2+1j)*3
(6+3j)
>>> import math
>>> math.pi
3.14159265359
>>>
>>> abs(-42), 2**4, pow(2, 4)
(42, 16, 16)
*** Page 37-38 ****************************************************************
% python
>>> len('abc') # length: number items
3
>>> 'abc' + 'def' # concatenation: a new string
'abcdef'
>>> 'Ni!' * 4 # like "Ni!" + "Ni!" + ...
'Ni!Ni!Ni!Ni!'
>>> myjob = "hacker"
>>> for c in myjob: print c, # step though items
...
h a c k e r
>>> "k" in myjob # 1 means true
1
>>> S = 'spam'
>>> S[0], S[-2] # indexing from front or end
('s', 'a')
>>> S[1:3], S[1:], S[:-1] # slicing: extract section
('pa', 'pam', 'spa')
*** Page 39 *******************************************************************
% cat echo.py
import sys
print sys.argv
% python echo.py -a -b -c
['echo.py', '-a', '-b', '-c']
*** Page 40 *******************************************************************
>>> S = 'spam'
>>> S[0] = "x"
Raises an error!
>>> S = S + 'Spam!' # to change a string, make a new one
>>> S
'spamSpam!'
>>> S = S[:4] + 'Burger' + S[-1]
>>> S
'spamBurger!'
>>> 'That is %d %s bird!' % (1, 'dead') # like C sprintf
That is 1 dead bird!
>>> exclamation = "Ni"
>>> "The knights who say %s!" % exclamation
'The knights who say Ni!'
>>> "%d %s %d you" % (1, 'spam', 4)
'1 spam 4 you'
>>> "%s -- %s -- %s" % (42, 3.14159, [1, 2, 3])
'42 -- 3.14159 -- [1, 2, 3]'
>>> "%e %f %g" % (1.1, 2.2, 3.3)
*** Page 41-43 ****************************************************************
>>> import string # standard utilities module
>>> S = "spammify"
>>> string.upper(S) # convert to uppercase
'SPAMMIFY'
>>> string.find(S, "mm") # return index of substring
3
>>> string.atoi("42"), `42` # convert from/to string
(42, '42')
>>> string.join(string.split(S, "mm"), "XX")
'spaXXify'
>>> "spam" + 42
Raises an error
>>> "spam" + `42`
'spam42'
>>> string.atoi("42") + 1
43
>>> mixed = "Guido's" # single in double
>>> mixed
"Guido's"
>>> mixed = 'Guido"s' # double in single
>>> mixed
'Guido"s'
>>> mixed = 'Guido\'s' # backslash escape
>>> mixed
"Guido's"
>>> split = "This" "is" "concatenated"
>>> split
'Thisisconcatenated'
>>> big = """This is
... a multi-line block
... of text; Python puts
... an end-of-line marker
... after each line."""
>>>
>>> big
'This is\012a multi-line block\012of text; Python puts\012an end-of-line
marker\012after each line.'
*** Page 46-49 ****************************************************************
% python
>>> len([1, 2, 3]) # length
3
>>> [1, 2, 3] + [4, 5, 6] # concatenation
[1, 2, 3, 4, 5, 6]
>>> ['Ni!'] * 4 # repetition
['Ni!', 'Ni!', 'Ni!', 'Ni!']
>>> for x in [1, 2, 3]: print x, # iteration
...
1 2 3
>>> `[1, 2]` + "34" # same as "[1, 2]" + "34"
'[1, 2]34'
>>> [1, 2] + list("34") # same as [1, 2] + ["3", "4"]
[1, 2, '3', '4']
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[2] # offsets start at zero
'SPAM!'
>>> L[-2] # negative: count from the right
'Spam'
>>> L[1:] # slicing fetches sections
['Spam', 'SPAM!']
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[1] = 'eggs' # index assignment
>>> L
['spam', 'eggs', 'SPAM!']
>>> L[0:2] = ['eat', 'more'] # slice assignment: delete+insert
>>> L # replaces items 0,1
['eat', 'more', 'SPAM!']
>>> L.append('please') # append method call
>>> L
['eat', 'more', 'SPAM!', 'please']
>>> L.sort() # sort list items ('S' < 'e')
>>> L
['SPAM!', 'eat', 'more', 'please']
>>> L
['SPAM!', 'eat', 'more', 'please']
>>> del L[0] # delete one item
>>> L
['eat', 'more', 'please']
>>> del L[1:] # delete an entire section
>>> L # same as L[1:] = []
['eat']
*** Page 51-52 ****************************************************************
% python
>>> d2 = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> d2['spam'] # fetch value for key
2
>>> len(d2) # number of entries in dictionary
3
>>> d2.has_key('ham') # key membership test (1 means true)
1
>>> d2.keys() # list of my keys
['eggs', 'spam', 'ham']
>>> d2['ham'] = ['grill', 'bake', 'fry'] # change entry
>>> d2
{'eggs': 3, 'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> del d2['eggs'] # delete entry
>>> d2
{'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> d2['brunch'] = 'Bacon' # add new entry
>>> d2
{'brunch': 'Bacon', 'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> table = {'Python': 'Guido van Rossum',
... 'Perl': 'Larry Wall',
... 'Tcl': 'John Ousterhout' }
...
>>> language = 'Python'
>>> creator = table[language]
>>> creator
'Guido van Rossum'
>>> for lang in table.keys(): print lang, '\t', table[lang]
...
Tcl John Ousterhout
Python Guido van Rossum
Perl Larry Wall
*** Page 54 *******************************************************************
import anydbm
file = anydbm.open("filename") # link to external file
file['key'] = 'data' # store data by key
data = file['key'] # fetch data by key
import cgi
form = cgi.FieldStorage() # parse form data (stdin, environ)
if form.has_key('name'):
showReply('Hello, ' + form['name'].value)
*** Page 57 *******************************************************************
>>> myfile = open('myfile', 'w') # open for output (creates)
>>> myfile.write('hello text file\n') # write a line of text
>>> myfile.close()
>>> myfile = open('myfile', 'r') # open for input
>>> myfile.readline() # read the line back
'hello text file\012'
>>> myfile.readline() # empty string: end of file
''
*** Page 59-61 ****************************************************************
class MySequence:
def __getitem__(self, index):
# called on self[index], for x in self, x in self
def __getslice__(self, low, high):
# called on self[low:high]
def __add__(self, other):
# called on self + other
>>> L = ['abc', [(1, 2), ([3], 4)], 5]
>>> L[1]
[(1, 2), ([3], 4)]
>>> L[1][1]
([3], 4)
>>> L[1][1][0]
[3]
>>> L[1][1][0][0]
3
>>> X = [1, 2, 3]
>>> L = ['a', X, 'b']
>>> D = {'x':X, 'y':2}
>>> X[1] = 'surprise' # changes all three references!
>>> L
['a', [1, 'surprise', 3], 'b']
>>> D
{'x': [1, 'surprise', 3], 'y': 2}
>>> L1 = [1, ('a', 3)] # same value, unique objects
>>> L2 = [1, ('a', 3)]
>>> L1 == L2, L1 is L2 # equivalent?, same object?
(1, 0)
>>> L1 = [1, ('a', 3)]
>>> L2 = [1, ('a', 2)]
>>> L1 < L2, L1 == L2, L1 > L2 # less, equal, greater: a tuple of results
(0, 0, 1)
*** Page 64-65 ****************************************************************
>>> L = [1, 2, 3]
>>> M = ['X', L, 'Y'] # embed a reference to L
>>> M
['X', [1, 2, 3], 'Y']
>>> L[1] = 0 # changes M too
>>> M
['X', [1, 0, 3], 'Y']
>>> L = [1, 2, 3]
>>> M = ['X', L[:], 'Y'] # embed a copy of L
>>> L[1] = 0 # only changes L, not M
>>> L
[1, 0, 3]
>>> M
['X', [1, 2, 3], 'Y']
>>> L = [4, 5, 6]
>>> X = L * 4 # like [4, 5, 6] + [4, 5, 6] + ...
>>> Y = [L] * 4 # [L] + [L] + ... = [L, L,...]
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> Y
[[4, 5, 6], [4, 5, 6], [4, 5, 6], [4, 5, 6]]
>>> L[1] = 0 # impacts Y but not X
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> Y
[[4, 0, 6], [4, 0, 6], [4, 0, 6], [4, 0, 6]]
>>> L = ['hi.']; L.append(L) # append reference to same object
>>> L # before 1.5.1: a loop! (cntl-C breaks)
T = (1, 2, 3)
T[2] = 4 # error!
T = T[:2] + (4,) # okay: (1, 2, 4)
***see solutions file file exercise source code***
lpython/unix/examples/chapter1.txt 001777 000000 000000 00000005736 06713575230 013326 *** Page 12 *******************************************************************
% python
>>> print 'Hello world!'
Hello world!
>>> lumberjack = "okay"
>>> # Ctrl D to exit (Ctrl Z on some platforms)
*** Page 13 *******************************************************************
[file spam.py]
import sys
print sys.argv # more on this later
% python spam.py -i eggs -o bacon
['spam.py', '-i', 'eggs', '-o', 'bacon']
*** Page 14 *******************************************************************
[file brian]
#!/usr/local/bin/python
print 'The Bright Side of Life...' # another comment here
% chmod +x brian
% brian
The Bright Side of Life...
C:\book\tests> python brian
The Bright Side of Life...
*** Page 17 *******************************************************************
[file myfile.py]
title = "The Meaning of Life"
% python
>>> import myfile # Run file, load module as a whole
>>> print myfile.title # Use its names: '.' qualification
The Meaning of Life
% python
>>> from myfile import title # Run file, load its names
>>> print title # Use name directly: no need to qualify
The Meaning of Life
% python
>>> import myfile # Run/load module
>>> print myfile.title # Qualify to fetch name
The Meaning of Life
... Change myfile.py in your text editor
>>> import myfile # Will NOT rerun the file’s code
>>> reload(myfile) # WILL rerun the file’s (current) code
*** Page 19 *******************************************************************
>>> x = 1
>>> y = "shrubbery"
>>> dir()
['__builtins__', '__doc__', '__name__', 'x', 'y']
[file threenames.py]
a = 'dead'
b = 'parrot'
c = 'sketch'
% cat threenames.py
a = 'dead'
b = 'parrot'
c = 'sketch'
% python
>>> import threenames
>>> dir(threenames)
['__builtins__', '__doc__', '__file__', '__name__', 'a', 'b', 'c']
>>> dir(__builtins__)
All the names Python predefines for you
*** Page 21 *******************************************************************
[file runpy]
#!/bin/csh
# Give this file executable privileges (chmod +x runpy).
# Put this info in your .cshrc file to make it permanent.
# 1) Add path to command-line interpreter
set path = (/usr/local/bin $path)
# 2) Set python library search paths (unless predefined)
# add your module file directories to the list as desired
setenv PYTHONPATH \
.:/usr/local/lib/python:/usr/local/lib/python/tkinter
# 3) Set tk library search paths for GUIs (unless predefined)
setenv TCL_LIBRARY /usr/local/lib/tcl8.0
setenv TK_LIBRARY /usr/local/lib/tk8.0
# 4) Start up the interactive command-line
python
[file runpy.bat]
PATH c:\python;%PATH%
set PYTHONPATH=.;c:\python\lib;c:\python\lib\tkinter
set TCL_LIBRARY=c:\Program Files\Tcl\lib\tcl8.0
set TK_LIBRARY=c:\Program Files\Tcl\lib\tk8.0
python
% runpy
version/copyright information...
>>> from Tkinter import *
>>> w = Button(text="Hello", command='exit')
>>> w.pack()
>>> w.mainloop()
***see solutions directory for exercises code***
lpython/unix/examples/chapter4.txt 001777 000000 000000 00000021102 06713575264 013321 ** Page 99-100 ****************************************************************
>>> def times(x, y): # create and assign function
... return x * y # body executed when called
...
>>> times(2, 4) # arguments in parentheses
8
>>> times('Ni', 4) # functions are 'typeless'
'NiNiNiNi'
** Page 101 *******************************************************************
# put this in an imported module file
# it could be typed interactively too
def intersect(seq1, seq2):
res = [] # start empty
for x in seq1: # scan seq1
if x in seq2: # common item?
res.append(x) # add to end
return res
>>> s1 = "SPAM"
>>> s2 = "SCAM"
>>> intersect(s1, s2) # strings
['S', 'A', 'M']
>>> intersect([1, 2, 3], (1, 4)) # mixed types
[1]
** Page 103 *******************************************************************
# global scope
X = 99 # X and func assigned in module: global
def func(Y): # Y and Z assigned in function: locals
# local scope
Z = X + Y # X is not assigned, so it's a global
return Z
func(1) # func in module: result=100
** Page 104 *******************************************************************
y, z = 1, 2 # global variables in module
def all_global():
global x # declare globals assigned
x = y + z # no need to declare y,z: 3-scope rule
** Page 105 *******************************************************************
>>> def changer(x, y):
... x = 2 # changes local name's value only
... y[0] = 'spam' # changes shared object in place
...
>>> X = 1
>>> L = [1, 2]
>>> changer(X, L) # pass immutable and mutable (use L[:] to avoid changes)
>>> X, L # X unchanged, L is different
(1, ['spam', 2])
** Page 107 *******************************************************************
>>> def multiple(x, y):
... x = 2 # changes local names only
... y = [3, 4]
... return x, y # return new values in a tuple
...
>>> X = 1
>>> L = [1, 2]
>>> X, L = multiple(X, L) # assign results to caller's names
>>> X, L
(2, [3, 4])
** Page 108-110 ***************************************************************
def func(spam, eggs, toast=0, ham=0): # first 2 required
print (spam, eggs, toast, ham)
func(1, 2) # output: (1, 2, 0, 0)
func(1, ham=1, eggs=0) # output: (1, 0, 0, 1)
func(spam=1, eggs=0) # output: (1, 0, 0, 0)
func(toast=1, eggs=2, spam=3) # output: (3, 2, 1, 0)
func(1, 2, 3, 4) # output: (1, 2, 3, 4)
# put this code in a new module file called
# "inter2.py", in a directory on PYTHONPATH
def intersect(*args):
res = []
for x in args[0]: # scan first sequence
for other in args[1:]: # for all other args
if x not in other: break # item in each one?
else: # no: break out of loop
res.append(x) # yes: add items to end
return res
def union(*args):
res = []
for seq in args: # for all args
for x in seq: # for all nodes
if not x in res:
res.append(x) # add new items to result
return res
% python
>>> from inter2 import intersect, union
>>> s1, s2, s3 = "SPAM", "SCAM", "SLAM"
>>> intersect(s1, s2), union(s1, s2) # 2 operands
(['S', 'A', 'M'], ['S', 'P', 'A', 'M', 'C'])
>>> intersect([1,2,3], (1,4)) # mixed types
[1]
>>> intersect(s1, s2, s3) # 3 operands
['S', 'A', 'M']
>>> union(s1, s2, s3)
['S', 'P', 'A', 'M', 'C', 'L']
** Page 112-115 ***************************************************************
>>> def func(x, y, z): return x + y + z
...
>>> func(2, 3, 4)
9
>>> f = lambda x, y, z: x + y + z
>>> f(2, 3, 4)
9
>>> x = (lambda a="fee", b="fie", c="foe": a + b + c)
>>> x("wee")
'weefiefoe'
>>> apply(func, (2, 3, 4))
9
>>> apply(f, (2, 3, 4))
9
L = [lambda x: x**2, lambda x: x**3, lambda x: x**4]
for f in L:
print f(2) # prints 4, 8, 16
print L[0](3) # prints 9
>>> counters = [1, 2, 3, 4]
>>>
>>> updated = []
>>> for x in counters:
... updated.append(x + 10) # add 10 to each item
...
>>> updated
[11, 12, 13, 14]
>>> def inc(x): return x + 10 # function to be run
...
>>> map(inc, counters) # collect results
[11, 12, 13, 14]
>>> map((lambda x: x + 3), counters) # function expression
[4, 5, 6, 7]
>>> def proc(x):
... print x # no return is a None return
...
>>> x = proc('testing 123...')
testing 123...
>>> print x
None
>>> list = [1, 2, 3]
>>> list = list.append(4) # append is a 'procedure'
>>> print list # append changes list in-place
None
** Page 116 *******************************************************************
>>> def echo(message): # echo assigned to a function object
... print message
...
>>> x = echo # now x references it too
>>> x('Hello world!') # call the object by adding ()
Hello world!
>>> def indirect(func, arg):
... func(arg) # call object by adding ()
...
>>> indirect(echo, 'Hello jello!') # pass function to a function
Hello jello!
>>> schedule = [ (echo, 'Spam!'), (echo, 'Ham!') ]
>>> for (func, arg) in schedule:
... apply(func, (arg,))
...
Spam!
Ham!
** Page 117-118 ***************************************************************
>>> X = 99
>>> def selector(): # X used but not assigned
... print X # X found in global scope
...
>>> selector()
99
>>> def selector():
... print X # does not yet exist!
... X = 88 # X classified as a local name (everywhere)
... # can also happen if "import X", "def X",...
>>> selector()
>>> def selector():
... global X # force X to be global (everywhere)
... print X
... X = 88
...
>>> selector()
99
>>> X = 99
>>> def selector():
... import __main__ # import enclosing module
... print __main__.X # qualify to get to global version of name
... X = 88 # unqualified X classified as local
... print X # prints local version of name
...
>>> selector()
99
88
** Page 119 *******************************************************************
>>> def outer(x):
... def inner(i): # assign in outer's local
... print i, # i is in inner's local
... if i: inner(i-1) # not in my local or global!
... inner(x)
...
>>> outer(3)
3
Traceback (innermost last):
>>> def outer(x):
... global inner
... def inner(i): # assign in enclosing module
... print i,
... if i: inner(i-1) # found in my global scope now
... inner(x)
...
>>> outer(3)
3 2 1 0
** Page 120-121 **************************************************************
>>> def outer(x, y):
... def inner(a=x, b=y): # save outer's x,y bindings/objects
... return a**b # can't use x and y directly here
... return inner
...
>>> x = outer(2, 4)
>>> x()
16
>>> def outer(x, y):
... return lambda a=x, b=y: a**b
...
>>> y = outer(2, 5)
>>> y()
32
>>> def outer(x):
... def inner(i, self=inner): # name not defined yet
... print i,
... if i: self(i-1)
... inner(x)
...
>>> outer(3)
Traceback (innermost last):
>>> def outer(x):
... fillin = [None]
... def inner(i, self=fillin): # save mutable
... print i,
... if i: self[0](i-1) # assume it's set
... fillin[0] = inner # plug value now
... inner(x)
...
>>> outer(3)
3 2 1 0
>>> def inner(i): # define module level name
... print i,
... if i: inner(i-1) # no worries: it's a global
...
>>> def outer(x):
... inner(x)
...
>>> outer(3)
3 2 1 0
** Page 122 *******************************************************************
>>> def saver(x=[]): # saves away a list object
... x.append(1) # changes same object each time!
... print x
...
>>> saver([2]) # default not used
[2, 1]
>>> saver() # default used
[1]
>>> saver() # grows on each call
[1, 1]
>>> saver()
[1, 1, 1]
>>> def saver(x=None):
... if x is None: # no argument passed?
... x = [] # run code to make a new list
... x.append(1) # changes new list object
... print x
...
>>> saver([2])
[2, 1]
>>> saver() # doesn't grow here
[1]
>>> saver()
[1]
*** see solutions file for this chapter for exercise code ***
lpython/unix/examples/chapter5.txt 001777 000000 000000 00000016102 06713574764 013332 ** Page 128 *******************************************************************
# put this code in a file called "module1.py",
# located in a directory on PYTHONPATH (or ".")
def printer(x): # module attribute
print x
# then, import it in the interactive prompt
% python
>>> import module1 # get module
>>> module1.printer('Hello world!') # qualify to get names (module.name)
Hello world!
>>> from module1 import printer # get an export
>>> printer('Hello world!') # no need to qualify name
Hello world!
>>> from module1 import * # get all exports
>>> printer('Hello world!')
Hello world!
** Page 130 *******************************************************************
# put this code in a file called "module2.py"
print 'starting to load...'
import sys
name = 42
def func(): pass
class klass: pass
print 'done loading.'
# now, use in interactively
>>> import module2
starting to load...
done loading.
>>> module2.sys
>>> module2.name
42
>>> module2.func, module2.klass
(, )
>>> module2.__dict__.keys()
['__file__', 'name', '__name__', 'sys', '__doc__', '__builtins__', 'klass',
'func']
** Page 132 ******************************************************************
% cat simple.py
print 'hello'
spam = 1 # initialize variable
% python
>>> import simple # first import: loads and runs file's code
hello
>>> simple.spam # assignment makes an attribute
1
>>> simple.spam = 2 # change attribute in module
>>>
>>> import simple # just fetches already-loaded module
>>> simple.spam # code wasn't rerun: attribute unchanged
2
** Page 133 *******************************************************************
% cat small.py
x = 1
y = [1, 2]
% python
>>> from small import x, y # copy two names out
>>> x = 42 # changes local x only
>>> y[0] = 42 # changes shared mutable in-place
>>>
>>> import small # get module name (from doesn't)
>>> small.x # small's x is not my x
1
>>> small.y # but we share a changed mutable
[42, 2]
# emulating "from"
import module # fetch the module object
name1 = module.name1 # copy names out by assignment
name2 = module.name2
...
del module # get rid of the module name
** Page 135 *******************************************************************
% cat changer.py
message = "First version"
def printer():
print message
% python
>>> import changer
>>> changer.printer()
First version
>>>
# change "changer.py" now...
% vi changer.py
% cat changer.py
message = "After editing"
def printer():
print 'reloaded:', message
# back to the interpreter...
>>> import changer
>>> changer.printer() # no effect: uses loaded module
First version
>>> reload(changer) # forces new code to load/run
>>> changer.printer() # runs the new version now
reloaded: After editing
** Page 138 *******************************************************************
# put this in a file called runme.py
def tester():
print "It's Christmas in Heaven..."
if __name__ == '__main__': # only when run
tester() # not when imported
% python
>>> import runme
>>> runme.tester()
It's Christmas in Heaven...
% python runme.py
It's Christmas in Heaven...
>>> import sys
>>> sys.path
['.', 'c:\\python\\lib', 'c:\\python\\lib\\tkinter']
>>> sys.path = ['.'] # change module search path
>>> sys.path.append('c:\\book\\examples') # escape backlashes as "\\"
>>> sys.path # or use r'...' strings
['.', 'c:\\book\\examples']
>>> import string
Traceback (innermost last):
** Page 142 *******************************************************************
# mydir.py: a module which lists the namespaces of other modules
verbose = 1
def listing(module):
if verbose:
print "-"*30
print "name:", module.___name__, "file:", module.__file__
print "-"*30
count = 0
for attr in module.__dict__.keys(): # scan namespace
print "%02d) %s" % (count, attr),
if attr[0:2] == "__":
print "" # skip __file__, etc.
else:
print getattr(module, attr) # same as .__dict__[attr]
count = count+1
if verbose:
print "-"*30
print module.__name__, "has %d names" % count
print "-"*30
if __name__ == "__main__":
import mydir
listing(mydir) # self-test code: list myself
C:\python> python mydir.py
------------------------------
name: mydir file: mydir.py
------------------------------
00) __file__
01) __name__
02) listing
03) __doc__
04) __builtins__
05) verbose 1
------------------------------
mydir has 6 names
------------------------------
** Page 143 *******************************************************************
>>> modname = "string"
>>> exec "import " + modname # run a string of code
>>> string # imported in this namespace
>>> modname = "string"
>>> string = __import__(modname)
>>> string
** Page 144 *******************************************************************
# module nested1.py
X = 99
def printer(): print X
# module nested2.py
from nested1 import X, printer # copy names out
X = 88 # changes my "X" only!
printer() # nested1's X is still 99
% python nested2.py
99
# module nested3.py
import nested1 # get module as a whole
nested1.X = 88 # okay: change nested1's X
nested1.printer()
% python nested3.py
88
** Page 145 *******************************************************************
func1() # error: "func1" not yet assigned
def func1():
print func2() # okay: "func2" looked up later
func1() # error: "func2" not yet assigned
def func2():
return "Hello"
func1() # okay: "func1" and "func2" assigned
** Page 146 *******************************************************************
# recur1.py
X = 1
import recur2 # run recur2 now if doesn't exist
Y = 2
# recur2.py
from recur1 import X # okay: "X" already assigned
from recur1 import Y # error: "Y" not yet assigned
>>> import recur1
Traceback (innermost last):
** Page 147 *******************************************************************
from module import X # X may not reflect any module reloads!
...
reload(module) # changes module, not my names
X # still references old object
# versus
import module # get module, not names
...
reload(module) # changes module in-place
module.X # get current X: reflects module reloads
% cat A.py
import B # not reloaded when A is
import C # just an import of an already-loaded module
% python
>>> . . .
>>> reload(A)
lpython/unix/examples/chapter6.txt 001777 000000 000000 00000047360 06713574764 013345 ** Page 153-154 ***************************************************************
>>> class FirstClass: # define a class object
... def setdata(self, value): # define class methods
... self.data = value # self is the instance
... def display(self):
... print self.data # self.data: per instance
>>> x = FirstClass() # make two instances
>>> y = FirstClass() # each is a new namespace
>>> x.setdata("King Arthur") # call methods: self is x or y
>>> y.setdata(3.14159) # runs: FirstClass.setdata(y, 3.14159)
>>> x.display() # self.data differs in each
King Arthur
>>> y.display()
3.14159
>>> x.data = "New value" # can get/set attributes
>>> x.display() # outside the class too
New value
** Page 155-156 ***************************************************************
>>> class SecondClass(FirstClass): # inherits setdata
... def display(self): # changes display
... print 'Current value = "%s"' % self.data
>>> z = SecondClass()
>>> z.setdata(42) # setdata found in FirstClass
>>> z.display() # finds overridden method in SecondClass
Current value = "42"
>>> x.display() # x is still a FirstClass instance (old message)
New value
** Page 157 *******************************************************************
>>> class ThirdClass(SecondClass): # is-a SecondClass
... def __init__(self, value): # on "ThirdClass(value)"
... self.data = value
... def __add__(self, other): # on "self + other"
... return ThirdClass(self.data + other)
... def __mul__(self, other):
... self.data = self.data * other # on "self * other"
>>> a = ThirdClass("abc") # new __init__ called
>>> a.display() # inherited method
Current value = "abc"
>>> b = a + 'xyz' # new __add__ called: makes a new instance
>>> b.display()
Current value = "abcxyz"
>>> a * 3 # new __mul__ called: changes instance in-place
>>> a.display()
Current value = "abcabcabc"
** Page 159 *******************************************************************
# type these interactively, or import from a module file
class aSuperclass: pass
class Subclass(aSuperclass): # define subclass
data = 'spam' # assign class attr
def __init__(self, value): # assign class attr
self.data = value # assign instance attr
def display(self):
print self.data, Subclass.data # instance, class
>>> x = Subclass(1) # make two instance objects
>>> y = Subclass(2) # each has its own "data"
>>> x.display(); y.display() # "self.data" differs, "Subclass.data" same
1 spam
2 spam
** Page 160 *******************************************************************
class NextClass: # define class
def printer(self, text): # define method
print text
>>> x = NextClass() # make instance
>>> x.printer('Hello world!') # call its method
Hello world!
>>> NextClass.printer(x, 'Hello world!') # class method
Hello world!
** Page 162 *******************************************************************
>>> class Super:
... def method(self):
... print 'in Super.method'
...
>>> class Sub(Super):
... def method(self): # override method
... print 'starting Sub.method' # add actions here
... Super.method(self) # run default action
... print 'ending Sub.method'
...
>>> x = Super() # make a Super instance
>>> x.method() # runs Super.method
in Super.method
>>> x = Sub() # make a Sub instance
>>> x.method() # runs Sub.method, which calls Super.method
starting Sub.method
in Super.method
ending Sub.method
** Page 163 *******************************************************************
# file specialize.py
class Super:
def method(self):
print 'in Super.method' # default
def delegate(self):
self.action() # expected
class Inheritor(Super):
pass
class Replacer(Super):
def method(self):
print 'in Replacer.method'
class Extender(Super):
def method(self):
print 'starting Extender.method'
Super.method(self)
print 'ending Extender.method'
class Provider(Super):
def action(self):
print 'in Provider.action'
if __name__ == '__main__':
for klass in (Inheritor, Replacer, Extender):
print '\n' + klass.__name__ + '...'
klass().method()
print '\nProvider...'
Provider().delegate()
% python specialize.py
Inheritor...
in Super.method
Replacer...
in Replacer.method
Extender...
starting Extender.method
in Super.method
ending Extender.method
Provider...
in Provider.action
** Page 165-168 ***************************************************************
# number.py
class Number:
def __init__(self, start): # on Number(start)
self.data = start
def __sub__(self, other): # on instance - other
return Number(self.data - other) # result is a new instance
>>> from number import Number # fetch class from module
>>> X = Number(5) # calls Number.__init__(X, 5)
>>> Y = X - 2 # calls Number.__sub__(X, 2)
>>> Y.data
3
>>> class indexer:
... def __getitem__(self, index):
... return index ** 2
...
>>> X = indexer()
>>> for i in range(5):
... print X[i], # X[i] calls __getitem__(X, i)
...
0 1 4 9 16
>>> class stepper:
... def __getitem__(self, i):
... return self.data[i]
...
>>> X = stepper() # X is a stepper object
>>> X.data = "Spam"
>>>
>>> for item in X: # for loops call __getitem__
... print item, # for indexes items 0..N
...
S p a m
>>>
>>> 'p' in X # 'in' operator calls __getitem__ too
1
>>> class empty:
... def __getattr__(self, attrname):
... if attrname == "age":
... return 37
... else:
... raise AttributeError, attrname
...
>>> X = empty()
>>> X.age
37
>>> X.name
Traceback (innermost last):
File "", line 1, in ?
File "", line 6, in __getattr__
AttributeError: name
>>> class adder:
... def __init__(self, value=0):
... self.data = value # initialize data
... def __add__(self, other):
... self.data = self.data + other # add other in-place
... def __repr__(self):
... return `self.data` # convert to string
...
>>> X = adder(1) # __init__
>>> X + 2; X + 2 # __add__
>>> X # __repr__
5
** Page 169 *******************************************************************
>>> class super:
... def hello(self):
... self.data1 = "spam"
...
>>> class sub(super):
... def howdy(self):
... self.data2 = "eggs"
...
>>> X = sub() # make a new namespace (dictionary)
>>> X.__dict__
{}
>>> X.hello() # changes instance namespace
>>> X.__dict__
{'data1': 'spam'}
>>> X.howdy() # changes instance namespace
>>> X.__dict__
{'data2': 'eggs', 'data1': 'spam'}
>>> super.__dict__
{'hello': , '__doc__': None}
>>> sub.__dict__
{'__doc__': None, 'howdy': }
>>> X.data3 = "toast"
>>> X.__dict__
{'data3': 'toast', 'data2': 'eggs', 'data1': 'spam'}
** Page 171 *******************************************************************
# file employees.py
class Employee:
def __init__(self, name, salary=0):
self.name = name
self.salary = salary
def giveRaise(self, percent):
self.salary = self.salary + (self.salary * percent)
def work(self):
print self.name, "does stuff"
def __repr__(self):
return "" % (self.name, self.salary)
class Chef(Employee):
def __init__(self, name):
Employee.__init__(self, name, 50000)
def work(self):
print self.name, "makes food"
class Server(Employee):
def __init__(self, name):
Employee.__init__(self, name, 40000)
def work(self):
print self.name, "interfaces with customer"
class PizzaRobot(Chef):
def __init__(self, name):
Chef.__init__(self, name)
def work(self):
print self.name, "makes pizza"
if __name__ == "__main__":
bob = PizzaRobot('bob') # make a robot named bob
print bob # runs inherited __repr__
bob.giveRaise(0.20) # give bob a 20% raise
print bob; print
for klass in Employee, Chef, Server, PizzaRobot:
obj = klass(klass.__name__)
obj.work()
C:\python\examples> python employees.py
Employee does stuff
Chef makes food
Server interfaces with customer
PizzaRobot makes pizza
** Page 173 *******************************************************************
# file pizzashop.py
from employees import PizzaRobot, Server
class Customer:
def __init__(self, name):
self.name = name
def order(self, server):
print self.name, "orders from", server
def pay(self, server):
print self.name, "pays for item to", server
class Oven:
def bake(self):
print "oven bakes"
class PizzaShop:
def __init__(self):
self.server = Server('Pat') # embed other objects
self.chef = PizzaRobot('Bob') # a robot named bob
self.oven = Oven()
def order(self, name):
customer = Customer(name) # activate other objects
customer.order(self.server) # customer orders from server
self.chef.work()
self.oven.bake()
customer.pay(self.server)
if __name__ == "__main__":
scene = PizzaShop() # make the composite
scene.order('Homer') # simulate Homer's order
print '...'
scene.order('Shaggy') # simulate Shaggy's order
C:\python\examples> python pizzashop.py
Homer orders from
Bob makes pizza
oven bakes
Homer pays for item to
...
Shaggy orders from
Bob makes pizza
oven bakes
Shaggy pays for item to
** Page 174 *******************************************************************
import pickle
object = someClass()
file = open(filename, 'w') # create external file
pickle.dump(object, file) # save object in file
file = open(filename, 'r')
object = pickle.load(file) # fetch it back later
import shelve
object = someClass()
dbase = shelve.open('filename')
dbase['key'] = object # save under key
...
object = dbase['key'] # fetch it back later
** Page 175 *******************************************************************
# file trace.py
class wrapper:
def __init__(self, object):
self.wrapped = object # save object
def __getattr__(self, attrname):
print 'Trace:', attrname # trace fetch
return getattr(self.wrapped, attrname) # delegate fetch
>>> from trace import wrapper
>>> x = wrapper([1,2,3]) # wrap a list
>>> x.append(4) # delegate to list method
Trace: append
>>> x.wrapped # print my member
[1, 2, 3, 4]
>>> x = wrapper({"a": 1, "b": 2}) # wrap a dictionary
>>> x.keys() # delegate to dictionary method
Trace: keys
['a', 'b']
# file set.py
class Set:
def __init__(self, value = []): # constructor
self.data = [] # manages a list
self.concat(value)
def intersect(self, other): # other is any sequence
res = [] # self is the subject
for x in self.data:
if x in other: # pick common items
res.append(x)
return Set(res) # return a new Set
def union(self, other): # other is any sequence
res = self.data[:] # copy of my list
for x in other: # add items in other
if not x in res:
res.append(x)
return Set(res)
def concat(self, value): # value: list, Set...
for x in value: # removes duplicates
if not x in self.data:
self.data.append(x)
def __len__(self): return len(self.data) # on len(self)
def __getitem__(self, key): return self.data[key] # on self[i]
def __and__(self, other): return self.intersect(other) # on self & other
def __or__(self, other): return self.union(other) # on self | other
def __repr__(self): return 'Set:' + `self.data` # on print
** Page 177 *******************************************************************
>>> class Spam:
... def __init__(self): # no __repr__
... self.data1 = "food"
...
>>> X = Spam()
>>> print X # default format: class, address
# file mytools.py
# Lister can be mixed-in to any class, to
# provide a formatted print of instances
# via inheritance of __repr__ coded here;
# self is the instance of the lowest class;
class Lister:
def __repr__(self):
return ("" %
(self.__class__.__name__, # my class's name
id(self), # my address
self.attrnames()) ) # name=value list
def attrnames(self):
result = ''
for attr in self.__dict__.keys(): # scan instance namespace dict
if attr[:2] == '__':
result = result + "\tname %s=\n" % attr
else:
result = result + "\tname %s=%s\n" % (attr, self.__dict__[attr])
return result
# file testmixin.py
from mytools import Lister # get tool class
class Super:
def __init__(self): # superclass __init__
self.data1 = "spam"
class Sub(Super, Lister): # mix-in a __repr__
def __init__(self): # Lister has access to self
Super.__init__(self)
self.data2 = "eggs" # more instance attrs
self.data3 = 42
if __name__ == "__main__":
X = Sub()
print X # mixed-in repr
C:\python\examples> python testmixin.py
>>> from mytools import Lister
>>> class x(Lister):
... pass
...
>>> t = x()
>>> t.a = 1; t.b = 2; t.c = 3
>>> t
** Page 179 *******************************************************************
def factory(aClass, *args): # varargs tuple
return apply(aClass, args) # call aClass
class Spam:
def doit(self, message):
print message
class Person:
def __init__(self, name, job):
self.name = name
self.job = job
object1 = factory(Spam) # make a Spam
object2 = factory(Person, "Guido", "guru") # make a Person
def factory(aClass, *args, **kwargs): # +kwargs dict
return apply(aClass, args, kwargs) # call aClass
** Page 180 *******************************************************************
class Spam:
def doit(self, message):
print message
object1 = Spam()
x = object1.doit # bound method object
x('hello world') # instance is implied
t = Spam.doit # unbound method object
t(object1, 'howdy') # pass in instance
** Page 182 *******************************************************************
# file docstr.py
"I am: docstr.__doc__"
class spam:
"I am: spam.__doc__ or docstr.spam.__doc__"
def method(self, arg):
"I am: spam.method.__doc__ or self.method.__doc__"
pass
def func(args):
"I am: docstr.func.__doc__"
pass
>>> import docstr
>>> docstr.__doc__
'I am: docstr.__doc__'
>>> docstr.spam.__doc__
'I am: spam.__doc__ or docstr.spam.__doc__'
>>> docstr.spam.method.__doc__
'I am: spam.method.__doc__ or self.method.__doc__'
>>> docstr.func.__doc__
'I am: docstr.func.__doc__'
** Page 183 *******************************************************************
>>> class X:
... a = 1 # class attribute
...
>>> I = X()
>>> I.a # inherited by instance
1
>>> X.a
1
>>> X.a = 2 # may change more than X
>>> I.a # I changes too
2
>>> J = X() # J inherits from X's runtime values
>>> J.a # (but assigning to J.a changes a in J, not X or I)
2
class X: pass # make a few attribute namespaces
class Y: pass
X.a = 1 # use class attributes as variables
X.b = 2 # no instances anywhere to be found
X.c = 3
Y.a = X.a + X.b + X.c
for X.i in range(Y.a): print X.i # prints 0..5
>>> class Record: pass
...
>>> X = Record()
>>> X.name = 'bob'
>>> X.job = 'Pizza maker'
** Page 185 *******************************************************************
class Lister:
def __repr__(self): ...
def other(self): ...
class Super:
def __repr__(self): ...
def other(self): ...
class Sub(Super, Lister): # pick up Super's __repr__, by listing it first
other = Lister.other # but explicitly pick up Lister's version of other
def __init__(self):
...
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
def printNumInstances():
print "Number of instances created: ", Spam.numInstances
>>> from spam import *
>>> a = Spam()
>>> b = Spam()
>>> c = Spam()
>>> Spam.printNumInstances()
Traceback (innermost last):
File "", line 1, in ?
TypeError: unbound method must be called with class instance 1st argument
def printNumInstances():
print "Number of instances created: ", Spam.numInstances
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
>>> import spam
>>> a = spam.Spam()
>>> b = spam.Spam()
>>> c = spam.Spam()
>>> spam.printNumInstances()
Number of instances created: 3
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
def printNumInstances(self):
print "Number of instances created: ", Spam.numInstances
>>> from spam import Spam
>>> a, b, c = Spam(), Spam(), Spam()
>>> a.printNumInstances()
Number of instances created: 3
>>> b.printNumInstances()
Number of instances created: 3
>>> Spam().printNumInstances()
Number of instances created: 4
** Page 187 *******************************************************************
# file nester.py
def generate():
class Spam:
count = 1
def method(self): # name Spam not visible:
print Spam.count # not local (def), global (module), built-in
return Spam()
generate().method()
C:\python\examples> python nester.py
Traceback (innermost last):
...
NameError: Spam
def generate():
global Spam # force Spam to module scope
class Spam:
count = 1
def method(self):
print Spam.count # works: in global (enclosing module)
return Spam()
generate().method() # prints 1
def generate():
return Spam()
class Spam: # define at module top-level
count = 1
def method(self):
print Spam.count # works: in global (enclosing module)
generate().method()
def generate():
class Spam:
count = 1
def method(self):
print self.__class__.count # works: qualify to get class
return Spam()
generate().method()
def generate():
class Spam:
count = 1
fillin = [None]
def method(self, klass=fillin): # save from enclosing scope
print klass[0].count # works: default plugged-in
Spam.fillin[0] = Spam
return Spam()
generate().method()
lpython/unix/examples/chapter7.txt 001777 000000 000000 00000011732 06713574764 013340 ** Page 198 *******************************************************************
% cat bad.py
def gobad(x, y):
return x / y
def gosouth(x):
print gobad(x, 0)
gosouth(1)
% python bad.py
Traceback (innermost last):
File "bad.py", line 7, in ?
gosouth(1)
File "bad.py", line 5, in gosouth
print gobad(x, 0)
File "bad.py", line 2, in gobad
return x / y
ZeroDivisionError: integer division or modulo
** Page 199 *******************************************************************
def kaboom(list, n):
print list[n] # trigger IndexError
try:
kaboom([0, 1, 2], 3)
except IndexError: # catch exception here
print 'Hello world!'
MyError = "my error"
def stuff(file):
raise MyError
file = open('data', 'r') # open an existing file
try:
stuff(file) # raises exception
finally:
file.close() # always close file
** Page 200 *******************************************************************
while 1:
try:
line = raw_input() # read line from stdin
except EOFError:
break # exit loop at end of file
else:
Process next 'line' here...
Found = "Item found"
def searcher():
raise found or return
try:
searcher()
except Found: # exception if item was found
Success
else: # else returned: not found
Failure
try:
Run program
except: # all uncaught exceptions come here
import sys
print 'uncaught!', sys.exc_type, sys.exc_value
try:
action()
except NameError:
...
except IndexError
...
except KeyError:
...
except (AttributeError, TypeError, SyntaxError):
...
else:
...
** Page 203 *******************************************************************
# file nestexc.py
def action2():
print 1 + [] # generate TypeError
def action1():
try:
action2()
except TypeError: # most recent matching try
print 'inner try'
try:
action1()
except TypeError: # here only if action1 reraises
print 'outer try'
% python nestexc.py
inner try
# file finally.py
def divide(x, y):
return x / y # divide-by-zero error?
def tester(y):
try:
print divide(8, y)
finally:
print 'on the way out...'
print '\nTest 1:'; tester(2)
print '\nTest 2:'; tester(0) # trigger error
% python finally.py
Test 1:
4
on the way out...
Test 2:
on the way out...
Traceback (innermost last):
File "finally.py", line 11, in ?
print 'Test 2:'; tester(0)
File "finally.py", line 6, in tester
print divide(8, y)
File "finally.py", line 2, in divide
return x / y # divide-by-zero error?
ZeroDivisionError: integer division or modulo
** Page 204 *******************************************************************
# file helloexc.py
myException = 'Error' # string object
def raiser1():
raise myException, "hello" # raise, pass data
def raiser2():
raise myException # raise, None implied
def tryer(func):
try:
func()
except myException, extraInfo: # run func, catch exception + data
print 'got this:', extraInfo
% python
>>> from helloexc import *
>>> tryer(raiser1) # gets explicitly passed extra data
got this: hello
>>> tryer(raiser2) # gets None by default
got this: None
# sidebar
def doStuff():
doFirstThing() # we don't care about exceptions here
doNextThing() # so we don’t need to detect them here
...
doLastThing()
if__name__ == '__main__':
try:
doStuff() # this is where we care about the result
except: #so it's the only place we need to check
badEnding()
else:
goodEnding()
** Page 207 *******************************************************************
# file classexc.py
class General: pass
class Specific(General): pass
def raiser1():
X = General() # raise listed class instance
raise X
def raiser2():
X = Specific() # raise instance of subclass
raise X
for func in (raiser1, raiser2):
try:
func()
except General: # match General or any subclass of it
import sys
print 'caught:', sys.exc_type
% python classexc.py
caught:
caught:
** Page 209 *******************************************************************
>>> ex1 = "spam"
>>> ex2 = "spam"
>>>
>>> ex1 == ex2, ex1 is ex2
(1, 0)
>>> try:
... raise ex1
... except ex1:
... print 'got it'
...
got it
>>> try:
... raise ex1
... except ex2:
... print 'Got it'
...
Traceback (innermost last):
File "", line 2, in ?
spam
try:
...
except:
... # everything comes here!
try:
x = myditctionary[spam] # oops: misspelled
except:
x = None # assume we got KeyError or IndexError
try:
...
except (myerror1, myerror2): # what if I add a myerror3?
... # nonerrors
else:
... # assumed to be an error
lpython/unix/examples/chapter8.txt 001777 000000 000000 00000034571 06713574764 013347 ** Page 216 *******************************************************************
>>> dir([]) # what are the attributes of lists?
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort']
>>> dir(()) # what are the attributes of tuples?
[] # tuples have no attributes!
>>> dir(sys.stdin) # what are the attributes of files?
['close', 'closed', 'fileno', 'flush', 'isatty', 'mode', 'name', 'read',
'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate',
'write', 'writelines']
>>> dir(sys) # modules are objects too
['__doc__', '__name__', 'argv', 'builtin_module_names', 'copyright', 'dllhandle'
, 'exc_info', 'exc_type', 'exec_prefix', 'executable', 'exit', 'getrefcount',
'maxint', 'modules', 'path', 'platform', 'prefix', 'ps1', 'ps2',
'setcheckinterval', 'setprofile', 'settrace', 'stderr', 'stdin', 'stdout',
'version', 'winver']
>>> type(sys.version) # what kind of thing is 'version'?
>>> print sys.version # what is the value of this string?
1.5 (#0, Dec 30 1997, 23:24:20) [MSC 32 bit (Intel)]
** Page 217 *******************************************************************
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'EOFError', 'Ellipsis',
'Exception', 'FloatingPointError', 'IOError', 'ImportError', 'IndexError',
'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError',
'None', 'OverflowError', 'RuntimeError', 'StandardError', 'SyntaxError',
'SystemError', 'SystemExit', 'TypeError', 'ValueError', 'ZeroDivisionError',
'__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'callable',
'chr', 'cmp', 'coerce', 'compile', 'complex', 'delattr', 'dir', 'divmod', 'eval',
'execfile', 'filter', 'float', 'getattr', 'globals', 'hasattr', 'hash', 'hex',
'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'len', 'list',
'locals', 'long', 'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'range',
'raw_input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'slice', 'str',
'tuple', 'type', 'vars', 'xrange']
** Page 218 *******************************************************************
>>> int(1.0), int(1.4), int(1.9), round(1.9), int(round(1.9))
(1, 1, 1, 2.0, 2)
>>> int("1")
1
>>> int("1.2") # this doesn't work
Traceback (innermost last):
File "", line 1, in ?
ValueError: invalid literal for int(): 1.2
>>> int("1.0") # interestingly, neither does this
Traceback (innermost last): # since 1.0 is also not a valid
File "", line 1, in ? # integer literal
ValueError: invalid literal for int(): 1.0
>>> hex(1000), oct(1000), complex(1000), long(1000)
('0x3e8', '01750', (1000+0j), 1000L)
>>> def safeint(candidate):
... import math
... truncated = math.floor(float(candidate))
... rounded = round(float(candidate))
... if truncated == rounded:
... return int(truncated)
... else:
... raise ValueError, "argument would lose precision when cast to integer"
...
>>> safeint(3.0)
3
>>> safeint("3.0")
3
>>> safeint(3.1)
Traceback (innermost last):
File "", line 1, in ?
File "", line 6, in safeint
ValueError: argument would lose precision when cast to integer
>>> abs(-1), abs(-1.2), abs(-3+4j)
(1, 1.2, 5.0) # 5 is sqrt(3*3 + 4*4)
>>> map(ord, "test") # remember that strings are sequences
[116, 101, 115, 116] # of characters, so map can be used
>>> chr(64)
'@'
>>> ord('@')
64
# map returns a list of single characters, so it
# needs to be 'join'ed into a str
>>> map(chr, (83, 112, 97, 109, 33))
['S', 'p', 'a', 'm', '! ']
>>> import string
>>> string.join(map(chr, (83, 112, 97, 109, 33)), '')
'Spam!'
>>> min("pif", "paf", "pof") # when called with multiple 'paf' arguments
# return appropriate one
>>> min("ZELDA!"), max("ZELDA!") # when called with a sequence, '!', 'Z'
# return the min/max element of it
** Page 220 *******************************************************************
>>> str(dir())
"['__builtins__', '__doc__', '__name__']"
>>> list("tomato")
['t', 'o', 'm', 'a', 't', 'o']
>>> list((1,2,3))
[1, 2, 3]
>>> tuple("tomato")
('t', 'o', 'm', 'a', 't', 'o')
>>> tuple([0])
(0,)
>>> int("3")
3
>>> long("3")
3L
>>> float("3")
3.0
>>> complex(3,5)
(3+5j)
>>> hex(10000)
'0x2710'
>>> oct(10000)
'023420'
>>> ord('A')
64
>>> chr(65)
'A'
>>> min([5,1,2,3,4])
1
>>> min(5,1,2,3,4)
1
>>> max([5,1,2,3,4])
5
>>> max(5,1,2,3,4)
5
** Page 221 *******************************************************************
>>> def increment_attribute(object, attrname):
... if not hasattr(object, attrname):
... setattr(object, attrname, 1)
... else:
... setattr(object, attrname, getattr(object, attrname) + 1)
...
>>> class Test: pass
...
>>> aname = 'foo'
>>> increment_attribute(Test, aname) # create Test.foo and set it to
1
>>> increment_attribute(Test, aname) # increment Test.foo
>>> Test.foo
2
def increment_attribute(object, attrname):
setattr(object, attrname, getattr(object, attrname, 0) + 1)
** Page 222 *******************************************************************
>>> code = "x = 'Something'"
>>> x = "Nothing" # sets the value of x
>>> exec code # modifies the value of x!
>>> print x
'Something'
import sys
for argument in sys.argv[1:]: # we'll skip ourselves, or it'll loop!
execfile(argument) # do whatever
>>> z = eval("'xo'*10")
>>> print z
'xoxoxoxoxoxoxoxoxoxo'
>>> z = eval("x = 3")
Traceback (innermost last):
File "", line 1, in ?
File "", line 1
x = 3
^
SyntaxError: invalid syntax
>>> callable(sys.exit), type(sys.exit)
(1, )
>>> callable(sys.version), type(sys.version)
(0, )
** Page 225 *******************************************************************
>>> string.atof("1.4")
1.4
>>> string.atoi("365")
365
>>> string.atol("987654321")
987654321L
>>> string.capitalize("tomato")
'Tomato'
>>> string.capwords("now is the time")
'Now Is The Time'
>>> string.find("now is the time", 'is')
4
>>> string.count("now is the time", 'i')
2
>>> string.replace("now is the time", ' ', '_')
'now_is_the_time'
>>> string.split("now is the time")
['now', 'is', 'the', 'time']
>>> string.join(["now","is","the","time", '*'])
'now*is*the*time'
>>> string.join("now is the time", '*')
'n*o*w* *i*s* *t*h*e* *t*i*m*e'
>>> string.strip(" before and after ")
'before and after'
** Page 228 *******************************************************************
# file pepper.txt
This is a paragraph that mentions bell peppers multiple times. For
one, here is a red pepper and dried tomato salad recipe. I don't like
to use green peppers in my salads as much because they have a harsher
flavor.
This second paragraph mentions red peppers and green peppers but not
the "s" word (s-a-l-a-d), so no bells should show up.
This third paragraph mentions red peppercorns and green peppercorns,
which aren't vegetables but spices (by the way, bell peppers really
aren't peppers, they're chilies, but would you rather have a good cook
or a good botanist prepare your salad?).
# file pepper.py
file = open('pepper.txt')
text = file.read()
import string
paragraphs = string.split(text, '\n\n')
import re
matchstr = re.compile(
r"""\b(red|green) # 'red' or 'green' starting new words
(\s+ # followed by whitespace
pepper # the word 'pepper'
(?!corn) # if not followed immediately by 'corn'
(?=.*salad))""", # and if followed at some point by 'salad'',
re.IGNORECASE | # allow pepper, Pepper, PEPPER, etc.
re.DOTALL | # allow to match newlines as well
re.VERBOSE) # this allows the comments and the newlines above
for paragraph in paragraphs:
fixed_paragraph = matchstr.sub(r'bell\2', paragraph)
print fixed_paragraph+'\n'
/home/David/book$ python pepper.py
This is a paragraph that mentions bell peppers multiple times. For
one, here is a bell pepper and dried tomato salad recipe. I don’t like
to use bell peppers in my salads as much because they have a harsher
flavor.
This second paragraph mentions red peppers and green peppers but not
the "s" word (s-a-l-a-d), so no bells should show up.
This third paragraph mentions red peppercorns and green peppercorns,
which aren’t vegetables but spices (by the way, bell peppers really
aren’t peppers, they’re chilies, but would you rather have a good cook
or a good botanist prepare your salad?).
** Page 231 *******************************************************************
>>> print os.getcwd()
h:\David\book
>>> os.listdir(os.getcwd())
['preface.doc', 'part1.doc', 'part2.doc']
>>> os.rmdir('nonexistent_directory') # how it usually shows up
Traceback (innermost last):
File "", line 1, in ?
os.error: (2, 'No such file or directory')
>>> try: # we can catch the error and take
... os.rmdir('nonexistent directory') # it apart
... except os.error, value:
... print value[0], value[1]
...
2 No such file or directory
>>> print os.environ['SHELL']
/bin/sh
>>> os.environ['STARTDIR'] = 'MyStartDir'
>>> os.system('echo $STARTDIR') # 'echo %STARTDIR%' on DOS/Win
MyStartDir # printed by the shell
0 # return code from echo
** Page 233 *******************************************************************
>>> os.path.split("h:/David/book/part2.doc"
('h:/David/book', 'part2.doc')
>>> print os.path.join(os.getcwd(),
... os.pardir, 'backup', 'part2.doc')
h:\David\book\..\backup\part2.doc
>>> print os.path.expanduser('~/mydir')
h:\David\mydir
>>> print os.path.expandvars('$TMP')
C:\TEMP
>>> print os.path.normpath("/foo/bar\\../tmp")
\foo\tmp
>>> def test_walk(arg, dirname, names):
... print arg, dirname, names
...
>>> os.path.walk('..', test_walk, 'show')
show ..\logs ['errors.log', 'access.log']
show ..\cgi-bin ['test.cgi']
...
** Page 235 *******************************************************************
>>> page = urlopen('http://www.python.org')
>>> page.readline()
'\012'
>>> page.readline()
'\012'
>>> urllib.urlretrieve('http://www.python.org/', 'wwwpython.html')
>>> quote('this & that @ home')
'this%20%26%20that%20%40%20home'
>>> unquote('this%20%26%20that%20%40%20home')
'this & that @ home'
>>> locals()
{'urllib': , '__doc__': None, 'x':3,
'__name__': '__main__', '__builtins__': }
>>> urllib.urlencode(locals())
'urllib=%3cmodule+%27urllib%27%3e&__doc__=None&x=3&
__ name__=__main__&__builtins__=%3cmodule+%27
__builtin__%27%3e'
>>> urlparse('http://www.python.org/FAQ.html')
('http', 'www.python.org', '/FAQ.html', '', '','')
>>> urljoin('http://www.python.org', 'doc/lib')
'http://www.python.org/doc/lib'
** Page 238 *******************************************************************
import struct
data = open('bindat.dat').read()
start, stop = 0, struct.calcsize('fl')
version_number, num_bytes = struct.unpack('fl', data[start:stop])
start, stop = stop, start + struct.calcsize('B'*num_bytes)
bytes = struct.unpack('B'*num_bytes, data[start:stop])
** Page 239 *******************************************************************
>>> import spam # import the module we wish to debug
>>> import pdb # import pdb
>>> pdb.run('instance = spam.Spam()') # start pdb with a statement to run
> (0)?()
(Pdb) break spam.Spam.__init__ # we can set break points
(Pdb) next
> (1)?()
(Pdb) n # 'n' is short for 'next'
> spam.py(3)__init__()
-> def __init__(self):
(Pdb) n
> spam.py(4)__init__()
-> Spam.numInstances = Spam.numInstances + 1
(Pdb) list # show the source code listing
1 class Spam:
2 numInstances = 0
3 B def __init__(self): # note the B for Breakpoint
4 -> Spam.numInstances = Spam.numInstances + 1 # where we are
5 def printNumInstances(self):
6 print "Number of instances created: ", Spam.numInstances
7
[EOF]
(Pdb) where # show the calling stack
(1)?()
> spam.py(4)__init__()
-> Spam.numInstances = Spam.numInstances + 1
(Pdb) Spam.numInstances = 10 # note that we can modify variables
(Pdb) print Spam.numInstances # while the program is being debugged
10
(Pdb) continue # this continues until the next break-
--Return-- # point, but there is none, so we're
> (1)?()->None # done
(Pdb) c # this ends up quitting Pdb
# this is the returned instance
>>> instance.numInstances # note that the change to numInstance
11 # was *before* the increment op
** Page 240 *******************************************************************
# file makezeros.py
def lots_of_appends():
zeros = []
for i in range(10000):
zeros.append(0)
def one_multiply():
zeros = [0] * 10000
# file timings.py
import time, makezeros
def do_timing(num_times, *funcs):
totals = {}
for func in funcs: totals[func] = 0.0
for x in range(num_times):
for func in funcs:
starttime = time.time() # record starting time
apply(func)
stoptime = time.time() # record ending time
elapsed = stoptime-starttime # difference yields time elapsed
totals[func] = totals[func] + elapsed
for func in funcs:
print "Running %s %d times took %.3f seconds" % (func.__name__,
num_times,
totals[func])
do_timing(100, (makezeros.lots_of_appends, makezeros.one_multiply))
csh> python timings.py
Running lots_of_appends 100 times took 7.891 seconds
Running one_multiply 100 times took 0.120 seconds
>>> import profile
>>> from timings import *
>>> from makezeros import *
>>> profile.run('do_timing(100, (lots_of_appends, one_multiply))')
Running lots_of_appends 100 times took 8.773 seconds
Running one_multiply 100 times took 0.090 seconds
...
lpython/unix/examples/chapter9.txt 001777 000000 000000 00000046322 06713574764 013345 ** Page 243 *******************************************************************
newList = myList[:]
newDict = {}
for key in myDict.keys():
newDict[key] = myDict[key]
newDict = myDict.copy()
for key in otherDict.keys():
oneDict[key] = otherDict[key]
def mergeWithoutOverlap(oneDict, otherDict):
newDict = oneDict.copy()
for key in otherDict.keys():
if key in oneDict.keys():
raise ValueError, "the two dictionaries are sharing keys!"
newDict[key] = otherDict[key]
return newDict
def mergeWithOverlap(oneDict, otherDict):
newDict = oneDict.copy()
for key in otherDict.keys():
if key in oneDict.keys():
newDict[key] = oneDict[key], otherDict[key]
else:
newDict[key] = otherDict[key]
return newDict
phoneBook1 = {'michael': '555-1212', 'mark': '554-1121', 'emily': '556-0091'}
phoneBook2 = {'latoya': '555-1255', 'emily': '667-1234'}
** Page 245 *******************************************************************
>>> import copy
>>> listOne = [{"name": "Willie", "city": "Providence, RI"}, 1, "tomato", 3.0]
>>> listTwo = listOne[:] # or listTwo=copy.copy(listOne)
>>> listThree = copy.deepcopy(listOne)
>>> listOne.append("kid")
>>> listOne[0]["city"] = "San Francisco, CA"
>>> print listOne, listTwo, listThree
[{'name': 'Willie', 'city': 'San Francisco, CA'}, 1, 'tomato', 3.0, 'kid']
[{'name': 'Willie', 'city': 'San Francisco, CA'}, 1, 'tomato', 3.0]
[{'name': 'Willie', 'city': 'Providence, RI'}, 1, 'tomato', 3.0]
** Page 246 *******************************************************************
listCopy = list(myTuple)
listCopy.sort()
for item in listCopy:
print item # or whatever needs doing
keys = myDict.keys() # returns an unsorted list of the keys in the dict
keys.sort()
for key in keys: # print key, value pairs
print key, myDict[key] # sorted by key
>>> def caseIndependentSort(something, other):
... something, other = string.lower(something), string.lower(other)
... return cmp(something, other)
...
>>> testList = ['this', 'is', 'A', 'sorted', 'List']
>>> testList.sort()
>>> print testList
['A', 'List', 'is', 'sorted', 'this']
>>> testList.sort(caseIndependentSort)
>>> print testList
['A', 'is', 'List', 'sorted', 'this']
while myList: # will stop looping when myList is empty
element = whrandom.choice(myList)
myList.remove(element)
print element,
** Page 248 *******************************************************************
class Stack:
def __init__(self, data):
self._data = list(data)
def push(self, item):
self._data.append(item)
def pop(self):
item = self._data[-1]
del self._data[-1]
return item
>>> thingsToDo = Stack(['write to mom', 'invite friend over', 'wash the
kid'])
>>> thingsToDo.push('do the dishes')
>>> print thingsToDo.pop()
do the dishes
>>> print thingsToDo.pop()
wash the kid
# import the UserList class from the UserList module
from UserList import UserList
# subclass the UserList class
class Stack(UserList):
push = UserList.append
def pop(self):
item = self[-1] # uses __getitem__
del self[-1]
return item
>>> thingsToDo = Stack(['write to mom', 'invite friend over', 'wash the
kid'])
>>> print thingsToDo # inherited from UserList
['write to mom', 'invite friend over', 'wash the kid']
>>> thingsToDo.pop()
'wash the kid'
>>> thingsToDo.push('change the oil')
>>> for chore in thingsToDo: # we can also iterate over the contents
... print chore # as "for .. in .." uses __getitem__
...
write to mom
invite friend over
change the oil
** Page 250 *******************************************************************
import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."
% cat countlines.py | python countlines.py
Counted 3 lines.
C:\> type countlines.py | python countlines.py
Counted 3 lines.
# Finding all lines that start with a #
import sys
for line in sys.stdin.readlines():
if line[0] == '#':
print line,
# Extracting the fourth column of a file (where columns are whitespace)
import sys, string
for line in sys.stdin.readlines():
words = string.split(line)
if len(words) >= 4:
print words[3]
# or...
try:
print words[3]
except IndexError: # there aren't enough words
pass
# Extracting the fourth column of a file,
# where columns are separated by colons, and lowercasing it
import sys, string
for line in sys.stdin.readlines():
words = string.split(line, ':')
if len(words) >= 4:
print string.lower(words[3])
# Printing the first 10 lines, the last 10 lines, and every other line
import sys, string
lines = sys.stdin.readlines()
sys.stdout.writelines(lines[:10]) # first ten lines
sys.stdout.writelines(lines[-10:]) # last ten lines
for lineIndex in range(0, len(lines), 2): # get 0, 2, 4, ...
sys.stdout.write(lines[lineIndex]) # get the indexed line
# Counting the number of times the word "Python" occurs in a file
import string
text = open(fname).read()
print string.count(text, 'Python')
# Changing a list of columns into a list of rows
import sys, string
lines = sys.stdin.readlines()
wordlists = []
for line in lines:
words = string.split(line)
wordlists.append(words)
for row in range(len(wordlists[0])):
for col in range(len(wordlists)):
print wordlists[col][row] + '\t',
print
** Page 252 *******************************************************************
# read character by character
while 1:
next = sys.stdin.read(1) # read a one-character string
if not next: # or an empty string at eof
break
Process character 'next'
# read line by line
while 1:
next = sys.stdin.readline() # read a one-line string
if not next: # or an empty string at EOF
break
Process line 'next'
% python myScript.py input1.txt input2.txt input3.txt output.txt
import sys
inputfilenames, outputfilename = sys.argv[1:-1], sys.argv[-1]
for inputfilename in inputfilenames:
inputfile = open(inputfilename, "r")
do_something_with_input(inputfile)
outputfile = open(outputfilename, "w")
write_results(outputfile)
def do_something_with_input(inputfile):
for line in inputfile.readlines()
process(line)
import fileinput
for line in fileinput.input():
process(line)
# take the first argument out of sys.argv and assign it to searchterm
searchterm, sys.argv[1:] = sys.argv[1], sys.argv[2:]
for line in fileinput.input():
num_matches = string.count(line, searchterm)
if num_matches: # a nonzero count means there was a match
print "found '%s' %d times in %s on line %d." % (searchterm, num_matches,
fileinput.filename(), fileinput.filelineno())
** Page 254 *******************************************************************
import os, string
if len(sys.argv) == 1: # if no filenames are specified,
filenames = os.listdir(os.curdir) # use current dir
else: # otherwise, use files specified
filenames = sys.argv[1:] # on the command line
for filename in filenames:
if ' ' in filename:
newfilename = string.replace(filename, ' ', '_')
print "Renaming", filename, "to", newfilename, "..."
os.rename(filename, newfilename)
import sys, glob, operator
print sys.argv[1:]
sys.argv = reduce(operator.add, map(glob.glob, sys.argv))
print sys.argv[1:]
/usr/python/book$ python showglob.py *.py
['countlines.py', 'mygrep.py', 'retest.py', 'showglob.py', 'testglob.py']
['countlines.py', 'mygrep.py', 'retest.py', 'showglob.py', 'testglob.py']
C:\python\book> python showglob.py *.py
['*.py']
['countlines.py', 'mygrep.py', 'retest.py', 'showglob.py', 'testglob.py']
>>> numbers = range(30)
>>> def even(x):
... return x % 2 == 0
...
>>> print numbers
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29]
>>> print filter(even, numbers)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
import string
words = string.split(open('myfile.txt').read()) # get all the words
def at_least_ten(word):
return len(word) >= 10
longwords = filter(at_least_ten, words)
lines = open('myfile.txt').readlines()
lines = filter(None, lines) # remember, the empty string is false
** Page 258 *******************************************************************
# read input file
inputFile = open('input.txt', 'r')
import tempfile
# create temporary file
tempFile = tempfile.TemporaryFile() # we don't even need to
first_process(input = inputFile, output = tempFile) # know the filename...
# create final output file
outputFile = open('output.txt', 'w')
second_process(input = tempFile, output = outputFile)
formletter = """Dear %s,\nI'm writing to you to suggest that ...""" # etc.
myDatabase = [('Bill Clinton', 'bill@whitehouse.gov.us'),
('Bill Gates', 'bill@microsoft.com'),
('Bob', 'bob@subgenius.org')]
for name, email in myDatabase:
specificLetter = formletter % name
tempfilename = tempfile.mktemp()
tempfile = open(tempfilename, 'w')
tempfile.write(specificLetter)
tempfile.close()
os.system('/usr/bin/mail %(email)s -s "Urgent!" < %(tempfilename)s'
% vars())
os.remove(tempfilename)
** Page 259 *******************************************************************
#!/usr/bin/env python
import sys, string
entries = {}
for line in open(sys.argv[1], 'r').readlines():
left, right = string.split(line)
try:
entries[right].append(left) # extend list
except KeyError:
entries[right] = [left] # first time seen
for (right, lefts) in entries.items():
print "%04d '%s'\titems => %s" % (len(lefts), right, lefts)
# or
if entries.has_key(right): # is it already in the dictionary?
entries[right].append(left) # add to the list of current values for key
else:
entries[right] = [left] # initialize key's values list
% cat data.txt
1 one
2 one
3 two
7 three
8 two
10 one
14 three
19 three
20 three
30 three
% python collector1.py data.txt
0003 'one' items => ['1', '2', '10']
0005 'three' items => ['7', '14', '19', '20', '30']
0002 'two' items => ['3', '8']
#!/usr/bin/env python
import sys, string
def collect(file):
entries = {}
for line in file.readlines():
left, right = string.split(line)
try:
entries[right].append(left) # extend list
except KeyError:
entries[right] = [left] # first time seen
return entries
if __name__ == "__main__": # when run as a script
if len(sys.argv) == 1:
result = collect(sys.stdin) # read from stdin stream
else:
result = collect(open(sys.argv[1], 'r')) # read from passed filename
for (right, lefts) in result.items():
print "%04d '%s'\titems => %s" % (len(lefts), right, lefts)
# run as a script file
% collector2.py < data.txt
result displayed here...
# use in some other component (or interactively)
from collector2 import collect
result = collect(open("spam.txt", "r"))
process result here...
>>> from collector2 import collect
>>> from StringIO import StringIO
>>>
>>> str = StringIO("1 one\n2 one\n3 two")
>>> result = collect(str) # scans the wrapped string
>>> print result # {'one':['1','2'],'two':['3']}
** Page 262 *******************************************************************
for datafname in ['data.001', 'data.002', 'data.003']:
for parameter1 in range(1, 10):
os.system("analyzeData -in %(datafname)s -param1 %(paramter1)d" % vars())
#!/usr/bin/env python
# find files, search for tabs
import string, os
cmd = 'find . -name "*.py" -print' # find is a standard Unix tool
for file in os.popen(cmd).readlines(): # run find command
num = 1
name = file[:-1] # strip '\n'
for line in open(name).readlines(): # scan the file
pos = string.find(line, "\t")
if pos >= 0:
print name, num, pos # report tab found
print '....', line[:-1] # [:-1] strips final \n
print '....', ' '*pos + '*', '\n'
num = num+1
C:\python\book-examples> python findtabs.py
./happyfingers.py 2 0
.... for i in range(10):
.... *
./happyfingers.py 3 0
.... print "oops..."
.... *
./happyfingers.py 5 5
.... print "bad style"
.... *
if sys.platform == "win32": # on a Windows port
try:
import win32pipe
popen = win32pipe.popen
except ImportError:
raise ImportError, "The win32pipe module could not be found"
else: # else on POSIX box
import os
popen = os.popen
...And use popen in blissful platform ignorance
** Page 265 *******************************************************************
# file get_temperature.py
import urllib, urlparse, string, time
def get_temperature(country, state, city):
url = urlparse.urljoin('http://www.weather.com/weather/cities/',
string.lower(country)+'_' + \
string.lower(state) + '_' + \
string.replace(string.lower(city), ' ',
'_') + '.html')
data = urllib.urlopen(url).read()
start = string.index(data, 'current temp: ') + len('current temp: ')
stop = string.index(data, '°F', start-1)
temp = int(data[start:stop])
localtime = time.asctime(time.localtime(time.time()))
print ("On %(localtime)s, the temperature in %(city)s, " +\
"%(state)s %(country)s is %(temp)s F.") % vars()
get_temperature('FR', '', 'Paris')
get_temperature('US', 'RI', 'Providence')
get_temperature('US', 'CA', 'San Francisco')
~/book:> python get_temperature.py
On Wed Nov 25 16:22:25 1998, the temperature in Paris, FR is 39 F.
On Wed Nov 25 16:22:30 1998, the temperature in Providence, RI US is 39 F.
On Wed Nov 25 16:22:35 1998, the temperature in San Francisco, CA US is 58 F.
** Page 266 *******************************************************************
>>> from poplib import *
>>> server = POP3('mailserver.spam.org')
>>> print server.getwelcome()
+OK QUALCOMM Pop server derived from UCB (version 2.1.4-R3) at spam starting.
>>> server.user('da')
'+OK Password required for da.'
>>> server.pass_('youllneverguess')
'+OK da has 153 message(s) (458167 octets).'
>>> header, msg, octets = server.retr(152) # let's get the latest msgs
>>> import string
>>> print string.join(msg[:3], '\n') # and look at the first three lines
Return-Path:
Received: from gator.bigbad.com by mailserver.spam.org (4.1/SMI-4.1)
id AA29605; Wed, 25 Nov 98 15:59:24 PST
** Page 267 *******************************************************************
# file interest.py
trace = 1 # print each year?
def calc(principal, interest, years):
for y in range(years):
principal = principal * (1.00 + (interest / 100.0))
if trace: print y+1, '=> %.2f' % principal
return principal
% python
>>> from interest import calc
>>> calc(65000, 5.5, 10)
1 => 68575.00
2 => 72346.63
3 => 76325.69
4 => 80523.60
5 => 84952.40
6 => 89624.78
7 => 94554.15
8 => 99754.62
9 => 105241.13
10 => 111029.39
111029.389793
>>> import interest
>>> interest.trace = 0
>>> calc(65000, 5.5, 10)
111029.389793
def calc(principal, interest, years):
interest = interest / 100.0
for y in range(years):
earnings = principal * interest
principal = principal + earnings
if trace: print y+1, '(+%d)' % earnings, '=> %.2f' % principal
return principal
>>> interest.trace = 1
>>> calc(65000, 5.5, 10)
1 (+3575) => 68575.00
2 (+3771) => 72346.63
3 (+3979) => 76325.69
4 (+4197) => 80523.60
5 (+4428) => 84952.40
6 (+4672) => 89624.78
7 (+4929) => 94554.15
8 (+5200) => 99754.62
9 (+5486) => 105241.13
10 (+5788) => 111029.39
111029.389793
** Page 269 *******************************************************************
#!/usr/bin/env python
# find a free modem to dial out on
import glob, os, string
LOCKS = "/var/spool/locks/"
locked = [0] * 10
for lockname in glob.glob(LOCKS + "LCK*modem*"): # find locked modems
print "Found lock:", lockname
locked[string.atoi(lockname[-1])] = 1 # 0..9 at end of name
print 'free: ',
for i in range(10): # report, dial-out
if not locked[i]: print i,
print
for i in range(10):
if not locked[i]:
if raw_input("Try %d? " % i) == 'y':
os.system("kermit -m hayes -l /dev/modem%d -b 19200 -S" % i)
if raw_input("More? ") != 'y': break
** Page 270 *******************************************************************
# file rolo.py
#!/usr/bin/env python
# An interactive rolodex
import string, sys, pickle, cmd
class Rolodex(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self) # initialize the base class
self.prompt = "Monty's Friends: " # customize the prompt
self.people = {} # at first, we know nobody
def help_add(self):
print "Adds an entry (specify a name)"
def do_add(self, name):
if name == "": name = raw_input("Enter Name: ")
phone = raw_input("Enter Phone Number for "+ name+": ")
self.people[name] = phone # add phone number for name
def help_find(self):
print "Find an entry (specify a name)"
def do_find(self, name):
if name == "": name = raw_input("Enter Name: ")
if self.people.has_key(name):
print "The number for %s is %s." % (name, self.people[name])
else:
print "We have no record for %s." % (name,)
def help_list(self):
print "Prints the contents of the directory"
def do_list(self, line):
names = self.people.keys() # the keys are the names
if names == []: return # if there are no names, exit
names.sort() # we want them in alphabetic order
print '='*41
for name in names:
print string.rjust(name, 20), ":", string.ljust(self.people[name], 20)
print '='*41
def help_EOF(self):
print "Quits the program"
def do_EOF(self, line):
sys.exit()
def help_save(self):
print "save the current state of affairs"
def do_save(self, filename):
if filename == "": filename = raw_input("Enter filename: ")
saveFile = open(filename, 'w')
pickle.dump(self.people, saveFile)
def help_load(self):
print "load a directory"
def do_load(self, filename):
if filename == "": filename = raw_input("Enter filename: ")
saveFile = open(filename, 'r')
self.people = pickle.load(saveFile) # note that this will override
# any existing people directory
if __name__ == '__main__': # this way the module can be
rolo = Rolodex() # imported by other programs as well
rolo.cmdloop()
% python rolo.py
Monty's Friends: help
Documented commands (type help ):
========================================
EOF add find list load
save
Undocumented commands:
======================
help
lpython/unix/solutions/ 000777 000000 000000 00000000000 06713513710 011246 lpython/unix/solutions/chapter3.txt 001777 000000 000000 00000003675 06713575374 013562 1. Coding basic loops. ********************************************************
>>> S = 'spam'
>>> for c in S:
... print ord(c)
...
115
112
97
109
>>> x = 0
>>> for c in S: x = x + ord(c)
...
>>> x
433
>>> x = []
>>> for c in S: x.append(ord(c))
...
>>> x
[115, 112, 97, 109]
>>> map(ord, S)
[115, 112, 97, 109]
2. Backslash characters. ******************************************************
>>> for i in range(50):
>>> print 'hello %d\n\a' % i
3. Sorting dictionaries. ******************************************************
>>> D = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}
>>> D
{'f': 6, 'c': 3, 'a': 1, 'g': 7, 'e': 5, 'd': 4, 'b': 2}
>>>
>>> keys = D.keys()
>>> keys.sort()
>>> for key in keys:
... print key, '=>', D[key]
...
a => 1
b => 2
c => 3
d => 4
e => 5
f => 6
g => 7
4. Program logic alternatives. ************************************************
start)
# power.py
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
found = i = 0
while not found and i < len(L):
if 2 ** X == L[i]:
found = 1
else:
i = i+1
if found:
print 'at index', i
else:
print X, 'not found'
C:\book\tests> python power.py
at index 5
a)
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
i = 0
while i < len(L):
if 2 ** X == L[i]:
print 'at index', i
break
i = i+1
else:
print X, 'not found'
b)
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
for p in L:
if (2 ** X) == p:
print (2 ** X), 'was found at', L.index(p)
break
else:
print X, 'not found'
c)
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
d)
X = 5
L = []
for i in range(7): L.append(2 ** i)
print L
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
e)
X = 5
L = map(lambda x: 2**x, range(7))
print L
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
lpython/unix/solutions/chapter10.txt 001777 000000 000000 00000006040 06713575374 013625 1. Faking the Web. ************************************************************
class FormData:
def __init__(self, dict):
for k, v in dict.items():
setattr(self, k, v)
class FeedbackData(FormData):
""" A FormData generated by the comment.html form. """
fieldnames = ('name', 'address', 'email', 'type', 'text')
def __repr__(self):
return "%(type)s from %(name)s on %(time)s" % vars(self)
fake_entries = [
{'name': "John Doe",
'address': '500 Main St., SF CA 94133',
'email': 'john@sf.org',
'type': 'comment',
'text': 'Great toothpaste!'},
{'name': "Suzy Doe",
'address': '500 Main St., SF CA 94133',
'email': 'suzy@sf.org',
'type': 'complaint',
'text': "It doesn't taste good when I kiss John!"},
]
DIRECTORY = r'C:\complaintdir'
if __name__ == '__main__':
import tempfile, pickle, time
tempfile.tempdir = DIRECTORY
for fake_entry in fake_entries:
data = FeedbackData(fake_entry)
filename = tempfile.mktemp()
data.time = time.asctime(time.localtime(time.time()))
pickle.dump(data, open(filename, 'w'))
2. Cleaning up. ***************************************************************
if __name__ == '__main__':
import os, pickle
CACHEFILE = 'C:\cache.pik'
from feedback import DIRECTORY#, FormData, FeedbackData
if os.path.exists(CACHEFILE):
processed_files = pickle.load(open(CACHEFILE))
else:
processed_files = []
for filename in os.listdir(DIRECTORY):
if filename in processed_files: continue # skip this filename
processed_files.append(filename)
data = pickle.load(open(os.path.join(DIRECTORY, filename)))
if data.type == 'complaint':
print "Printing letter for %(name)s." % vars(data)
print_formletter(data)
else:
print "Got comment from %(name)s, skipping printing." % vars(data)
pickle.dump(processed_file, open(CACHEFILE, 'w')
3. Adding parametric plotting to grapher.py. **********************************
# this one's for mathematically-inclined readers only
if not hasattr(self.data[0], '__len__'): # it's probably a number (1D)
xmin, xmax = 0, N-1
# code from existing program, up to graphics.fillPolygon(xs, ys, len(xs))
elif len(self.data[0]) == 2: # we'll only deal with 2-D
xmin = reduce(min, map(lambda d: d[0], self.data))
xmax = reduce(max, map(lambda d: d[0], self.data))
ymin = reduce(min, map(lambda d: d[1], self.data))
ymax = reduce(max, map(lambda d: d[1], self.data))
zero_y = y_offset - int(-ymin/(ymax-ymin)*height)
zero_x = x_offset + int(-xmin/(xmax-xmin)*width)
for i in range(N):
xs[i] = x_offset + int((self.data[i][0]-xmin)/(xmax-xmin)*width)
ys[i] = y_offset - int((self.data[i][1]-ymin)/(ymax-ymin)*height)
graphics.color = self.color
if self.style == "Line":
graphics.drawPolyline(xs, ys, len(xs))
else:
xs.append(xs[0]); ys.append(ys[0])
graphics.fillPolygon(xs, ys, len(xs))
lpython/unix/solutions/chapter2.txt 001777 000000 000000 00000011641 06713575374 013551 1. The basics. ****************************************************************
## Numbers
>>> 2 ** 16 # 2 raised to the power 16
65536
>>> 2 / 5, 2 / 5.0 # integer / truncates, float / doesn't
(0, 0.4)
## Strings
>>> "spam" + "eggs" # concatenation
'spameggs'
>>> S = "ham"
>>> "eggs " + S
'eggs ham'
>>> S * 5 # repetition
'hamhamhamhamham'
>>> S[:0] # an empty slice at the front--[0:0]
''
>>> "green %s and %s" % ("eggs", S) # formatting
'green eggs and ham'
## Tuples
>>> ('x',)[0] # indexing a single-item tuple
'x'
>>> ('x', 'y')[1] # indexing a 2-item tuple
'y'
## Lists
>>> L = [1,2,3] + [4,5,6] # list operations
>>> L, L[:], L[:0], L[-2], L[-2:]
([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6], [], 5, [5, 6])
>>> ([1,2,3]+[4,5,6])[2:4]
[3, 4]
>>> [L[2], L[3]] # fetch from offsets, store in a list
[3, 4]
>>> L.reverse(); L # method: reverse list in-place
[6, 5, 4, 3, 2, 1]
>>> L.sort(); L # method: sort list in-place
[1, 2, 3, 4, 5, 6]
>>> L.index(4) # method: offset of first 4 (search)
3
## Dictionaries
>>> {'a':1, 'b':2}['b'] # index a dictionary by key
2
>>> D = {'x':1, 'y':2, 'z':3}
>>> D['w'] = 0 # create a new entry
>>> D['x'] + D['w']
1
>>> D[(1,2,3)] = 4 # a tuple used as a key (immutable)
>>> D
{'w': 0, 'z': 3, 'y': 2, (1, 2, 3): 4, 'x': 1}
>>> D.keys(), D.values(), D.has_key((1,2,3)) # methods
(['w', 'z', 'y', (1, 2, 3), 'x'], [0, 3, 2, 4, 1], 1)
## Empties
>>> [[]], ["",[],(),{},None] # lots of nothings
([[]], ['', [], (), {}, None])
2. Indexing and slicing. ******************************************************
>>> L = [1, 2, 3, 4]
>>> L[4]
Traceback (innermost last):
File "", line 1, in ?
IndexError: list index out of range
>>> L[-1000:100]
[1, 2, 3, 4]
>>> L[3:1]
[]
>>> L
[1, 2, 3, 4]
>>> L[3:1] = ['?']
>>> L
[1, 2, 3, '?', 4]
3. Indexing, slicing, and del. ************************************************
>>> L = [1,2,3,4]
>>> L[2] = []
>>> L
[1, 2, [], 4]
>>> L[2:3] = []
>>> L
[1, 2, 4]
>>> del L[0]
>>> L
[2, 4]
>>> del L[1:]
>>> L
[2]
>>> L[1:2] = 1
Traceback (innermost last):
File "", line 1, in ?
TypeError: illegal argument type for built-in operation
4. Tuple assignment. **********************************************************
>>> X = 'spam'
>>> Y = 'eggs'
>>> X, Y = Y, X
>>> X
'eggs'
>>> Y
'spam'
5. Dictionary keys. ***********************************************************
>>> D = {}
>>> D[1] = 'a'
>>> D[2] = 'b'
>>> D[(1, 2, 3)] = 'c'
>>> D
{1: 'a', 2: 'b', (1, 2, 3): 'c'}
6. Dictionary indexing. *******************************************************
>>> D = {'a':1, 'b':2, 'c':3}
>>> D['a']
1
>>> D['d']
Traceback (innermost last):
File "", line 1, in ?
KeyError: d
>>> D['d'] = 4
>>> D
{'b': 2, 'd': 4, 'a': 1, 'c': 3}
>>>
>>> L = [0,1]
>>> L[2]
Traceback (innermost last):
File "", line 1, in ?
IndexError: list index out of range
>>> L[2] = 3
Traceback (innermost last):
File "", line 1, in ?
IndexError: list assignment index out of range
7. Generic operations. ********************************************************
>>> "x" + 1
Traceback (innermost last):
File "", line 1, in ?
TypeError: illegal argument type for built-in operation
>>>
>>> {} + {}
Traceback (innermost last):
File "", line 1, in ?
TypeError: bad operand type(s) for +
>>>
>>> [].append(9)
>>> "".append('s')
Traceback (innermost last):
File "", line 1, in ?
AttributeError: attribute-less object
>>>
>>> {}.keys()
[]
>>> [].keys()
Traceback (innermost last):
File "", line 1, in ?
AttributeError: keys
>>>
>>> [][:]
[]
>>> ""[:]
''
8. String indexing. ***********************************************************
>>> S = "spam"
>>> S[0][0][0][0][0]
's'
>>> L = ['s', 'p']
>>> L[0][0][0]
's'
9. Immutable types. ***********************************************************
>>> S = "spam"
>>> S = S[0] + 'l' + S[2:]
>>> S
'slam'
>>> S = S[0] + 'l' + S[2] + S[3]
>>> S
'slam'
10. Nesting. ******************************************************************
>>> me = {'name':('mark', 'e', 'lutz'), 'age':'?', 'job':'engineer'}
>>> me['job']
'engineer'
>>> me['name'][2]
'lutz'
11. Files. ********************************************************************
% cat maker.py
file = open('myfile.txt', 'w')
file.write('Hello file world!\n')
file.close() # close not always needed
% cat reader.py
file = open('myfile.txt', 'r')
print file.read()
% python maker.py
% python reader.py
Hello file world!
% ls -l myfile.txt
-rwxrwxrwa 1 0 0 19 Apr 13 16:33 myfile.txt
12. The dir function revisited. ***********************************************
>>> [].__methods__
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort']
>>> dir([])
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort']
lpython/unix/solutions/chapter1.txt 001777 000000 000000 00000002173 06713575374 013550 1. Interaction. ***************************************************************
% python
copyright information lines...
>>> "Hello World!"
'Hello World!'
>>> #
2. Programs. ******************************************************************
% cat module1.py
print 'Hello module world!'
% python module1.py
Hello module world!
3. Modules. *******************************************************************
% python
>>> import module1
Hello module world!
>>>
4. Scripts. *******************************************************************
% cat module1.py
#!/usr/local/bin/python (or #!/usr/bin/env python)
print 'Hello module world!'
% chmod +x module1.py
% module1.py
Hello module world!
5. Errors. ********************************************************************
% python
>>> 1 / 0
Traceback (innermost last):
File "", line 1, in ?
ZeroDivisionError: integer division or modulo
>>>
>>> x
Traceback (innermost last):
File "", line 1, in ?
NameError: x
6. Breaks. ********************************************************************
% python
>>> L = [1, 2]
>>> L.append(L)
lpython/unix/solutions/chapter4.txt 001777 000000 000000 00000006434 06713575374 013557 1. Basics. ********************************************************************
% python
>>> def func(x): print x
...
>>> func("spam")
spam
>>> func(42)
42
>>> func([1, 2, 3])
[1, 2, 3]
>>> func({'food': 'spam'})
{'food': 'spam'}
2. Arguments. *****************************************************************
% cat mod.py
def adder(x, y):
return x + y
print adder(2, 3)
print adder('spam', 'eggs')
print adder(['a', 'b'], ['c', 'd'])
% python mod.py
5
spameggs
['a', 'b', 'c', 'd']
3. varargs. *******************************************************************
% cat adders.py
def adder1(*args):
print 'adder1',
if type(args[0]) == type(0): # integer?
sum = 0 # init to zero
else: # else sequence:
sum = args[0][:0] # use empty slice of arg1
for arg in args:
sum = sum + arg
return sum
def adder2(*args):
print 'adder2',
sum = args[0] # init to arg1
for next in args[1:]:
sum = sum + next # add items 2..N
return sum
for func in (adder1, adder2):
print func(2, 3, 4)
print func('spam', 'eggs', 'toast')
print func(['a', 'b'], ['c', 'd'], ['e', 'f'])
% python adders.py
adder1 9
adder1 spameggstoast
adder1 ['a', 'b', 'c', 'd', 'e', 'f']
adder2 9
adder2 spameggstoast
adder2 ['a', 'b', 'c', 'd', 'e', 'f']
4. Keywords. ******************************************************************
% cat mod.py
def adder(good=1, bad=2, ugly=3):
return good + bad + ugly
print adder()
print adder(5)
print adder(5, 6)
print adder(5, 6, 7)
print adder(ugly=7, good=6, bad=5)
% python mod.py
6
10
14
18
18
5. and 6. *********************************************************************
% cat dict.py
def copyDict(old):
new = {}
for key in old.keys():
new[key] = old[key]
return new
def addDict(d1, d2):
new = {}
for key in d1.keys():
new[key] = d1[key]
for key in d2.keys():
new[key] = d2[key]
return new
% python
>>> from dict import *
>>> d = {1:1, 2:2}
>>> e = copyDict(d)
>>> d[2] = '?'
>>> d
{1: 1, 2: '?'}
>>> e
{1: 1, 2: 2}
>>> x = {1:1}
>>> y = {2:2}
>>> z = addDict(x, y)
>>> z
{1: 1, 2: 2}
7. More argument matching examples. *******************************************
# put these in a module and ftech with "from mod import *"
def f1(a, b): print a, b # normal args
def f2(a, *b): print a, b # positional varargs
def f3(a, **b): print a, b # keyword varargs
def f4(a, *b, **c): print a, b, c # mixed modes
def f5(a, b=2, c=3): print a, b, c # defaults
def f6(a, b=2, *c): print a, b, c # defaults + positional varargs
% python
>>> f1(1, 2) # matched by position (order matters)
1 2
>>> f1(b=2, a=1) # matched by name (order doesn't matter)
1 2
>>> f2(1, 2, 3) # extra positionals collected in a tuple
1 (2, 3)
>>> f3(1, x=2, y=3) # extra keywords collected in a dictionary
1 {'x': 2, 'y': 3}
>>> f4(1, 2, 3, x=2, y=3) # extra of both kinds
1 (2, 3) {'x': 2, 'y': 3}
>>> f5(1) # both defaults kick in
1 2 3
>>> f5(1, 4) # only one default used
1 4 3
>>> f6(1) # one argument: matches "a"
1 2 ()
>>> f6(1, 3, 4) # extra positional collected
1 3 (4,)
lpython/unix/solutions/chapter5.txt 001777 000000 000000 00000004233 06713575374 013553 1. Basics, import. ************************************************************
% cat mymod.py
def countLines(name):
file = open(name, 'r')
return len(file.readlines())
def countChars(name):
return len(open(name, 'r').read())
def test(name): # or pass file object
return countLines(name), countChars(name) # or return a dictionary
% python
>>> import mymod
>>> mymod.test('mymod.py')
(10, 291)
% cat mymod2.py
def countLines(file):
file.seek(0) # rewind to start of file
return len(file.readlines())
def countChars(file):
file.seek(0) # ditto (rewind if needed)
return len(file.read())
def test(name):
file = open(name, 'r') # pass file object
return countLines(file), countChars(file) # only open file once
>>> import mymod2
>>> mymod2.test("mymod2.py")
(11, 392)
2. from/from*. ****************************************************************
% python
>>> from mymod import *
>>> countChars("mymod.py")
291
3. __main__. ******************************************************************
% cat mymod.py
def countLines(name):
file = open(name, 'r')
return len(file.readlines())
def countChars(name):
return len(open(name, 'r').read())
def test(name): # or pass file object
return countLines(name), countChars(name) # or return a dictionary
if __name__ == '__main__':
print test('mymod.py')
% python mymod.py
(13, 346)
4. Nested imports. ************************************************************
% cat myclient.py
from mymod import countLines
from mymod import countChars
print countLines('mymod.py'), countChars('mymod.py')
% python myclient.py
13 346
% cat mod1.py
somename = 42
% cat collector.py
from mod1 import * # collect lots of names here
from mod2 import * # from assigns to my names
from mod3 import *
>>> from collector import somename
5. Reload. ********************************************************************
# see chapter examples file
6. Circular imports. **********************************************************
# see chapter examples file
lpython/unix/solutions/chapter6.txt 001777 000000 000000 00000022214 06713575374 013553 1. The basics. ****************************************************************
% cat adder.py
class Adder:
def add(self, x, y):
print 'not implemented!'
def __init__(self, start=[]):
self.data = start
def __add__(self, other):
return self.add(self.data, other) # or in subclasses--return type?
class ListAdder(Adder):
def add(self, x, y):
return x + y
class DictAdder(Adder):
def add(self, x, y):
new = {}
for k in x.keys(): new[k] = x[k]
for k in y.keys(): new[k] = y[k]
return new
% python
>>> from adder import *
>>> x = Adder()
>>> x.add(1, 2)
not implemented!
>>> x = ListAdder()
>>> x.add([1], [2])
[1, 2]
>>> x = DictAdder()
>>> x.add({1:1}, {2:2})
{1: 1, 2: 2}
>>> x = Adder([1])
>>> x + [2]
not implemented!
>>>
>>> x = ListAdder([1])
>>> x + [2]
[1, 2]
>>> [2] + x
Traceback (innermost last):
File "", line 1, in ?
TypeError: __add__ nor __radd__ defined for these operands
2. Operator overloading. ******************************************************
% cat mylist.py
class MyList:
def __init__(self, start):
#self.wrapped = start[:] # copy start: no sideeffects
self.wrapped = [] # make sure it's a list here
for x in start: self.wrapped.append(x)
def __add__(self, other):
return MyList(self.wrapped + other)
def __mul__(self, time):
return MyList(self.wrapped * time)
def __getitem__(self, offset):
return self.wrapped[offset]
def __len__(self):
return len(self.wrapped)
def __getslice__(self, low, high):
return MyList(self.wrapped[low:high])
def append(self, node):
self.wrapped.append(node)
def __getattr__(self, name): # other members--sort/reverse/etc.
return getattr(self.wrapped, name)
def __repr__(self):
return `self.wrapped`
if __name__ == '__main__':
x = MyList('spam')
print x
print x[2]
print x[1:]
print x + ['eggs']
print x * 3
x.append('a')
x.sort()
for c in x: print c,
% python mylist.py
['s', 'p', 'a', 'm']
a
['p', 'a', 'm']
['s', 'p', 'a', 'm', 'eggs']
['s', 'p', 'a', 'm', 's', 'p', 'a', 'm', 's', 'p', 'a', 'm']
a a m p s
3. Subclassing. ***************************************************************
% cat mysub.py
from mylist import MyList
class MyListSub(MyList):
calls = 0 # shared by instances
def __init__(self, start):
self.adds = 0 # varies in each instance
MyList.__init__(self, start)
def __add__(self, other):
MyListSub.calls = MyListSub.calls + 1 # class-wide counter
self.adds = self.adds + 1 # per instance counts
return MyList.__add__(self, other)
def stats(self):
return self.calls, self.adds # all adds, my adds
if __name__ == '__main__':
x = MyListSub('spam')
y = MyListSub('foo')
print x[2]
print x[1:]
print x + ['eggs']
print x + ['toast']
print y + ['bar']
print x.stats()
% python mysub.py
a
['p', 'a', 'm']
['s', 'p', 'a', 'm', 'eggs']
['s', 'p', 'a', 'm', 'toast']
['f', 'o', 'o', 'bar']
(3, 2)
4. Metaclass methods. *********************************************************
>>> class Meta:
... def __getattr__(self, name): print 'get', name
... def __setattr__(self, name, value): print 'set', name, value
...
>>> x = Meta()
>>> x.append
get append
>>> x.spam = "pork"
set spam pork
>>>
>>> x + 2
get __coerce__
Traceback (innermost last):
File "", line 1, in ?
TypeError: call of non-function
>>>
>>> x[1]
get __getitem__
Traceback (innermost last):
File "", line 1, in ?
TypeError: call of non-function
>>> x[1:5]
get __len__
Traceback (innermost last):
File "", line 1, in ?
TypeError: call of non-function
5. Set objects. ***************************************************************
# make sure to put the Set class code from the chapter examples
# file into a file "set.py", in a directory on your PYTHONPATH
% python
>>> from set import Set
>>> x = Set([1,2,3,4]) # runs __init__
>>> y = Set([3,4,5])
>>> x & y # __and__, intersect, then __repr__
Set:[3, 4]
>>> x | y # __or__, union, then __repr__
Set:[1, 2, 3, 4, 5]
>>> z = Set("hello") # __init__ removes duplicates
>>> z[0], z[-1] # __getitem__
('h', 'o')
>>> for c in z: print c, # __getitem__
...
h e l o
>>> len(z), z # __len__, __repr__
(4, Set:['h', 'e', 'l', 'o'])
>>> z & "mello", z | "mello"
(Set:['e', 'l', 'o'], Set:['h', 'e', 'l', 'o', 'm'])
# multiset.py: multiple-operand extension subclass
from set import Set
class MultiSet(Set):
"""
inherits all Set names, but extends intersect
and union to support multiple operands; note
that "self" is still the first argument (stored
in the *args argument now); also note that the
inherited & and | operators call the new methods
here with 2 arguments, but processing more than
2 requires a method call, not an expression:
"""
def intersect(self, *others):
res = []
for x in self: # scan first sequence
for other in others: # for all other args
if x not in other: break # item in each one?
else: # no: break out of loop
res.append(x) # yes: add item to end
return Set(res)
def union(*args): # self is args[0]
res = []
for seq in args: # for all args
for x in seq: # for all nodes
if not x in res:
res.append(x) # add new items to result
return Set(res)
>>> from multiset import *
>>> x = MultiSet([1,2,3,4])
>>> y = MultiSet([3,4,5])
>>> z = MultiSet([0,1,2])
>>> x & y, x | y # 2 operands
(Set:[3, 4], Set:[1, 2, 3, 4, 5])
>>> x.intersect(y, z) # 3 operands
Set:[]
>>> x.union(y, z)
Set:[1, 2, 3, 4, 5, 0]
>>> x.intersect([1,2,3], [2,3,4], [1,2,3]) # 4 operands
Set:[2, 3]
>>> x.union(range(10)) # non-MultiSets work too
Set:[1, 2, 3, 4, 0, 5, 6, 7, 8, 9]
6. Class tree links. **********************************************************
class Lister:
def __repr__(self):
return ("" %
(self.__class__.__name__, # my class's name
self.supers(), # my class's supers
id(self), # my address
self.attrnames()) ) # name=value list
def attrnames(self):
# Unchanged...
def supers(self):
result = ""
first = 1
for super in self.__class__.__bases__: # one level up from class
if not first:
result = result + ", "
first = 0
result = result + super.__name__
return result
C:\python\examples> python testmixin.py
7. Composition. ***************************************************************
# starting point...
class Lunch:
def __init__(self) # make/embed Customer and Employee
def order(self, foodName) # start a Customer order simulation
def result(self) # ask the Customer what kind of Food it has
class Customer:
def __init__(self) # initialize my food to None
def placeOrder(self, foodName, employee) # place order with an Employee
def printFood(self) # print the name of my food
class Employee:
def takeOrder(self, foodName) # return a Food, with requested name
class Food:
def __init__(self, name) # store food name
# solution...
# put all this code in a module file called lunch.py;
# it's run, not imported, so it need not be in PYTHONPATH
class Lunch:
def __init__(self):
# make/embed Customer and Employee
self.cust = Customer()
self.empl = Employee()
def order(self, foodName):
# start a Customer order simulation
self.cust.placeOrder(foodName, self.empl)
def result(self):
# ask the Customer what kind of Food it has
self.cust.printFood()
class Customer:
def __init__(self):
# initialize my food to None
self.food = None
def placeOrder(self, foodName, employee):
# place order with an Employee
self.food = employee.takeOrder(foodName)
def printFood(self):
# print the name of my food
print self.food.name
class Employee:
def takeOrder(self, foodName):
# return a Food, with requested name
return Food(foodName)
class Food:
def __init__(self, name):
# store food name
self.name = name
if __name__ == '__main__':
x = Lunch()
x.order('burritos')
x.result()
x.order('pizza')
x.result()
% python lunch.py
burritos
pizza
lpython/unix/solutions/chapter7.txt 001777 000000 000000 00000002512 06713575374 013553 1. Try/except. ****************************************************************
% cat oops.py
def oops():
raise IndexError
def doomed():
try:
oops()
except IndexError:
print 'caught an index error!'
else:
print 'no error caught...'
if __name__ == '__main__': doomed()
% python oops.py
caught an index error!
2. Exception lists. ***********************************************************
% cat oops.py
MyError = 'hello'
def oops():
raise MyError, 'world'
def doomed():
try:
oops()
except IndexError:
print 'caught an index error!'
except MyError, data:
print 'caught error:', MyError, data
else:
print 'no error caught...'
if __name__ == '__main__':
doomed()
% python oops.py
caught error: hello world
3. Error handling. ************************************************************
% cat safe2.py
import sys, traceback
def safe(entry, *args):
try:
apply(entry, args) # catch everything else
except:
traceback.print_exc()
print 'Got', sys.exc_type, sys.exc_value
import oops
safe(oops.oops)
% python safe2.py
Traceback (innermost last):
File "safe2.py", line 5, in safe
apply(entry, args) # catch everything else
File "oops.py", line 4, in oops
raise MyError, 'world'
hello: world
Got hello world
lpython/unix/solutions/chapter8.txt 001777 000000 000000 00000011365 06713575374 013562 1. Describing a directory. ****************************************************
import os, sys, stat
def describedir(start):
def describedir_helper(arg, dirname, files):
""" Helper function for describing directories """
print "Directory %s has files:" % dirname
for file in files:
# find the full path to the file (directory + filename)
fullname = os.path.join(dirname, file)
if os.path.isdir(fullname):
# if it's a directory, say so; no need to find the size
print ' '+ file + ' (subdir)'
else:
# find out the size, and print the info.
size = os.stat(fullname)[stat.ST_SIZE]
print ' '+file+' size=' + `size`
# Start the 'walk'.
os.path.walk(start, describedir_helper, None)
>>> import describedir
>>> describedir.describedir2('testdir')
Directory testdir has files:
describedir.py size=939
subdir1 (subdir)
subdir2 (subdir)
Directory testdir\subdir1 has files:
makezeros.py size=125
subdir3 (subdir)
Directory testdir\subdir1\subdir3 has files:
Directory testdir\subdir2 has files:
2. Modifying the prompt. ******************************************************
# modifyprompt.py
import sys, os
class MyPrompt:
def __init__(self, subprompt='>>> '):
self.lineno = 0
self.subprompt = subprompt
def __repr__(self):
self.lineno = self.lineno + 1
return os.getcwd()+'|%d'%(self.lineno)+self.subprompt
sys.ps1 = MyPrompt()
sys.ps2 = MyPrompt('... ')
h:\David\book> python -i modifyprompt.py
h:\David\book|1>>> x = 3
h:\David\book|2>>> y = 3
h:\David\book|3>>> def foo():
h:\David\book|3... x = 3 # the secondary prompt is supported
h:\David\book|3...
h:\David\book|4>>> import os
h:\David\book|5>>> os.chdir('..')
h:\David|6>>> # note the prompt changed!
3. Avoiding regular expressions. **********************************************
import string
file = open('pepper.txt')
text = file.read()
paragraphs = string.split(text, '\n\n')
def find_indices_for(big, small):
indices = []
cum = 0
while 1:
index = string.find(big, small)
if index == -1:
return indices
indices.append(index+cum)
big = big[index+len(small):]
cum = cum + index + len(small)
def fix_paragraphs_with_word(paragraphs, word):
lenword = len(word)
for par_no in range(len(paragraphs)):
p = paragraphs[par_no]
wordpositions = find_indices_for(p, word)
if wordpositions == []: return
for start in wordpositions:
# look for 'pepper' ahead
indexpepper = string.find(p, 'pepper')
if indexpepper == -1: return -1
if string.strip(p[start:indexpepper]) != '':
# something other than whitespace in between!
continue
where = indexpepper+len('pepper')
if p[where:where+len('corn')] == 'corn':
# it's immediately followed by 'corn'!
continue
if string.find(p, 'salad') < where:
# it's not followed by 'salad'
continue
# Finally! we get to do a change!
p = p[:start] + 'bell' + p[start+lenword:]
paragraphs[par_no] = p # change mutable argument!
fix_paragraphs_with_word(paragraphs, 'red')
fix_paragraphs_with_word(paragraphs, 'green')
for paragraph in paragraphs:
print paragraph+'\n'
4. Wrapping a text file with a class. *****************************************
import string
class FileStrings:
def __init__(self, filename=None, data=None):
if data == None:
self.data = open(filename).read()
else:
self.data = data
self.paragraphs = string.split(self.data, '\n\n')
self.lines = string.split(self.data, '\n')
self.words = string.split(self.data)
def __repr__(self):
return self.data
def paragraph(self, index):
return FileStrings(data=self.paragraphs[index])
def line(self, index):
return FileStrings(data=self.lines[index])
def word(self, index):
return self.words[index]
>>> from FileStrings import FileStrings
>>> bigtext = FileStrings('pepper.txt')
>>> print bigtext.paragraph(0)
This is a paragraph that mentions bell peppers multiple times. For
one, here is a red Pepper and dried tomato salad recipe. I don't like
to use green peppers in my salads as much because they have a harsher
flavor.
>>> print bigtext.line(0)
This is a paragraph that mentions bell peppers multiple times. For
>>> print bigtext.line(-4)
aren't peppers, they're chilies, but would you rather have a good cook
>>> print bigtext.word(-4)
botanist
>>> print bigtext.paragraph(2).line(2).word(-1)
'cook'
lpython/unix/solutions/chapter9.txt 001777 000000 000000 00000005310 06713575374 013554 1. Redirecting stdout. ********************************************************
import fileinput, sys, string # no change here
sys.stdout = open(sys.argv[-1], 'w') # open the output file
del sys.argv[-1] # we've dealt with this argument
... # continue as before
2. Writing a simple shell. ****************************************************
import cmd, os, string, sys, shutil
class UnixShell(cmd.Cmd):
def do_EOF(self, line):
""" The do_EOF command is called when the user presses Ctrl-D (unix)
or Ctrl-Z (PC). """
sys.exit()
def help_ls(self):
print "ls : list the contents of the specified directory"
print " (current directory used by default)"
def do_ls(self, line):
# 'ls' by itself means 'list current directory'
if line == '': dirs = [os.curdir]
else: dirs = string.split(line)
for dirname in dirs:
print 'Listing of %s:' % dirname
print string.join(os.listdir(dirname), '\n')
def do_cd(self, dirname):
# 'cd' by itself means 'go home'
if dirname == '': dirname = os.environ['HOME']
os.chdir(dirname)
def do_mkdir(self, dirname):
os.mkdir(dirname)
def do_cp(self, line):
words = string.split(line)
sourcefiles,target = words[:-1], words[-1] # target could be a dir
for sourcefile in sourcefiles:
shutil.copy(sourcefile, target)
def do_mv(self, line):
source, target = string.split(line)
os.rename(source, target)
def do_rm(self, line):
map(os.remove, string.split(line))
class DirectoryPrompt:
def __repr__(self):
return os.getcwd()+'> '
cmd.PROMPT = DirectoryPrompt()
shell = UnixShell()
shell.cmdloop()
h:\David\book> python -i shell.py
h:\David\book> cd ../tmp
h:\David\tmp> ls
Listing of .:
api
ERREUR.DOC
ext
giant_~1.jpg
icons
index.html
lib
pythlp.hhc
pythlp.hhk
ref
tut
h:\David\tmp> cd ..
h:\David> cd tmp
h:\David\tmp> cp index.html backup.html
h:\David\tmp> rm backup.html
h:\David\tmp> ^Z
3. Understanding map, reduce and filter. **************************************
def map2(function, sequence):
if function is None: return list(sequence)
retvals = []
for element in sequence:
retvals.append(function(element))
return retvals
def reduce2(function, sequence):
arg1 = function(sequence[0])
for arg2 in sequence[1:]:
arg1 = function(arg1, arg2)
return arg1
def filter2(function, sequence):
retvals = []
for element in sequence:
if (function is None and element) or function(element):
retvals.append(element)
return retvals
lpython/dos/ 000777 000000 000000 00000000000 06713575720 007022 lpython/dos/lp-code-readme.txt 001777 000000 000000 00000006540 06713575720 012357 File: lp-code-readme.txt
Home: http://rmi.net/~lutz/examples-lp.html
Date: May 3, 1999
-------------------------------------------
About this file
This tar file contains source code for all the examples
and exercise solutions in the book _Learning Python_.
We're providing it as an additional resource, to help
you save typing time as you work through the book.
Using this file
To use this file, simply download it to your machine, and
untar to create the directory structure and files. To untar
on UNIX and UNIX-like platforms, put the downloaded file in
a directory that is easy for you to access (e.g., in your
home directory), and execute a command like:
tar xvf lp-code.tar
On other machines, other tools may have the same effect
(e.g., the winzip program for MS-Windows knows how to untar
tar files too). Untarring the file will generate a new
subdirectory structure that looks like this:
lpython/ --top level directory
lpython/lp-code-readme.txt --this file
lpython/unix --version with UNIX-style newlines
lpython/unix/examples --code for examples in the chapters
lpython/unix/solutions --code for exercise solutions
lpython/dos --version with MS-DOS newlines
lpython/dos/examples --code for examples in the chapters
lpython/dos/solutions --code for exercise solutions
This structure appears in the directory where you ran the
untar operation, and of course you should think "\" instead
of "/" if you're on a DOS or Windows machine.
Once you've untarred the files, you wind up with a set of
text files on your machine, which you can view with your
favorite text editor. To run the code, simply cut-and-paste
the program text into other text files (aka modules), or
Python's interactive command line; see chapter 1 for details.
Why unix and dos directories?
The "unix" and "dos" directories contain identical data, but
files on the "unix" branch have UNIX-style end-of-line, and
"dos" branch files have the MS-DOS end-of-line. Either form
can sometimes look odd when edited on the other kind of platform,
so we provided both as a convenience. If you don't know what the
difference is, just use the version that looks best on your
platform and text editor.
What's in the text files?
Within the "examples" and "solutions" subdirectories, you'll
find one text file per chapter. For example:
lpython/unix/examples/chapter1.txt
lpython/unix/examples/chapter2.txt
lpython/unix/examples/chapter3.txt
and so on. In the "solutions" directory, the per-chapter text
files contain code snippets labeled with exercise numbers, and
correspond to the items in appendix C. In "examples", the code
snippets are labeled with the page number they appear on or near.
Some code listings are from interactive sessions; to run them
yourself, cut and paste all but the ">>>" or "..." prompts.
Other hints
All of the above will make more sense once you start poking
around the source files. And remember, be sure to see the
resources listed in the Preface of the book for updates and
book-related contact points.
lpython/dos/todos.py 001777 000000 000000 00000000402 06713525162 010524 import string, sys, os
# os.mkdir("converted")
for f in sys.argv[1:]:
print f
i = open(f, 'r')
t = i.read()
i.close()
s = string.join(string.split(t, "\012"), "\015\012")
o = open(f, 'w')
o.write(s)
o.close()
lpython/dos/solutions/ 000777 000000 000000 00000000000 06671363306 011057 lpython/dos/solutions/chapter1.txt 001777 000000 000000 00000002264 06713143040 013330 1. Interaction. ***************************************************************
% python
copyright information lines...
>>> "Hello World!"
'Hello World!'
>>> #
2. Programs. ******************************************************************
% cat module1.py
print 'Hello module world!'
% python module1.py
Hello module world!
3. Modules. *******************************************************************
% python
>>> import module1
Hello module world!
>>>
4. Scripts. *******************************************************************
% cat module1.py
#!/usr/local/bin/python (or #!/usr/bin/env python)
print 'Hello module world!'
% chmod +x module1.py
% module1.py
Hello module world!
5. Errors. ********************************************************************
% python
>>> 1 / 0
Traceback (innermost last):
File "", line 1, in ?
ZeroDivisionError: integer division or modulo
>>>
>>> x
Traceback (innermost last):
File "", line 1, in ?
NameError: x
6. Breaks. ********************************************************************
% python
>>> L = [1, 2]
>>> L.append(L)
lpython/dos/solutions/chapter4.txt 001777 000000 000000 00000006667 06713143564 013361 1. Basics. ********************************************************************
% python
>>> def func(x): print x
...
>>> func("spam")
spam
>>> func(42)
42
>>> func([1, 2, 3])
[1, 2, 3]
>>> func({'food': 'spam'})
{'food': 'spam'}
2. Arguments. *****************************************************************
% cat mod.py
def adder(x, y):
return x + y
print adder(2, 3)
print adder('spam', 'eggs')
print adder(['a', 'b'], ['c', 'd'])
% python mod.py
5
spameggs
['a', 'b', 'c', 'd']
3. varargs. *******************************************************************
% cat adders.py
def adder1(*args):
print 'adder1',
if type(args[0]) == type(0): # integer?
sum = 0 # init to zero
else: # else sequence:
sum = args[0][:0] # use empty slice of arg1
for arg in args:
sum = sum + arg
return sum
def adder2(*args):
print 'adder2',
sum = args[0] # init to arg1
for next in args[1:]:
sum = sum + next # add items 2..N
return sum
for func in (adder1, adder2):
print func(2, 3, 4)
print func('spam', 'eggs', 'toast')
print func(['a', 'b'], ['c', 'd'], ['e', 'f'])
% python adders.py
adder1 9
adder1 spameggstoast
adder1 ['a', 'b', 'c', 'd', 'e', 'f']
adder2 9
adder2 spameggstoast
adder2 ['a', 'b', 'c', 'd', 'e', 'f']
4. Keywords. ******************************************************************
% cat mod.py
def adder(good=1, bad=2, ugly=3):
return good + bad + ugly
print adder()
print adder(5)
print adder(5, 6)
print adder(5, 6, 7)
print adder(ugly=7, good=6, bad=5)
% python mod.py
6
10
14
18
18
5. and 6. *********************************************************************
% cat dict.py
def copyDict(old):
new = {}
for key in old.keys():
new[key] = old[key]
return new
def addDict(d1, d2):
new = {}
for key in d1.keys():
new[key] = d1[key]
for key in d2.keys():
new[key] = d2[key]
return new
% python
>>> from dict import *
>>> d = {1:1, 2:2}
>>> e = copyDict(d)
>>> d[2] = '?'
>>> d
{1: 1, 2: '?'}
>>> e
{1: 1, 2: 2}
>>> x = {1:1}
>>> y = {2:2}
>>> z = addDict(x, y)
>>> z
{1: 1, 2: 2}
7. More argument matching examples. *******************************************
# put these in a module and ftech with "from mod import *"
def f1(a, b): print a, b # normal args
def f2(a, *b): print a, b # positional varargs
def f3(a, **b): print a, b # keyword varargs
def f4(a, *b, **c): print a, b, c # mixed modes
def f5(a, b=2, c=3): print a, b, c # defaults
def f6(a, b=2, *c): print a, b, c # defaults + positional varargs
% python
>>> f1(1, 2) # matched by position (order matters)
1 2
>>> f1(b=2, a=1) # matched by name (order doesn't matter)
1 2
>>> f2(1, 2, 3) # extra positionals collected in a tuple
1 (2, 3)
>>> f3(1, x=2, y=3) # extra keywords collected in a dictionary
1 {'x': 2, 'y': 3}
>>> f4(1, 2, 3, x=2, y=3) # extra of both kinds
1 (2, 3) {'x': 2, 'y': 3}
>>> f5(1) # both defaults kick in
1 2 3
>>> f5(1, 4) # only one default used
1 4 3
>>> f6(1) # one argument: matches "a"
1 2 ()
>>> f6(1, 3, 4) # extra positional collected
1 3 (4,)
lpython/dos/solutions/chapter2.txt 001777 000000 000000 00000012225 06713143260 013333 1. The basics. ****************************************************************
## Numbers
>>> 2 ** 16 # 2 raised to the power 16
65536
>>> 2 / 5, 2 / 5.0 # integer / truncates, float / doesn't
(0, 0.4)
## Strings
>>> "spam" + "eggs" # concatenation
'spameggs'
>>> S = "ham"
>>> "eggs " + S
'eggs ham'
>>> S * 5 # repetition
'hamhamhamhamham'
>>> S[:0] # an empty slice at the front--[0:0]
''
>>> "green %s and %s" % ("eggs", S) # formatting
'green eggs and ham'
## Tuples
>>> ('x',)[0] # indexing a single-item tuple
'x'
>>> ('x', 'y')[1] # indexing a 2-item tuple
'y'
## Lists
>>> L = [1,2,3] + [4,5,6] # list operations
>>> L, L[:], L[:0], L[-2], L[-2:]
([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6], [], 5, [5, 6])
>>> ([1,2,3]+[4,5,6])[2:4]
[3, 4]
>>> [L[2], L[3]] # fetch from offsets, store in a list
[3, 4]
>>> L.reverse(); L # method: reverse list in-place
[6, 5, 4, 3, 2, 1]
>>> L.sort(); L # method: sort list in-place
[1, 2, 3, 4, 5, 6]
>>> L.index(4) # method: offset of first 4 (search)
3
## Dictionaries
>>> {'a':1, 'b':2}['b'] # index a dictionary by key
2
>>> D = {'x':1, 'y':2, 'z':3}
>>> D['w'] = 0 # create a new entry
>>> D['x'] + D['w']
1
>>> D[(1,2,3)] = 4 # a tuple used as a key (immutable)
>>> D
{'w': 0, 'z': 3, 'y': 2, (1, 2, 3): 4, 'x': 1}
>>> D.keys(), D.values(), D.has_key((1,2,3)) # methods
(['w', 'z', 'y', (1, 2, 3), 'x'], [0, 3, 2, 4, 1], 1)
## Empties
>>> [[]], ["",[],(),{},None] # lots of nothings
([[]], ['', [], (), {}, None])
2. Indexing and slicing. ******************************************************
>>> L = [1, 2, 3, 4]
>>> L[4]
Traceback (innermost last):
File "", line 1, in ?
IndexError: list index out of range
>>> L[-1000:100]
[1, 2, 3, 4]
>>> L[3:1]
[]
>>> L
[1, 2, 3, 4]
>>> L[3:1] = ['?']
>>> L
[1, 2, 3, '?', 4]
3. Indexing, slicing, and del. ************************************************
>>> L = [1,2,3,4]
>>> L[2] = []
>>> L
[1, 2, [], 4]
>>> L[2:3] = []
>>> L
[1, 2, 4]
>>> del L[0]
>>> L
[2, 4]
>>> del L[1:]
>>> L
[2]
>>> L[1:2] = 1
Traceback (innermost last):
File "", line 1, in ?
TypeError: illegal argument type for built-in operation
4. Tuple assignment. **********************************************************
>>> X = 'spam'
>>> Y = 'eggs'
>>> X, Y = Y, X
>>> X
'eggs'
>>> Y
'spam'
5. Dictionary keys. ***********************************************************
>>> D = {}
>>> D[1] = 'a'
>>> D[2] = 'b'
>>> D[(1, 2, 3)] = 'c'
>>> D
{1: 'a', 2: 'b', (1, 2, 3): 'c'}
6. Dictionary indexing. *******************************************************
>>> D = {'a':1, 'b':2, 'c':3}
>>> D['a']
1
>>> D['d']
Traceback (innermost last):
File "", line 1, in ?
KeyError: d
>>> D['d'] = 4
>>> D
{'b': 2, 'd': 4, 'a': 1, 'c': 3}
>>>
>>> L = [0,1]
>>> L[2]
Traceback (innermost last):
File "", line 1, in ?
IndexError: list index out of range
>>> L[2] = 3
Traceback (innermost last):
File "", line 1, in ?
IndexError: list assignment index out of range
7. Generic operations. ********************************************************
>>> "x" + 1
Traceback (innermost last):
File "", line 1, in ?
TypeError: illegal argument type for built-in operation
>>>
>>> {} + {}
Traceback (innermost last):
File "", line 1, in ?
TypeError: bad operand type(s) for +
>>>
>>> [].append(9)
>>> "".append('s')
Traceback (innermost last):
File "", line 1, in ?
AttributeError: attribute-less object
>>>
>>> {}.keys()
[]
>>> [].keys()
Traceback (innermost last):
File "", line 1, in ?
AttributeError: keys
>>>
>>> [][:]
[]
>>> ""[:]
''
8. String indexing. ***********************************************************
>>> S = "spam"
>>> S[0][0][0][0][0]
's'
>>> L = ['s', 'p']
>>> L[0][0][0]
's'
9. Immutable types. ***********************************************************
>>> S = "spam"
>>> S = S[0] + 'l' + S[2:]
>>> S
'slam'
>>> S = S[0] + 'l' + S[2] + S[3]
>>> S
'slam'
10. Nesting. ******************************************************************
>>> me = {'name':('mark', 'e', 'lutz'), 'age':'?', 'job':'engineer'}
>>> me['job']
'engineer'
>>> me['name'][2]
'lutz'
11. Files. ********************************************************************
% cat maker.py
file = open('myfile.txt', 'w')
file.write('Hello file world!\n')
file.close() # close not always needed
% cat reader.py
file = open('myfile.txt', 'r')
print file.read()
% python maker.py
% python reader.py
Hello file world!
% ls -l myfile.txt
-rwxrwxrwa 1 0 0 19 Apr 13 16:33 myfile.txt
12. The dir function revisited. ***********************************************
>>> [].__methods__
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort']
>>> dir([])
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort']
lpython/dos/solutions/chapter5.txt 001777 000000 000000 00000004372 06713143670 013347 1. Basics, import. ************************************************************
% cat mymod.py
def countLines(name):
file = open(name, 'r')
return len(file.readlines())
def countChars(name):
return len(open(name, 'r').read())
def test(name): # or pass file object
return countLines(name), countChars(name) # or return a dictionary
% python
>>> import mymod
>>> mymod.test('mymod.py')
(10, 291)
% cat mymod2.py
def countLines(file):
file.seek(0) # rewind to start of file
return len(file.readlines())
def countChars(file):
file.seek(0) # ditto (rewind if needed)
return len(file.read())
def test(name):
file = open(name, 'r') # pass file object
return countLines(file), countChars(file) # only open file once
>>> import mymod2
>>> mymod2.test("mymod2.py")
(11, 392)
2. from/from*. ****************************************************************
% python
>>> from mymod import *
>>> countChars("mymod.py")
291
3. __main__. ******************************************************************
% cat mymod.py
def countLines(name):
file = open(name, 'r')
return len(file.readlines())
def countChars(name):
return len(open(name, 'r').read())
def test(name): # or pass file object
return countLines(name), countChars(name) # or return a dictionary
if __name__ == '__main__':
print test('mymod.py')
% python mymod.py
(13, 346)
4. Nested imports. ************************************************************
% cat myclient.py
from mymod import countLines
from mymod import countChars
print countLines('mymod.py'), countChars('mymod.py')
% python myclient.py
13 346
% cat mod1.py
somename = 42
% cat collector.py
from mod1 import * # collect lots of names here
from mod2 import * # from assigns to my names
from mod3 import *
>>> from collector import somename
5. Reload. ********************************************************************
# see chapter examples file
6. Circular imports. **********************************************************
# see chapter examples file
lpython/dos/solutions/chapter6.txt 001777 000000 000000 00000022743 06713246646 013361 1. The basics. ****************************************************************
% cat adder.py
class Adder:
def add(self, x, y):
print 'not implemented!'
def __init__(self, start=[]):
self.data = start
def __add__(self, other):
return self.add(self.data, other) # or in subclasses--return type?
class ListAdder(Adder):
def add(self, x, y):
return x + y
class DictAdder(Adder):
def add(self, x, y):
new = {}
for k in x.keys(): new[k] = x[k]
for k in y.keys(): new[k] = y[k]
return new
% python
>>> from adder import *
>>> x = Adder()
>>> x.add(1, 2)
not implemented!
>>> x = ListAdder()
>>> x.add([1], [2])
[1, 2]
>>> x = DictAdder()
>>> x.add({1:1}, {2:2})
{1: 1, 2: 2}
>>> x = Adder([1])
>>> x + [2]
not implemented!
>>>
>>> x = ListAdder([1])
>>> x + [2]
[1, 2]
>>> [2] + x
Traceback (innermost last):
File "", line 1, in ?
TypeError: __add__ nor __radd__ defined for these operands
2. Operator overloading. ******************************************************
% cat mylist.py
class MyList:
def __init__(self, start):
#self.wrapped = start[:] # copy start: no sideeffects
self.wrapped = [] # make sure it's a list here
for x in start: self.wrapped.append(x)
def __add__(self, other):
return MyList(self.wrapped + other)
def __mul__(self, time):
return MyList(self.wrapped * time)
def __getitem__(self, offset):
return self.wrapped[offset]
def __len__(self):
return len(self.wrapped)
def __getslice__(self, low, high):
return MyList(self.wrapped[low:high])
def append(self, node):
self.wrapped.append(node)
def __getattr__(self, name): # other members--sort/reverse/etc.
return getattr(self.wrapped, name)
def __repr__(self):
return `self.wrapped`
if __name__ == '__main__':
x = MyList('spam')
print x
print x[2]
print x[1:]
print x + ['eggs']
print x * 3
x.append('a')
x.sort()
for c in x: print c,
% python mylist.py
['s', 'p', 'a', 'm']
a
['p', 'a', 'm']
['s', 'p', 'a', 'm', 'eggs']
['s', 'p', 'a', 'm', 's', 'p', 'a', 'm', 's', 'p', 'a', 'm']
a a m p s
3. Subclassing. ***************************************************************
% cat mysub.py
from mylist import MyList
class MyListSub(MyList):
calls = 0 # shared by instances
def __init__(self, start):
self.adds = 0 # varies in each instance
MyList.__init__(self, start)
def __add__(self, other):
MyListSub.calls = MyListSub.calls + 1 # class-wide counter
self.adds = self.adds + 1 # per instance counts
return MyList.__add__(self, other)
def stats(self):
return self.calls, self.adds # all adds, my adds
if __name__ == '__main__':
x = MyListSub('spam')
y = MyListSub('foo')
print x[2]
print x[1:]
print x + ['eggs']
print x + ['toast']
print y + ['bar']
print x.stats()
% python mysub.py
a
['p', 'a', 'm']
['s', 'p', 'a', 'm', 'eggs']
['s', 'p', 'a', 'm', 'toast']
['f', 'o', 'o', 'bar']
(3, 2)
4. Metaclass methods. *********************************************************
>>> class Meta:
... def __getattr__(self, name): print 'get', name
... def __setattr__(self, name, value): print 'set', name, value
...
>>> x = Meta()
>>> x.append
get append
>>> x.spam = "pork"
set spam pork
>>>
>>> x + 2
get __coerce__
Traceback (innermost last):
File "", line 1, in ?
TypeError: call of non-function
>>>
>>> x[1]
get __getitem__
Traceback (innermost last):
File "", line 1, in ?
TypeError: call of non-function
>>> x[1:5]
get __len__
Traceback (innermost last):
File "", line 1, in ?
TypeError: call of non-function
5. Set objects. ***************************************************************
# make sure to put the Set class code from the chapter examples
# file into a file "set.py", in a directory on your PYTHONPATH
% python
>>> from set import Set
>>> x = Set([1,2,3,4]) # runs __init__
>>> y = Set([3,4,5])
>>> x & y # __and__, intersect, then __repr__
Set:[3, 4]
>>> x | y # __or__, union, then __repr__
Set:[1, 2, 3, 4, 5]
>>> z = Set("hello") # __init__ removes duplicates
>>> z[0], z[-1] # __getitem__
('h', 'o')
>>> for c in z: print c, # __getitem__
...
h e l o
>>> len(z), z # __len__, __repr__
(4, Set:['h', 'e', 'l', 'o'])
>>> z & "mello", z | "mello"
(Set:['e', 'l', 'o'], Set:['h', 'e', 'l', 'o', 'm'])
# multiset.py: multiple-operand extension subclass
from set import Set
class MultiSet(Set):
"""
inherits all Set names, but extends intersect
and union to support multiple operands; note
that "self" is still the first argument (stored
in the *args argument now); also note that the
inherited & and | operators call the new methods
here with 2 arguments, but processing more than
2 requires a method call, not an expression:
"""
def intersect(self, *others):
res = []
for x in self: # scan first sequence
for other in others: # for all other args
if x not in other: break # item in each one?
else: # no: break out of loop
res.append(x) # yes: add item to end
return Set(res)
def union(*args): # self is args[0]
res = []
for seq in args: # for all args
for x in seq: # for all nodes
if not x in res:
res.append(x) # add new items to result
return Set(res)
>>> from multiset import *
>>> x = MultiSet([1,2,3,4])
>>> y = MultiSet([3,4,5])
>>> z = MultiSet([0,1,2])
>>> x & y, x | y # 2 operands
(Set:[3, 4], Set:[1, 2, 3, 4, 5])
>>> x.intersect(y, z) # 3 operands
Set:[]
>>> x.union(y, z)
Set:[1, 2, 3, 4, 5, 0]
>>> x.intersect([1,2,3], [2,3,4], [1,2,3]) # 4 operands
Set:[2, 3]
>>> x.union(range(10)) # non-MultiSets work too
Set:[1, 2, 3, 4, 0, 5, 6, 7, 8, 9]
6. Class tree links. **********************************************************
class Lister:
def __repr__(self):
return ("" %
(self.__class__.__name__, # my class's name
self.supers(), # my class's supers
id(self), # my address
self.attrnames()) ) # name=value list
def attrnames(self):
# Unchanged...
def supers(self):
result = ""
first = 1
for super in self.__class__.__bases__: # one level up from class
if not first:
result = result + ", "
first = 0
result = result + super.__name__
return result
C:\python\examples> python testmixin.py
7. Composition. ***************************************************************
# starting point...
class Lunch:
def __init__(self) # make/embed Customer and Employee
def order(self, foodName) # start a Customer order simulation
def result(self) # ask the Customer what kind of Food it has
class Customer:
def __init__(self) # initialize my food to None
def placeOrder(self, foodName, employee) # place order with an Employee
def printFood(self) # print the name of my food
class Employee:
def takeOrder(self, foodName) # return a Food, with requested name
class Food:
def __init__(self, name) # store food name
# solution...
# put all this code in a module file called lunch.py;
# it's run, not imported, so it need not be in PYTHONPATH
class Lunch:
def __init__(self):
# make/embed Customer and Employee
self.cust = Customer()
self.empl = Employee()
def order(self, foodName):
# start a Customer order simulation
self.cust.placeOrder(foodName, self.empl)
def result(self):
# ask the Customer what kind of Food it has
self.cust.printFood()
class Customer:
def __init__(self):
# initialize my food to None
self.food = None
def placeOrder(self, foodName, employee):
# place order with an Employee
self.food = employee.takeOrder(foodName)
def printFood(self):
# print the name of my food
print self.food.name
class Employee:
def takeOrder(self, foodName):
# return a Food, with requested name
return Food(foodName)
class Food:
def __init__(self, name):
# store food name
self.name = name
if __name__ == '__main__':
x = Lunch()
x.order('burritos')
x.result()
x.order('pizza')
x.result()
% python lunch.py
burritos
pizza
lpython/dos/solutions/chapter7.txt 001777 000000 000000 00000002617 06713150770 013350 1. Try/except. ****************************************************************
% cat oops.py
def oops():
raise IndexError
def doomed():
try:
oops()
except IndexError:
print 'caught an index error!'
else:
print 'no error caught...'
if __name__ == '__main__': doomed()
% python oops.py
caught an index error!
2. Exception lists. ***********************************************************
% cat oops.py
MyError = 'hello'
def oops():
raise MyError, 'world'
def doomed():
try:
oops()
except IndexError:
print 'caught an index error!'
except MyError, data:
print 'caught error:', MyError, data
else:
print 'no error caught...'
if __name__ == '__main__':
doomed()
% python oops.py
caught error: hello world
3. Error handling. ************************************************************
% cat safe2.py
import sys, traceback
def safe(entry, *args):
try:
apply(entry, args) # catch everything else
except:
traceback.print_exc()
print 'Got', sys.exc_type, sys.exc_value
import oops
safe(oops.oops)
% python safe2.py
Traceback (innermost last):
File "safe2.py", line 5, in safe
apply(entry, args) # catch everything else
File "oops.py", line 4, in oops
raise MyError, 'world'
hello: world
Got hello world
lpython/dos/solutions/chapter8.txt 001777 000000 000000 00000011612 06713151050 013334 1. Describing a directory. ****************************************************
import os, sys, stat
def describedir(start):
def describedir_helper(arg, dirname, files):
""" Helper function for describing directories """
print "Directory %s has files:" % dirname
for file in files:
# find the full path to the file (directory + filename)
fullname = os.path.join(dirname, file)
if os.path.isdir(fullname):
# if it's a directory, say so; no need to find the size
print ' '+ file + ' (subdir)'
else:
# find out the size, and print the info.
size = os.stat(fullname)[stat.ST_SIZE]
print ' '+file+' size=' + `size`
# Start the 'walk'.
os.path.walk(start, describedir_helper, None)
>>> import describedir
>>> describedir.describedir2('testdir')
Directory testdir has files:
describedir.py size=939
subdir1 (subdir)
subdir2 (subdir)
Directory testdir\subdir1 has files:
makezeros.py size=125
subdir3 (subdir)
Directory testdir\subdir1\subdir3 has files:
Directory testdir\subdir2 has files:
2. Modifying the prompt. ******************************************************
# modifyprompt.py
import sys, os
class MyPrompt:
def __init__(self, subprompt='>>> '):
self.lineno = 0
self.subprompt = subprompt
def __repr__(self):
self.lineno = self.lineno + 1
return os.getcwd()+'|%d'%(self.lineno)+self.subprompt
sys.ps1 = MyPrompt()
sys.ps2 = MyPrompt('... ')
h:\David\book> python -i modifyprompt.py
h:\David\book|1>>> x = 3
h:\David\book|2>>> y = 3
h:\David\book|3>>> def foo():
h:\David\book|3... x = 3 # the secondary prompt is supported
h:\David\book|3...
h:\David\book|4>>> import os
h:\David\book|5>>> os.chdir('..')
h:\David|6>>> # note the prompt changed!
3. Avoiding regular expressions. **********************************************
import string
file = open('pepper.txt')
text = file.read()
paragraphs = string.split(text, '\n\n')
def find_indices_for(big, small):
indices = []
cum = 0
while 1:
index = string.find(big, small)
if index == -1:
return indices
indices.append(index+cum)
big = big[index+len(small):]
cum = cum + index + len(small)
def fix_paragraphs_with_word(paragraphs, word):
lenword = len(word)
for par_no in range(len(paragraphs)):
p = paragraphs[par_no]
wordpositions = find_indices_for(p, word)
if wordpositions == []: return
for start in wordpositions:
# look for 'pepper' ahead
indexpepper = string.find(p, 'pepper')
if indexpepper == -1: return -1
if string.strip(p[start:indexpepper]) != '':
# something other than whitespace in between!
continue
where = indexpepper+len('pepper')
if p[where:where+len('corn')] == 'corn':
# it's immediately followed by 'corn'!
continue
if string.find(p, 'salad') < where:
# it's not followed by 'salad'
continue
# Finally! we get to do a change!
p = p[:start] + 'bell' + p[start+lenword:]
paragraphs[par_no] = p # change mutable argument!
fix_paragraphs_with_word(paragraphs, 'red')
fix_paragraphs_with_word(paragraphs, 'green')
for paragraph in paragraphs:
print paragraph+'\n'
4. Wrapping a text file with a class. *****************************************
import string
class FileStrings:
def __init__(self, filename=None, data=None):
if data == None:
self.data = open(filename).read()
else:
self.data = data
self.paragraphs = string.split(self.data, '\n\n')
self.lines = string.split(self.data, '\n')
self.words = string.split(self.data)
def __repr__(self):
return self.data
def paragraph(self, index):
return FileStrings(data=self.paragraphs[index])
def line(self, index):
return FileStrings(data=self.lines[index])
def word(self, index):
return self.words[index]
>>> from FileStrings import FileStrings
>>> bigtext = FileStrings('pepper.txt')
>>> print bigtext.paragraph(0)
This is a paragraph that mentions bell peppers multiple times. For
one, here is a red Pepper and dried tomato salad recipe. I don't like
to use green peppers in my salads as much because they have a harsher
flavor.
>>> print bigtext.line(0)
This is a paragraph that mentions bell peppers multiple times. For
>>> print bigtext.line(-4)
aren't peppers, they're chilies, but would you rather have a good cook
>>> print bigtext.word(-4)
botanist
>>> print bigtext.paragraph(2).line(2).word(-1)
'cook'
lpython/dos/solutions/chapter9.txt 001777 000000 000000 00000005456 06713151126 013352 1. Redirecting stdout. ********************************************************
import fileinput, sys, string # no change here
sys.stdout = open(sys.argv[-1], 'w') # open the output file
del sys.argv[-1] # we've dealt with this argument
... # continue as before
2. Writing a simple shell. ****************************************************
import cmd, os, string, sys, shutil
class UnixShell(cmd.Cmd):
def do_EOF(self, line):
""" The do_EOF command is called when the user presses Ctrl-D (unix)
or Ctrl-Z (PC). """
sys.exit()
def help_ls(self):
print "ls : list the contents of the specified directory"
print " (current directory used by default)"
def do_ls(self, line):
# 'ls' by itself means 'list current directory'
if line == '': dirs = [os.curdir]
else: dirs = string.split(line)
for dirname in dirs:
print 'Listing of %s:' % dirname
print string.join(os.listdir(dirname), '\n')
def do_cd(self, dirname):
# 'cd' by itself means 'go home'
if dirname == '': dirname = os.environ['HOME']
os.chdir(dirname)
def do_mkdir(self, dirname):
os.mkdir(dirname)
def do_cp(self, line):
words = string.split(line)
sourcefiles,target = words[:-1], words[-1] # target could be a dir
for sourcefile in sourcefiles:
shutil.copy(sourcefile, target)
def do_mv(self, line):
source, target = string.split(line)
os.rename(source, target)
def do_rm(self, line):
map(os.remove, string.split(line))
class DirectoryPrompt:
def __repr__(self):
return os.getcwd()+'> '
cmd.PROMPT = DirectoryPrompt()
shell = UnixShell()
shell.cmdloop()
h:\David\book> python -i shell.py
h:\David\book> cd ../tmp
h:\David\tmp> ls
Listing of .:
api
ERREUR.DOC
ext
giant_~1.jpg
icons
index.html
lib
pythlp.hhc
pythlp.hhk
ref
tut
h:\David\tmp> cd ..
h:\David> cd tmp
h:\David\tmp> cp index.html backup.html
h:\David\tmp> rm backup.html
h:\David\tmp> ^Z
3. Understanding map, reduce and filter. **************************************
def map2(function, sequence):
if function is None: return list(sequence)
retvals = []
for element in sequence:
retvals.append(function(element))
return retvals
def reduce2(function, sequence):
arg1 = function(sequence[0])
for arg2 in sequence[1:]:
arg1 = function(arg1, arg2)
return arg1
def filter2(function, sequence):
retvals = []
for element in sequence:
if (function is None and element) or function(element):
retvals.append(element)
return retvals
lpython/dos/solutions/chapter10.txt 001777 000000 000000 00000006167 06713513060 013421 1. Faking the Web. ************************************************************
class FormData:
def __init__(self, dict):
for k, v in dict.items():
setattr(self, k, v)
class FeedbackData(FormData):
""" A FormData generated by the comment.html form. """
fieldnames = ('name', 'address', 'email', 'type', 'text')
def __repr__(self):
return "%(type)s from %(name)s on %(time)s" % vars(self)
fake_entries = [
{'name': "John Doe",
'address': '500 Main St., SF CA 94133',
'email': 'john@sf.org',
'type': 'comment',
'text': 'Great toothpaste!'},
{'name': "Suzy Doe",
'address': '500 Main St., SF CA 94133',
'email': 'suzy@sf.org',
'type': 'complaint',
'text': "It doesn't taste good when I kiss John!"},
]
DIRECTORY = r'C:\complaintdir'
if __name__ == '__main__':
import tempfile, pickle, time
tempfile.tempdir = DIRECTORY
for fake_entry in fake_entries:
data = FeedbackData(fake_entry)
filename = tempfile.mktemp()
data.time = time.asctime(time.localtime(time.time()))
pickle.dump(data, open(filename, 'w'))
2. Cleaning up. ***************************************************************
if __name__ == '__main__':
import os, pickle
CACHEFILE = 'C:\cache.pik'
from feedback import DIRECTORY#, FormData, FeedbackData
if os.path.exists(CACHEFILE):
processed_files = pickle.load(open(CACHEFILE))
else:
processed_files = []
for filename in os.listdir(DIRECTORY):
if filename in processed_files: continue # skip this filename
processed_files.append(filename)
data = pickle.load(open(os.path.join(DIRECTORY, filename)))
if data.type == 'complaint':
print "Printing letter for %(name)s." % vars(data)
print_formletter(data)
else:
print "Got comment from %(name)s, skipping printing." % vars(data)
pickle.dump(processed_file, open(CACHEFILE, 'w')
3. Adding parametric plotting to grapher.py. **********************************
# this one's for mathematically-inclined readers only
if not hasattr(self.data[0], '__len__'): # it's probably a number (1D)
xmin, xmax = 0, N-1
# code from existing program, up to graphics.fillPolygon(xs, ys, len(xs))
elif len(self.data[0]) == 2: # we'll only deal with 2-D
xmin = reduce(min, map(lambda d: d[0], self.data))
xmax = reduce(max, map(lambda d: d[0], self.data))
ymin = reduce(min, map(lambda d: d[1], self.data))
ymax = reduce(max, map(lambda d: d[1], self.data))
zero_y = y_offset - int(-ymin/(ymax-ymin)*height)
zero_x = x_offset + int(-xmin/(xmax-xmin)*width)
for i in range(N):
xs[i] = x_offset + int((self.data[i][0]-xmin)/(xmax-xmin)*width)
ys[i] = y_offset - int((self.data[i][1]-ymin)/(ymax-ymin)*height)
graphics.color = self.color
if self.style == "Line":
graphics.drawPolyline(xs, ys, len(xs))
else:
xs.append(xs[0]); ys.append(ys[0])
graphics.fillPolygon(xs, ys, len(xs))
lpython/dos/solutions/chapter3.txt 001777 000000 000000 00000004111 06713143460 013331 1. Coding basic loops. ********************************************************
>>> S = 'spam'
>>> for c in S:
... print ord(c)
...
115
112
97
109
>>> x = 0
>>> for c in S: x = x + ord(c)
...
>>> x
433
>>> x = []
>>> for c in S: x.append(ord(c))
...
>>> x
[115, 112, 97, 109]
>>> map(ord, S)
[115, 112, 97, 109]
2. Backslash characters. ******************************************************
>>> for i in range(50):
>>> print 'hello %d\n\a' % i
3. Sorting dictionaries. ******************************************************
>>> D = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}
>>> D
{'f': 6, 'c': 3, 'a': 1, 'g': 7, 'e': 5, 'd': 4, 'b': 2}
>>>
>>> keys = D.keys()
>>> keys.sort()
>>> for key in keys:
... print key, '=>', D[key]
...
a => 1
b => 2
c => 3
d => 4
e => 5
f => 6
g => 7
4. Program logic alternatives. ************************************************
start)
# power.py
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
found = i = 0
while not found and i < len(L):
if 2 ** X == L[i]:
found = 1
else:
i = i+1
if found:
print 'at index', i
else:
print X, 'not found'
C:\book\tests> python power.py
at index 5
a)
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
i = 0
while i < len(L):
if 2 ** X == L[i]:
print 'at index', i
break
i = i+1
else:
print X, 'not found'
b)
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
for p in L:
if (2 ** X) == p:
print (2 ** X), 'was found at', L.index(p)
break
else:
print X, 'not found'
c)
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
d)
X = 5
L = []
for i in range(7): L.append(2 ** i)
print L
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
e)
X = 5
L = map(lambda x: 2**x, range(7))
print L
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
lpython/dos/examples/ 000777 000000 000000 00000000000 06671363274 010642 lpython/dos/examples/chapter2.txt 001777 000000 000000 00000022255 06713510522 013115 *** Page 28 *******************************************************************
Numbers 3.1415, 1234, 999L, 3+4j
Strings 'spam', "guido's"
Lists [1, [2, 'three'], 4]
Dictionaries {'food':'spam', 'taste':'yum'}
Tuples (1,'spam', 4, 'U')
Files text = open('eggs', 'r').read()
1234, -24, 0 Normal integers (C longs)
999999999999L Long integers (unlimited size)
1.23, 3.14e-10, 4E210, 4.0e+210 Floating-point (C doubles)
0177, 0x9ff Octal and hex constants
3+4j, 3.0+4.0j, 3J Complex number constants
*** Page 32-35 ****************************************************************
% python
>>> a = 3 # name created
>>> b = 4
>>> b / 2 + a # same as ((4 / 2) + 3)
5
>>> b / (2.0 + a) # same as (4 / (2.0 + 3))
0.8
>>> x = 1 # 0001
>>> x << 2 # shift left 2 bits: 0100
4
>>> x | 2 # bitwise OR: 0011
3
>>> x & 1 # bitwise AND: 0001
1
>>> 9999999999999999999999999999 + 1
OverflowError: integer literal too large
>>> 9999999999999999999999999999L + 1
10000000000000000000000000000L
>>> 1j * 1J
(-1+0j)
>>> 2 + 1j * 3
(2+3j)
>>> (2+1j)*3
(6+3j)
>>> import math
>>> math.pi
3.14159265359
>>>
>>> abs(-42), 2**4, pow(2, 4)
(42, 16, 16)
*** Page 37-38 ****************************************************************
% python
>>> len('abc') # length: number items
3
>>> 'abc' + 'def' # concatenation: a new string
'abcdef'
>>> 'Ni!' * 4 # like "Ni!" + "Ni!" + ...
'Ni!Ni!Ni!Ni!'
>>> myjob = "hacker"
>>> for c in myjob: print c, # step though items
...
h a c k e r
>>> "k" in myjob # 1 means true
1
>>> S = 'spam'
>>> S[0], S[-2] # indexing from front or end
('s', 'a')
>>> S[1:3], S[1:], S[:-1] # slicing: extract section
('pa', 'pam', 'spa')
*** Page 39 *******************************************************************
% cat echo.py
import sys
print sys.argv
% python echo.py -a -b -c
['echo.py', '-a', '-b', '-c']
*** Page 40 *******************************************************************
>>> S = 'spam'
>>> S[0] = "x"
Raises an error!
>>> S = S + 'Spam!' # to change a string, make a new one
>>> S
'spamSpam!'
>>> S = S[:4] + 'Burger' + S[-1]
>>> S
'spamBurger!'
>>> 'That is %d %s bird!' % (1, 'dead') # like C sprintf
That is 1 dead bird!
>>> exclamation = "Ni"
>>> "The knights who say %s!" % exclamation
'The knights who say Ni!'
>>> "%d %s %d you" % (1, 'spam', 4)
'1 spam 4 you'
>>> "%s -- %s -- %s" % (42, 3.14159, [1, 2, 3])
'42 -- 3.14159 -- [1, 2, 3]'
>>> "%e %f %g" % (1.1, 2.2, 3.3)
*** Page 41-43 ****************************************************************
>>> import string # standard utilities module
>>> S = "spammify"
>>> string.upper(S) # convert to uppercase
'SPAMMIFY'
>>> string.find(S, "mm") # return index of substring
3
>>> string.atoi("42"), `42` # convert from/to string
(42, '42')
>>> string.join(string.split(S, "mm"), "XX")
'spaXXify'
>>> "spam" + 42
Raises an error
>>> "spam" + `42`
'spam42'
>>> string.atoi("42") + 1
43
>>> mixed = "Guido's" # single in double
>>> mixed
"Guido's"
>>> mixed = 'Guido"s' # double in single
>>> mixed
'Guido"s'
>>> mixed = 'Guido\'s' # backslash escape
>>> mixed
"Guido's"
>>> split = "This" "is" "concatenated"
>>> split
'Thisisconcatenated'
>>> big = """This is
... a multi-line block
... of text; Python puts
... an end-of-line marker
... after each line."""
>>>
>>> big
'This is\012a multi-line block\012of text; Python puts\012an end-of-line
marker\012after each line.'
*** Page 46-49 ****************************************************************
% python
>>> len([1, 2, 3]) # length
3
>>> [1, 2, 3] + [4, 5, 6] # concatenation
[1, 2, 3, 4, 5, 6]
>>> ['Ni!'] * 4 # repetition
['Ni!', 'Ni!', 'Ni!', 'Ni!']
>>> for x in [1, 2, 3]: print x, # iteration
...
1 2 3
>>> `[1, 2]` + "34" # same as "[1, 2]" + "34"
'[1, 2]34'
>>> [1, 2] + list("34") # same as [1, 2] + ["3", "4"]
[1, 2, '3', '4']
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[2] # offsets start at zero
'SPAM!'
>>> L[-2] # negative: count from the right
'Spam'
>>> L[1:] # slicing fetches sections
['Spam', 'SPAM!']
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[1] = 'eggs' # index assignment
>>> L
['spam', 'eggs', 'SPAM!']
>>> L[0:2] = ['eat', 'more'] # slice assignment: delete+insert
>>> L # replaces items 0,1
['eat', 'more', 'SPAM!']
>>> L.append('please') # append method call
>>> L
['eat', 'more', 'SPAM!', 'please']
>>> L.sort() # sort list items ('S' < 'e')
>>> L
['SPAM!', 'eat', 'more', 'please']
>>> L
['SPAM!', 'eat', 'more', 'please']
>>> del L[0] # delete one item
>>> L
['eat', 'more', 'please']
>>> del L[1:] # delete an entire section
>>> L # same as L[1:] = []
['eat']
*** Page 51-52 ****************************************************************
% python
>>> d2 = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> d2['spam'] # fetch value for key
2
>>> len(d2) # number of entries in dictionary
3
>>> d2.has_key('ham') # key membership test (1 means true)
1
>>> d2.keys() # list of my keys
['eggs', 'spam', 'ham']
>>> d2['ham'] = ['grill', 'bake', 'fry'] # change entry
>>> d2
{'eggs': 3, 'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> del d2['eggs'] # delete entry
>>> d2
{'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> d2['brunch'] = 'Bacon' # add new entry
>>> d2
{'brunch': 'Bacon', 'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> table = {'Python': 'Guido van Rossum',
... 'Perl': 'Larry Wall',
... 'Tcl': 'John Ousterhout' }
...
>>> language = 'Python'
>>> creator = table[language]
>>> creator
'Guido van Rossum'
>>> for lang in table.keys(): print lang, '\t', table[lang]
...
Tcl John Ousterhout
Python Guido van Rossum
Perl Larry Wall
*** Page 54 *******************************************************************
import anydbm
file = anydbm.open("filename") # link to external file
file['key'] = 'data' # store data by key
data = file['key'] # fetch data by key
import cgi
form = cgi.FieldStorage() # parse form data (stdin, environ)
if form.has_key('name'):
showReply('Hello, ' + form['name'].value)
*** Page 57 *******************************************************************
>>> myfile = open('myfile', 'w') # open for output (creates)
>>> myfile.write('hello text file\n') # write a line of text
>>> myfile.close()
>>> myfile = open('myfile', 'r') # open for input
>>> myfile.readline() # read the line back
'hello text file\012'
>>> myfile.readline() # empty string: end of file
''
*** Page 59-61 ****************************************************************
class MySequence:
def __getitem__(self, index):
# called on self[index], for x in self, x in self
def __getslice__(self, low, high):
# called on self[low:high]
def __add__(self, other):
# called on self + other
>>> L = ['abc', [(1, 2), ([3], 4)], 5]
>>> L[1]
[(1, 2), ([3], 4)]
>>> L[1][1]
([3], 4)
>>> L[1][1][0]
[3]
>>> L[1][1][0][0]
3
>>> X = [1, 2, 3]
>>> L = ['a', X, 'b']
>>> D = {'x':X, 'y':2}
>>> X[1] = 'surprise' # changes all three references!
>>> L
['a', [1, 'surprise', 3], 'b']
>>> D
{'x': [1, 'surprise', 3], 'y': 2}
>>> L1 = [1, ('a', 3)] # same value, unique objects
>>> L2 = [1, ('a', 3)]
>>> L1 == L2, L1 is L2 # equivalent?, same object?
(1, 0)
>>> L1 = [1, ('a', 3)]
>>> L2 = [1, ('a', 2)]
>>> L1 < L2, L1 == L2, L1 > L2 # less, equal, greater: a tuple of results
(0, 0, 1)
*** Page 64-65 ****************************************************************
>>> L = [1, 2, 3]
>>> M = ['X', L, 'Y'] # embed a reference to L
>>> M
['X', [1, 2, 3], 'Y']
>>> L[1] = 0 # changes M too
>>> M
['X', [1, 0, 3], 'Y']
>>> L = [1, 2, 3]
>>> M = ['X', L[:], 'Y'] # embed a copy of L
>>> L[1] = 0 # only changes L, not M
>>> L
[1, 0, 3]
>>> M
['X', [1, 2, 3], 'Y']
>>> L = [4, 5, 6]
>>> X = L * 4 # like [4, 5, 6] + [4, 5, 6] + ...
>>> Y = [L] * 4 # [L] + [L] + ... = [L, L,...]
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> Y
[[4, 5, 6], [4, 5, 6], [4, 5, 6], [4, 5, 6]]
>>> L[1] = 0 # impacts Y but not X
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> Y
[[4, 0, 6], [4, 0, 6], [4, 0, 6], [4, 0, 6]]
>>> L = ['hi.']; L.append(L) # append reference to same object
>>> L # before 1.5.1: a loop! (cntl-C breaks)
T = (1, 2, 3)
T[2] = 4 # error!
T = T[:2] + (4,) # okay: (1, 2, 4)
***see solutions file file exercise source code*** lpython/dos/examples/chapter1.txt 001777 000000 000000 00000006126 06713507520 013117 *** Page 12 *******************************************************************
% python
>>> print 'Hello world!'
Hello world!
>>> lumberjack = "okay"
>>> # Ctrl D to exit (Ctrl Z on some platforms)
*** Page 13 *******************************************************************
[file spam.py]
import sys
print sys.argv # more on this later
% python spam.py -i eggs -o bacon
['spam.py', '-i', 'eggs', '-o', 'bacon']
*** Page 14 *******************************************************************
[file brian]
#!/usr/local/bin/python
print 'The Bright Side of Life...' # another comment here
% chmod +x brian
% brian
The Bright Side of Life...
C:\book\tests> python brian
The Bright Side of Life...
*** Page 17 *******************************************************************
[file myfile.py]
title = "The Meaning of Life"
% python
>>> import myfile # Run file, load module as a whole
>>> print myfile.title # Use its names: '.' qualification
The Meaning of Life
% python
>>> from myfile import title # Run file, load its names
>>> print title # Use name directly: no need to qualify
The Meaning of Life
% python
>>> import myfile # Run/load module
>>> print myfile.title # Qualify to fetch name
The Meaning of Life
... Change myfile.py in your text editor
>>> import myfile # Will NOT rerun the file’s code
>>> reload(myfile) # WILL rerun the file’s (current) code
*** Page 19 *******************************************************************
>>> x = 1
>>> y = "shrubbery"
>>> dir()
['__builtins__', '__doc__', '__name__', 'x', 'y']
[file threenames.py]
a = 'dead'
b = 'parrot'
c = 'sketch'
% cat threenames.py
a = 'dead'
b = 'parrot'
c = 'sketch'
% python
>>> import threenames
>>> dir(threenames)
['__builtins__', '__doc__', '__file__', '__name__', 'a', 'b', 'c']
>>> dir(__builtins__)
All the names Python predefines for you
*** Page 21 *******************************************************************
[file runpy]
#!/bin/csh
# Give this file executable privileges (chmod +x runpy).
# Put this info in your .cshrc file to make it permanent.
# 1) Add path to command-line interpreter
set path = (/usr/local/bin $path)
# 2) Set python library search paths (unless predefined)
# add your module file directories to the list as desired
setenv PYTHONPATH \
.:/usr/local/lib/python:/usr/local/lib/python/tkinter
# 3) Set tk library search paths for GUIs (unless predefined)
setenv TCL_LIBRARY /usr/local/lib/tcl8.0
setenv TK_LIBRARY /usr/local/lib/tk8.0
# 4) Start up the interactive command-line
python
[file runpy.bat]
PATH c:\python;%PATH%
set PYTHONPATH=.;c:\python\lib;c:\python\lib\tkinter
set TCL_LIBRARY=c:\Program Files\Tcl\lib\tcl8.0
set TK_LIBRARY=c:\Program Files\Tcl\lib\tk8.0
python
% runpy
version/copyright information...
>>> from Tkinter import *
>>> w = Button(text="Hello", command='exit')
>>> w.pack()
>>> w.mainloop()
***see solutions directory for exercises code*** lpython/dos/examples/chapter3.txt 001777 000000 000000 00000014726 06713511012 013115 *** Page 73-74 ****************************************************************
>>> nudge = 1
>>> wink = 2
>>> A, B = nudge, wink # tuples
>>> A, B
(1, 2)
>>> [C, D] = [nudge, wink] # lists
>>> C, D
(1, 2)
>>> nudge, wink = wink, nudge # tuples: swaps values
>>> nudge, wink # same as T=nudge; nudge=wink; wink=T
(2, 1)
>>> x = 0 # x bound to an integer object
>>> x = "Hello" # now it's a string
>>> x = [1, 2, 3] # and now it's a list
*** Page 76-77 ****************************************************************
>>> print "a", "b"
a b
>>> print "a" + "b"
ab
>>> print "%s...%s" % ("a", "b")
a...b
>>> print 'hello world' # print a string object
hello world
>>> 'hello world' # interactive prints
'hello world'
>>> import sys # printing the hard way
>>> sys.stdout.write('hello world\n')
hello world
class FileFaker:
def write(self, string):
# do something with the string
import sys
sys.stdout = FileFaker()
print someObjects # sends to the write method of the class
python script.py < inputfile > outputfile
python script.py | filter
*** Page 78-79 ****************************************************************
>>> if 1:
... print 'true'
...
true
>>> if not 1:
... print 'true'
... else:
... print 'false'
...
false
>>> x = 'killer rabbit'
>>> if x == 'roger':
... print "how's jessica?"
... elif x == 'bugs':
... print "what's up doc?"
... else:
... print 'Run away! Run away!'
...
Run away! Run away!
>>> choice = 'ham'
>>> print {'spam': 1.25, # a dictionary-based 'switch'
... 'ham': 1.99, # use has_key() test for default case
... 'eggs': 0.99,
... 'bacon': 1.10}[choice]
1.99
>>> if choice == 'spam':
... print 1.25
... elif choice == 'ham':
... print 1.99
... elif choice == 'eggs':
... print 0.99
... elif choice == 'bacon':
... print 1.10
... else:
... print 'Bad choice'
...
1.99
*** Page 80-82 ****************************************************************
x = 1
if x:
y = 2
if y:
print 'block2'
print 'block1'
print 'block0'
L = ["Good",
"Bad",
"Ugly"] # open pairs may span lines
if a == b and c == d and \
d == e and f == g:
print 'olde' # backslashes allow continuations
if (a == b and c == d and
d == e and e == f):
print 'new ' # but parentheses usually do too
x = 1; y = 2; print x # more than 1 simple statement
if 1: print 'hello' # simple statement on header line
*** Page 83 *******************************************************************
>>> 2 < 3, 3 < 2 # less-than: return 1 or 0
(1, 0)
>>> 2 or 3, 3 or 2 # return left operand if true
(2, 3) # else return right operand (whether true or false)
>>> [] or 3
3
>>> [] or {}
{}
>>> 2 and 3, 3 and 2 # return left operand if false
(3, 2) # else return right operand (whether true or false)
>>> [] and {}
[]
>>> 3 and []
[]
*** Page 85 *******************************************************************
>>> while 1:
... print 'Type Ctrl-C to stop me!'
>>> x = 'spam'
>>> while x:
... print x,
... x = x[1:] # strip first character 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
*** Page 86-87 ****************************************************************
while 1: pass # type ctrl-C to stop me!
x = 10
while x:
x = x-1
if x % 2 != 0: continue # odd?--skip print
print x,
# y = some value
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'
*** Page 88-91 ****************************************************************
>>> for x in ["spam", "eggs", "ham"]:
... print x,
...
spam eggs ham
>>> sum = 0
>>> for x in [1, 2, 3, 4]:
... sum = sum + x
...
>>> sum
10
>>> prod = 1
>>> for item in [1, 2, 3, 4]: prod = prod * item
...
>>> prod
24
>>> S, T = "lumberjack", ("and", "I'm", "okay")
>>> for x in S: print x,
...
l u m b e r j a c k
>>> for x in T: print x,
...
and I'm okay
>>> T = [(1, 2), (3, 4), (5, 6)]
>>> for (a, b) in T: # tuple assignment at work
... print a, b
...
1 2
3 4
5 6
>>> items = ["aaa", 111, (4, 5), 2.01] # a set of objects
>>> tests = [(4, 5), 3.14] # keys to search for
>>>
>>> for key in tests: # for all keys
... for item in items: # for all items
... if item == key: # check for match
... print key, "was found"
... break
... else:
... print key, "not found!"
...
(4, 5) was found
3.14 not found!
>>> for key in tests: # for all keys
... if key in items: # let Python check for a match
... print key, "was found"
... else:
... print key, "not found!"
...
(4, 5) was found
3.14 not found!
>>> seq1 = "spam"
>>> seq2 = "scam"
>>>
>>> res = [] # start empty
>>> for x in seq1: # scan first sequence
... if x in seq2: # common item?
... res.append(x) # add to result end
...
>>> res
['s', 'a', 'm']
file = open("name", "r")
while 1:
line = file.readline() # fetch next line, if any
if not line: break # exit loop on end-of-file (empty string)
Process line here...
file = open("name", "r")
for line in file.readlines(): # read into a lines list
Process line here...
*** Page 91-92 ****************************************************************
>>> range(5), range(2, 5), range(0, 10, 2)
([0, 1, 2, 3, 4], [2, 3, 4], [0, 2, 4, 6, 8])
>>> X = 'spam'
>>> for item in X: print item, # simple iteration
...
s p a m
>>> i = 0
>>> while i < len(X): # while iteration
... print X[i],; i = i+1
...
s p a m
>>> for i in range(len(X)): print X[i], # manual indexing
...
s p a m
>>> for i in range(3): print i, 'Pythons'
...
0 Pythons
1 Pythons
2 Pythons
*** see solutions file for exercises' source code *** lpython/dos/examples/chapter4.txt 001777 000000 000000 00000021637 06713511316 013124 ** Page 99-100 ****************************************************************
>>> def times(x, y): # create and assign function
... return x * y # body executed when called
...
>>> times(2, 4) # arguments in parentheses
8
>>> times('Ni', 4) # functions are 'typeless'
'NiNiNiNi'
** Page 101 *******************************************************************
# put this in an imported module file
# it could be typed interactively too
def intersect(seq1, seq2):
res = [] # start empty
for x in seq1: # scan seq1
if x in seq2: # common item?
res.append(x) # add to end
return res
>>> s1 = "SPAM"
>>> s2 = "SCAM"
>>> intersect(s1, s2) # strings
['S', 'A', 'M']
>>> intersect([1, 2, 3], (1, 4)) # mixed types
[1]
** Page 103 *******************************************************************
# global scope
X = 99 # X and func assigned in module: global
def func(Y): # Y and Z assigned in function: locals
# local scope
Z = X + Y # X is not assigned, so it's a global
return Z
func(1) # func in module: result=100
** Page 104 *******************************************************************
y, z = 1, 2 # global variables in module
def all_global():
global x # declare globals assigned
x = y + z # no need to declare y,z: 3-scope rule
** Page 105 *******************************************************************
>>> def changer(x, y):
... x = 2 # changes local name's value only
... y[0] = 'spam' # changes shared object in place
...
>>> X = 1
>>> L = [1, 2]
>>> changer(X, L) # pass immutable and mutable (use L[:] to avoid changes)
>>> X, L # X unchanged, L is different
(1, ['spam', 2])
** Page 107 *******************************************************************
>>> def multiple(x, y):
... x = 2 # changes local names only
... y = [3, 4]
... return x, y # return new values in a tuple
...
>>> X = 1
>>> L = [1, 2]
>>> X, L = multiple(X, L) # assign results to caller's names
>>> X, L
(2, [3, 4])
** Page 108-110 ***************************************************************
def func(spam, eggs, toast=0, ham=0): # first 2 required
print (spam, eggs, toast, ham)
func(1, 2) # output: (1, 2, 0, 0)
func(1, ham=1, eggs=0) # output: (1, 0, 0, 1)
func(spam=1, eggs=0) # output: (1, 0, 0, 0)
func(toast=1, eggs=2, spam=3) # output: (3, 2, 1, 0)
func(1, 2, 3, 4) # output: (1, 2, 3, 4)
# put this code in a new module file called
# "inter2.py", in a directory on PYTHONPATH
def intersect(*args):
res = []
for x in args[0]: # scan first sequence
for other in args[1:]: # for all other args
if x not in other: break # item in each one?
else: # no: break out of loop
res.append(x) # yes: add items to end
return res
def union(*args):
res = []
for seq in args: # for all args
for x in seq: # for all nodes
if not x in res:
res.append(x) # add new items to result
return res
% python
>>> from inter2 import intersect, union
>>> s1, s2, s3 = "SPAM", "SCAM", "SLAM"
>>> intersect(s1, s2), union(s1, s2) # 2 operands
(['S', 'A', 'M'], ['S', 'P', 'A', 'M', 'C'])
>>> intersect([1,2,3], (1,4)) # mixed types
[1]
>>> intersect(s1, s2, s3) # 3 operands
['S', 'A', 'M']
>>> union(s1, s2, s3)
['S', 'P', 'A', 'M', 'C', 'L']
** Page 112-115 ***************************************************************
>>> def func(x, y, z): return x + y + z
...
>>> func(2, 3, 4)
9
>>> f = lambda x, y, z: x + y + z
>>> f(2, 3, 4)
9
>>> x = (lambda a="fee", b="fie", c="foe": a + b + c)
>>> x("wee")
'weefiefoe'
>>> apply(func, (2, 3, 4))
9
>>> apply(f, (2, 3, 4))
9
L = [lambda x: x**2, lambda x: x**3, lambda x: x**4]
for f in L:
print f(2) # prints 4, 8, 16
print L[0](3) # prints 9
>>> counters = [1, 2, 3, 4]
>>>
>>> updated = []
>>> for x in counters:
... updated.append(x + 10) # add 10 to each item
...
>>> updated
[11, 12, 13, 14]
>>> def inc(x): return x + 10 # function to be run
...
>>> map(inc, counters) # collect results
[11, 12, 13, 14]
>>> map((lambda x: x + 3), counters) # function expression
[4, 5, 6, 7]
>>> def proc(x):
... print x # no return is a None return
...
>>> x = proc('testing 123...')
testing 123...
>>> print x
None
>>> list = [1, 2, 3]
>>> list = list.append(4) # append is a 'procedure'
>>> print list # append changes list in-place
None
** Page 116 *******************************************************************
>>> def echo(message): # echo assigned to a function object
... print message
...
>>> x = echo # now x references it too
>>> x('Hello world!') # call the object by adding ()
Hello world!
>>> def indirect(func, arg):
... func(arg) # call object by adding ()
...
>>> indirect(echo, 'Hello jello!') # pass function to a function
Hello jello!
>>> schedule = [ (echo, 'Spam!'), (echo, 'Ham!') ]
>>> for (func, arg) in schedule:
... apply(func, (arg,))
...
Spam!
Ham!
** Page 117-118 ***************************************************************
>>> X = 99
>>> def selector(): # X used but not assigned
... print X # X found in global scope
...
>>> selector()
99
>>> def selector():
... print X # does not yet exist!
... X = 88 # X classified as a local name (everywhere)
... # can also happen if "import X", "def X",...
>>> selector()
>>> def selector():
... global X # force X to be global (everywhere)
... print X
... X = 88
...
>>> selector()
99
>>> X = 99
>>> def selector():
... import __main__ # import enclosing module
... print __main__.X # qualify to get to global version of name
... X = 88 # unqualified X classified as local
... print X # prints local version of name
...
>>> selector()
99
88
** Page 119 *******************************************************************
>>> def outer(x):
... def inner(i): # assign in outer's local
... print i, # i is in inner's local
... if i: inner(i-1) # not in my local or global!
... inner(x)
...
>>> outer(3)
3
Traceback (innermost last):
>>> def outer(x):
... global inner
... def inner(i): # assign in enclosing module
... print i,
... if i: inner(i-1) # found in my global scope now
... inner(x)
...
>>> outer(3)
3 2 1 0
** Page 120-121 **************************************************************
>>> def outer(x, y):
... def inner(a=x, b=y): # save outer's x,y bindings/objects
... return a**b # can't use x and y directly here
... return inner
...
>>> x = outer(2, 4)
>>> x()
16
>>> def outer(x, y):
... return lambda a=x, b=y: a**b
...
>>> y = outer(2, 5)
>>> y()
32
>>> def outer(x):
... def inner(i, self=inner): # name not defined yet
... print i,
... if i: self(i-1)
... inner(x)
...
>>> outer(3)
Traceback (innermost last):
>>> def outer(x):
... fillin = [None]
... def inner(i, self=fillin): # save mutable
... print i,
... if i: self[0](i-1) # assume it's set
... fillin[0] = inner # plug value now
... inner(x)
...
>>> outer(3)
3 2 1 0
>>> def inner(i): # define module level name
... print i,
... if i: inner(i-1) # no worries: it's a global
...
>>> def outer(x):
... inner(x)
...
>>> outer(3)
3 2 1 0
** Page 122 *******************************************************************
>>> def saver(x=[]): # saves away a list object
... x.append(1) # changes same object each time!
... print x
...
>>> saver([2]) # default not used
[2, 1]
>>> saver() # default used
[1]
>>> saver() # grows on each call
[1, 1]
>>> saver()
[1, 1, 1]
>>> def saver(x=None):
... if x is None: # no argument passed?
... x = [] # run code to make a new list
... x.append(1) # changes new list object
... print x
...
>>> saver([2])
[2, 1]
>>> saver() # doesn't grow here
[1]
>>> saver()
[1]
*** see solutions file for this chapter for exercise code *** lpython/dos/examples/chapter5.txt 001777 000000 000000 00000016577 06713511474 013141 ** Page 128 *******************************************************************
# put this code in a file called "module1.py",
# located in a directory on PYTHONPATH (or ".")
def printer(x): # module attribute
print x
# then, import it in the interactive prompt
% python
>>> import module1 # get module
>>> module1.printer('Hello world!') # qualify to get names (module.name)
Hello world!
>>> from module1 import printer # get an export
>>> printer('Hello world!') # no need to qualify name
Hello world!
>>> from module1 import * # get all exports
>>> printer('Hello world!')
Hello world!
** Page 130 *******************************************************************
# put this code in a file called "module2.py"
print 'starting to load...'
import sys
name = 42
def func(): pass
class klass: pass
print 'done loading.'
# now, use in interactively
>>> import module2
starting to load...
done loading.
>>> module2.sys
>>> module2.name
42
>>> module2.func, module2.klass
(, )
>>> module2.__dict__.keys()
['__file__', 'name', '__name__', 'sys', '__doc__', '__builtins__', 'klass',
'func']
** Page 132 ******************************************************************
% cat simple.py
print 'hello'
spam = 1 # initialize variable
% python
>>> import simple # first import: loads and runs file's code
hello
>>> simple.spam # assignment makes an attribute
1
>>> simple.spam = 2 # change attribute in module
>>>
>>> import simple # just fetches already-loaded module
>>> simple.spam # code wasn't rerun: attribute unchanged
2
** Page 133 *******************************************************************
% cat small.py
x = 1
y = [1, 2]
% python
>>> from small import x, y # copy two names out
>>> x = 42 # changes local x only
>>> y[0] = 42 # changes shared mutable in-place
>>>
>>> import small # get module name (from doesn't)
>>> small.x # small's x is not my x
1
>>> small.y # but we share a changed mutable
[42, 2]
# emulating "from"
import module # fetch the module object
name1 = module.name1 # copy names out by assignment
name2 = module.name2
...
del module # get rid of the module name
** Page 135 *******************************************************************
% cat changer.py
message = "First version"
def printer():
print message
% python
>>> import changer
>>> changer.printer()
First version
>>>
# change "changer.py" now...
% vi changer.py
% cat changer.py
message = "After editing"
def printer():
print 'reloaded:', message
# back to the interpreter...
>>> import changer
>>> changer.printer() # no effect: uses loaded module
First version
>>> reload(changer) # forces new code to load/run
>>> changer.printer() # runs the new version now
reloaded: After editing
** Page 138 *******************************************************************
# put this in a file called runme.py
def tester():
print "It's Christmas in Heaven..."
if __name__ == '__main__': # only when run
tester() # not when imported
% python
>>> import runme
>>> runme.tester()
It's Christmas in Heaven...
% python runme.py
It's Christmas in Heaven...
>>> import sys
>>> sys.path
['.', 'c:\\python\\lib', 'c:\\python\\lib\\tkinter']
>>> sys.path = ['.'] # change module search path
>>> sys.path.append('c:\\book\\examples') # escape backlashes as "\\"
>>> sys.path # or use r'...' strings
['.', 'c:\\book\\examples']
>>> import string
Traceback (innermost last):
** Page 142 *******************************************************************
# mydir.py: a module which lists the namespaces of other modules
verbose = 1
def listing(module):
if verbose:
print "-"*30
print "name:", module.___name__, "file:", module.__file__
print "-"*30
count = 0
for attr in module.__dict__.keys(): # scan namespace
print "%02d) %s" % (count, attr),
if attr[0:2] == "__":
print "" # skip __file__, etc.
else:
print getattr(module, attr) # same as .__dict__[attr]
count = count+1
if verbose:
print "-"*30
print module.__name__, "has %d names" % count
print "-"*30
if __name__ == "__main__":
import mydir
listing(mydir) # self-test code: list myself
C:\python> python mydir.py
------------------------------
name: mydir file: mydir.py
------------------------------
00) __file__
01) __name__
02) listing
03) __doc__
04) __builtins__
05) verbose 1
------------------------------
mydir has 6 names
------------------------------
** Page 143 *******************************************************************
>>> modname = "string"
>>> exec "import " + modname # run a string of code
>>> string # imported in this namespace
>>> modname = "string"
>>> string = __import__(modname)
>>> string
** Page 144 *******************************************************************
# module nested1.py
X = 99
def printer(): print X
# module nested2.py
from nested1 import X, printer # copy names out
X = 88 # changes my "X" only!
printer() # nested1's X is still 99
% python nested2.py
99
# module nested3.py
import nested1 # get module as a whole
nested1.X = 88 # okay: change nested1's X
nested1.printer()
% python nested3.py
88
** Page 145 *******************************************************************
func1() # error: "func1" not yet assigned
def func1():
print func2() # okay: "func2" looked up later
func1() # error: "func2" not yet assigned
def func2():
return "Hello"
func1() # okay: "func1" and "func2" assigned
** Page 146 *******************************************************************
# recur1.py
X = 1
import recur2 # run recur2 now if doesn't exist
Y = 2
# recur2.py
from recur1 import X # okay: "X" already assigned
from recur1 import Y # error: "Y" not yet assigned
>>> import recur1
Traceback (innermost last):
** Page 147 *******************************************************************
from module import X # X may not reflect any module reloads!
...
reload(module) # changes module, not my names
X # still references old object
# versus
import module # get module, not names
...
reload(module) # changes module in-place
module.X # get current X: reflects module reloads
% cat A.py
import B # not reloaded when A is
import C # just an import of an already-loaded module
% python
>>> . . .
>>> reload(A)
lpython/dos/examples/chapter6.txt 001777 000000 000000 00000050760 06713511756 013135 ** Page 153-154 ***************************************************************
>>> class FirstClass: # define a class object
... def setdata(self, value): # define class methods
... self.data = value # self is the instance
... def display(self):
... print self.data # self.data: per instance
>>> x = FirstClass() # make two instances
>>> y = FirstClass() # each is a new namespace
>>> x.setdata("King Arthur") # call methods: self is x or y
>>> y.setdata(3.14159) # runs: FirstClass.setdata(y, 3.14159)
>>> x.display() # self.data differs in each
King Arthur
>>> y.display()
3.14159
>>> x.data = "New value" # can get/set attributes
>>> x.display() # outside the class too
New value
** Page 155-156 ***************************************************************
>>> class SecondClass(FirstClass): # inherits setdata
... def display(self): # changes display
... print 'Current value = "%s"' % self.data
>>> z = SecondClass()
>>> z.setdata(42) # setdata found in FirstClass
>>> z.display() # finds overridden method in SecondClass
Current value = "42"
>>> x.display() # x is still a FirstClass instance (old message)
New value
** Page 157 *******************************************************************
>>> class ThirdClass(SecondClass): # is-a SecondClass
... def __init__(self, value): # on "ThirdClass(value)"
... self.data = value
... def __add__(self, other): # on "self + other"
... return ThirdClass(self.data + other)
... def __mul__(self, other):
... self.data = self.data * other # on "self * other"
>>> a = ThirdClass("abc") # new __init__ called
>>> a.display() # inherited method
Current value = "abc"
>>> b = a + 'xyz' # new __add__ called: makes a new instance
>>> b.display()
Current value = "abcxyz"
>>> a * 3 # new __mul__ called: changes instance in-place
>>> a.display()
Current value = "abcabcabc"
** Page 159 *******************************************************************
# type these interactively, or import from a module file
class aSuperclass: pass
class Subclass(aSuperclass): # define subclass
data = 'spam' # assign class attr
def __init__(self, value): # assign class attr
self.data = value # assign instance attr
def display(self):
print self.data, Subclass.data # instance, class
>>> x = Subclass(1) # make two instance objects
>>> y = Subclass(2) # each has its own "data"
>>> x.display(); y.display() # "self.data" differs, "Subclass.data" same
1 spam
2 spam
** Page 160 *******************************************************************
class NextClass: # define class
def printer(self, text): # define method
print text
>>> x = NextClass() # make instance
>>> x.printer('Hello world!') # call its method
Hello world!
>>> NextClass.printer(x, 'Hello world!') # class method
Hello world!
** Page 162 *******************************************************************
>>> class Super:
... def method(self):
... print 'in Super.method'
...
>>> class Sub(Super):
... def method(self): # override method
... print 'starting Sub.method' # add actions here
... Super.method(self) # run default action
... print 'ending Sub.method'
...
>>> x = Super() # make a Super instance
>>> x.method() # runs Super.method
in Super.method
>>> x = Sub() # make a Sub instance
>>> x.method() # runs Sub.method, which calls Super.method
starting Sub.method
in Super.method
ending Sub.method
** Page 163 *******************************************************************
# file specialize.py
class Super:
def method(self):
print 'in Super.method' # default
def delegate(self):
self.action() # expected
class Inheritor(Super):
pass
class Replacer(Super):
def method(self):
print 'in Replacer.method'
class Extender(Super):
def method(self):
print 'starting Extender.method'
Super.method(self)
print 'ending Extender.method'
class Provider(Super):
def action(self):
print 'in Provider.action'
if __name__ == '__main__':
for klass in (Inheritor, Replacer, Extender):
print '\n' + klass.__name__ + '...'
klass().method()
print '\nProvider...'
Provider().delegate()
% python specialize.py
Inheritor...
in Super.method
Replacer...
in Replacer.method
Extender...
starting Extender.method
in Super.method
ending Extender.method
Provider...
in Provider.action
** Page 165-168 ***************************************************************
# number.py
class Number:
def __init__(self, start): # on Number(start)
self.data = start
def __sub__(self, other): # on instance - other
return Number(self.data - other) # result is a new instance
>>> from number import Number # fetch class from module
>>> X = Number(5) # calls Number.__init__(X, 5)
>>> Y = X - 2 # calls Number.__sub__(X, 2)
>>> Y.data
3
>>> class indexer:
... def __getitem__(self, index):
... return index ** 2
...
>>> X = indexer()
>>> for i in range(5):
... print X[i], # X[i] calls __getitem__(X, i)
...
0 1 4 9 16
>>> class stepper:
... def __getitem__(self, i):
... return self.data[i]
...
>>> X = stepper() # X is a stepper object
>>> X.data = "Spam"
>>>
>>> for item in X: # for loops call __getitem__
... print item, # for indexes items 0..N
...
S p a m
>>>
>>> 'p' in X # 'in' operator calls __getitem__ too
1
>>> class empty:
... def __getattr__(self, attrname):
... if attrname == "age":
... return 37
... else:
... raise AttributeError, attrname
...
>>> X = empty()
>>> X.age
37
>>> X.name
Traceback (innermost last):
File "", line 1, in ?
File "", line 6, in __getattr__
AttributeError: name
>>> class adder:
... def __init__(self, value=0):
... self.data = value # initialize data
... def __add__(self, other):
... self.data = self.data + other # add other in-place
... def __repr__(self):
... return `self.data` # convert to string
...
>>> X = adder(1) # __init__
>>> X + 2; X + 2 # __add__
>>> X # __repr__
5
** Page 169 *******************************************************************
>>> class super:
... def hello(self):
... self.data1 = "spam"
...
>>> class sub(super):
... def howdy(self):
... self.data2 = "eggs"
...
>>> X = sub() # make a new namespace (dictionary)
>>> X.__dict__
{}
>>> X.hello() # changes instance namespace
>>> X.__dict__
{'data1': 'spam'}
>>> X.howdy() # changes instance namespace
>>> X.__dict__
{'data2': 'eggs', 'data1': 'spam'}
>>> super.__dict__
{'hello': , '__doc__': None}
>>> sub.__dict__
{'__doc__': None, 'howdy': }
>>> X.data3 = "toast"
>>> X.__dict__
{'data3': 'toast', 'data2': 'eggs', 'data1': 'spam'}
** Page 171 *******************************************************************
# file employees.py
class Employee:
def __init__(self, name, salary=0):
self.name = name
self.salary = salary
def giveRaise(self, percent):
self.salary = self.salary + (self.salary * percent)
def work(self):
print self.name, "does stuff"
def __repr__(self):
return "" % (self.name, self.salary)
class Chef(Employee):
def __init__(self, name):
Employee.__init__(self, name, 50000)
def work(self):
print self.name, "makes food"
class Server(Employee):
def __init__(self, name):
Employee.__init__(self, name, 40000)
def work(self):
print self.name, "interfaces with customer"
class PizzaRobot(Chef):
def __init__(self, name):
Chef.__init__(self, name)
def work(self):
print self.name, "makes pizza"
if __name__ == "__main__":
bob = PizzaRobot('bob') # make a robot named bob
print bob # runs inherited __repr__
bob.giveRaise(0.20) # give bob a 20% raise
print bob; print
for klass in Employee, Chef, Server, PizzaRobot:
obj = klass(klass.__name__)
obj.work()
C:\python\examples> python employees.py
Employee does stuff
Chef makes food
Server interfaces with customer
PizzaRobot makes pizza
** Page 173 *******************************************************************
# file pizzashop.py
from employees import PizzaRobot, Server
class Customer:
def __init__(self, name):
self.name = name
def order(self, server):
print self.name, "orders from", server
def pay(self, server):
print self.name, "pays for item to", server
class Oven:
def bake(self):
print "oven bakes"
class PizzaShop:
def __init__(self):
self.server = Server('Pat') # embed other objects
self.chef = PizzaRobot('Bob') # a robot named bob
self.oven = Oven()
def order(self, name):
customer = Customer(name) # activate other objects
customer.order(self.server) # customer orders from server
self.chef.work()
self.oven.bake()
customer.pay(self.server)
if __name__ == "__main__":
scene = PizzaShop() # make the composite
scene.order('Homer') # simulate Homer's order
print '...'
scene.order('Shaggy') # simulate Shaggy's order
C:\python\examples> python pizzashop.py
Homer orders from
Bob makes pizza
oven bakes
Homer pays for item to
...
Shaggy orders from
Bob makes pizza
oven bakes
Shaggy pays for item to
** Page 174 *******************************************************************
import pickle
object = someClass()
file = open(filename, 'w') # create external file
pickle.dump(object, file) # save object in file
file = open(filename, 'r')
object = pickle.load(file) # fetch it back later
import shelve
object = someClass()
dbase = shelve.open('filename')
dbase['key'] = object # save under key
...
object = dbase['key'] # fetch it back later
** Page 175 *******************************************************************
# file trace.py
class wrapper:
def __init__(self, object):
self.wrapped = object # save object
def __getattr__(self, attrname):
print 'Trace:', attrname # trace fetch
return getattr(self.wrapped, attrname) # delegate fetch
>>> from trace import wrapper
>>> x = wrapper([1,2,3]) # wrap a list
>>> x.append(4) # delegate to list method
Trace: append
>>> x.wrapped # print my member
[1, 2, 3, 4]
>>> x = wrapper({"a": 1, "b": 2}) # wrap a dictionary
>>> x.keys() # delegate to dictionary method
Trace: keys
['a', 'b']
# file set.py
class Set:
def __init__(self, value = []): # constructor
self.data = [] # manages a list
self.concat(value)
def intersect(self, other): # other is any sequence
res = [] # self is the subject
for x in self.data:
if x in other: # pick common items
res.append(x)
return Set(res) # return a new Set
def union(self, other): # other is any sequence
res = self.data[:] # copy of my list
for x in other: # add items in other
if not x in res:
res.append(x)
return Set(res)
def concat(self, value): # value: list, Set...
for x in value: # removes duplicates
if not x in self.data:
self.data.append(x)
def __len__(self): return len(self.data) # on len(self)
def __getitem__(self, key): return self.data[key] # on self[i]
def __and__(self, other): return self.intersect(other) # on self & other
def __or__(self, other): return self.union(other) # on self | other
def __repr__(self): return 'Set:' + `self.data` # on print
** Page 177 *******************************************************************
>>> class Spam:
... def __init__(self): # no __repr__
... self.data1 = "food"
...
>>> X = Spam()
>>> print X # default format: class, address
# file mytools.py
# Lister can be mixed-in to any class, to
# provide a formatted print of instances
# via inheritance of __repr__ coded here;
# self is the instance of the lowest class;
class Lister:
def __repr__(self):
return ("" %
(self.__class__.__name__, # my class's name
id(self), # my address
self.attrnames()) ) # name=value list
def attrnames(self):
result = ''
for attr in self.__dict__.keys(): # scan instance namespace dict
if attr[:2] == '__':
result = result + "\tname %s=\n" % attr
else:
result = result + "\tname %s=%s\n" % (attr, self.__dict__[attr])
return result
# file testmixin.py
from mytools import Lister # get tool class
class Super:
def __init__(self): # superclass __init__
self.data1 = "spam"
class Sub(Super, Lister): # mix-in a __repr__
def __init__(self): # Lister has access to self
Super.__init__(self)
self.data2 = "eggs" # more instance attrs
self.data3 = 42
if __name__ == "__main__":
X = Sub()
print X # mixed-in repr
C:\python\examples> python testmixin.py
>>> from mytools import Lister
>>> class x(Lister):
... pass
...
>>> t = x()
>>> t.a = 1; t.b = 2; t.c = 3
>>> t
** Page 179 *******************************************************************
def factory(aClass, *args): # varargs tuple
return apply(aClass, args) # call aClass
class Spam:
def doit(self, message):
print message
class Person:
def __init__(self, name, job):
self.name = name
self.job = job
object1 = factory(Spam) # make a Spam
object2 = factory(Person, "Guido", "guru") # make a Person
def factory(aClass, *args, **kwargs): # +kwargs dict
return apply(aClass, args, kwargs) # call aClass
** Page 180 *******************************************************************
class Spam:
def doit(self, message):
print message
object1 = Spam()
x = object1.doit # bound method object
x('hello world') # instance is implied
t = Spam.doit # unbound method object
t(object1, 'howdy') # pass in instance
** Page 182 *******************************************************************
# file docstr.py
"I am: docstr.__doc__"
class spam:
"I am: spam.__doc__ or docstr.spam.__doc__"
def method(self, arg):
"I am: spam.method.__doc__ or self.method.__doc__"
pass
def func(args):
"I am: docstr.func.__doc__"
pass
>>> import docstr
>>> docstr.__doc__
'I am: docstr.__doc__'
>>> docstr.spam.__doc__
'I am: spam.__doc__ or docstr.spam.__doc__'
>>> docstr.spam.method.__doc__
'I am: spam.method.__doc__ or self.method.__doc__'
>>> docstr.func.__doc__
'I am: docstr.func.__doc__'
** Page 183 *******************************************************************
>>> class X:
... a = 1 # class attribute
...
>>> I = X()
>>> I.a # inherited by instance
1
>>> X.a
1
>>> X.a = 2 # may change more than X
>>> I.a # I changes too
2
>>> J = X() # J inherits from X's runtime values
>>> J.a # (but assigning to J.a changes a in J, not X or I)
2
class X: pass # make a few attribute namespaces
class Y: pass
X.a = 1 # use class attributes as variables
X.b = 2 # no instances anywhere to be found
X.c = 3
Y.a = X.a + X.b + X.c
for X.i in range(Y.a): print X.i # prints 0..5
>>> class Record: pass
...
>>> X = Record()
>>> X.name = 'bob'
>>> X.job = 'Pizza maker'
** Page 185 *******************************************************************
class Lister:
def __repr__(self): ...
def other(self): ...
class Super:
def __repr__(self): ...
def other(self): ...
class Sub(Super, Lister): # pick up Super's __repr__, by listing it first
other = Lister.other # but explicitly pick up Lister's version of other
def __init__(self):
...
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
def printNumInstances():
print "Number of instances created: ", Spam.numInstances
>>> from spam import *
>>> a = Spam()
>>> b = Spam()
>>> c = Spam()
>>> Spam.printNumInstances()
Traceback (innermost last):
File "", line 1, in ?
TypeError: unbound method must be called with class instance 1st argument
def printNumInstances():
print "Number of instances created: ", Spam.numInstances
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
>>> import spam
>>> a = spam.Spam()
>>> b = spam.Spam()
>>> c = spam.Spam()
>>> spam.printNumInstances()
Number of instances created: 3
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
def printNumInstances(self):
print "Number of instances created: ", Spam.numInstances
>>> from spam import Spam
>>> a, b, c = Spam(), Spam(), Spam()
>>> a.printNumInstances()
Number of instances created: 3
>>> b.printNumInstances()
Number of instances created: 3
>>> Spam().printNumInstances()
Number of instances created: 4
** Page 187 *******************************************************************
# file nester.py
def generate():
class Spam:
count = 1
def method(self): # name Spam not visible:
print Spam.count # not local (def), global (module), built-in
return Spam()
generate().method()
C:\python\examples> python nester.py
Traceback (innermost last):
...
NameError: Spam
def generate():
global Spam # force Spam to module scope
class Spam:
count = 1
def method(self):
print Spam.count # works: in global (enclosing module)
return Spam()
generate().method() # prints 1
def generate():
return Spam()
class Spam: # define at module top-level
count = 1
def method(self):
print Spam.count # works: in global (enclosing module)
generate().method()
def generate():
class Spam:
count = 1
def method(self):
print self.__class__.count # works: qualify to get class
return Spam()
generate().method()
def generate():
class Spam:
count = 1
fillin = [None]
def method(self, klass=fillin): # save from enclosing scope
print klass[0].count # works: default plugged-in
Spam.fillin[0] = Spam
return Spam()
generate().method()
lpython/dos/examples/chapter7.txt 001777 000000 000000 00000012334 06713512076 013125 ** Page 198 *******************************************************************
% cat bad.py
def gobad(x, y):
return x / y
def gosouth(x):
print gobad(x, 0)
gosouth(1)
% python bad.py
Traceback (innermost last):
File "bad.py", line 7, in ?
gosouth(1)
File "bad.py", line 5, in gosouth
print gobad(x, 0)
File "bad.py", line 2, in gobad
return x / y
ZeroDivisionError: integer division or modulo
** Page 199 *******************************************************************
def kaboom(list, n):
print list[n] # trigger IndexError
try:
kaboom([0, 1, 2], 3)
except IndexError: # catch exception here
print 'Hello world!'
MyError = "my error"
def stuff(file):
raise MyError
file = open('data', 'r') # open an existing file
try:
stuff(file) # raises exception
finally:
file.close() # always close file
** Page 200 *******************************************************************
while 1:
try:
line = raw_input() # read line from stdin
except EOFError:
break # exit loop at end of file
else:
Process next 'line' here...
Found = "Item found"
def searcher():
raise found or return
try:
searcher()
except Found: # exception if item was found
Success
else: # else returned: not found
Failure
try:
Run program
except: # all uncaught exceptions come here
import sys
print 'uncaught!', sys.exc_type, sys.exc_value
try:
action()
except NameError:
...
except IndexError
...
except KeyError:
...
except (AttributeError, TypeError, SyntaxError):
...
else:
...
** Page 203 *******************************************************************
# file nestexc.py
def action2():
print 1 + [] # generate TypeError
def action1():
try:
action2()
except TypeError: # most recent matching try
print 'inner try'
try:
action1()
except TypeError: # here only if action1 reraises
print 'outer try'
% python nestexc.py
inner try
# file finally.py
def divide(x, y):
return x / y # divide-by-zero error?
def tester(y):
try:
print divide(8, y)
finally:
print 'on the way out...'
print '\nTest 1:'; tester(2)
print '\nTest 2:'; tester(0) # trigger error
% python finally.py
Test 1:
4
on the way out...
Test 2:
on the way out...
Traceback (innermost last):
File "finally.py", line 11, in ?
print 'Test 2:'; tester(0)
File "finally.py", line 6, in tester
print divide(8, y)
File "finally.py", line 2, in divide
return x / y # divide-by-zero error?
ZeroDivisionError: integer division or modulo
** Page 204 *******************************************************************
# file helloexc.py
myException = 'Error' # string object
def raiser1():
raise myException, "hello" # raise, pass data
def raiser2():
raise myException # raise, None implied
def tryer(func):
try:
func()
except myException, extraInfo: # run func, catch exception + data
print 'got this:', extraInfo
% python
>>> from helloexc import *
>>> tryer(raiser1) # gets explicitly passed extra data
got this: hello
>>> tryer(raiser2) # gets None by default
got this: None
# sidebar
def doStuff():
doFirstThing() # we don't care about exceptions here
doNextThing() # so we don’t need to detect them here
...
doLastThing()
if__name__ == '__main__':
try:
doStuff() # this is where we care about the result
except: #so it's the only place we need to check
badEnding()
else:
goodEnding()
** Page 207 *******************************************************************
# file classexc.py
class General: pass
class Specific(General): pass
def raiser1():
X = General() # raise listed class instance
raise X
def raiser2():
X = Specific() # raise instance of subclass
raise X
for func in (raiser1, raiser2):
try:
func()
except General: # match General or any subclass of it
import sys
print 'caught:', sys.exc_type
% python classexc.py
caught:
caught:
** Page 209 *******************************************************************
>>> ex1 = "spam"
>>> ex2 = "spam"
>>>
>>> ex1 == ex2, ex1 is ex2
(1, 0)
>>> try:
... raise ex1
... except ex1:
... print 'got it'
...
got it
>>> try:
... raise ex1
... except ex2:
... print 'Got it'
...
Traceback (innermost last):
File "", line 2, in ?
spam
try:
...
except:
... # everything comes here!
try:
x = myditctionary[spam] # oops: misspelled
except:
x = None # assume we got KeyError or IndexError
try:
...
except (myerror1, myerror2): # what if I add a myerror3?
... # nonerrors
else:
... # assumed to be an error
lpython/dos/examples/chapter8.txt 001777 000000 000000 00000035540 06713512334 013127 ** Page 216 *******************************************************************
>>> dir([]) # what are the attributes of lists?
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort']
>>> dir(()) # what are the attributes of tuples?
[] # tuples have no attributes!
>>> dir(sys.stdin) # what are the attributes of files?
['close', 'closed', 'fileno', 'flush', 'isatty', 'mode', 'name', 'read',
'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate',
'write', 'writelines']
>>> dir(sys) # modules are objects too
['__doc__', '__name__', 'argv', 'builtin_module_names', 'copyright', 'dllhandle'
, 'exc_info', 'exc_type', 'exec_prefix', 'executable', 'exit', 'getrefcount',
'maxint', 'modules', 'path', 'platform', 'prefix', 'ps1', 'ps2',
'setcheckinterval', 'setprofile', 'settrace', 'stderr', 'stdin', 'stdout',
'version', 'winver']
>>> type(sys.version) # what kind of thing is 'version'?
>>> print sys.version # what is the value of this string?
1.5 (#0, Dec 30 1997, 23:24:20) [MSC 32 bit (Intel)]
** Page 217 *******************************************************************
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'EOFError', 'Ellipsis',
'Exception', 'FloatingPointError', 'IOError', 'ImportError', 'IndexError',
'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError',
'None', 'OverflowError', 'RuntimeError', 'StandardError', 'SyntaxError',
'SystemError', 'SystemExit', 'TypeError', 'ValueError', 'ZeroDivisionError',
'__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'callable',
'chr', 'cmp', 'coerce', 'compile', 'complex', 'delattr', 'dir', 'divmod', 'eval',
'execfile', 'filter', 'float', 'getattr', 'globals', 'hasattr', 'hash', 'hex',
'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'len', 'list',
'locals', 'long', 'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'range',
'raw_input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'slice', 'str',
'tuple', 'type', 'vars', 'xrange']
** Page 218 *******************************************************************
>>> int(1.0), int(1.4), int(1.9), round(1.9), int(round(1.9))
(1, 1, 1, 2.0, 2)
>>> int("1")
1
>>> int("1.2") # this doesn't work
Traceback (innermost last):
File "", line 1, in ?
ValueError: invalid literal for int(): 1.2
>>> int("1.0") # interestingly, neither does this
Traceback (innermost last): # since 1.0 is also not a valid
File "", line 1, in ? # integer literal
ValueError: invalid literal for int(): 1.0
>>> hex(1000), oct(1000), complex(1000), long(1000)
('0x3e8', '01750', (1000+0j), 1000L)
>>> def safeint(candidate):
... import math
... truncated = math.floor(float(candidate))
... rounded = round(float(candidate))
... if truncated == rounded:
... return int(truncated)
... else:
... raise ValueError, "argument would lose precision when cast to integer"
...
>>> safeint(3.0)
3
>>> safeint("3.0")
3
>>> safeint(3.1)
Traceback (innermost last):
File "", line 1, in ?
File "", line 6, in safeint
ValueError: argument would lose precision when cast to integer
>>> abs(-1), abs(-1.2), abs(-3+4j)
(1, 1.2, 5.0) # 5 is sqrt(3*3 + 4*4)
>>> map(ord, "test") # remember that strings are sequences
[116, 101, 115, 116] # of characters, so map can be used
>>> chr(64)
'@'
>>> ord('@')
64
# map returns a list of single characters, so it
# needs to be 'join'ed into a str
>>> map(chr, (83, 112, 97, 109, 33))
['S', 'p', 'a', 'm', '! ']
>>> import string
>>> string.join(map(chr, (83, 112, 97, 109, 33)), '')
'Spam!'
>>> min("pif", "paf", "pof") # when called with multiple 'paf' arguments
# return appropriate one
>>> min("ZELDA!"), max("ZELDA!") # when called with a sequence, '!', 'Z'
# return the min/max element of it
** Page 220 *******************************************************************
>>> str(dir())
"['__builtins__', '__doc__', '__name__']"
>>> list("tomato")
['t', 'o', 'm', 'a', 't', 'o']
>>> list((1,2,3))
[1, 2, 3]
>>> tuple("tomato")
('t', 'o', 'm', 'a', 't', 'o')
>>> tuple([0])
(0,)
>>> int("3")
3
>>> long("3")
3L
>>> float("3")
3.0
>>> complex(3,5)
(3+5j)
>>> hex(10000)
'0x2710'
>>> oct(10000)
'023420'
>>> ord('A')
64
>>> chr(65)
'A'
>>> min([5,1,2,3,4])
1
>>> min(5,1,2,3,4)
1
>>> max([5,1,2,3,4])
5
>>> max(5,1,2,3,4)
5
** Page 221 *******************************************************************
>>> def increment_attribute(object, attrname):
... if not hasattr(object, attrname):
... setattr(object, attrname, 1)
... else:
... setattr(object, attrname, getattr(object, attrname) + 1)
...
>>> class Test: pass
...
>>> aname = 'foo'
>>> increment_attribute(Test, aname) # create Test.foo and set it to
1
>>> increment_attribute(Test, aname) # increment Test.foo
>>> Test.foo
2
def increment_attribute(object, attrname):
setattr(object, attrname, getattr(object, attrname, 0) + 1)
** Page 222 *******************************************************************
>>> code = "x = 'Something'"
>>> x = "Nothing" # sets the value of x
>>> exec code # modifies the value of x!
>>> print x
'Something'
import sys
for argument in sys.argv[1:]: # we'll skip ourselves, or it'll loop!
execfile(argument) # do whatever
>>> z = eval("'xo'*10")
>>> print z
'xoxoxoxoxoxoxoxoxoxo'
>>> z = eval("x = 3")
Traceback (innermost last):
File "", line 1, in ?
File "", line 1
x = 3
^
SyntaxError: invalid syntax
>>> callable(sys.exit), type(sys.exit)
(1, )
>>> callable(sys.version), type(sys.version)
(0, )
** Page 225 *******************************************************************
>>> string.atof("1.4")
1.4
>>> string.atoi("365")
365
>>> string.atol("987654321")
987654321L
>>> string.capitalize("tomato")
'Tomato'
>>> string.capwords("now is the time")
'Now Is The Time'
>>> string.find("now is the time", 'is')
4
>>> string.count("now is the time", 'i')
2
>>> string.replace("now is the time", ' ', '_')
'now_is_the_time'
>>> string.split("now is the time")
['now', 'is', 'the', 'time']
>>> string.join(["now","is","the","time", '*'])
'now*is*the*time'
>>> string.join("now is the time", '*')
'n*o*w* *i*s* *t*h*e* *t*i*m*e'
>>> string.strip(" before and after ")
'before and after'
** Page 228 *******************************************************************
# file pepper.txt
This is a paragraph that mentions bell peppers multiple times. For
one, here is a red pepper and dried tomato salad recipe. I don't like
to use green peppers in my salads as much because they have a harsher
flavor.
This second paragraph mentions red peppers and green peppers but not
the "s" word (s-a-l-a-d), so no bells should show up.
This third paragraph mentions red peppercorns and green peppercorns,
which aren't vegetables but spices (by the way, bell peppers really
aren't peppers, they're chilies, but would you rather have a good cook
or a good botanist prepare your salad?).
# file pepper.py
file = open('pepper.txt')
text = file.read()
import string
paragraphs = string.split(text, '\n\n')
import re
matchstr = re.compile(
r"""\b(red|green) # 'red' or 'green' starting new words
(\s+ # followed by whitespace
pepper # the word 'pepper'
(?!corn) # if not followed immediately by 'corn'
(?=.*salad))""", # and if followed at some point by 'salad'',
re.IGNORECASE | # allow pepper, Pepper, PEPPER, etc.
re.DOTALL | # allow to match newlines as well
re.VERBOSE) # this allows the comments and the newlines above
for paragraph in paragraphs:
fixed_paragraph = matchstr.sub(r'bell\2', paragraph)
print fixed_paragraph+'\n'
/home/David/book$ python pepper.py
This is a paragraph that mentions bell peppers multiple times. For
one, here is a bell pepper and dried tomato salad recipe. I don’t like
to use bell peppers in my salads as much because they have a harsher
flavor.
This second paragraph mentions red peppers and green peppers but not
the "s" word (s-a-l-a-d), so no bells should show up.
This third paragraph mentions red peppercorns and green peppercorns,
which aren’t vegetables but spices (by the way, bell peppers really
aren’t peppers, they’re chilies, but would you rather have a good cook
or a good botanist prepare your salad?).
** Page 231 *******************************************************************
>>> print os.getcwd()
h:\David\book
>>> os.listdir(os.getcwd())
['preface.doc', 'part1.doc', 'part2.doc']
>>> os.rmdir('nonexistent_directory') # how it usually shows up
Traceback (innermost last):
File "", line 1, in ?
os.error: (2, 'No such file or directory')
>>> try: # we can catch the error and take
... os.rmdir('nonexistent directory') # it apart
... except os.error, value:
... print value[0], value[1]
...
2 No such file or directory
>>> print os.environ['SHELL']
/bin/sh
>>> os.environ['STARTDIR'] = 'MyStartDir'
>>> os.system('echo $STARTDIR') # 'echo %STARTDIR%' on DOS/Win
MyStartDir # printed by the shell
0 # return code from echo
** Page 233 *******************************************************************
>>> os.path.split("h:/David/book/part2.doc"
('h:/David/book', 'part2.doc')
>>> print os.path.join(os.getcwd(),
... os.pardir, 'backup', 'part2.doc')
h:\David\book\..\backup\part2.doc
>>> print os.path.expanduser('~/mydir')
h:\David\mydir
>>> print os.path.expandvars('$TMP')
C:\TEMP
>>> print os.path.normpath("/foo/bar\\../tmp")
\foo\tmp
>>> def test_walk(arg, dirname, names):
... print arg, dirname, names
...
>>> os.path.walk('..', test_walk, 'show')
show ..\logs ['errors.log', 'access.log']
show ..\cgi-bin ['test.cgi']
...
** Page 235 *******************************************************************
>>> page = urlopen('http://www.python.org')
>>> page.readline()
'\012'
>>> page.readline()
'\012'
>>> urllib.urlretrieve('http://www.python.org/', 'wwwpython.html')
>>> quote('this & that @ home')
'this%20%26%20that%20%40%20home'
>>> unquote('this%20%26%20that%20%40%20home')
'this & that @ home'
>>> locals()
{'urllib': , '__doc__': None, 'x':3,
'__name__': '__main__', '__builtins__': }
>>> urllib.urlencode(locals())
'urllib=%3cmodule+%27urllib%27%3e&__doc__=None&x=3&
__ name__=__main__&__builtins__=%3cmodule+%27
__builtin__%27%3e'
>>> urlparse('http://www.python.org/FAQ.html')
('http', 'www.python.org', '/FAQ.html', '', '','')
>>> urljoin('http://www.python.org', 'doc/lib')
'http://www.python.org/doc/lib'
** Page 238 *******************************************************************
import struct
data = open('bindat.dat').read()
start, stop = 0, struct.calcsize('fl')
version_number, num_bytes = struct.unpack('fl', data[start:stop])
start, stop = stop, start + struct.calcsize('B'*num_bytes)
bytes = struct.unpack('B'*num_bytes, data[start:stop])
** Page 239 *******************************************************************
>>> import spam # import the module we wish to debug
>>> import pdb # import pdb
>>> pdb.run('instance = spam.Spam()') # start pdb with a statement to run
> (0)?()
(Pdb) break spam.Spam.__init__ # we can set break points
(Pdb) next
> (1)?()
(Pdb) n # 'n' is short for 'next'
> spam.py(3)__init__()
-> def __init__(self):
(Pdb) n
> spam.py(4)__init__()
-> Spam.numInstances = Spam.numInstances + 1
(Pdb) list # show the source code listing
1 class Spam:
2 numInstances = 0
3 B def __init__(self): # note the B for Breakpoint
4 -> Spam.numInstances = Spam.numInstances + 1 # where we are
5 def printNumInstances(self):
6 print "Number of instances created: ", Spam.numInstances
7
[EOF]
(Pdb) where # show the calling stack
(1)?()
> spam.py(4)__init__()
-> Spam.numInstances = Spam.numInstances + 1
(Pdb) Spam.numInstances = 10 # note that we can modify variables
(Pdb) print Spam.numInstances # while the program is being debugged
10
(Pdb) continue # this continues until the next break-
--Return-- # point, but there is none, so we're
> (1)?()->None # done
(Pdb) c # this ends up quitting Pdb
# this is the returned instance
>>> instance.numInstances # note that the change to numInstance
11 # was *before* the increment op
** Page 240 *******************************************************************
# file makezeros.py
def lots_of_appends():
zeros = []
for i in range(10000):
zeros.append(0)
def one_multiply():
zeros = [0] * 10000
# file timings.py
import time, makezeros
def do_timing(num_times, *funcs):
totals = {}
for func in funcs: totals[func] = 0.0
for x in range(num_times):
for func in funcs:
starttime = time.time() # record starting time
apply(func)
stoptime = time.time() # record ending time
elapsed = stoptime-starttime # difference yields time elapsed
totals[func] = totals[func] + elapsed
for func in funcs:
print "Running %s %d times took %.3f seconds" % (func.__name__,
num_times,
totals[func])
do_timing(100, (makezeros.lots_of_appends, makezeros.one_multiply))
csh> python timings.py
Running lots_of_appends 100 times took 7.891 seconds
Running one_multiply 100 times took 0.120 seconds
>>> import profile
>>> from timings import *
>>> from makezeros import *
>>> profile.run('do_timing(100, (lots_of_appends, one_multiply))')
Running lots_of_appends 100 times took 8.773 seconds
Running one_multiply 100 times took 0.090 seconds
...
lpython/dos/examples/chapter9.txt 001777 000000 000000 00000047562 06713512564 013144 ** Page 243 *******************************************************************
newList = myList[:]
newDict = {}
for key in myDict.keys():
newDict[key] = myDict[key]
newDict = myDict.copy()
for key in otherDict.keys():
oneDict[key] = otherDict[key]
def mergeWithoutOverlap(oneDict, otherDict):
newDict = oneDict.copy()
for key in otherDict.keys():
if key in oneDict.keys():
raise ValueError, "the two dictionaries are sharing keys!"
newDict[key] = otherDict[key]
return newDict
def mergeWithOverlap(oneDict, otherDict):
newDict = oneDict.copy()
for key in otherDict.keys():
if key in oneDict.keys():
newDict[key] = oneDict[key], otherDict[key]
else:
newDict[key] = otherDict[key]
return newDict
phoneBook1 = {'michael': '555-1212', 'mark': '554-1121', 'emily': '556-0091'}
phoneBook2 = {'latoya': '555-1255', 'emily': '667-1234'}
** Page 245 *******************************************************************
>>> import copy
>>> listOne = [{"name": "Willie", "city": "Providence, RI"}, 1, "tomato", 3.0]
>>> listTwo = listOne[:] # or listTwo=copy.copy(listOne)
>>> listThree = copy.deepcopy(listOne)
>>> listOne.append("kid")
>>> listOne[0]["city"] = "San Francisco, CA"
>>> print listOne, listTwo, listThree
[{'name': 'Willie', 'city': 'San Francisco, CA'}, 1, 'tomato', 3.0, 'kid']
[{'name': 'Willie', 'city': 'San Francisco, CA'}, 1, 'tomato', 3.0]
[{'name': 'Willie', 'city': 'Providence, RI'}, 1, 'tomato', 3.0]
** Page 246 *******************************************************************
listCopy = list(myTuple)
listCopy.sort()
for item in listCopy:
print item # or whatever needs doing
keys = myDict.keys() # returns an unsorted list of the keys in the dict
keys.sort()
for key in keys: # print key, value pairs
print key, myDict[key] # sorted by key
>>> def caseIndependentSort(something, other):
... something, other = string.lower(something), string.lower(other)
... return cmp(something, other)
...
>>> testList = ['this', 'is', 'A', 'sorted', 'List']
>>> testList.sort()
>>> print testList
['A', 'List', 'is', 'sorted', 'this']
>>> testList.sort(caseIndependentSort)
>>> print testList
['A', 'is', 'List', 'sorted', 'this']
while myList: # will stop looping when myList is empty
element = whrandom.choice(myList)
myList.remove(element)
print element,
** Page 248 *******************************************************************
class Stack:
def __init__(self, data):
self._data = list(data)
def push(self, item):
self._data.append(item)
def pop(self):
item = self._data[-1]
del self._data[-1]
return item
>>> thingsToDo = Stack(['write to mom', 'invite friend over', 'wash the
kid'])
>>> thingsToDo.push('do the dishes')
>>> print thingsToDo.pop()
do the dishes
>>> print thingsToDo.pop()
wash the kid
# import the UserList class from the UserList module
from UserList import UserList
# subclass the UserList class
class Stack(UserList):
push = UserList.append
def pop(self):
item = self[-1] # uses __getitem__
del self[-1]
return item
>>> thingsToDo = Stack(['write to mom', 'invite friend over', 'wash the
kid'])
>>> print thingsToDo # inherited from UserList
['write to mom', 'invite friend over', 'wash the kid']
>>> thingsToDo.pop()
'wash the kid'
>>> thingsToDo.push('change the oil')
>>> for chore in thingsToDo: # we can also iterate over the contents
... print chore # as "for .. in .." uses __getitem__
...
write to mom
invite friend over
change the oil
** Page 250 *******************************************************************
import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."
% cat countlines.py | python countlines.py
Counted 3 lines.
C:\> type countlines.py | python countlines.py
Counted 3 lines.
# Finding all lines that start with a #
import sys
for line in sys.stdin.readlines():
if line[0] == '#':
print line,
# Extracting the fourth column of a file (where columns are whitespace)
import sys, string
for line in sys.stdin.readlines():
words = string.split(line)
if len(words) >= 4:
print words[3]
# or...
try:
print words[3]
except IndexError: # there aren't enough words
pass
# Extracting the fourth column of a file,
# where columns are separated by colons, and lowercasing it
import sys, string
for line in sys.stdin.readlines():
words = string.split(line, ':')
if len(words) >= 4:
print string.lower(words[3])
# Printing the first 10 lines, the last 10 lines, and every other line
import sys, string
lines = sys.stdin.readlines()
sys.stdout.writelines(lines[:10]) # first ten lines
sys.stdout.writelines(lines[-10:]) # last ten lines
for lineIndex in range(0, len(lines), 2): # get 0, 2, 4, ...
sys.stdout.write(lines[lineIndex]) # get the indexed line
# Counting the number of times the word "Python" occurs in a file
import string
text = open(fname).read()
print string.count(text, 'Python')
# Changing a list of columns into a list of rows
import sys, string
lines = sys.stdin.readlines()
wordlists = []
for line in lines:
words = string.split(line)
wordlists.append(words)
for row in range(len(wordlists[0])):
for col in range(len(wordlists)):
print wordlists[col][row] + '\t',
print
** Page 252 *******************************************************************
# read character by character
while 1:
next = sys.stdin.read(1) # read a one-character string
if not next: # or an empty string at eof
break
Process character 'next'
# read line by line
while 1:
next = sys.stdin.readline() # read a one-line string
if not next: # or an empty string at EOF
break
Process line 'next'
% python myScript.py input1.txt input2.txt input3.txt output.txt
import sys
inputfilenames, outputfilename = sys.argv[1:-1], sys.argv[-1]
for inputfilename in inputfilenames:
inputfile = open(inputfilename, "r")
do_something_with_input(inputfile)
outputfile = open(outputfilename, "w")
write_results(outputfile)
def do_something_with_input(inputfile):
for line in inputfile.readlines()
process(line)
import fileinput
for line in fileinput.input():
process(line)
# take the first argument out of sys.argv and assign it to searchterm
searchterm, sys.argv[1:] = sys.argv[1], sys.argv[2:]
for line in fileinput.input():
num_matches = string.count(line, searchterm)
if num_matches: # a nonzero count means there was a match
print "found '%s' %d times in %s on line %d." % (searchterm, num_matches,
fileinput.filename(), fileinput.filelineno())
** Page 254 *******************************************************************
import os, string
if len(sys.argv) == 1: # if no filenames are specified,
filenames = os.listdir(os.curdir) # use current dir
else: # otherwise, use files specified
filenames = sys.argv[1:] # on the command line
for filename in filenames:
if ' ' in filename:
newfilename = string.replace(filename, ' ', '_')
print "Renaming", filename, "to", newfilename, "..."
os.rename(filename, newfilename)
import sys, glob, operator
print sys.argv[1:]
sys.argv = reduce(operator.add, map(glob.glob, sys.argv))
print sys.argv[1:]
/usr/python/book$ python showglob.py *.py
['countlines.py', 'mygrep.py', 'retest.py', 'showglob.py', 'testglob.py']
['countlines.py', 'mygrep.py', 'retest.py', 'showglob.py', 'testglob.py']
C:\python\book> python showglob.py *.py
['*.py']
['countlines.py', 'mygrep.py', 'retest.py', 'showglob.py', 'testglob.py']
>>> numbers = range(30)
>>> def even(x):
... return x % 2 == 0
...
>>> print numbers
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29]
>>> print filter(even, numbers)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
import string
words = string.split(open('myfile.txt').read()) # get all the words
def at_least_ten(word):
return len(word) >= 10
longwords = filter(at_least_ten, words)
lines = open('myfile.txt').readlines()
lines = filter(None, lines) # remember, the empty string is false
** Page 258 *******************************************************************
# read input file
inputFile = open('input.txt', 'r')
import tempfile
# create temporary file
tempFile = tempfile.TemporaryFile() # we don't even need to
first_process(input = inputFile, output = tempFile) # know the filename...
# create final output file
outputFile = open('output.txt', 'w')
second_process(input = tempFile, output = outputFile)
formletter = """Dear %s,\nI'm writing to you to suggest that ...""" # etc.
myDatabase = [('Bill Clinton', 'bill@whitehouse.gov.us'),
('Bill Gates', 'bill@microsoft.com'),
('Bob', 'bob@subgenius.org')]
for name, email in myDatabase:
specificLetter = formletter % name
tempfilename = tempfile.mktemp()
tempfile = open(tempfilename, 'w')
tempfile.write(specificLetter)
tempfile.close()
os.system('/usr/bin/mail %(email)s -s "Urgent!" < %(tempfilename)s'
% vars())
os.remove(tempfilename)
** Page 259 *******************************************************************
#!/usr/bin/env python
import sys, string
entries = {}
for line in open(sys.argv[1], 'r').readlines():
left, right = string.split(line)
try:
entries[right].append(left) # extend list
except KeyError:
entries[right] = [left] # first time seen
for (right, lefts) in entries.items():
print "%04d '%s'\titems => %s" % (len(lefts), right, lefts)
# or
if entries.has_key(right): # is it already in the dictionary?
entries[right].append(left) # add to the list of current values for key
else:
entries[right] = [left] # initialize key's values list
% cat data.txt
1 one
2 one
3 two
7 three
8 two
10 one
14 three
19 three
20 three
30 three
% python collector1.py data.txt
0003 'one' items => ['1', '2', '10']
0005 'three' items => ['7', '14', '19', '20', '30']
0002 'two' items => ['3', '8']
#!/usr/bin/env python
import sys, string
def collect(file):
entries = {}
for line in file.readlines():
left, right = string.split(line)
try:
entries[right].append(left) # extend list
except KeyError:
entries[right] = [left] # first time seen
return entries
if __name__ == "__main__": # when run as a script
if len(sys.argv) == 1:
result = collect(sys.stdin) # read from stdin stream
else:
result = collect(open(sys.argv[1], 'r')) # read from passed filename
for (right, lefts) in result.items():
print "%04d '%s'\titems => %s" % (len(lefts), right, lefts)
# run as a script file
% collector2.py < data.txt
result displayed here...
# use in some other component (or interactively)
from collector2 import collect
result = collect(open("spam.txt", "r"))
process result here...
>>> from collector2 import collect
>>> from StringIO import StringIO
>>>
>>> str = StringIO("1 one\n2 one\n3 two")
>>> result = collect(str) # scans the wrapped string
>>> print result # {'one':['1','2'],'two':['3']}
** Page 262 *******************************************************************
for datafname in ['data.001', 'data.002', 'data.003']:
for parameter1 in range(1, 10):
os.system("analyzeData -in %(datafname)s -param1 %(paramter1)d" % vars())
#!/usr/bin/env python
# find files, search for tabs
import string, os
cmd = 'find . -name "*.py" -print' # find is a standard Unix tool
for file in os.popen(cmd).readlines(): # run find command
num = 1
name = file[:-1] # strip '\n'
for line in open(name).readlines(): # scan the file
pos = string.find(line, "\t")
if pos >= 0:
print name, num, pos # report tab found
print '....', line[:-1] # [:-1] strips final \n
print '....', ' '*pos + '*', '\n'
num = num+1
C:\python\book-examples> python findtabs.py
./happyfingers.py 2 0
.... for i in range(10):
.... *
./happyfingers.py 3 0
.... print "oops..."
.... *
./happyfingers.py 5 5
.... print "bad style"
.... *
if sys.platform == "win32": # on a Windows port
try:
import win32pipe
popen = win32pipe.popen
except ImportError:
raise ImportError, "The win32pipe module could not be found"
else: # else on POSIX box
import os
popen = os.popen
...And use popen in blissful platform ignorance
** Page 265 *******************************************************************
# file get_temperature.py
import urllib, urlparse, string, time
def get_temperature(country, state, city):
url = urlparse.urljoin('http://www.weather.com/weather/cities/',
string.lower(country)+'_' + \
string.lower(state) + '_' + \
string.replace(string.lower(city), ' ',
'_') + '.html')
data = urllib.urlopen(url).read()
start = string.index(data, 'current temp: ') + len('current temp: ')
stop = string.index(data, '°F', start-1)
temp = int(data[start:stop])
localtime = time.asctime(time.localtime(time.time()))
print ("On %(localtime)s, the temperature in %(city)s, " +\
"%(state)s %(country)s is %(temp)s F.") % vars()
get_temperature('FR', '', 'Paris')
get_temperature('US', 'RI', 'Providence')
get_temperature('US', 'CA', 'San Francisco')
~/book:> python get_temperature.py
On Wed Nov 25 16:22:25 1998, the temperature in Paris, FR is 39 F.
On Wed Nov 25 16:22:30 1998, the temperature in Providence, RI US is 39 F.
On Wed Nov 25 16:22:35 1998, the temperature in San Francisco, CA US is 58 F.
** Page 266 *******************************************************************
>>> from poplib import *
>>> server = POP3('mailserver.spam.org')
>>> print server.getwelcome()
+OK QUALCOMM Pop server derived from UCB (version 2.1.4-R3) at spam starting.
>>> server.user('da')
'+OK Password required for da.'
>>> server.pass_('youllneverguess')
'+OK da has 153 message(s) (458167 octets).'
>>> header, msg, octets = server.retr(152) # let's get the latest msgs
>>> import string
>>> print string.join(msg[:3], '\n') # and look at the first three lines
Return-Path:
Received: from gator.bigbad.com by mailserver.spam.org (4.1/SMI-4.1)
id AA29605; Wed, 25 Nov 98 15:59:24 PST
** Page 267 *******************************************************************
# file interest.py
trace = 1 # print each year?
def calc(principal, interest, years):
for y in range(years):
principal = principal * (1.00 + (interest / 100.0))
if trace: print y+1, '=> %.2f' % principal
return principal
% python
>>> from interest import calc
>>> calc(65000, 5.5, 10)
1 => 68575.00
2 => 72346.63
3 => 76325.69
4 => 80523.60
5 => 84952.40
6 => 89624.78
7 => 94554.15
8 => 99754.62
9 => 105241.13
10 => 111029.39
111029.389793
>>> import interest
>>> interest.trace = 0
>>> calc(65000, 5.5, 10)
111029.389793
def calc(principal, interest, years):
interest = interest / 100.0
for y in range(years):
earnings = principal * interest
principal = principal + earnings
if trace: print y+1, '(+%d)' % earnings, '=> %.2f' % principal
return principal
>>> interest.trace = 1
>>> calc(65000, 5.5, 10)
1 (+3575) => 68575.00
2 (+3771) => 72346.63
3 (+3979) => 76325.69
4 (+4197) => 80523.60
5 (+4428) => 84952.40
6 (+4672) => 89624.78
7 (+4929) => 94554.15
8 (+5200) => 99754.62
9 (+5486) => 105241.13
10 (+5788) => 111029.39
111029.389793
** Page 269 *******************************************************************
#!/usr/bin/env python
# find a free modem to dial out on
import glob, os, string
LOCKS = "/var/spool/locks/"
locked = [0] * 10
for lockname in glob.glob(LOCKS + "LCK*modem*"): # find locked modems
print "Found lock:", lockname
locked[string.atoi(lockname[-1])] = 1 # 0..9 at end of name
print 'free: ',
for i in range(10): # report, dial-out
if not locked[i]: print i,
print
for i in range(10):
if not locked[i]:
if raw_input("Try %d? " % i) == 'y':
os.system("kermit -m hayes -l /dev/modem%d -b 19200 -S" % i)
if raw_input("More? ") != 'y': break
** Page 270 *******************************************************************
# file rolo.py
#!/usr/bin/env python
# An interactive rolodex
import string, sys, pickle, cmd
class Rolodex(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self) # initialize the base class
self.prompt = "Monty's Friends: " # customize the prompt
self.people = {} # at first, we know nobody
def help_add(self):
print "Adds an entry (specify a name)"
def do_add(self, name):
if name == "": name = raw_input("Enter Name: ")
phone = raw_input("Enter Phone Number for "+ name+": ")
self.people[name] = phone # add phone number for name
def help_find(self):
print "Find an entry (specify a name)"
def do_find(self, name):
if name == "": name = raw_input("Enter Name: ")
if self.people.has_key(name):
print "The number for %s is %s." % (name, self.people[name])
else:
print "We have no record for %s." % (name,)
def help_list(self):
print "Prints the contents of the directory"
def do_list(self, line):
names = self.people.keys() # the keys are the names
if names == []: return # if there are no names, exit
names.sort() # we want them in alphabetic order
print '='*41
for name in names:
print string.rjust(name, 20), ":", string.ljust(self.people[name], 20)
print '='*41
def help_EOF(self):
print "Quits the program"
def do_EOF(self, line):
sys.exit()
def help_save(self):
print "save the current state of affairs"
def do_save(self, filename):
if filename == "": filename = raw_input("Enter filename: ")
saveFile = open(filename, 'w')
pickle.dump(self.people, saveFile)
def help_load(self):
print "load a directory"
def do_load(self, filename):
if filename == "": filename = raw_input("Enter filename: ")
saveFile = open(filename, 'r')
self.people = pickle.load(saveFile) # note that this will override
# any existing people directory
if __name__ == '__main__': # this way the module can be
rolo = Rolodex() # imported by other programs as well
rolo.cmdloop()
% python rolo.py
Monty's Friends: help
Documented commands (type help ):
========================================
EOF add find list load
save
Undocumented commands:
======================
help
lpython/dos/examples/chapter10.txt 001777 000000 000000 00000041534 06713512744 013205 ** Page 276 *******************************************************************
# file feedback.py (CGI)
import cgi, os, sys, string
def gush(data):
print "Content-type: text/html\n"
print "
Thanks, %(name)s!
" % vars(data)
print "Our customer's comments are always appreciated."
print "They drive our business directions, as well as"
print "help us with our karma."
print "
Thanks again for the feedback!
"
print "And feel free to enter more comments if you wish."
print "
" % vars(data)
print "We're very sorry to read that you had a complaint"
print "regarding our product__We'll read your comments"
print "carefully and will be in touch with you."
print "
Nevertheless, thanks for the feedback.
"
print "
"+10*" "+"--Joe."
def bail():
print "
Error filling out form
"
print "Please fill in all the fields in the form.
"
print ''
print 'Go back to the form'
sys.exit()
class FormData:
""" A repository for information gleaned from a CGI form """
def __init__(self, formdict):
for fieldname in self.fieldnames:
if not form.has_key(fieldname) or form[fieldname].value == "":
bail()
else:
setattr(self, fieldname, form[fieldname].value)
class FeedbackData(FormData):
""" A FormData generated by the comment.html form. """
fieldnames = ('name', 'address', 'email', 'type', 'text')
def __repr__(self):
return "%(type)s from %(name)s on %(time)s" % vars(self)
DIRECTORY = r'C:\complaintdir'
if __name__ == '__main__':
sys.stderr = sys.stdout
form = cgi.FieldStorage()
data = FeedbackData(form)
if data.type == 'comment':
gush(data)
else:
whimper(data)
# save the data to file
import tempfile, pickle, time
tempfile.tempdir = DIRECTORY
data.time = time.asctime(time.localtime(time.time()))
pickle.dump(data, open(tempfile.mktemp(), 'w'))
# html file excerpt
# similar code snippet
form = cgi.FieldStorage()
form_ok = 1
if not form.has_key("name") or form["name"].value == "":
form_ok = 0
else:
data_name = form["name"].value
if not form.has_key("email") or form["email"].value == "":
form_ok = 0
else:
data_email = form["email"].value
...
** Page 283 *******************************************************************
# file formletter.py (COM)
from win32com.client import constants, Dispatch
WORD = 'Word.Application.8'
False, True = 0, -1
import string
class Word:
def __init__(self):
self.app = Dispatch(WORD)
def open(self, doc):
self.app.Documents.Open(FileName=doc)
def replace(self, source, target):
self.app.Selection.HomeKey(Unit=constants.wdLine)
find = self.app.Selection.Find
find.Text = "%"+source+"%"
self.app.Selection.Find.Execute()
self.app.Selection.TypeText(Text=target)
def printdoc(self):
self.app.Application.PrintOut()
def close(self):
self.app.ActiveDocument.Close(SaveChanges=False)
def print_formletter(data):
word.open(r"h:\David\Book\tofutemplate.doc")
word.replace("name", data.name)
word.replace("address", data.address)
word.replace("firstname", string.split(data.name)[0])
word.printdoc()
word.close()
if __name__ == '__main__':
import os, pickle
from feedback import DIRECTORY, FormData, FeedbackData
word = Word()
for filename in os.listdir(DIRECTORY):
data = pickle.load(open(os.path.join(DIRECTORY, filename)))
if data.type == 'complaint':
print "Printing letter for %(name)s." % vars(data)
print_formletter(data)
else:
print "Got comment from %(name)s, skipping printing." % vars(data)
# program run
C:\Programs> python formletter.py
Printing letter for John Doe.
Got comment from Your Mom, skipping printing.
Printing letter for Susan B. Anthony.
** Page 288 *******************************************************************
# file feedbackeditor.py (Tkinter)
from FormEditor import FormEditor
from feedback import FeedbackData, FormData
from Tkinter import mainloop
FormEditor("Feedback Editor", FeedbackData, r"c:\Complaintdir")
mainloop()
# file FormEditor
from Tkinter import *
import string, os, pickle
class FormEditor:
def __init__(self, name, dataclass, storagedir):
self.storagedir = storagedir # stash away some references
self.dataclass = dataclass
self.row = 0
self.current = None
self.root = root = Tk() # create window and size it
root.minsize(300,200)
root.rowconfigure(0, weight=1) # define how columns and rows scale
root.columnconfigure(0, weight=1) # when the window is resized
root.columnconfigure(1, weight=2)
# create the title Label
Label(root, text=name, font='bold').grid(columnspan=2)
self.row = self.row + 1
# create the main listbox and configure it
self.listbox = Listbox(root, selectmode=SINGLE)
self.listbox.grid(columnspan=2,sticky=E+W+N+S)
self.listbox.bind('', self.select)
self.row = self.row + 1
# call self.add_variable once per variable in the class's fieldnames var
for fieldname in dataclass.fieldnames:
setattr(self, fieldname, self.add_variable(root, fieldname))
# create a couple of buttons, with assigned commands
self.add_button(self.root, self.row, 0, 'Delete Entry', self.delentry)
self.add_button(self.root, self.row, 1, 'Reload', self.load_data)
self.load_data()
def add_variable(self, root, varname):
Label(root, text=varname).grid(row=self.row, column=0, sticky=E)
value = Label(root, text='', background='gray90',
relief=SUNKEN, anchor=W, justify=LEFT)
value.grid(row=self.row, column=1, sticky=E+W)
self.row = self.row + 1
return value
def add_button(self, root, row, column, text, command):
button = Button(root, text=text, command=command)
button.grid(row=row, column=column, sticky=E+W, padx=5, pady=5)
def load_data(self):
self.listbox.delete(0,END)
self.items = []
for filename in os.listdir(self.storagedir):
item = pickle.load(open(os.path.join(self.storagedir, filename)))
item._filename = filename
self.items.append(item)
self.listbox.insert('end', `item`)
self.listbox.select_set(0)
self.select(None)
def select(self, event):
selection = self.listbox.curselection()
self.selection = self.items[int(selection[0])]
for fieldname in self.dataclass.fieldnames:
label = getattr(self, fieldname) # GUI field
labelstr = getattr(self.selection, fieldname) # instance attribute
labelstr = string.replace(labelstr,'\r'), '')
label.config(text=labelstr)
def delentry(self):
os.remove(os.path.join(self.storagedir,self.selection._filename))
self.load_data()
** Page 295 *******************************************************************
~/book> jpython
JPython 1.0.3 on java1.2beta4
Copyright 1997-1998 Corporation for National Research Initiatives
>>> 2 + 3
5
# file jpythondemo.py
from pawt import swing
import java
def exit(e): java.lang.System.exit(0)
frame = swing.JFrame('Swing Example', visible=1)
button = swing.JButton(This is a Swinging button!', actionPerformed=exit)
frame.contentPane.add(button)
frame.pack()
** Page 298 *******************************************************************
# file grapher.py (JPython)
# note: this requires a JPython that supports the
# struct module, which is used by the pickle module
from pawt import swing, awt, colors, GridBag
RIGHT = swing.JLabel.RIGHT
APPROVE_OPTION = swing.JFileChooser.APPROVE_OPTION
import java.io
import pickle, os
default_setup = """from math import *
def squarewave(x,order):
total = 0.0
for i in range(1, order*2+1, 2):
total = total + sin(x*i/10.0)/(float(i))
return total
"""
default_expression = "squarewave(x, order=3)"
class Chart(awt.Canvas):
color = colors.darkturquoise
style = 'Filled'
def getPreferredSize(self):
return awt.Dimension(600,300)
def paint(self, graphics):
clip = self.bounds
graphics.color = colors.white
graphics.fillRect(0, 0, clip.width, clip.height)
width = int(clip.width * .8)
height = int(clip.height * .8)
x_offset = int(clip.width * .1)
y_offset = clip.height - int(clip.height * .1)
N = len(self.data); xs = [0]*N; ys = [0]*N
xmin, xmax = 0, N-1
ymax = max(self.data)
ymin = min(self.data)
zero_y = y_offset - int(-ymin/(ymax-ymin)*height)
zero_x = x_offset + int(-xmin/(xmax-xmin)*width)
for i in range(N):
xs[i] = int(float(i)*width/N) + x_offset
ys[i] = y_offset - int((self.data[i]-ymin)/(ymax-ymin)*height)
graphics.color = self.color
if self.style == "Line":
graphics.drawPolyline(xs, ys, len(xs))
else:
xs.insert(0, xs[0]); ys.insert(0, zero_y)
xs.append(xs[-1]); ys.append(zero_y)
graphics.fillPolygon(xs, ys, len(xs))
# draw axes
graphics.color = colors.black
graphics.drawLine(x_offset,zero_y, x_offset+width, zero_y)
graphics.drawLine(zero_x, y_offset, zero_x, y_offset-height)
# draw labels
leading = graphics.font.size
graphics.drawString("%.3f" % xmin, x_offset, zero_y+leading)
graphics.drawString("%.3f" % xmax, x_offset+width, zero_y+leading)
graphics.drawString("%.3f" % ymin, zero_x-50, y_offset)
graphics.drawString("%.3f" % ymax, zero_x-50, y_offset-height+leading)
class GUI:
def __init__(self):
self.numelements = 100
self.frame = swing.JFrame(windowClosing=self.do_quit)
# build menu bar
menubar = swing.JMenuBar()
file = swing.JMenu("File")
file.add(swing.JMenuItem("Load", actionPerformed = self.do_load))
file.add(swing.JMenuItem("Save", actionPerformed = self.do_save))
file.add(swing.JMenuItem("Quit", actionPerformed = self.do_quit))
menubar.add(file)
self.frame.JMenuBar = menubar
# create widgets
self.chart = Chart(visible=1)
self.execentry = swing.JTextArea(default_setup, 8, 60)
self.evalentry = swing.JTextField(default_expression,
actionPerformed = self.update)
# create options panel
optionsPanel = swing.JPanel(awt.FlowLayout(
alignment=awt.FlowLayout.LEFT))
# whether the plot is a line graph or a filled graph
self.filled = swing.JRadioButton("Filled",
actionPerformed=self.set_filled)
optionsPanel.add(self.filled)
self.line = swing.JRadioButton("Line",
actionPerformed=self.set_line)
optionsPanel.add(self.line)
styleGroup = swing.ButtonGroup()
styleGroup.add(self.filled)
styleGroup.add(self.line)
# color selection
optionsPanel.add(swing.JLabel("Color:", RIGHT))
colors = filter(lambda x: x[0] != '_', dir(colors))
self.colorname = swing.JComboBox(colors)
self.colorname.itemStateChanged = self.set_color
optionsPanel.add(self.colorname)
# number of points
optionsPanel.add(swing.JLabel("Number of Points:", RIGHT))
self.sizes = [50, 100, 200, 500]
self.numpoints = swing.JComboBox(self.sizes)
self.numpoints.selectedIndex = self.sizes.index(self.numelements)
self.numpoints.itemStateChanged = self.set_numpoints
optionsPanel.add(self.numpoints)
# do the rest of the layout in a GridBag
self.do_layout(optionsPanel)
def do_layout(self, optionsPanel):
bag = GridBag(self.frame.contentPane, fill='BOTH',
weightx=1.0, weighty=1.0)
bag.add(swing.JLabel("Setup Code: ", RIGHT))
bag.addRow(swing.JScrollPane(self.execentry), weighty=10.0)
bag.add(swing.JLabel("Expression: ", RIGHT))
bag.addRow(self.evalentry, weighty=2.0)
bag.add(swing.JLabel("Output: ", RIGHT))
bag.addRow(self.chart, weighty=20.0)
bag.add(swing.JLabel("Options: ", RIGHT))
bag.addRow(optionsPanel, weighty=2.0)
self.update(None)
self.frame.visible = 1
self.frame.size = self.frame.getPreferredSize()
self.chooser = swing.JFileChooser()
self.chooser.currentDirectory = java.io.File(os.getcwd())
def do_save(self, event=None):
self.chooser.rescanCurrentDirectory()
returnVal = self.chooser.showSaveDialog(self.frame)
if returnVal == APPROVE_OPTION:
object = (self.execentry.text, self.evalentry.text,
self.chart.style,
self.chart.color.RGB,
self.colorname.selectedIndex,
self.numelements)
file = open(os.path.join(self.chooser.currentDirectory.path,
self.chooser.selectedFile.name), 'w')
pickle.dump(object, file)
file.close()
def do_load(self, event=None):
self.chooser.rescanCurrentDirectory()
returnVal = self.chooser.showOpenDialog(self.frame)
if returnVal == APPROVE_OPTION:
file = open(os.path.join(self.chooser.currentDirectory.path,
self.chooser.selectedFile.name))
(setup, each, style, color,
colorname, self.numelements) = pickle.load(file)
file.close()
self.chart.color = java.awt.Color(color)
self.colorname.selectedIndex = colorname
self.chart.style = style
self.execentry.text = setup
self.numpoints.selectedIndex = self.sizes.index(self.numelements)
self.evalentry.text = each
self.update(None)
def do_quit(self, event=None):
import sys
sys.exit(0)
def set_color(self, event):
self.chart.color = getattr(colors, event.item)
self.chart.repaint()
def set_numpoints(self, event):
self.numelements = event.item
self.update(None)
def set_filled(self, event):
self.chart.style = 'Filled'
self.chart.repaint()
def set_line(self, event):
self.chart.style = 'Line'
self.chart.repaint()
def update(self, event):
context = {}
exec self.execentry.text in context
each = compile(self.evalentry.text, '', 'eval')
numbers = [0]*self.numelements
for x in range(self.numelements):
context['x'] = float(x)
numbers[x] = eval(each, context)
self.chart.data = numbers
if self.chart.style == 'Line':
self.line.setSelected(1)
else:
self.filled.setSelected(1)
self.chart.repaint()
GUI()
** Page 303 *******************************************************************
from Numeric import *
coords = arange(-6, 6, .02) # create a range of coordinates
xs = sin(coords) # take the sine of all of the x's
ys = cos(coords)*exp(-coords*coords/18.0) # take a complex function of the y's
zx = xs * ys[:,NewAxis] # multiply the x row with the y column